소스 검색

Merge branch 'master' of https://github.com/hakimel/reveal.js

Conflicts:
	README.md
	index.html
	js/reveal.js
	package.json
	plugin/speakernotes/client.js
David Banham 11 년 전
부모
커밋
61c229a4f9
50개의 변경된 파일4076개의 추가작업 그리고 2033개의 파일을 삭제
  1. 1 0
      .gitignore
  2. 5 0
      .travis.yml
  3. 82 0
      Gruntfile.js
  4. 1 1
      LICENSE
  5. 2 3
      README.md
  6. 42 33
      css/print/paper.css
  7. 164 0
      css/print/pdf.css
  8. 0 57
      css/reset.css
  9. 34 25
      css/reveal.css
  10. 6 0
      css/reveal.min.css
  11. 25 0
      css/theme/README.md
  12. 163 0
      css/theme/beige.css
  13. 163 0
      css/theme/default.css
  14. 150 0
      css/theme/night.css
  15. 150 0
      css/theme/serif.css
  16. 152 0
      css/theme/simple.css
  17. 156 0
      css/theme/sky.css
  18. 50 0
      css/theme/source/beige.scss
  19. 42 0
      css/theme/source/default.scss
  20. 35 0
      css/theme/source/night.scss
  21. 33 0
      css/theme/source/serif.scss
  22. 38 0
      css/theme/source/simple.scss
  23. 41 0
      css/theme/source/sky.scss
  24. 29 0
      css/theme/template/mixins.scss
  25. 33 0
      css/theme/template/settings.scss
  26. 163 0
      css/theme/template/theme.scss
  27. 188 169
      index.html
  28. 904 334
      js/reveal.js
  29. 7 0
      js/reveal.min.js
  30. 19 0
      lib/font/league_gothic-webfont.svg
  31. BIN
      lib/font/league_gothic-webfont.woff
  32. 0 27
      lib/js/data-markdown.js
  33. 0 4
      lib/js/highlight.js
  34. 0 1341
      lib/js/showdown.js
  35. 21 17
      package.json
  36. 8 0
      plugin/highlight/highlight.js
  37. 97 0
      plugin/markdown/example.html
  38. 29 0
      plugin/markdown/example.md
  39. 147 0
      plugin/markdown/markdown.js
  40. 61 0
      plugin/markdown/showdown.js
  41. 24 2
      plugin/notes-server/client.js
  42. 8 5
      plugin/notes-server/index.js
  43. 45 15
      plugin/notes-server/notes.html
  44. 252 0
      plugin/notes/notes.html
  45. 100 0
      plugin/notes/notes.js
  46. 39 0
      plugin/postmessage/example.html
  47. 42 0
      plugin/postmessage/postmessage.js
  48. 39 0
      plugin/print-pdf/print-pdf.js
  49. 30 0
      plugin/remotes/remotes.js
  50. 256 0
      plugin/zoom-js/zoom.js

+ 1 - 0
.gitignore

@@ -3,3 +3,4 @@
 log/*.log
 log/*.log
 tmp/**
 tmp/**
 node_modules/
 node_modules/
+.sass-cache

+ 5 - 0
.travis.yml

@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+  - 0.8
+before_script:
+  - npm install -g grunt-cli

+ 82 - 0
Gruntfile.js

@@ -0,0 +1,82 @@
+/* global module:false */
+module.exports = function(grunt) {
+
+	// Project configuration
+	grunt.initConfig({
+		pkg: grunt.file.readJSON('package.json'),
+		meta: {
+			banner:
+				'/*!\n' +
+				' * reveal.js <%= pkg.version %> (<%= grunt.template.today("yyyy-mm-dd, HH:MM") %>)\n' +
+				' * http://lab.hakim.se/reveal-js\n' +
+				' * MIT licensed\n' +
+				' *\n' +
+				' * Copyright (C) 2013 Hakim El Hattab, http://hakim.se\n' +
+				' */'
+		},
+
+		jshint: {
+			files: [ 'Gruntfile.js', 'js/reveal.js' ]
+		},
+
+		// Tests will be added soon
+		qunit: {
+			files: [ 'test/**/*.html' ]
+		},
+
+		uglify: {
+			options: {
+				banner: '<%= meta.banner %>\n'
+			},
+			build: {
+				src: 'js/reveal.js',
+				dest: 'js/reveal.min.js'
+			}
+		},
+
+		cssmin: {
+			compress: {
+				files: {
+					'css/reveal.min.css': [ 'css/reveal.css' ]
+				}
+			}
+		},
+
+		jshint: {
+			options: {
+				curly: false,
+				eqeqeq: true,
+				immed: true,
+				latedef: true,
+				newcap: true,
+				noarg: true,
+				sub: true,
+				undef: true,
+				eqnull: true,
+				browser: true,
+				expr: true
+			},
+			globals: {
+				head: false,
+				module: false,
+				console: false
+			}
+		},
+
+		watch: {
+			files: [ 'Gruntfile.js', 'js/reveal.js', 'css/reveal.css' ],
+			tasks: 'default'
+		}
+
+	});
+
+	// Dependencies
+	grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+	grunt.loadNpmTasks( 'grunt-contrib-cssmin' );
+	grunt.loadNpmTasks( 'grunt-contrib-uglify' );
+	grunt.loadNpmTasks( 'grunt-contrib-watch' );
+
+	// Default task
+	grunt.registerTask( 'default', [ 'jshint', 'cssmin', 'uglify' ] );
+
+};

+ 1 - 1
LICENSE

@@ -1,4 +1,4 @@
-Copyright (C) 2012 Hakim El Hattab, http://hakim.se
+Copyright (C) 2013 Hakim El Hattab, http://hakim.se
 
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
 of this software and associated documentation files (the "Software"), to deal

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 2 - 3
README.md


+ 42 - 33
css/print.css → css/print/paper.css

@@ -11,7 +11,7 @@
    beyond the edge of the printed page, and prevents
    beyond the edge of the printed page, and prevents
    unnecessary background images from printing */
    unnecessary background images from printing */
 body {
 body {
-	background: #fff url(none);
+	background: #fff;
 	font-size: 13pt;
 	font-size: 13pt;
 	width: auto;
 	width: auto;
 	height: auto;
 	height: auto;
@@ -31,16 +31,19 @@ html {
 /* SECTION 2: Remove any elements not needed in print. 
 /* SECTION 2: Remove any elements not needed in print. 
    This would include navigation, ads, sidebars, etc. */
    This would include navigation, ads, sidebars, etc. */
 .nestedarrow, 
 .nestedarrow, 
-.controls a, 
-.reveal .progress span, 
-.reveal.overview {
-	display:none;
+.controls, 
+.reveal .progress, 
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
 }
 }
 
 
 /* SECTION 3: Set body font face, size, and color.
 /* SECTION 3: Set body font face, size, and color.
    Consider using a serif font for readability. */
    Consider using a serif font for readability. */
 body, p, td, li, div, a {
 body, p, td, li, div, a {
-	font-size: 13pt;
+	font-size: 16pt!important;
 	font-family: Georgia, "Times New Roman", Times, serif !important;
 	font-family: Georgia, "Times New Roman", Times, serif !important;
 	color: #000; 
 	color: #000; 
 }
 }
@@ -74,12 +77,14 @@ a:visited {
 	font-weight: bold;
 	font-weight: bold;
 	text-decoration: underline;
 	text-decoration: underline;
 }
 }
+/*
 .reveal a:link:after, 
 .reveal a:link:after, 
 .reveal a:visited:after {
 .reveal a:visited:after {
 	content: " (" attr(href) ") ";
 	content: " (" attr(href) ") ";
 	color: #222 !important;
 	color: #222 !important;
 	font-size: 90%;
 	font-size: 90%;
 }
 }
+*/
 
 
 
 
 /* SECTION 6: more reveal.js specific additions by @skypanther */
 /* SECTION 6: more reveal.js specific additions by @skypanther */
@@ -118,45 +123,49 @@ ul, ol, div, p {
 	    -ms-perspective-origin: 50% 50%;
 	    -ms-perspective-origin: 50% 50%;
 	        perspective-origin: 50% 50%;
 	        perspective-origin: 50% 50%;
 }
 }
-.reveal .slides>section, .reveal .slides>section>section, 
-.reveal .slides>section.past, .reveal .slides>section.future,
-.reveal.linear .slides>section, .reveal.linear .slides>section>section,
-.reveal.linear .slides>section.past, .reveal.linear .slides>section.future {
+.reveal .slides>section, 
+.reveal .slides>section>section {
 	
 	
-	visibility: visible;
-	position: static;
-	width: 90%;
-	height: auto;
-	display: block;
-	overflow: visible;
+	visibility: visible !important;
+	position: static !important;
+	width: 90% !important;
+	height: auto !important;
+	display: block !important;
+	overflow: visible !important;
 
 
-	left: 0%;
-	top: 0%;
-	margin-left: 0px;
-	margin-top: 0px;
-	padding: 20px 0px;
+	left: 0% !important;
+	top: 0% !important;
+	margin-left: 0px !important;
+	margin-top: 0px !important;
+	padding: 20px 0px !important;
 
 
-	opacity: 1;
+	opacity: 1 !important;
 
 
-	-webkit-transform-style: flat;
-	   -moz-transform-style: flat;
-	    -ms-transform-style: flat;
-	        transform-style: flat;
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
 
 
-	-webkit-transform: none;
-	   -moz-transform: none;
-	    -ms-transform: none;
-	        transform: none;
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
 }
 }
 .reveal section {
 .reveal section {
 	page-break-after: always !important; 
 	page-break-after: always !important; 
 	display: block !important;
 	display: block !important;
 }
 }
-.reveal section.stack {
-	page-break-after: avoid !important; 
-}
 .reveal section .fragment {
 .reveal section .fragment {
 	opacity: 1 !important;
 	opacity: 1 !important;
+	visibility: visible !important;
+	
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section:last-of-type {
+	page-break-after: avoid !important; 
 }
 }
 .reveal section img {
 .reveal section img {
 	display: block;
 	display: block;

+ 164 - 0
css/print/pdf.css

@@ -0,0 +1,164 @@
+/* Default Print Stylesheet Template
+   by Rob Glazebrook of CSSnewbie.com
+   Last Updated: June 4, 2008
+
+   Feel free (nay, compelled) to edit, append, and
+   manipulate this file as you see fit. */
+
+
+/* SECTION 1: Set default width, margin, float, and
+   background. This prevents elements from extending
+   beyond the edge of the printed page, and prevents
+   unnecessary background images from printing */
+
+* {
+	-webkit-print-color-adjust: exact;
+}
+
+body {
+	font-size: 18pt;
+	width: auto;
+	height: auto;
+	border: 0;
+	padding: 0;
+	float: none !important;
+	overflow: visible;
+}
+
+html {
+	width: 100%;
+	height: 100%;
+	overflow: visible;
+}
+
+@page {
+	size: letter landscape;
+	margin: 0;
+}
+
+/* SECTION 2: Remove any elements not needed in print.
+   This would include navigation, ads, sidebars, etc. */
+.nestedarrow,
+.controls,
+.reveal .progress,
+.reveal.overview,
+.fork-reveal,
+.share-reveal,
+.state-background {
+	display: none !important;
+}
+
+/* SECTION 3: Set body font face, size, and color.
+   Consider using a serif font for readability. */
+body, p, td, li, div {
+	font-size: 18pt;
+}
+
+/* SECTION 4: Set heading font face, sizes, and color.
+   Diffrentiate your headings from your body text.
+   Perhaps use a large sans-serif for distinction. */
+h1,h2,h3,h4,h5,h6 {
+	text-shadow: 0 0 0 #000 !important;
+}
+
+/* SECTION 5: Make hyperlinks more usable.
+   Ensure links are underlined, and consider appending
+   the URL to the end of the link for usability. */
+a:link,
+a:visited {
+	font-weight: bold;
+	text-decoration: underline;
+}
+
+
+/* SECTION 6: more reveal.js specific additions by @skypanther */
+ul, ol, div, p {
+	visibility: visible;
+	position: static;
+	width: auto;
+	height: auto;
+	display: block;
+	overflow: visible;
+	margin: auto;
+}
+.reveal .slides {
+	position: static;
+	width: 100%;
+	height: auto;
+
+	left: auto;
+	top: auto;
+	margin-left: auto;
+	margin-right: auto;
+	margin-top: auto;
+	padding: auto;
+
+	overflow: visible;
+	display: block;
+
+	text-align: center;
+
+	-webkit-perspective: none;
+	   -moz-perspective: none;
+	    -ms-perspective: none;
+	        perspective: none;
+
+	-webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */
+	   -moz-perspective-origin: 50% 50%;
+	    -ms-perspective-origin: 50% 50%;
+	        perspective-origin: 50% 50%;
+}
+.reveal .slides section {
+
+	page-break-after: always !important;
+
+	visibility: visible !important;
+	position: static !important;
+	width: 100% !important;
+	height: auto !important;
+	min-height: initial !important;
+	display: block !important;
+	overflow: visible !important;
+
+	left: 0 !important;
+	top: 0 !important;
+	margin-left: 0px !important;
+	margin-top: 50px !important;
+	padding: 20px 0px !important;
+
+	opacity: 1 !important;
+
+	-webkit-transform-style: flat !important;
+	   -moz-transform-style: flat !important;
+	    -ms-transform-style: flat !important;
+	        transform-style: flat !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal section.stack {
+	margin: 0px !important;
+	padding: 0px !important;
+	page-break-after: avoid !important;
+}
+.reveal section .fragment {
+	opacity: 1 !important;
+	visibility: visible !important;
+
+	-webkit-transform: none !important;
+	   -moz-transform: none !important;
+	    -ms-transform: none !important;
+	        transform: none !important;
+}
+.reveal img {
+	box-shadow: none;
+}
+.reveal .roll {
+	overflow: visible;
+	line-height: 1em;
+}
+.reveal small a {
+	font-size: 16pt !important;
+}

+ 0 - 57
css/reset.css

@@ -1,57 +0,0 @@
-/* http://meyerweb.com/eric/tools/css/reset/ 
-   v2.0 | 20110126
-   License: none (public domain)
-*/
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed, 
-figure, figcaption, footer, header, hgroup, 
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
-	margin: 0;
-	padding: 0;
-	border: 0;
-	font-size: 100%;
-	font: inherit;
-	vertical-align: baseline;
-}
-/* HTML5 display-role reset for older browsers */
-article, aside, details, figcaption, figure, 
-footer, header, hgroup, menu, nav, section {
-	display: block;
-}
-body {
-	line-height: 1;
-}
-ol, ul {
-	list-style: none;
-}
-blockquote, q {
-	quotes: none;
-}
-blockquote:before, blockquote:after,
-q:before, q:after {
-	content: '';
-	content: none;
-}
-table {
-	border-collapse: collapse;
-	border-spacing: 0;
-}
-
-
-/* HTML5BP:
-   These selection declarations have to be separate.
-   No text-shadow: twitter.com/miketaylr/status/12228805301
-   Also: hot pink. */
-::-moz-selection{ background: #FF5E99; color:#fff; text-shadow: none; }
-::selection { background:#FF5E99; color:#fff; text-shadow: none; }
-

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 34 - 25
css/reveal.css


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 6 - 0
css/reveal.min.css


+ 25 - 0
css/theme/README.md

@@ -0,0 +1,25 @@
+## Dependencies
+
+Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Find out how to install Sass here http://sass-lang.com/, once Sass is installed run the follwing command to start monitoring the source files for changes.
+
+```
+sass --watch css/theme/source/:css/theme --style expanded
+```
+
+
+
+## Creating a Theme
+
+To create your own theme, start by duplicating any ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). Each theme does four things in the following order:
+
+1. **Include [/css/theme/template/mixins.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/mixins.scss)**  
+Shared utility functions.
+
+2. **Include [/css/theme/template/settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss)**  
+Declares a set of custom variables that the template file (step 4) expects. Can be overridden in step 3.
+
+3. **Override**  
+This is where you override the default theme. Either by specifying variables (see [settings.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/settings.scss) for reference) or by adding full selectors with hardcoded styles.
+
+4. **Include [/css/theme/template/theme.scss](https://github.com/hakimel/reveal.js/blob/master/css/theme/template/theme.scss)**  
+The template theme file which will generate final CSS output based on the currently defined variables.

+ 163 - 0
css/theme/beige.css

@@ -0,0 +1,163 @@
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Beige theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f7f2d3;
+  background: -moz-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, white), color-stop(100%, #f7f2d3));
+  background: -webkit-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -o-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: -ms-radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background: radial-gradient(center, circle cover, white 0%, #f7f2d3 100%);
+  background-color: #f7f3de;
+}
+
+.reveal {
+  font-family: "Lato", Times, "Times New Roman", serif;
+  font-size: 36px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: #333333;
+}
+
+::selection {
+  color: white;
+  background: rgba(79, 64, 28, 0.99);
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: none;
+}
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #8b743d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #c0a86e;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #564826;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #8b743d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #8b743d;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #8b743d;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #8b743d;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #8b743d;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #c0a86e;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #c0a86e;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #c0a86e;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #c0a86e;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: #8b743d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 163 - 0
css/theme/default.css

@@ -0,0 +1,163 @@
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * Default theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+@font-face {
+  font-family: 'League Gothic';
+  src: url("../../lib/font/league_gothic-webfont.eot");
+  src: url("../../lib/font/league_gothic-webfont.eot?#iefix") format("embedded-opentype"), url("../../lib/font/league_gothic-webfont.woff") format("woff"), url("../../lib/font/league_gothic-webfont.ttf") format("truetype"), url("../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular") format("svg");
+  font-weight: normal;
+  font-style: normal;
+}
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #1c1e20;
+  background: -moz-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #555a5f), color-stop(100%, #1c1e20));
+  background: -webkit-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -o-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: -ms-radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background: radial-gradient(center, circle cover, #555a5f 0%, #1c1e20 100%);
+  background-color: #2b2b2b;
+}
+
+.reveal {
+  font-family: "Lato", Times, "Times New Roman", serif;
+  font-size: 36px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: #eeeeee;
+}
+
+::selection {
+  color: white;
+  background: #ff5e99;
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "League Gothic", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: uppercase;
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+}
+
+.reveal h1 {
+  text-shadow: 0 1px 0 #cccccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbbbbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaaaaa, 0 6px 1px rgba(0, 0, 0, 0.1), 0 0 5px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2), 0 5px 10px rgba(0, 0, 0, 0.25), 0 20px 20px rgba(0, 0, 0, 0.15);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #13daec;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #71e9f4;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #0d99a5;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #13daec;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #13daec;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #13daec;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #13daec;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #13daec;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #71e9f4;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #71e9f4;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #71e9f4;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #71e9f4;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: #13daec;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 150 - 0
css/theme/night.css

@@ -0,0 +1,150 @@
+@import url(http://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+/**
+ * Black theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #111111;
+  background-color: #111111;
+}
+
+.reveal {
+  font-family: "Open Sans", Times, "Times New Roman", serif;
+  font-size: 30px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: #eeeeee;
+}
+
+::selection {
+  color: white;
+  background: #e7ad52;
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #eeeeee;
+  font-family: "Montserrat", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.03em;
+  text-transform: none;
+  text-shadow: none;
+}
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #e7ad52;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #f3d7ac;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #d08a1d;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #eeeeee;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #e7ad52;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #e7ad52;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #e7ad52;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #e7ad52;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #e7ad52;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #f3d7ac;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #f3d7ac;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #f3d7ac;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #f3d7ac;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: #e7ad52;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 150 - 0
css/theme/serif.css

@@ -0,0 +1,150 @@
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se; so is the theme - beige.css - that this is based off of.
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #f0f1eb;
+  background-color: #f0f1eb;
+}
+
+.reveal {
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  font-size: 36px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: black;
+}
+
+::selection {
+  color: white;
+  background: #26351c;
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #383d3d;
+  font-family: "Palatino Linotype", "Book Antiqua", Palatino, FreeSerif, serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none;
+}
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #51483d;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #8b7c69;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #25211c;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #51483d;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #51483d;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #51483d;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #51483d;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #51483d;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #8b7c69;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #8b7c69;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #8b7c69;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #8b7c69;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: #51483d;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 152 - 0
css/theme/simple.css

@@ -0,0 +1,152 @@
+@import url(http://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: white;
+  background-color: white;
+}
+
+.reveal {
+  font-family: "Lato", Times, "Times New Roman", serif;
+  font-size: 36px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: black;
+}
+
+::selection {
+  color: white;
+  background: rgba(0, 0, 0, 0.99);
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: black;
+  font-family: "News Cycle", Impact, sans-serif;
+  line-height: 0.9em;
+  letter-spacing: 0.02em;
+  text-transform: none;
+  text-shadow: none;
+}
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: darkblue;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #0000f1;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #00003f;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid black;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: darkblue;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: darkblue;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: darkblue;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: darkblue;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: darkblue;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #0000f1;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #0000f1;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #0000f1;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #0000f1;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: darkblue;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 156 - 0
css/theme/sky.css

@@ -0,0 +1,156 @@
+@import url(http://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+/**
+ * Sky theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+  background: #add9e4;
+  background: -moz-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -webkit-gradient(radial, center center, 0px, center center, 100%, color-stop(0%, #f7fbfc), color-stop(100%, #add9e4));
+  background: -webkit-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -o-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: -ms-radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background: radial-gradient(center, circle cover, #f7fbfc 0%, #add9e4 100%);
+  background-color: #f7fbfc;
+}
+
+.reveal {
+  font-family: "Open Sans", sans-serif;
+  font-size: 36px;
+  font-weight: 200;
+  letter-spacing: -0.02em;
+  color: #333333;
+}
+
+::selection {
+  color: white;
+  background: #134674;
+  text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+  margin: 0 0 20px 0;
+  color: #333333;
+  font-family: "Quicksand", sans-serif;
+  line-height: 0.9em;
+  letter-spacing: -0.08em;
+  text-transform: uppercase;
+  text-shadow: none;
+}
+
+.reveal h1 {
+  text-shadow: 0px 0px 6px rgba(0, 0, 0, 0.2);
+}
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a:not(.image) {
+  color: #3b759e;
+  text-decoration: none;
+  -webkit-transition: color .15s ease;
+  -moz-transition: color .15s ease;
+  -ms-transition: color .15s ease;
+  -o-transition: color .15s ease;
+  transition: color .15s ease;
+}
+
+.reveal a:not(.image):hover {
+  color: #74a7cb;
+  text-shadow: none;
+  border: none;
+}
+
+.reveal .roll span:after {
+  color: #fff;
+  background: #264c66;
+}
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+  margin: 15px 0px;
+  background: rgba(255, 255, 255, 0.12);
+  border: 4px solid #333333;
+  box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+  -webkit-transition: all .2s linear;
+  -moz-transition: all .2s linear;
+  -ms-transition: all .2s linear;
+  -o-transition: all .2s linear;
+  transition: all .2s linear;
+}
+
+.reveal a:hover img {
+  background: rgba(255, 255, 255, 0.2);
+  border-color: #3b759e;
+  box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+}
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+  border-right-color: #3b759e;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+  border-left-color: #3b759e;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+  border-bottom-color: #3b759e;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+  border-top-color: #3b759e;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+  border-right-color: #74a7cb;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+  border-left-color: #74a7cb;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+  border-bottom-color: #74a7cb;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+  border-top-color: #74a7cb;
+}
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+  background: rgba(0, 0, 0, 0.2);
+}
+
+.reveal .progress span {
+  background: #3b759e;
+  -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -ms-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  -o-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+  transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+}

+ 50 - 0
css/theme/source/beige.scss

@@ -0,0 +1,50 @@
+/**
+ * Beige theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainColor: #333;
+$headingColor: #333;
+$headingTextShadow: none;
+$backgroundColor: #f7f3de;
+$linkColor: #8b743d;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(79, 64, 28, 0.99);
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(247,242,211,1), rgba(255,255,255,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 42 - 0
css/theme/source/default.scss

@@ -0,0 +1,42 @@
+/**
+ * Default theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@font-face {
+	font-family: 'League Gothic';
+	src: url('../../lib/font/league_gothic-webfont.eot');
+	src: url('../../lib/font/league_gothic-webfont.eot?#iefix') format('embedded-opentype'),
+		 url('../../lib/font/league_gothic-webfont.woff') format('woff'),
+		 url('../../lib/font/league_gothic-webfont.ttf') format('truetype'),
+		 url('../../lib/font/league_gothic-webfont.svg#LeagueGothicRegular') format('svg');
+
+	font-weight: normal;
+	font-style: normal;
+}
+
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+// Override theme settings (see ../template/settings.scss)
+$heading1TextShadow: 0 1px 0 #ccc, 0 2px 0 #c9c9c9, 0 3px 0 #bbb, 0 4px 0 #b9b9b9, 0 5px 0 #aaa, 0 6px 1px rgba(0,0,0,.1), 0 0 5px rgba(0,0,0,.1), 0 1px 3px rgba(0,0,0,.3), 0 3px 5px rgba(0,0,0,.2), 0 5px 10px rgba(0,0,0,.25), 0 20px 20px rgba(0,0,0,.15);
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( rgba(28,30,32,1), rgba(85,90,95,1) );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 35 - 0
css/theme/source/night.scss

@@ -0,0 +1,35 @@
+/**
+ * Black theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+// Include theme-specific fonts
+@import url(http://fonts.googleapis.com/css?family=Montserrat:700);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$backgroundColor: #111;
+
+$mainFont: 'Open Sans', Times, 'Times New Roman', serif;
+$linkColor: #e7ad52;
+$linkColorHover: lighten( $linkColor, 20% );
+$headingFont: 'Montserrat', Impact, sans-serif;
+$headingTextShadow: none;
+$headingLetterSpacing: -0.03em;
+$headingTextTransform: none;
+$selectionBackgroundColor: #e7ad52;
+$mainFontSize: 30px;
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 33 - 0
css/theme/source/serif.scss

@@ -0,0 +1,33 @@
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se; so is the theme - beige.css - that this is based off of.
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$mainColor: #000;
+$headingFont: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif;
+$headingColor: #383D3D;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #F0F1EB;
+$linkColor: #51483D;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #26351C;
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 38 - 0
css/theme/source/simple.scss

@@ -0,0 +1,38 @@
+/**
+ * A simple theme for reveal.js presentations, similar 
+ * to the default theme. The accent color is darkblue.
+ * 
+ * This theme is Copyright (C) 2012 Owen Versteeg, https://github.com/StereotypicalApps. It is MIT licensed.
+ * reveal.js is Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(http://fonts.googleapis.com/css?family=News+Cycle:400,700);
+@import url(http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Lato', Times, 'Times New Roman', serif;
+$mainColor: #000;
+$headingFont: 'News Cycle', Impact, sans-serif;
+$headingColor: #000;
+$headingTextShadow: none;
+$headingTextTransform: none;
+$backgroundColor: #fff;
+$linkColor: #00008B;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: rgba(0, 0, 0, 0.99);
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 41 - 0
css/theme/source/sky.scss

@@ -0,0 +1,41 @@
+/**
+ * Sky theme for reveal.js.
+ * 
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+
+
+// Default mixins and settings -----------------
+@import "../template/mixins";
+@import "../template/settings";
+// ---------------------------------------------
+
+
+
+// Include theme-specific fonts
+@import url(http://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
+@import url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,400,700);
+
+
+// Override theme settings (see ../template/settings.scss)
+$mainFont: 'Open Sans', sans-serif;
+$mainColor: #333;
+$headingFont: 'Quicksand', sans-serif;
+$headingColor: #333;
+$headingLetterSpacing: -0.08em;
+$headingTextShadow: none;
+$backgroundColor: #f7fbfc;
+$linkColor: #3b759e;
+$linkColorHover: lighten( $linkColor, 20% );
+$selectionBackgroundColor: #134674;
+
+// Background generator
+@mixin bodyBackground() {
+	@include radial-gradient( #add9e4, #f7fbfc );
+}
+
+
+
+// Theme template ------------------------------
+@import "../template/theme";
+// ---------------------------------------------

+ 29 - 0
css/theme/template/mixins.scss

@@ -0,0 +1,29 @@
+@mixin vertical-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, left bottom, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( top, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( top, $top 0%, $bottom 100% );
+	background: linear-gradient( top, $top 0%, $bottom 100% );
+}
+
+@mixin horizontal-gradient( $top, $bottom ) {
+	background: $top;
+	background: -moz-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -webkit-gradient( linear, left top, right top, color-stop(0%,$top), color-stop(100%,$bottom) );
+	background: -webkit-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -o-linear-gradient( left, $top 0%, $bottom 100% );
+	background: -ms-linear-gradient( left, $top 0%, $bottom 100% );
+	background: linear-gradient( left, $top 0%, $bottom 100% );
+}
+
+@mixin radial-gradient( $outer, $inner, $type: circle ) {
+	background: $outer;
+	background: -moz-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -webkit-gradient( radial, center center, 0px, center center, 100%, color-stop(0%,$inner), color-stop(100%,$outer) );
+	background: -webkit-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -o-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: -ms-radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+	background: radial-gradient( center, $type cover,  $inner 0%, $outer 100% );
+}

+ 33 - 0
css/theme/template/settings.scss

@@ -0,0 +1,33 @@
+// Base settings for all themes that can optionally be 
+// overridden by the super-theme
+
+// Background of the presentation
+$backgroundColor: #2b2b2b;
+
+// Primary/body text
+$mainFont: 'Lato', Times, 'Times New Roman', serif;
+$mainFontSize: 36px;
+$mainColor: #eee;
+
+// Headings
+$headingFont: 'League Gothic', Impact, sans-serif;
+$headingColor: #eee;
+$headingLineHeight: 0.9em;
+$headingLetterSpacing: 0.02em;
+$headingTextTransform: uppercase;
+$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);
+$heading1TextShadow: $headingTextShadow;
+
+// Links and actions
+$linkColor: #13DAEC;
+$linkColorHover: lighten( $linkColor, 20% );
+
+// Text selection
+$selectionBackgroundColor: #FF5E99;
+$selectionColor: #fff;
+
+// Generates the presentation background, can be overridden
+// to return a background image or gradient
+@mixin bodyBackground() {
+	background: $backgroundColor;
+}

+ 163 - 0
css/theme/template/theme.scss

@@ -0,0 +1,163 @@
+// Base theme template for reveal.js
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+
+body {
+	@include bodyBackground();
+	background-color: $backgroundColor;
+}
+
+.reveal {
+	font-family: $mainFont;
+	font-size: $mainFontSize;
+	font-weight: 200;
+	letter-spacing: -0.02em;
+	color: $mainColor;
+}
+
+::selection {
+	color: $selectionColor;
+	background: $selectionBackgroundColor;
+	text-shadow: none;
+}
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+
+.reveal h1,
+.reveal h2,
+.reveal h3,
+.reveal h4,
+.reveal h5,
+.reveal h6 {
+	margin: 0 0 20px 0;
+	color: $headingColor;
+
+	font-family: $headingFont;
+	line-height: $headingLineHeight;
+	letter-spacing: $headingLetterSpacing;
+
+	text-transform: $headingTextTransform;
+	text-shadow: $headingTextShadow;
+}
+
+.reveal h1 {
+	text-shadow: $heading1TextShadow;
+}
+
+
+/*********************************************
+ * LINKS
+ *********************************************/
+
+.reveal a:not(.image) {
+	color: $linkColor;
+	text-decoration: none;
+
+	-webkit-transition: color .15s ease;
+	   -moz-transition: color .15s ease;
+	    -ms-transition: color .15s ease;
+	     -o-transition: color .15s ease;
+	        transition: color .15s ease;
+}
+	.reveal a:not(.image):hover {
+		color: $linkColorHover;
+
+		text-shadow: none;
+		border: none;
+	}
+
+.reveal .roll span:after {
+	color: #fff;
+	background: darken( $linkColor, 15% );
+}
+
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+
+.reveal section img {
+	margin: 15px 0px;
+	background: rgba(255,255,255,0.12);
+	border: 4px solid $mainColor;
+
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
+
+	-webkit-transition: all .2s linear;
+	   -moz-transition: all .2s linear;
+	    -ms-transition: all .2s linear;
+	     -o-transition: all .2s linear;
+	        transition: all .2s linear;
+}
+
+	.reveal a:hover img {
+		background: rgba(255,255,255,0.2);
+		border-color: $linkColor;
+
+		box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
+	}
+
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+
+.reveal .controls div.navigate-left,
+.reveal .controls div.navigate-left.enabled {
+	border-right-color: $linkColor;
+}
+
+.reveal .controls div.navigate-right,
+.reveal .controls div.navigate-right.enabled {
+	border-left-color: $linkColor;
+}
+
+.reveal .controls div.navigate-up,
+.reveal .controls div.navigate-up.enabled {
+	border-bottom-color: $linkColor;
+}
+
+.reveal .controls div.navigate-down,
+.reveal .controls div.navigate-down.enabled {
+	border-top-color: $linkColor;
+}
+
+.reveal .controls div.navigate-left.enabled:hover {
+	border-right-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-right.enabled:hover {
+	border-left-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-up.enabled:hover {
+	border-bottom-color: $linkColorHover;
+}
+
+.reveal .controls div.navigate-down.enabled:hover {
+	border-top-color: $linkColorHover;
+}
+
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+
+.reveal .progress {
+	background: rgba(0,0,0,0.2);
+}
+	.reveal .progress span {
+		background: $linkColor;
+
+		-webkit-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		   -moz-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		    -ms-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		     -o-transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+		        transition: width 800ms cubic-bezier(0.260, 0.860, 0.440, 0.985);
+	}
+
+

+ 188 - 169
index.html

@@ -1,73 +1,72 @@
-<!doctype html>  
+<!doctype html>
 <html lang="en">
 <html lang="en">
-	
+
 	<head>
 	<head>
 		<meta charset="utf-8">
 		<meta charset="utf-8">
-		
-		<title>reveal.js - HTML5 Presentations</title>
 
 
-		<meta name="description" content="An easy to use CSS 3D slideshow tool for quickly creating good looking HTML presentations.">
+		<title>reveal.js - The HTML Presentation Framework</title>
+
+		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
 		<meta name="author" content="Hakim El Hattab">
 		<meta name="author" content="Hakim El Hattab">
 
 
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<meta name="apple-mobile-web-app-capable" content="yes" />
 		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
 		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
-		
-		<link href='http://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic' rel='stylesheet' type='text/css'>
-		
-		<link rel="stylesheet" href="css/reset.css">
-		<link rel="stylesheet" href="css/main.css">
-		<link rel="stylesheet" href="css/print.css" type="text/css" media="print">
 
 
+		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
+
+		<link rel="stylesheet" href="css/reveal.min.css">
+		<link rel="stylesheet" href="css/theme/default.css" id="theme">
+
+		<!-- For syntax highlighting -->
 		<link rel="stylesheet" href="lib/css/zenburn.css">
 		<link rel="stylesheet" href="lib/css/zenburn.css">
 
 
+		<!-- If the query includes 'print-pdf', use the PDF print sheet -->
+		<script>
+			document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
+		</script>
+
 		<!--[if lt IE 9]>
 		<!--[if lt IE 9]>
 		<script src="lib/js/html5shiv.js"></script>
 		<script src="lib/js/html5shiv.js"></script>
 		<![endif]-->
 		<![endif]-->
 	</head>
 	</head>
-	
+
 	<body>
 	<body>
-		
+
 		<div class="reveal">
 		<div class="reveal">
 
 
-			<!-- Used to fade in a background when a specific slide state is reached -->
-			<div class="state-background"></div>
-			
 			<!-- Any section element inside of this container is displayed as a slide -->
 			<!-- Any section element inside of this container is displayed as a slide -->
 			<div class="slides">
 			<div class="slides">
+
 				<section>
 				<section>
 					<h1>Reveal.js</h1>
 					<h1>Reveal.js</h1>
-					<h3 class="inverted">CSS 3D Presentations</h3>
-					<script>
-						// Delicously hacky. Look away.
-						if( navigator.userAgent.match( /(iPhone|iPad|iPod|Android)/i ) ) document.write( '<p style="color: rgba(0,0,0,0.3); text-shadow: none;">('+'Tap to navigate'+')</p>' );
-					</script>
+					<h3>HTML Presentations Made Easy</h3>
+					<p>
+						<small>Created by <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small>
+					</p>
 				</section>
 				</section>
-				
+
 				<section>
 				<section>
 					<h2>Heads Up</h2>
 					<h2>Heads Up</h2>
 					<p>
 					<p>
-						reveal.js is an easy to use, HTML based, presentation tool. You'll need a modern browser with 
+						reveal.js is a framework for easily creating beautiful presentations using HTML. You'll need a browser with
 						support for CSS 3D transforms to see it in its full glory.
 						support for CSS 3D transforms to see it in its full glory.
 					</p>
 					</p>
-					<p>
-						<i><small>- <a href="http://hakim.se">Hakim El Hattab</a> / <a href="http://twitter.com/hakimel">@hakimel</a></small></i>
-					</p>
 
 
 					<aside class="notes">
 					<aside class="notes">
-						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you run the speaker notes server.
+						Oh hey, these are some notes. They'll be hidden in your presentation, but you can see them if you open the speaker notes window (hit 's' on your keyboard).
 					</aside>
 					</aside>
 				</section>
 				</section>
-				
+
 				<!-- Example of nested vertical slides -->
 				<!-- Example of nested vertical slides -->
 				<section>
 				<section>
 					<section>
 					<section>
 						<h2>Vertical Slides</h2>
 						<h2>Vertical Slides</h2>
 						<p>
 						<p>
-							Slides can be nested inside of other slides,<br/>
-							try pressing <a href="#/2/1">down</a>.
+							Slides can be nested inside of other slides,
+							try pressing <a href="#" class="navigate-down">down</a>.
 						</p>
 						</p>
-						<a href="#/2/1" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png">
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
 						</a>
 						</a>
 					</section>
 					</section>
 					<section>
 					<section>
@@ -78,29 +77,36 @@
 						<h2>Basement Level 2</h2>
 						<h2>Basement Level 2</h2>
 						<p>Cornify</p>
 						<p>Cornify</p>
 						<a class="test" href="http://cornify.com">
 						<a class="test" href="http://cornify.com">
-							<img width="280" height="326" src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif">
+							<img width="280" height="326" src="https://s3.amazonaws.com/hakim-static/reveal-js/cornify.gif" alt="Unicorn">
 						</a>
 						</a>
 					</section>
 					</section>
 					<section>
 					<section>
 						<h2>Basement Level 3</h2>
 						<h2>Basement Level 3</h2>
 						<p>That's it, time to go back up.</p>
 						<p>That's it, time to go back up.</p>
 						<a href="#/2" class="image">
 						<a href="#/2" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" style="-webkit-transform: rotate(180deg);">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(180deg);">
 						</a>
 						</a>
 					</section>
 					</section>
 				</section>
 				</section>
 
 
 				<section>
 				<section>
-					<h2>Holistic Overview</h2>
+					<h2>Point of View</h2>
+					<p>
+						Press <strong>ESC</strong> to enter the slide overview. Hold down alt and click on any element to zoom in on it using <a href="http://lab.hakim.se/zoom-js">zoom.js</a>. Alt + click anywhere to zoom back out.
+					</p>
+				</section>
+
+				<section>
+					<h2>rvl.io</h2>
 					<p>
 					<p>
-						Press <strong>ESC</strong> to enter the slide overview!
+						If you don't like writing slides in HTML you can use the online editor <a href="http://www.rvl.io" target="_blank">rvl.io</a>.
 					</p>
 					</p>
 				</section>
 				</section>
 
 
 				<section>
 				<section>
 					<h2>Works in Mobile Safari</h2>
 					<h2>Works in Mobile Safari</h2>
 					<p>
 					<p>
-						Try it out! You can swipe through the slides pinch your way to the overview.
+						Try it out! You can swipe through the slides and pinch your way to the overview.
 					</p>
 					</p>
 				</section>
 				</section>
 
 
@@ -113,7 +119,7 @@
 						<li>Or here</li>
 						<li>Or here</li>
 					</ul>
 					</ul>
 				</section>
 				</section>
-				
+
 				<section>
 				<section>
 					<h2>Fantastic Ordered List</h2>
 					<h2>Fantastic Ordered List</h2>
 					<ol>
 					<ol>
@@ -124,31 +130,51 @@
 				</section>
 				</section>
 
 
 				<section data-markdown>
 				<section data-markdown>
-					## Markdown support
-					
-					For those of you who like that sort of thing.  
-                    Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+					<script type="text/template">
+						## Markdown support
 
 
-					<pre><code contenteditable style="margin-top: 20px;">&lt;section data-markdown&gt;
-  ## Markdown support
+						For those of you who like that sort of thing. Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
 
 
-  For those of you who like that sort of thing. 
-  Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
-&lt;/section&gt;
-					</code></pre>
+							<section data-markdown>
+							  ## Markdown support
+
+							  For those of you who like that sort of thing.
+							  Instructions and a bit more info available [here](https://github.com/hakimel/reveal.js#markdown).
+							</section>
+					</script>
 				</section>
 				</section>
 
 
-				<section>
+				<section id="transitions">
 					<h2>Transition Styles</h2>
 					<h2>Transition Styles</h2>
 					<p>
 					<p>
-						You can select from different transitions, like:
+						You can select from different transitions, like: <br>
+						<a href="?transition=cube#/transitions">Cube</a> -
+						<a href="?transition=page#/transitions">Page</a> -
+						<a href="?transition=concave#/transitions">Concave</a> -
+						<a href="?transition=zoom#/transitions">Zoom</a> -
+						<a href="?transition=linear#/transitions">Linear</a> -
+						<a href="?transition=fade#/transitions">Fade</a> -
+						<a href="?transition=none#/transitions">None</a> -
+						<a href="?#/transitions">Default</a>
+					</p>
+				</section>
+
+				<section id="themes">
+					<h2>Themes</h2>
+					<p>
+						Reveal.js comes with a few themes built in: <br>
+						<a href="?theme=sky#/themes">Sky</a> -
+						<a href="?theme=beige#/themes">Beige</a> -
+						<a href="?theme=simple#/themes">Simple</a> -
+						<a href="?theme=serif#/themes">Serif</a> -
+						<a href="?theme=night#/themes">Night</a> -
+						<a href="?#/themes">Default</a>
+					</p>
+					<p>
+						<small>
+							* Theme demos are loaded after the presentation which leads to flicker. In production you should load your theme in the <code>&lt;head&gt;</code> using a <code>&lt;link&gt;</code>.
+						</small>
 					</p>
 					</p>
-					<ul>
-						<li><a href="http://lab.hakim.se/reveal-js/?transition=cube">Cube</a></li>
-						<li><a href="http://lab.hakim.se/reveal-js/?transition=page">Page</a></li>
-						<li><a href="http://lab.hakim.se/reveal-js/?transition=concave">Concave</a></li>
-						<li><a href="http://lab.hakim.se/reveal-js/?transition=linear">Linear</a></li>
-					</ul>
 				</section>
 				</section>
 
 
 				<section>
 				<section>
@@ -156,23 +182,23 @@
 						<h2>Global State</h2>
 						<h2>Global State</h2>
 						<p>
 						<p>
 							Set <code>data-state="something"</code> on a slide and <code>"something"</code>
 							Set <code>data-state="something"</code> on a slide and <code>"something"</code>
-							will be added as a class to the document element when the slide is open. This let's you
+							will be added as a class to the document element when the slide is open. This lets you
 							apply broader style changes, like switching the background.
 							apply broader style changes, like switching the background.
 						</p>
 						</p>
-						<a href="#/7/1" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png">
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
 						</a>
 						</a>
 					</section>
 					</section>
 					<section data-state="blackout">
 					<section data-state="blackout">
 						<h2>"blackout"</h2>
 						<h2>"blackout"</h2>
-						<a href="#/7/2" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png">
+						<a href="#" class="image navigate-down">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Down arrow">
 						</a>
 						</a>
 					</section>
 					</section>
 					<section data-state="soothe">
 					<section data-state="soothe">
 						<h2>"soothe"</h2>
 						<h2>"soothe"</h2>
-						<a href="#/7/0" class="image">
-							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" style="-webkit-transform: rotate(180deg);">
+						<a href="#" class="image navigate-next">
+							<img width="178" height="238" src="https://s3.amazonaws.com/hakim-static/reveal-js/arrow.png" alt="Up arrow" style="-webkit-transform: rotate(-90deg);">
 						</a>
 						</a>
 					</section>
 					</section>
 				</section>
 				</section>
@@ -195,20 +221,20 @@
 						The nice thing about standards is that there are so many to choose from</q> and block:
 						The nice thing about standards is that there are so many to choose from</q> and block:
 					</p>
 					</p>
 					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
 					<blockquote cite="http://searchservervirtualization.techtarget.com/definition/Our-Favorite-Technology-Quotations">
-						For years there has been a theory that millions of monkeys typing at random on millions of typewriters would 
+						For years there has been a theory that millions of monkeys typing at random on millions of typewriters would
 						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.
 						reproduce the entire works of Shakespeare. The Internet has proven this theory to be untrue.
 					</blockquote>
 					</blockquote>
 				</section>
 				</section>
-				
+
 				<section>
 				<section>
 					<h2>Pretty Code</h2>
 					<h2>Pretty Code</h2>
 					<pre><code contenteditable>
 					<pre><code contenteditable>
 function linkify( selector ) {
 function linkify( selector ) {
   if( supports3DTransforms ) {
   if( supports3DTransforms ) {
-    
+
     var nodes = document.querySelectorAll( selector );
     var nodes = document.querySelectorAll( selector );
 
 
-    for( var i = 0, len = nodes.length; i < len; i++ ) {
+    for( var i = 0, len = nodes.length; i &lt; len; i++ ) {
       var node = nodes[i];
       var node = nodes[i];
 
 
       if( !node.className ) ) {
       if( !node.className ) ) {
@@ -220,138 +246,131 @@ function linkify( selector ) {
 					</code></pre>
 					</code></pre>
 					<p>Courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
 					<p>Courtesy of <a href="http://softwaremaniacs.org/soft/highlight/en/description/">highlight.js</a>.</p>
 				</section>
 				</section>
-				
+
 				<section>
 				<section>
 					<h2>Intergalactic Interconnections</h2>
 					<h2>Intergalactic Interconnections</h2>
 					<p>
 					<p>
-						You can link between slides internally,<br/>
+						You can link between slides internally,
 						<a href="#/2/3">like this</a>.
 						<a href="#/2/3">like this</a>.
 					</p>
 					</p>
 				</section>
 				</section>
 
 
 				<section>
 				<section>
-					<h2>Fragmented Views</h2>
-					<p>Hit the next arrow...</p>
-					<p class="fragment">... to step through ...</p>
-					<ol>
-						<li class="fragment"><code>any type</code></li>
-						<li class="fragment"><em>of view</em></li>
-						<li class="fragment"><strong>fragments</strong></li>
-					</ol>
+					<section>
+						<h2>Fragmented Views</h2>
+						<p>Hit the next arrow...</p>
+						<p class="fragment">... to step through ...</p>
+						<ol>
+							<li class="fragment"><code>any type</code></li>
+							<li class="fragment"><em>of view</em></li>
+							<li class="fragment"><strong>fragments</strong></li>
+						</ol>
+
+						<aside class="notes">
+							This slide has fragments which are also stepped through in the notes window.
+						</aside>
+					</section>
+					<section>
+						<h2>Fragment Styles</h2>
+						<p>There's a few styles of fragments, like:</p>
+						<p class="fragment grow">grow</p>
+						<p class="fragment shrink">shrink</p>
+						<p class="fragment roll-in">roll-in</p>
+						<p class="fragment fade-out">fade-out</p>
+						<p class="fragment highlight-red">highlight-red</p>
+						<p class="fragment highlight-green">highlight-green</p>
+						<p class="fragment highlight-blue">highlight-blue</p>
+					</section>
 				</section>
 				</section>
-				
+
 				<section>
 				<section>
 					<h2>Spectacular image!</h2>
 					<h2>Spectacular image!</h2>
-					<a class="image" href="http://hakim.se/experiments/html5/breakdom/" target="_blank">
-						<img width="320" height="412" src="https://s3.amazonaws.com/hakim-static/reveal-js/breakdom.png">
+					<a class="image" href="http://lab.hakim.se/meny/" target="_blank">
+						<img width="320" height="299" src="http://s3.amazonaws.com/hakim-static/portfolio/images/meny.png" alt="Meny">
 					</a>
 					</a>
 				</section>
 				</section>
-				
+
+				<section>
+					<h2>Export to PDF</h2>
+					<p>Presentations can be <a href="https://github.com/hakimel/reveal.js#pdf-export">exported to PDF</a>, below is an example that's been uploaded to SlideShare.</p>
+					<iframe id="slideshare" src="http://www.slideshare.net/slideshow/embed_code/13872948" width="455" height="356" style="margin:0;overflow:hidden;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe>
+					<script>
+						document.getElementById('slideshare').attributeName = 'allowfullscreen';
+					</script>
+				</section>
+
+				<section>
+					<h2>Take a Moment</h2>
+					<p>
+						Press b or period on your keyboard to enter the 'paused' mode. This mode is helpful when you want to take distracting slides off the screen
+						during a presentation.
+					</p>
+				</section>
+
 				<section>
 				<section>
 					<h2>Stellar Links</h2>
 					<h2>Stellar Links</h2>
 					<ul>
 					<ul>
-						<li><a href="https://github.com/hakimel/reveal.js">Source code on github</a></li>
-						<li><a href="http://hakim.se/projects/reveal-js">Read more on my site</a></li>
+						<li><a href="https://github.com/hakimel/reveal.js">Source code on GitHub</a></li>
+						<li><a href="http://hakim.se/projects/reveal-js">Leave feedback on my site</a></li>
 						<li><a href="http://twitter.com/hakimel">Follow me on Twitter</a></li>
 						<li><a href="http://twitter.com/hakimel">Follow me on Twitter</a></li>
 					</ul>
 					</ul>
 				</section>
 				</section>
-				
+
+				<section>
+					<h2>It's free</h2>
+					<p>
+						reveal.js and <a href="http://www.rvl.io">rvl.io</a> are entirely free but if you'd like to support the projects you can donate below.
+						Donations will go towards hosting and domain costs.
+					</p>
+					<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+						<input type="hidden" name="cmd" value="_donations">
+						<input type="hidden" name="business" value="hakim.elhattab@gmail.com">
+						<input type="hidden" name="lc" value="US">
+						<input type="hidden" name="item_name" value="reveal.js / rvl.io">
+						<input type="hidden" name="no_note" value="0">
+						<input type="hidden" name="currency_code" value="USD">
+						<input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest">
+						<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
+					</form>
+				</section>
+
 				<section>
 				<section>
 					<h1>THE END</h1>
 					<h1>THE END</h1>
-					<h3 class="inverted">BY Hakim El Hattab / hakim.se</h3>
+					<h3>BY Hakim El Hattab / hakim.se</h3>
 				</section>
 				</section>
+
 			</div>
 			</div>
 
 
-			<!-- The navigational controls UI -->
-			<aside class="controls">
-				<a class="left" href="#">&#x25C4;</a>
-				<a class="right" href="#">&#x25BA;</a>
-				<a class="up" href="#">&#x25B2;</a>
-				<a class="down" href="#">&#x25BC;</a>
-			</aside>
-
-			<!-- Presentation progress bar -->
-			<div class="progress"><span></span></div>
-			
 		</div>
 		</div>
 
 
 		<script src="lib/js/head.min.js"></script>
 		<script src="lib/js/head.min.js"></script>
+		<script src="js/reveal.min.js"></script>
 
 
 		<script>
 		<script>
 
 
-			var multiplex = {
-				id: null
-				, secret: null
-				, url: 'revealjs.jit.su'
-			};
-
-			var notes = false;
-
-			head.ready( function() {
-
-				// Fires when a slide with data-state=customevent is activated
-				Reveal.addEventListener( 'customevent', function() {
-					console.log( '"customevent" has fired' );
-				} );
-
-				// Fires each time a new slide is activated
-				Reveal.addEventListener( 'slidechanged', function( event ) {
-					// event.previousSlide, event.currentSlide, event.indexh, event.indexv
-				} );
-
-				// Full list of configuration options available here:
-				// https://github.com/hakimel/reveal.js#configuration
-				Reveal.initialize({
-					controls: true,
-					progress: true,
-					history: true,
-					
-					theme: Reveal.getQueryHash().theme || 'default', // default/neon/beige
-					transition: Reveal.getQueryHash().transition || 'default' // default/cube/page/concave/linear(2d)
-				});
-
-				// Load highlight.js for syntax highlighting of code samples
-				head.js( 'lib/js/highlight.js', function() { 
-					hljs.initHighlightingOnLoad(); 
-				} );
-
-			} );
-
-			// Scripts that should be loaded before initializing
-			var scripts = [];
-
-			// If the browser doesn't support classList, load a polyfill
-			if( !document.body.classList ) {
-				head.js( 'lib/js/classList.js' );
-			}
-
-			// Load markdown parser if there are slides defined using markdown
-			if( document.querySelector( '[data-markdown]' ) ) {
-				scripts.push( 'lib/js/showdown.js' );
-				scripts.push( 'lib/js/data-markdown.js' );
-			}
-
-			scripts.push( 'js/reveal.js' );
-
-			// If we're runnning the notes server we need to include some additional JS
-			// TODO Is there a better way to determine if we're running the notes server?
-			if( window.location.host === 'localhost:1947' || notes === true) {
-				scripts.push( 'socket.io/socket.io.js' );
-				scripts.push( 'plugin/speakernotes/client.js' );
-			}
-
-			if( multiplex.id !== null ) {
-				scripts.push( 'socket.io/socket.io.js' );
-				scripts.push( 'plugin/multiplex/client.js' );
-
-				if( multiplex.secret !== null ) {
-					scripts.push( 'plugin/multiplex/master.js' );
-				}
-			}
-
-			// Load the scripts and, when completed, initialize reveal.js
-			head.js.apply( null, scripts );
-			
+			// Full list of configuration options available here:
+			// https://github.com/hakimel/reveal.js#configuration
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
+				transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'plugin/markdown/showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
+					{ src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
+					{ src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
+					// { src: 'plugin/remotes/remotes.js', async: true, condition: function() { return !!document.body.classList; } }
+				]
+			});
+
 		</script>
 		</script>
 
 
 	</body>
 	</body>

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 904 - 334
js/reveal.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 7 - 0
js/reveal.min.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 19 - 0
lib/font/league_gothic-webfont.svg


BIN
lib/font/league_gothic-webfont.woff


+ 0 - 27
lib/js/data-markdown.js

@@ -1,27 +0,0 @@
-// From https://gist.github.com/1343518
-// Modified by Hakim to handle markdown indented with tabs
-(function(){
-
-    var slides = document.querySelectorAll('[data-markdown]');
-
-    for( var i = 0, len = slides.length; i < len; i++ ) {
-        var elem = slides[i];
-
-        // strip leading whitespace so it isn't evaluated as code
-        var text = elem.innerHTML;
-
-        var leadingWs = text.match(/^\n?(\s*)/)[1].length,
-            leadingTabs = text.match(/^\n?(\t*)/)[1].length;
-
-        if( leadingTabs > 0 ) {
-            text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
-        }
-        else if( leadingWs > 1 ) {
-            text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
-        }
-
-        // here, have sum HTML
-        elem.innerHTML = (new Showdown.converter()).makeHtml(text);
-    }
-
-})();

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 0 - 4
lib/js/highlight.js


+ 0 - 1341
lib/js/showdown.js

@@ -1,1341 +0,0 @@
-//
-// showdown.js -- A javascript port of Markdown.
-//
-// Copyright (c) 2007 John Fraser.
-//
-// Original Markdown Copyright (c) 2004-2005 John Gruber
-//   <http://daringfireball.net/projects/markdown/>
-//
-// Redistributable under a BSD-style open source license.
-// See license.txt for more information.
-//
-// The full source distribution is at:
-//
-//				A A L
-//				T C A
-//				T K B
-//
-//   <http://www.attacklab.net/>
-//
-
-//
-// Wherever possible, Showdown is a straight, line-by-line port
-// of the Perl version of Markdown.
-//
-// This is not a normal parser design; it's basically just a
-// series of string substitutions.  It's hard to read and
-// maintain this way,  but keeping Showdown close to the original
-// design makes it easier to port new features.
-//
-// More importantly, Showdown behaves like markdown.pl in most
-// edge cases.  So web applications can do client-side preview
-// in Javascript, and then build identical HTML on the server.
-//
-// This port needs the new RegExp functionality of ECMA 262,
-// 3rd Edition (i.e. Javascript 1.5).  Most modern web browsers
-// should do fine.  Even with the new regular expression features,
-// We do a lot of work to emulate Perl's regex functionality.
-// The tricky changes in this file mostly have the "attacklab:"
-// label.  Major or self-explanatory changes don't.
-//
-// Smart diff tools like Araxis Merge will be able to match up
-// this file with markdown.pl in a useful way.  A little tweaking
-// helps: in a copy of markdown.pl, replace "#" with "//" and
-// replace "$text" with "text".  Be sure to ignore whitespace
-// and line endings.
-//
-
-
-//
-// Showdown usage:
-//
-//   var text = "Markdown *rocks*.";
-//
-//   var converter = new Showdown.converter();
-//   var html = converter.makeHtml(text);
-//
-//   alert(html);
-//
-// Note: move the sample code to the bottom of this
-// file before uncommenting it.
-//
-
-
-//
-// Showdown namespace
-//
-var Showdown = {};
-
-//
-// converter
-//
-// Wraps all "globals" so that the only thing
-// exposed is makeHtml().
-//
-Showdown.converter = function() {
-
-//
-// Globals:
-//
-
-// Global hashes, used by various utility routines
-var g_urls;
-var g_titles;
-var g_html_blocks;
-
-// Used to track when we're inside an ordered or unordered list
-// (see _ProcessListItems() for details):
-var g_list_level = 0;
-
-
-this.makeHtml = function(text) {
-//
-// Main function. The order in which other subs are called here is
-// essential. Link and image substitutions need to happen before
-// _EscapeSpecialCharsWithinTagAttributes(), so that any *'s or _'s in the <a>
-// and <img> tags get encoded.
-//
-
-	// Clear the global hashes. If we don't clear these, you get conflicts
-	// from other articles when generating a page which contains more than
-	// one article (e.g. an index page that shows the N most recent
-	// articles):
-	g_urls = new Array();
-	g_titles = new Array();
-	g_html_blocks = new Array();
-
-	// attacklab: Replace ~ with ~T
-	// This lets us use tilde as an escape char to avoid md5 hashes
-	// The choice of character is arbitray; anything that isn't
-    // magic in Markdown will work.
-	text = text.replace(/~/g,"~T");
-
-	// attacklab: Replace $ with ~D
-	// RegExp interprets $ as a special character
-	// when it's in a replacement string
-	text = text.replace(/\$/g,"~D");
-
-	// Standardize line endings
-	text = text.replace(/\r\n/g,"\n"); // DOS to Unix
-	text = text.replace(/\r/g,"\n"); // Mac to Unix
-
-	// Make sure text begins and ends with a couple of newlines:
-	text = "\n\n" + text + "\n\n";
-
-	// Convert all tabs to spaces.
-	text = _Detab(text);
-
-	// Strip any lines consisting only of spaces and tabs.
-	// This makes subsequent regexen easier to write, because we can
-	// match consecutive blank lines with /\n+/ instead of something
-	// contorted like /[ \t]*\n+/ .
-	text = text.replace(/^[ \t]+$/mg,"");
-
-	// Handle github codeblocks prior to running HashHTML so that
-	// HTML contained within the codeblock gets escaped propertly
-	text = _DoGithubCodeBlocks(text);
-
-	// Turn block-level HTML blocks into hash entries
-	text = _HashHTMLBlocks(text);
-
-	// Strip link definitions, store in hashes.
-	text = _StripLinkDefinitions(text);
-
-	text = _RunBlockGamut(text);
-
-	text = _UnescapeSpecialChars(text);
-
-	// attacklab: Restore dollar signs
-	text = text.replace(/~D/g,"$$");
-
-	// attacklab: Restore tildes
-	text = text.replace(/~T/g,"~");
-
-	return text;
-};
-
-
-var _StripLinkDefinitions = function(text) {
-//
-// Strips link definitions from text, stores the URLs and titles in
-// hash references.
-//
-
-	// Link defs are in the form: ^[id]: url "optional title"
-
-	/*
-		var text = text.replace(/
-				^[ ]{0,3}\[(.+)\]:  // id = $1  attacklab: g_tab_width - 1
-				  [ \t]*
-				  \n?				// maybe *one* newline
-				  [ \t]*
-				<?(\S+?)>?			// url = $2
-				  [ \t]*
-				  \n?				// maybe one newline
-				  [ \t]*
-				(?:
-				  (\n*)				// any lines skipped = $3 attacklab: lookbehind removed
-				  ["(]
-				  (.+?)				// title = $4
-				  [")]
-				  [ \t]*
-				)?					// title is optional
-				(?:\n+|$)
-			  /gm,
-			  function(){...});
-	*/
-	var text = text.replace(/^[ ]{0,3}\[(.+)\]:[ \t]*\n?[ \t]*<?(\S+?)>?[ \t]*\n?[ \t]*(?:(\n*)["(](.+?)[")][ \t]*)?(?:\n+|\Z)/gm,
-		function (wholeMatch,m1,m2,m3,m4) {
-			m1 = m1.toLowerCase();
-			g_urls[m1] = _EncodeAmpsAndAngles(m2);  // Link IDs are case-insensitive
-			if (m3) {
-				// Oops, found blank lines, so it's not a title.
-				// Put back the parenthetical statement we stole.
-				return m3+m4;
-			} else if (m4) {
-				g_titles[m1] = m4.replace(/"/g,"&quot;");
-			}
-
-			// Completely remove the definition from the text
-			return "";
-		}
-	);
-
-	return text;
-}
-
-
-var _HashHTMLBlocks = function(text) {
-	// attacklab: Double up blank lines to reduce lookaround
-	text = text.replace(/\n/g,"\n\n");
-
-	// Hashify HTML blocks:
-	// We only want to do this for block-level HTML tags, such as headers,
-	// lists, and tables. That's because we still want to wrap <p>s around
-	// "paragraphs" that are wrapped in non-block-level tags, such as anchors,
-	// phrase emphasis, and spans. The list of tags we're looking for is
-	// hard-coded:
-	var block_tags_a = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del|style|section|header|footer|nav|article|aside";
-	var block_tags_b = "p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside";
-
-	// First, look for nested blocks, e.g.:
-	//   <div>
-	//     <div>
-	//     tags for inner block must be indented.
-	//     </div>
-	//   </div>
-	//
-	// The outermost tags must start at the left margin for this to match, and
-	// the inner nested divs must be indented.
-	// We need to do this before the next, more liberal match, because the next
-	// match will start at the first `<div>` and stop at the first `</div>`.
-
-	// attacklab: This regex can be expensive when it fails.
-	/*
-		var text = text.replace(/
-		(						// save in $1
-			^					// start of line  (with /m)
-			<($block_tags_a)	// start tag = $2
-			\b					// word break
-								// attacklab: hack around khtml/pcre bug...
-			[^\r]*?\n			// any number of lines, minimally matching
-			</\2>				// the matching end tag
-			[ \t]*				// trailing spaces/tabs
-			(?=\n+)				// followed by a newline
-		)						// attacklab: there are sentinel newlines at end of document
-		/gm,function(){...}};
-	*/
-	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|ins|del)\b[^\r]*?\n<\/\2>[ \t]*(?=\n+))/gm,hashElement);
-
-	//
-	// Now match more liberally, simply from `\n<tag>` to `</tag>\n`
-	//
-
-	/*
-		var text = text.replace(/
-		(						// save in $1
-			^					// start of line  (with /m)
-			<($block_tags_b)	// start tag = $2
-			\b					// word break
-								// attacklab: hack around khtml/pcre bug...
-			[^\r]*?				// any number of lines, minimally matching
-			.*</\2>				// the matching end tag
-			[ \t]*				// trailing spaces/tabs
-			(?=\n+)				// followed by a newline
-		)						// attacklab: there are sentinel newlines at end of document
-		/gm,function(){...}};
-	*/
-	text = text.replace(/^(<(p|div|h[1-6]|blockquote|pre|table|dl|ol|ul|script|noscript|form|fieldset|iframe|math|style|section|header|footer|nav|article|aside)\b[^\r]*?.*<\/\2>[ \t]*(?=\n+)\n)/gm,hashElement);
-
-	// Special case just for <hr />. It was easier to make a special case than
-	// to make the other regex more complicated.
-
-	/*
-		text = text.replace(/
-		(						// save in $1
-			\n\n				// Starting after a blank line
-			[ ]{0,3}
-			(<(hr)				// start tag = $2
-			\b					// word break
-			([^<>])*?			//
-			\/?>)				// the matching end tag
-			[ \t]*
-			(?=\n{2,})			// followed by a blank line
-		)
-		/g,hashElement);
-	*/
-	text = text.replace(/(\n[ ]{0,3}(<(hr)\b([^<>])*?\/?>)[ \t]*(?=\n{2,}))/g,hashElement);
-
-	// Special case for standalone HTML comments:
-
-	/*
-		text = text.replace(/
-		(						// save in $1
-			\n\n				// Starting after a blank line
-			[ ]{0,3}			// attacklab: g_tab_width - 1
-			<!
-			(--[^\r]*?--\s*)+
-			>
-			[ \t]*
-			(?=\n{2,})			// followed by a blank line
-		)
-		/g,hashElement);
-	*/
-	text = text.replace(/(\n\n[ ]{0,3}<!(--[^\r]*?--\s*)+>[ \t]*(?=\n{2,}))/g,hashElement);
-
-	// PHP and ASP-style processor instructions (<?...?> and <%...%>)
-
-	/*
-		text = text.replace(/
-		(?:
-			\n\n				// Starting after a blank line
-		)
-		(						// save in $1
-			[ ]{0,3}			// attacklab: g_tab_width - 1
-			(?:
-				<([?%])			// $2
-				[^\r]*?
-				\2>
-			)
-			[ \t]*
-			(?=\n{2,})			// followed by a blank line
-		)
-		/g,hashElement);
-	*/
-	text = text.replace(/(?:\n\n)([ ]{0,3}(?:<([?%])[^\r]*?\2>)[ \t]*(?=\n{2,}))/g,hashElement);
-
-	// attacklab: Undo double lines (see comment at top of this function)
-	text = text.replace(/\n\n/g,"\n");
-	return text;
-}
-
-var hashElement = function(wholeMatch,m1) {
-	var blockText = m1;
-
-	// Undo double lines
-	blockText = blockText.replace(/\n\n/g,"\n");
-	blockText = blockText.replace(/^\n/,"");
-
-	// strip trailing blank lines
-	blockText = blockText.replace(/\n+$/g,"");
-
-	// Replace the element text with a marker ("~KxK" where x is its key)
-	blockText = "\n\n~K" + (g_html_blocks.push(blockText)-1) + "K\n\n";
-
-	return blockText;
-};
-
-var _RunBlockGamut = function(text) {
-//
-// These are all the transformations that form block-level
-// tags like paragraphs, headers, and list items.
-//
-	text = _DoHeaders(text);
-
-	// Do Horizontal Rules:
-	var key = hashBlock("<hr />");
-	text = text.replace(/^[ ]{0,2}([ ]?\*[ ]?){3,}[ \t]*$/gm,key);
-	text = text.replace(/^[ ]{0,2}([ ]?\-[ ]?){3,}[ \t]*$/gm,key);
-	text = text.replace(/^[ ]{0,2}([ ]?\_[ ]?){3,}[ \t]*$/gm,key);
-
-	text = _DoLists(text);
-	text = _DoCodeBlocks(text);
-	text = _DoBlockQuotes(text);
-
-	// We already ran _HashHTMLBlocks() before, in Markdown(), but that
-	// was to escape raw HTML in the original Markdown source. This time,
-	// we're escaping the markup we've just created, so that we don't wrap
-	// <p> tags around block-level tags.
-	text = _HashHTMLBlocks(text);
-	text = _FormParagraphs(text);
-
-	return text;
-};
-
-
-var _RunSpanGamut = function(text) {
-//
-// These are all the transformations that occur *within* block-level
-// tags like paragraphs, headers, and list items.
-//
-
-	text = _DoCodeSpans(text);
-	text = _EscapeSpecialCharsWithinTagAttributes(text);
-	text = _EncodeBackslashEscapes(text);
-
-	// Process anchor and image tags. Images must come first,
-	// because ![foo][f] looks like an anchor.
-	text = _DoImages(text);
-	text = _DoAnchors(text);
-
-	// Make links out of things like `<http://example.com/>`
-	// Must come after _DoAnchors(), because you can use < and >
-	// delimiters in inline links like [this](<url>).
-	text = _DoAutoLinks(text);
-	text = _EncodeAmpsAndAngles(text);
-	text = _DoItalicsAndBold(text);
-
-	// Do hard breaks:
-	text = text.replace(/  +\n/g," <br />\n");
-
-	return text;
-}
-
-var _EscapeSpecialCharsWithinTagAttributes = function(text) {
-//
-// Within tags -- meaning between < and > -- encode [\ ` * _] so they
-// don't conflict with their use in Markdown for code, italics and strong.
-//
-
-	// Build a regex to find HTML tags and comments.  See Friedl's
-	// "Mastering Regular Expressions", 2nd Ed., pp. 200-201.
-	var regex = /(<[a-z\/!$]("[^"]*"|'[^']*'|[^'">])*>|<!(--.*?--\s*)+>)/gi;
-
-	text = text.replace(regex, function(wholeMatch) {
-		var tag = wholeMatch.replace(/(.)<\/?code>(?=.)/g,"$1`");
-		tag = escapeCharacters(tag,"\\`*_");
-		return tag;
-	});
-
-	return text;
-}
-
-var _DoAnchors = function(text) {
-//
-// Turn Markdown link shortcuts into XHTML <a> tags.
-//
-	//
-	// First, handle reference-style links: [link text] [id]
-	//
-
-	/*
-		text = text.replace(/
-		(							// wrap whole match in $1
-			\[
-			(
-				(?:
-					\[[^\]]*\]		// allow brackets nested one level
-					|
-					[^\[]			// or anything else
-				)*
-			)
-			\]
-
-			[ ]?					// one optional space
-			(?:\n[ ]*)?				// one optional newline followed by spaces
-
-			\[
-			(.*?)					// id = $3
-			\]
-		)()()()()					// pad remaining backreferences
-		/g,_DoAnchors_callback);
-	*/
-	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeAnchorTag);
-
-	//
-	// Next, inline-style links: [link text](url "optional title")
-	//
-
-	/*
-		text = text.replace(/
-			(						// wrap whole match in $1
-				\[
-				(
-					(?:
-						\[[^\]]*\]	// allow brackets nested one level
-					|
-					[^\[\]]			// or anything else
-				)
-			)
-			\]
-			\(						// literal paren
-			[ \t]*
-			()						// no id, so leave $3 empty
-			<?(.*?)>?				// href = $4
-			[ \t]*
-			(						// $5
-				(['"])				// quote char = $6
-				(.*?)				// Title = $7
-				\6					// matching quote
-				[ \t]*				// ignore any spaces/tabs between closing quote and )
-			)?						// title is optional
-			\)
-		)
-		/g,writeAnchorTag);
-	*/
-	text = text.replace(/(\[((?:\[[^\]]*\]|[^\[\]])*)\]\([ \t]*()<?(.*?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeAnchorTag);
-
-	//
-	// Last, handle reference-style shortcuts: [link text]
-	// These must come last in case you've also got [link test][1]
-	// or [link test](/foo)
-	//
-
-	/*
-		text = text.replace(/
-		(		 					// wrap whole match in $1
-			\[
-			([^\[\]]+)				// link text = $2; can't contain '[' or ']'
-			\]
-		)()()()()()					// pad rest of backreferences
-		/g, writeAnchorTag);
-	*/
-	text = text.replace(/(\[([^\[\]]+)\])()()()()()/g, writeAnchorTag);
-
-	return text;
-}
-
-var writeAnchorTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
-	if (m7 == undefined) m7 = "";
-	var whole_match = m1;
-	var link_text   = m2;
-	var link_id	 = m3.toLowerCase();
-	var url		= m4;
-	var title	= m7;
-
-	if (url == "") {
-		if (link_id == "") {
-			// lower-case and turn embedded newlines into spaces
-			link_id = link_text.toLowerCase().replace(/ ?\n/g," ");
-		}
-		url = "#"+link_id;
-
-		if (g_urls[link_id] != undefined) {
-			url = g_urls[link_id];
-			if (g_titles[link_id] != undefined) {
-				title = g_titles[link_id];
-			}
-		}
-		else {
-			if (whole_match.search(/\(\s*\)$/m)>-1) {
-				// Special case for explicit empty url
-				url = "";
-			} else {
-				return whole_match;
-			}
-		}
-	}
-
-	url = escapeCharacters(url,"*_");
-	var result = "<a href=\"" + url + "\"";
-
-	if (title != "") {
-		title = title.replace(/"/g,"&quot;");
-		title = escapeCharacters(title,"*_");
-		result +=  " title=\"" + title + "\"";
-	}
-
-	result += ">" + link_text + "</a>";
-
-	return result;
-}
-
-
-var _DoImages = function(text) {
-//
-// Turn Markdown image shortcuts into <img> tags.
-//
-
-	//
-	// First, handle reference-style labeled images: ![alt text][id]
-	//
-
-	/*
-		text = text.replace(/
-		(						// wrap whole match in $1
-			!\[
-			(.*?)				// alt text = $2
-			\]
-
-			[ ]?				// one optional space
-			(?:\n[ ]*)?			// one optional newline followed by spaces
-
-			\[
-			(.*?)				// id = $3
-			\]
-		)()()()()				// pad rest of backreferences
-		/g,writeImageTag);
-	*/
-	text = text.replace(/(!\[(.*?)\][ ]?(?:\n[ ]*)?\[(.*?)\])()()()()/g,writeImageTag);
-
-	//
-	// Next, handle inline images:  ![alt text](url "optional title")
-	// Don't forget: encode * and _
-
-	/*
-		text = text.replace(/
-		(						// wrap whole match in $1
-			!\[
-			(.*?)				// alt text = $2
-			\]
-			\s?					// One optional whitespace character
-			\(					// literal paren
-			[ \t]*
-			()					// no id, so leave $3 empty
-			<?(\S+?)>?			// src url = $4
-			[ \t]*
-			(					// $5
-				(['"])			// quote char = $6
-				(.*?)			// title = $7
-				\6				// matching quote
-				[ \t]*
-			)?					// title is optional
-		\)
-		)
-		/g,writeImageTag);
-	*/
-	text = text.replace(/(!\[(.*?)\]\s?\([ \t]*()<?(\S+?)>?[ \t]*((['"])(.*?)\6[ \t]*)?\))/g,writeImageTag);
-
-	return text;
-}
-
-var writeImageTag = function(wholeMatch,m1,m2,m3,m4,m5,m6,m7) {
-	var whole_match = m1;
-	var alt_text   = m2;
-	var link_id	 = m3.toLowerCase();
-	var url		= m4;
-	var title	= m7;
-
-	if (!title) title = "";
-
-	if (url == "") {
-		if (link_id == "") {
-			// lower-case and turn embedded newlines into spaces
-			link_id = alt_text.toLowerCase().replace(/ ?\n/g," ");
-		}
-		url = "#"+link_id;
-
-		if (g_urls[link_id] != undefined) {
-			url = g_urls[link_id];
-			if (g_titles[link_id] != undefined) {
-				title = g_titles[link_id];
-			}
-		}
-		else {
-			return whole_match;
-		}
-	}
-
-	alt_text = alt_text.replace(/"/g,"&quot;");
-	url = escapeCharacters(url,"*_");
-	var result = "<img src=\"" + url + "\" alt=\"" + alt_text + "\"";
-
-	// attacklab: Markdown.pl adds empty title attributes to images.
-	// Replicate this bug.
-
-	//if (title != "") {
-		title = title.replace(/"/g,"&quot;");
-		title = escapeCharacters(title,"*_");
-		result +=  " title=\"" + title + "\"";
-	//}
-
-	result += " />";
-
-	return result;
-}
-
-
-var _DoHeaders = function(text) {
-
-	// Setext-style headers:
-	//	Header 1
-	//	========
-	//
-	//	Header 2
-	//	--------
-	//
-	text = text.replace(/^(.+)[ \t]*\n=+[ \t]*\n+/gm,
-		function(wholeMatch,m1){return hashBlock('<h1 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h1>");});
-
-	text = text.replace(/^(.+)[ \t]*\n-+[ \t]*\n+/gm,
-		function(matchFound,m1){return hashBlock('<h2 id="' + headerId(m1) + '">' + _RunSpanGamut(m1) + "</h2>");});
-
-	// atx-style headers:
-	//  # Header 1
-	//  ## Header 2
-	//  ## Header 2 with closing hashes ##
-	//  ...
-	//  ###### Header 6
-	//
-
-	/*
-		text = text.replace(/
-			^(\#{1,6})				// $1 = string of #'s
-			[ \t]*
-			(.+?)					// $2 = Header text
-			[ \t]*
-			\#*						// optional closing #'s (not counted)
-			\n+
-		/gm, function() {...});
-	*/
-
-	text = text.replace(/^(\#{1,6})[ \t]*(.+?)[ \t]*\#*\n+/gm,
-		function(wholeMatch,m1,m2) {
-			var h_level = m1.length;
-			return hashBlock("<h" + h_level + ' id="' + headerId(m2) + '">' + _RunSpanGamut(m2) + "</h" + h_level + ">");
-		});
-
-	function headerId(m) {
-		return m.replace(/[^\w]/g, '').toLowerCase();
-	}
-	return text;
-}
-
-// This declaration keeps Dojo compressor from outputting garbage:
-var _ProcessListItems;
-
-var _DoLists = function(text) {
-//
-// Form HTML ordered (numbered) and unordered (bulleted) lists.
-//
-
-	// attacklab: add sentinel to hack around khtml/safari bug:
-	// http://bugs.webkit.org/show_bug.cgi?id=11231
-	text += "~0";
-
-	// Re-usable pattern to match any entirel ul or ol list:
-
-	/*
-		var whole_list = /
-		(									// $1 = whole list
-			(								// $2
-				[ ]{0,3}					// attacklab: g_tab_width - 1
-				([*+-]|\d+[.])				// $3 = first list item marker
-				[ \t]+
-			)
-			[^\r]+?
-			(								// $4
-				~0							// sentinel for workaround; should be $
-			|
-				\n{2,}
-				(?=\S)
-				(?!							// Negative lookahead for another list item marker
-					[ \t]*
-					(?:[*+-]|\d+[.])[ \t]+
-				)
-			)
-		)/g
-	*/
-	var whole_list = /^(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/gm;
-
-	if (g_list_level) {
-		text = text.replace(whole_list,function(wholeMatch,m1,m2) {
-			var list = m1;
-			var list_type = (m2.search(/[*+-]/g)>-1) ? "ul" : "ol";
-
-			// Turn double returns into triple returns, so that we can make a
-			// paragraph for the last item in a list, if necessary:
-			list = list.replace(/\n{2,}/g,"\n\n\n");;
-			var result = _ProcessListItems(list);
-
-			// Trim any trailing whitespace, to put the closing `</$list_type>`
-			// up on the preceding line, to get it past the current stupid
-			// HTML block parser. This is a hack to work around the terrible
-			// hack that is the HTML block parser.
-			result = result.replace(/\s+$/,"");
-			result = "<"+list_type+">" + result + "</"+list_type+">\n";
-			return result;
-		});
-	} else {
-		whole_list = /(\n\n|^\n?)(([ ]{0,3}([*+-]|\d+[.])[ \t]+)[^\r]+?(~0|\n{2,}(?=\S)(?![ \t]*(?:[*+-]|\d+[.])[ \t]+)))/g;
-		text = text.replace(whole_list,function(wholeMatch,m1,m2,m3) {
-			var runup = m1;
-			var list = m2;
-
-			var list_type = (m3.search(/[*+-]/g)>-1) ? "ul" : "ol";
-			// Turn double returns into triple returns, so that we can make a
-			// paragraph for the last item in a list, if necessary:
-			var list = list.replace(/\n{2,}/g,"\n\n\n");;
-			var result = _ProcessListItems(list);
-			result = runup + "<"+list_type+">\n" + result + "</"+list_type+">\n";
-			return result;
-		});
-	}
-
-	// attacklab: strip sentinel
-	text = text.replace(/~0/,"");
-
-	return text;
-}
-
-_ProcessListItems = function(list_str) {
-//
-//  Process the contents of a single ordered or unordered list, splitting it
-//  into individual list items.
-//
-	// The $g_list_level global keeps track of when we're inside a list.
-	// Each time we enter a list, we increment it; when we leave a list,
-	// we decrement. If it's zero, we're not in a list anymore.
-	//
-	// We do this because when we're not inside a list, we want to treat
-	// something like this:
-	//
-	//    I recommend upgrading to version
-	//    8. Oops, now this line is treated
-	//    as a sub-list.
-	//
-	// As a single paragraph, despite the fact that the second line starts
-	// with a digit-period-space sequence.
-	//
-	// Whereas when we're inside a list (or sub-list), that line will be
-	// treated as the start of a sub-list. What a kludge, huh? This is
-	// an aspect of Markdown's syntax that's hard to parse perfectly
-	// without resorting to mind-reading. Perhaps the solution is to
-	// change the syntax rules such that sub-lists must start with a
-	// starting cardinal number; e.g. "1." or "a.".
-
-	g_list_level++;
-
-	// trim trailing blank lines:
-	list_str = list_str.replace(/\n{2,}$/,"\n");
-
-	// attacklab: add sentinel to emulate \z
-	list_str += "~0";
-
-	/*
-		list_str = list_str.replace(/
-			(\n)?							// leading line = $1
-			(^[ \t]*)						// leading whitespace = $2
-			([*+-]|\d+[.]) [ \t]+			// list marker = $3
-			([^\r]+?						// list item text   = $4
-			(\n{1,2}))
-			(?= \n* (~0 | \2 ([*+-]|\d+[.]) [ \t]+))
-		/gm, function(){...});
-	*/
-	list_str = list_str.replace(/(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm,
-		function(wholeMatch,m1,m2,m3,m4){
-			var item = m4;
-			var leading_line = m1;
-			var leading_space = m2;
-
-			if (leading_line || (item.search(/\n{2,}/)>-1)) {
-				item = _RunBlockGamut(_Outdent(item));
-			}
-			else {
-				// Recursion for sub-lists:
-				item = _DoLists(_Outdent(item));
-				item = item.replace(/\n$/,""); // chomp(item)
-				item = _RunSpanGamut(item);
-			}
-
-			return  "<li>" + item + "</li>\n";
-		}
-	);
-
-	// attacklab: strip sentinel
-	list_str = list_str.replace(/~0/g,"");
-
-	g_list_level--;
-	return list_str;
-}
-
-
-var _DoCodeBlocks = function(text) {
-//
-//  Process Markdown `<pre><code>` blocks.
-//
-
-	/*
-		text = text.replace(text,
-			/(?:\n\n|^)
-			(								// $1 = the code block -- one or more lines, starting with a space/tab
-				(?:
-					(?:[ ]{4}|\t)			// Lines must start with a tab or a tab-width of spaces - attacklab: g_tab_width
-					.*\n+
-				)+
-			)
-			(\n*[ ]{0,3}[^ \t\n]|(?=~0))	// attacklab: g_tab_width
-		/g,function(){...});
-	*/
-
-	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
-	text += "~0";
-
-	text = text.replace(/(?:\n\n|^)((?:(?:[ ]{4}|\t).*\n+)+)(\n*[ ]{0,3}[^ \t\n]|(?=~0))/g,
-		function(wholeMatch,m1,m2) {
-			var codeblock = m1;
-			var nextChar = m2;
-
-			codeblock = _EncodeCode( _Outdent(codeblock));
-			codeblock = _Detab(codeblock);
-			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
-			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
-
-			codeblock = "<pre><code>" + codeblock + "\n</code></pre>";
-
-			return hashBlock(codeblock) + nextChar;
-		}
-	);
-
-	// attacklab: strip sentinel
-	text = text.replace(/~0/,"");
-
-	return text;
-};
-
-var _DoGithubCodeBlocks = function(text) {
-//
-//  Process Github-style code blocks
-//  Example:
-//  ```ruby
-//  def hello_world(x)
-//    puts "Hello, #{x}"
-//  end
-//  ```
-//
-
-
-	// attacklab: sentinel workarounds for lack of \A and \Z, safari\khtml bug
-	text += "~0";
-
-	text = text.replace(/(?:^|\n)```(.*)\n([\s\S]*?)\n```/g,
-		function(wholeMatch,m1,m2) {
-			var language = m1;
-			var codeblock = m2;
-
-			codeblock = _EncodeCode(codeblock);
-			codeblock = _Detab(codeblock);
-			codeblock = codeblock.replace(/^\n+/g,""); // trim leading newlines
-			codeblock = codeblock.replace(/\n+$/g,""); // trim trailing whitespace
-
-			codeblock = "<pre><code" + (language ? " class=\"" + language + '"' : "") + ">" + codeblock + "\n</code></pre>";
-
-			return hashBlock(codeblock);
-		}
-	);
-
-	// attacklab: strip sentinel
-	text = text.replace(/~0/,"");
-
-	return text;
-}
-
-var hashBlock = function(text) {
-	text = text.replace(/(^\n+|\n+$)/g,"");
-	return "\n\n~K" + (g_html_blocks.push(text)-1) + "K\n\n";
-}
-
-var _DoCodeSpans = function(text) {
-//
-//   *  Backtick quotes are used for <code></code> spans.
-//
-//   *  You can use multiple backticks as the delimiters if you want to
-//	 include literal backticks in the code span. So, this input:
-//
-//		 Just type ``foo `bar` baz`` at the prompt.
-//
-//	   Will translate to:
-//
-//		 <p>Just type <code>foo `bar` baz</code> at the prompt.</p>
-//
-//	There's no arbitrary limit to the number of backticks you
-//	can use as delimters. If you need three consecutive backticks
-//	in your code, use four for delimiters, etc.
-//
-//  *  You can use spaces to get literal backticks at the edges:
-//
-//		 ... type `` `bar` `` ...
-//
-//	   Turns to:
-//
-//		 ... type <code>`bar`</code> ...
-//
-
-	/*
-		text = text.replace(/
-			(^|[^\\])					// Character before opening ` can't be a backslash
-			(`+)						// $2 = Opening run of `
-			(							// $3 = The code block
-				[^\r]*?
-				[^`]					// attacklab: work around lack of lookbehind
-			)
-			\2							// Matching closer
-			(?!`)
-		/gm, function(){...});
-	*/
-
-	text = text.replace(/(^|[^\\])(`+)([^\r]*?[^`])\2(?!`)/gm,
-		function(wholeMatch,m1,m2,m3,m4) {
-			var c = m3;
-			c = c.replace(/^([ \t]*)/g,"");	// leading whitespace
-			c = c.replace(/[ \t]*$/g,"");	// trailing whitespace
-			c = _EncodeCode(c);
-			return m1+"<code>"+c+"</code>";
-		});
-
-	return text;
-}
-
-var _EncodeCode = function(text) {
-//
-// Encode/escape certain characters inside Markdown code runs.
-// The point is that in code, these characters are literals,
-// and lose their special Markdown meanings.
-//
-	// Encode all ampersands; HTML entities are not
-	// entities within a Markdown code span.
-	text = text.replace(/&/g,"&amp;");
-
-	// Do the angle bracket song and dance:
-	text = text.replace(/</g,"&lt;");
-	text = text.replace(/>/g,"&gt;");
-
-	// Now, escape characters that are magic in Markdown:
-	text = escapeCharacters(text,"\*_{}[]\\",false);
-
-// jj the line above breaks this:
-//---
-
-//* Item
-
-//   1. Subitem
-
-//            special char: *
-//---
-
-	return text;
-}
-
-
-var _DoItalicsAndBold = function(text) {
-
-	// <strong> must go first:
-	text = text.replace(/(\*\*|__)(?=\S)([^\r]*?\S[*_]*)\1/g,
-		"<strong>$2</strong>");
-
-	text = text.replace(/(\*|_)(?=\S)([^\r]*?\S)\1/g,
-		"<em>$2</em>");
-
-	return text;
-}
-
-
-var _DoBlockQuotes = function(text) {
-
-	/*
-		text = text.replace(/
-		(								// Wrap whole match in $1
-			(
-				^[ \t]*>[ \t]?			// '>' at the start of a line
-				.+\n					// rest of the first line
-				(.+\n)*					// subsequent consecutive lines
-				\n*						// blanks
-			)+
-		)
-		/gm, function(){...});
-	*/
-
-	text = text.replace(/((^[ \t]*>[ \t]?.+\n(.+\n)*\n*)+)/gm,
-		function(wholeMatch,m1) {
-			var bq = m1;
-
-			// attacklab: hack around Konqueror 3.5.4 bug:
-			// "----------bug".replace(/^-/g,"") == "bug"
-
-			bq = bq.replace(/^[ \t]*>[ \t]?/gm,"~0");	// trim one level of quoting
-
-			// attacklab: clean up hack
-			bq = bq.replace(/~0/g,"");
-
-			bq = bq.replace(/^[ \t]+$/gm,"");		// trim whitespace-only lines
-			bq = _RunBlockGamut(bq);				// recurse
-
-			bq = bq.replace(/(^|\n)/g,"$1  ");
-			// These leading spaces screw with <pre> content, so we need to fix that:
-			bq = bq.replace(
-					/(\s*<pre>[^\r]+?<\/pre>)/gm,
-				function(wholeMatch,m1) {
-					var pre = m1;
-					// attacklab: hack around Konqueror 3.5.4 bug:
-					pre = pre.replace(/^  /mg,"~0");
-					pre = pre.replace(/~0/g,"");
-					return pre;
-				});
-
-			return hashBlock("<blockquote>\n" + bq + "\n</blockquote>");
-		});
-	return text;
-}
-
-
-var _FormParagraphs = function(text) {
-//
-//  Params:
-//    $text - string to process with html <p> tags
-//
-
-	// Strip leading and trailing lines:
-	text = text.replace(/^\n+/g,"");
-	text = text.replace(/\n+$/g,"");
-
-	var grafs = text.split(/\n{2,}/g);
-	var grafsOut = new Array();
-
-	//
-	// Wrap <p> tags.
-	//
-	var end = grafs.length;
-	for (var i=0; i<end; i++) {
-		var str = grafs[i];
-
-		// if this is an HTML marker, copy it
-		if (str.search(/~K(\d+)K/g) >= 0) {
-			grafsOut.push(str);
-		}
-		else if (str.search(/\S/) >= 0) {
-			str = _RunSpanGamut(str);
-			str = str.replace(/^([ \t]*)/g,"<p>");
-			str += "</p>"
-			grafsOut.push(str);
-		}
-
-	}
-
-	//
-	// Unhashify HTML blocks
-	//
-	end = grafsOut.length;
-	for (var i=0; i<end; i++) {
-		// if this is a marker for an html block...
-		while (grafsOut[i].search(/~K(\d+)K/) >= 0) {
-			var blockText = g_html_blocks[RegExp.$1];
-			blockText = blockText.replace(/\$/g,"$$$$"); // Escape any dollar signs
-			grafsOut[i] = grafsOut[i].replace(/~K\d+K/,blockText);
-		}
-	}
-
-	return grafsOut.join("\n\n");
-}
-
-
-var _EncodeAmpsAndAngles = function(text) {
-// Smart processing for ampersands and angle brackets that need to be encoded.
-
-	// Ampersand-encoding based entirely on Nat Irons's Amputator MT plugin:
-	//   http://bumppo.net/projects/amputator/
-	text = text.replace(/&(?!#?[xX]?(?:[0-9a-fA-F]+|\w+);)/g,"&amp;");
-
-	// Encode naked <'s
-	text = text.replace(/<(?![a-z\/?\$!])/gi,"&lt;");
-
-	return text;
-}
-
-
-var _EncodeBackslashEscapes = function(text) {
-//
-//   Parameter:  String.
-//   Returns:	The string, with after processing the following backslash
-//			   escape sequences.
-//
-
-	// attacklab: The polite way to do this is with the new
-	// escapeCharacters() function:
-	//
-	// 	text = escapeCharacters(text,"\\",true);
-	// 	text = escapeCharacters(text,"`*_{}[]()>#+-.!",true);
-	//
-	// ...but we're sidestepping its use of the (slow) RegExp constructor
-	// as an optimization for Firefox.  This function gets called a LOT.
-
-	text = text.replace(/\\(\\)/g,escapeCharacters_callback);
-	text = text.replace(/\\([`*_{}\[\]()>#+-.!])/g,escapeCharacters_callback);
-	return text;
-}
-
-
-var _DoAutoLinks = function(text) {
-
-	text = text.replace(/<((https?|ftp|dict):[^'">\s]+)>/gi,"<a href=\"$1\">$1</a>");
-
-	// Email addresses: <address@domain.foo>
-
-	/*
-		text = text.replace(/
-			<
-			(?:mailto:)?
-			(
-				[-.\w]+
-				\@
-				[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+
-			)
-			>
-		/gi, _DoAutoLinks_callback());
-	*/
-	text = text.replace(/<(?:mailto:)?([-.\w]+\@[-a-z0-9]+(\.[-a-z0-9]+)*\.[a-z]+)>/gi,
-		function(wholeMatch,m1) {
-			return _EncodeEmailAddress( _UnescapeSpecialChars(m1) );
-		}
-	);
-
-	return text;
-}
-
-
-var _EncodeEmailAddress = function(addr) {
-//
-//  Input: an email address, e.g. "foo@example.com"
-//
-//  Output: the email address as a mailto link, with each character
-//	of the address encoded as either a decimal or hex entity, in
-//	the hopes of foiling most address harvesting spam bots. E.g.:
-//
-//	<a href="&#x6D;&#97;&#105;&#108;&#x74;&#111;:&#102;&#111;&#111;&#64;&#101;
-//	   x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;">&#102;&#111;&#111;
-//	   &#64;&#101;x&#x61;&#109;&#x70;&#108;&#x65;&#x2E;&#99;&#111;&#109;</a>
-//
-//  Based on a filter by Matthew Wickline, posted to the BBEdit-Talk
-//  mailing list: <http://tinyurl.com/yu7ue>
-//
-
-	// attacklab: why can't javascript speak hex?
-	function char2hex(ch) {
-		var hexDigits = '0123456789ABCDEF';
-		var dec = ch.charCodeAt(0);
-		return(hexDigits.charAt(dec>>4) + hexDigits.charAt(dec&15));
-	}
-
-	var encode = [
-		function(ch){return "&#"+ch.charCodeAt(0)+";";},
-		function(ch){return "&#x"+char2hex(ch)+";";},
-		function(ch){return ch;}
-	];
-
-	addr = "mailto:" + addr;
-
-	addr = addr.replace(/./g, function(ch) {
-		if (ch == "@") {
-		   	// this *must* be encoded. I insist.
-			ch = encode[Math.floor(Math.random()*2)](ch);
-		} else if (ch !=":") {
-			// leave ':' alone (to spot mailto: later)
-			var r = Math.random();
-			// roughly 10% raw, 45% hex, 45% dec
-			ch =  (
-					r > .9  ?	encode[2](ch)   :
-					r > .45 ?	encode[1](ch)   :
-								encode[0](ch)
-				);
-		}
-		return ch;
-	});
-
-	addr = "<a href=\"" + addr + "\">" + addr + "</a>";
-	addr = addr.replace(/">.+:/g,"\">"); // strip the mailto: from the visible part
-
-	return addr;
-}
-
-
-var _UnescapeSpecialChars = function(text) {
-//
-// Swap back in all the special characters we've hidden.
-//
-	text = text.replace(/~E(\d+)E/g,
-		function(wholeMatch,m1) {
-			var charCodeToReplace = parseInt(m1);
-			return String.fromCharCode(charCodeToReplace);
-		}
-	);
-	return text;
-}
-
-
-var _Outdent = function(text) {
-//
-// Remove one level of line-leading tabs or spaces
-//
-
-	// attacklab: hack around Konqueror 3.5.4 bug:
-	// "----------bug".replace(/^-/g,"") == "bug"
-
-	text = text.replace(/^(\t|[ ]{1,4})/gm,"~0"); // attacklab: g_tab_width
-
-	// attacklab: clean up hack
-	text = text.replace(/~0/g,"")
-
-	return text;
-}
-
-var _Detab = function(text) {
-// attacklab: Detab's completely rewritten for speed.
-// In perl we could fix it by anchoring the regexp with \G.
-// In javascript we're less fortunate.
-
-	// expand first n-1 tabs
-	text = text.replace(/\t(?=\t)/g,"    "); // attacklab: g_tab_width
-
-	// replace the nth with two sentinels
-	text = text.replace(/\t/g,"~A~B");
-
-	// use the sentinel to anchor our regex so it doesn't explode
-	text = text.replace(/~B(.+?)~A/g,
-		function(wholeMatch,m1,m2) {
-			var leadingText = m1;
-			var numSpaces = 4 - leadingText.length % 4;  // attacklab: g_tab_width
-
-			// there *must* be a better way to do this:
-			for (var i=0; i<numSpaces; i++) leadingText+=" ";
-
-			return leadingText;
-		}
-	);
-
-	// clean up sentinels
-	text = text.replace(/~A/g,"    ");  // attacklab: g_tab_width
-	text = text.replace(/~B/g,"");
-
-	return text;
-}
-
-
-//
-//  attacklab: Utility functions
-//
-
-
-var escapeCharacters = function(text, charsToEscape, afterBackslash) {
-	// First we have to escape the escape characters so that
-	// we can build a character class out of them
-	var regexString = "([" + charsToEscape.replace(/([\[\]\\])/g,"\\$1") + "])";
-
-	if (afterBackslash) {
-		regexString = "\\\\" + regexString;
-	}
-
-	var regex = new RegExp(regexString,"g");
-	text = text.replace(regex,escapeCharacters_callback);
-
-	return text;
-}
-
-
-var escapeCharacters_callback = function(wholeMatch,m1) {
-	var charCodeToEscape = m1.charCodeAt(0);
-	return "~E"+charCodeToEscape+"E";
-}
-
-} // end of Showdown.converter
-
-// export
-if (typeof module !== 'undefined') module.exports = Showdown;

+ 21 - 17
package.json

@@ -1,30 +1,34 @@
 {
 {
-  "author": "Hakim El Hattab",
   "name": "reveal.js",
   "name": "reveal.js",
-  "description": "HTML5 Slideware with Presenter Notes",
-  "version": "1.5.1",
+  "version": "2.3.0",
+  "description": "The HTML Presentation Framework",
+  "homepage": "http://lab.hakim.se/reveal-js",
+  "author": {
+    "name": "Hakim El Hattab",
+    "email": "hakim.elhattab@gmail.com",
+    "web": "http://hakim.se"
+  },
   "repository": {
   "repository": {
     "type": "git",
     "type": "git",
     "url": "git://github.com/hakimel/reveal.js.git"
     "url": "git://github.com/hakimel/reveal.js.git"
   },
   },
   "engines": {
   "engines": {
-    "node": "0.8.*"
+    "node": "~0.8.0"
   },
   },
   "scripts": {
   "scripts": {
-    "start": "node ./plugin/multiplex/index.js"
+    "test": "grunt jshint"
   },
   },
-  "licenses": [
-    {
-      "type": "MIT",
-      "url": "https://github.com/hakimel/reveal.js/raw/master/LICENSE"
-    }
-  ],
   "dependencies": {
   "dependencies": {
-    "underscore": "1.3.3",
-    "express": "2.5.9",
-    "socket.io": "0.9.6",
-    "mustache": "0.4.0"
+    "underscore": "~1.3.3",
+    "express": "~2.5.9",
+    "socket.io": "~0.9.6",
+    "mustache": "~0.4.0"
   },
   },
-  "devDependencies": {},
-  "subdomain": "revealjs"
+  "devDependencies": {
+    "grunt-contrib-jshint": "~0.2.0",
+    "grunt-contrib-cssmin": "~0.4.1",
+    "grunt-contrib-uglify": "~0.1.1",
+    "grunt-contrib-watch": "~0.2.0",
+    "grunt": "~0.4.0"
+  }
 }
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8 - 0
plugin/highlight/highlight.js


+ 97 - 0
plugin/markdown/example.html

@@ -0,0 +1,97 @@
+<!doctype html>
+<html lang="en">
+
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Markdown Demo</title>
+
+		<link rel="stylesheet" href="../../css/reveal.css">
+		<link rel="stylesheet" href="../../css/theme/default.css" id="theme">
+	</head>
+
+	<body>
+
+		<div class="reveal">
+
+			<div class="slides">
+
+                <!-- Use external markdown resource, and separate slides by three newlines; vertical slides by two newlines -->
+                <section data-markdown="example.md" data-separator="^\n\n\n" data-vertical="^\n\n"></section>
+
+                <!-- Slides are separated by three dashes (quick 'n dirty regular expression) -->
+                <section data-markdown data-separator="---">
+                    <script type="text/template">
+                        ## Demo 1
+                        Slide 1
+                        ---
+                        ## Demo 1
+                        Slide 2
+                        ---
+                        ## Demo 1
+                        Slide 3
+                    </script>
+                </section>
+
+                <!-- Slides are separated by newline + three dashes + newline, vertical slides identical but two dashes -->
+                <section data-markdown data-separator="^\n---\n$" data-vertical="^\n--\n$">
+                    <script type="text/template">
+                        ## Demo 2
+                        Slide 1.1
+
+                        --
+
+                        ## Demo 2
+                        Slide 1.2
+
+                        ---
+
+                        ## Demo 2
+                        Slide 2
+                    </script>
+                </section>
+
+                <!-- No "extra" slides, since there are no separators defined (so they'll become horizontal rulers) -->
+                <section data-markdown>
+                    <script type="text/template">
+                        A
+
+                        ---
+
+                        B
+
+                        ---
+
+                        C
+                    </script>
+                </section>
+
+            </div>
+		</div>
+
+		<script src="../../lib/js/head.min.js"></script>
+		<script src="../../js/reveal.js"></script>
+
+		<script>
+
+			Reveal.initialize({
+				controls: true,
+				progress: true,
+				history: true,
+				center: true,
+
+				theme: Reveal.getQueryHash().theme,
+				transition: Reveal.getQueryHash().transition || 'default',
+
+				// Optional libraries used to extend on reveal.js
+				dependencies: [
+					{ src: '../../lib/js/classList.js', condition: function() { return !document.body.classList; } },
+					{ src: 'showdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+					{ src: 'markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }
+				]
+			});
+
+		</script>
+
+	</body>
+</html>

+ 29 - 0
plugin/markdown/example.md

@@ -0,0 +1,29 @@
+# Markdown Demo
+
+
+
+## External 1.1
+
+Content 1.1
+
+
+## External 1.2
+
+Content 1.2
+
+
+
+## External 2
+
+Content 2.1
+
+
+
+## External 3.1
+
+Content 3.1
+
+
+## External 3.2
+
+Content 3.2

+ 147 - 0
plugin/markdown/markdown.js

@@ -0,0 +1,147 @@
+// From https://gist.github.com/1343518
+// Modified by Hakim to handle Markdown indented with tabs
+(function(){
+
+    if( typeof Showdown === 'undefined' ) {
+        throw 'The reveal.js Markdown plugin requires Showdown to be loaded';
+    }
+
+    var stripLeadingWhitespace = function(section) {
+
+        var template = section.querySelector( 'script' );
+
+        // strip leading whitespace so it isn't evaluated as code
+        var text = ( template || section ).textContent;
+
+        var leadingWs = text.match(/^\n?(\s*)/)[1].length,
+            leadingTabs = text.match(/^\n?(\t*)/)[1].length;
+
+        if( leadingTabs > 0 ) {
+            text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' );
+        }
+        else if( leadingWs > 1 ) {
+            text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' );
+        }
+
+        return text;
+
+    };
+
+    var slidifyMarkdown = function(markdown, separator, vertical) {
+
+        separator = separator || '^\n---\n$';
+
+        var reSeparator = new RegExp(separator + (vertical ? '|' + vertical : ''), 'mg'),
+            reHorSeparator = new RegExp(separator),
+            matches,
+            lastIndex = 0,
+            isHorizontal,
+            wasHorizontal = true,
+            content,
+            sectionStack = [],
+            markdownSections = '';
+
+        // iterate until all blocks between separators are stacked up
+        while( matches = reSeparator.exec(markdown) ) {
+
+            // determine direction (horizontal by default)
+            isHorizontal = reHorSeparator.test(matches[0]);
+
+            if( !isHorizontal && wasHorizontal ) {
+                // create vertical stack
+                sectionStack.push([]);
+            }
+
+            // pluck slide content from markdown input
+            content = markdown.substring(lastIndex, matches.index);
+
+            if( isHorizontal && wasHorizontal ) {
+                // add to horizontal stack
+                sectionStack.push(content);
+            } else {
+                // add to vertical stack
+                sectionStack[sectionStack.length-1].push(content);
+            }
+
+            lastIndex = reSeparator.lastIndex;
+            wasHorizontal = isHorizontal;
+
+        }
+
+        // add the remaining slide
+        (wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1]).push(markdown.substring(lastIndex));
+
+        // flatten the hierarchical stack, and insert <section data-markdown> tags
+        for( var k = 0, klen = sectionStack.length; k < klen; k++ ) {
+            markdownSections += typeof sectionStack[k] === 'string'
+                ? '<section data-markdown>' + sectionStack[k] + '</section>'
+                : '<section><section data-markdown>' + sectionStack[k].join('</section><section data-markdown>') + '</section></section>';
+        }
+
+        return markdownSections;
+    };
+
+    var querySlidingMarkdown = function() {
+
+        var sections = document.querySelectorAll( '[data-markdown]'),
+            section;
+
+        for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
+
+            section = sections[j];
+
+            if( section.getAttribute('data-markdown').length ) {
+
+                var xhr = new XMLHttpRequest(),
+                    url = section.getAttribute('data-markdown');
+
+                xhr.onreadystatechange = function () {
+                    if( xhr.readyState === 4 ) {
+                        section.outerHTML = slidifyMarkdown( xhr.responseText, section.getAttribute('data-separator'), section.getAttribute('data-vertical') );
+                    }
+                };
+
+                xhr.open('GET', url, false);
+                xhr.send();
+
+            } else if( section.getAttribute('data-separator') ) {
+
+                var markdown = stripLeadingWhitespace(section);
+                section.outerHTML = slidifyMarkdown( markdown, section.getAttribute('data-separator'), section.getAttribute('data-vertical') );
+
+            }
+        }
+
+    };
+
+    var queryMarkdownSlides = function() {
+
+        var sections = document.querySelectorAll( '[data-markdown]');
+
+        for( var j = 0, jlen = sections.length; j < jlen; j++ ) {
+
+            makeHtml(sections[j]);
+
+        }
+
+    };
+
+    var makeHtml = function(section) {
+
+        var notes = section.querySelector( 'aside.notes' );
+
+        var markdown = stripLeadingWhitespace(section);
+
+        section.innerHTML = (new Showdown.converter()).makeHtml(markdown);
+
+        if( notes ) {
+            section.appendChild( notes );
+        }
+
+    };
+
+    querySlidingMarkdown();
+
+    queryMarkdownSlides();
+
+})();

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 61 - 0
plugin/markdown/showdown.js


+ 24 - 2
plugin/speakernotes/client.js → plugin/notes-server/client.js

@@ -2,11 +2,31 @@
 	// don't emit events from inside the previews themselves
 	// don't emit events from inside the previews themselves
 	if ( window.location.search.match( /receiver/gi ) ) { return; }
 	if ( window.location.search.match( /receiver/gi ) ) { return; }
 
 
-	var socket = io.connect('127.0.0.1:1947');
+	var socket = io.connect(window.location.origin);
 	var socketId = Math.random().toString().slice(2);
 	var socketId = Math.random().toString().slice(2);
 	
 	
 	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
 	console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId);
+	window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId);
 
 
+	// Fires when a fragment is shown
+	Reveal.addEventListener( 'fragmentshown', function( event ) {
+		var fragmentData = {
+			fragment : 'next',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when a fragment is hidden
+	Reveal.addEventListener( 'fragmenthidden', function( event ) {
+		var fragmentData = {
+			fragment : 'previous',
+			socketId : socketId
+		};
+		socket.emit('fragmentchanged', fragmentData);
+	} );
+
+	// Fires when slide is changed
 	Reveal.addEventListener( 'slidechanged', function( event ) {
 	Reveal.addEventListener( 'slidechanged', function( event ) {
 		var nextindexh;
 		var nextindexh;
 		var nextindexv;
 		var nextindexv;
@@ -27,7 +47,9 @@
 			indexv : event.indexv,
 			indexv : event.indexv,
 			nextindexh : nextindexh,
 			nextindexh : nextindexh,
 			nextindexv : nextindexv,
 			nextindexv : nextindexv,
-			socketId : socketId
+			socketId : socketId,
+			markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false
+
 		};
 		};
 
 
 		socket.emit('slidechanged', slideData);
 		socket.emit('slidechanged', slideData);

+ 8 - 5
plugin/speakernotes/index.js → plugin/notes-server/index.js

@@ -18,10 +18,13 @@ io.sockets.on('connection', function(socket) {
 	socket.on('slidechanged', function(slideData) {
 	socket.on('slidechanged', function(slideData) {
 		socket.broadcast.emit('slidedata', slideData);
 		socket.broadcast.emit('slidedata', slideData);
 	});
 	});
+	socket.on('fragmentchanged', function(fragmentData) {
+		socket.broadcast.emit('fragmentdata', fragmentData);
+	});
 });
 });
 
 
 app.configure(function() {
 app.configure(function() {
-	[ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) {
+	[ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) {
 		app.use('/' + dir, staticDir(opts.baseDir + dir));
 		app.use('/' + dir, staticDir(opts.baseDir + dir));
 	});
 	});
 });
 });
@@ -32,19 +35,19 @@ app.get("/", function(req, res) {
 
 
 app.get("/notes/:socketId", function(req, res) {
 app.get("/notes/:socketId", function(req, res) {
 
 
-	fs.readFile(opts.baseDir + 'plugin/speakernotes/notes.html', function(err, data) {
+	fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) {
 		res.send(Mustache.to_html(data.toString(), {
 		res.send(Mustache.to_html(data.toString(), {
 			socketId : req.params.socketId
 			socketId : req.params.socketId
 		}));
 		}));
 	});
 	});
-	// fs.createReadStream(opts.baseDir + 'speakernotes/notes.html').pipe(res);
+	// fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res);
 });
 });
 
 
 // Actually listen
 // Actually listen
 app.listen(opts.port || null);
 app.listen(opts.port || null);
 
 
-var brown = '\033[33m', 
-	green = '\033[32m', 
+var brown = '\033[33m',
+	green = '\033[32m',
 	reset = '\033[0m';
 	reset = '\033[0m';
 
 
 var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );
 var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' );

+ 45 - 15
plugin/speakernotes/notes.html → plugin/notes-server/notes.html

@@ -27,17 +27,23 @@
 				width: 1280px;
 				width: 1280px;
 				height: 1024px;
 				height: 1024px;
 				border: none;
 				border: none;
-				-moz-transform: scale(0.5);
-				-moz-transform-origin: 0 0;
-				-o-transform: scale(0.5);
-				-o-transform-origin: 0 0;
-				-webkit-transform: scale(0.5);
+				
 				-webkit-transform-origin: 0 0;
 				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+				 
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+				    -ms-transform: scale(0.5);
+				     -o-transform: scale(0.5);
+				        transform: scale(0.5);
 			}
 			}
 
 
 			#wrap-next-slide {
 			#wrap-next-slide {
-				width: 320px;
-				height: 256px;
+				width: 448px;
+				height: 358px;
 				float: left;
 				float: left;
 				margin: 0 0 0 10px;
 				margin: 0 0 0 10px;
 				overflow: hidden;
 				overflow: hidden;
@@ -47,12 +53,18 @@
 				width: 1280px;
 				width: 1280px;
 				height: 1024px;
 				height: 1024px;
 				border: none;
 				border: none;
-				-moz-transform: scale(0.25);
-				-moz-transform-origin: 0 0;
-				-o-transform: scale(0.25);
-				-o-transform-origin: 0 0;
-				-webkit-transform: scale(0.25);
+				
 				-webkit-transform-origin: 0 0;
 				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+				    -ms-transform-origin: 0 0;
+				     -o-transform-origin: 0 0;
+				        transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+				    -ms-transform: scale(0.35);
+				     -o-transform: scale(0.35);
+				        transform: scale(0.35);
 			}
 			}
 
 
 			.slides {
 			.slides {
@@ -87,6 +99,7 @@
 		<div id="notes"></div>
 		<div id="notes"></div>
 
 
 		<script src="/socket.io/socket.io.js"></script>
 		<script src="/socket.io/socket.io.js"></script>
+		<script src="/plugin/markdown/showdown.js"></script>
 
 
 		<script>
 		<script>
 		var socketId = '{{socketId}}';
 		var socketId = '{{socketId}}';
@@ -99,9 +112,26 @@
 			// ignore data from sockets that aren't ours
 			// ignore data from sockets that aren't ours
 			if (data.socketId !== socketId) { return; }
 			if (data.socketId !== socketId) { return; }
 
 
-			notes.innerHTML = data.notes;
-			currentSlide.contentWindow.Reveal.navigateTo(data.indexh, data.indexv);
-			nextSlide.contentWindow.Reveal.navigateTo(data.nextindexh, data.nextindexv);
+			if (data.markdown) {
+				notes.innerHTML = (new Showdown.converter()).makeHtml(data.notes);
+			}
+			else {
+				notes.innerHTML = data.notes;
+			}
+
+			currentSlide.contentWindow.Reveal.slide(data.indexh, data.indexv);
+			nextSlide.contentWindow.Reveal.slide(data.nextindexh, data.nextindexv);
+		});
+		socket.on('fragmentdata', function(data) {
+			// ignore data from sockets that aren't ours
+			if (data.socketId !== socketId) { return; }
+
+			if (data.fragment === 'next') {
+				currentSlide.contentWindow.Reveal.nextFragment();
+			}
+			else if (data.fragment === 'previous') {
+				currentSlide.contentWindow.Reveal.prevFragment();
+			}
 		});
 		});
 		</script>
 		</script>
 
 

+ 252 - 0
plugin/notes/notes.html

@@ -0,0 +1,252 @@
+<!doctype html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+
+		<title>reveal.js - Slide Notes</title>
+
+		<style>
+			body {
+				font-family: Helvetica;
+			}
+
+			#notes {
+				font-size: 24px;
+				width: 640px;
+				margin-top: 5px;
+			}
+
+			#wrap-current-slide {
+				width: 640px;
+				height: 512px;
+				float: left;
+				overflow: hidden;
+			}
+
+			#current-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.5);
+				   -moz-transform: scale(0.5);
+					-ms-transform: scale(0.5);
+					 -o-transform: scale(0.5);
+						transform: scale(0.5);
+			}
+
+			#wrap-next-slide {
+				width: 448px;
+				height: 358px;
+				float: left;
+				margin: 0 0 0 10px;
+				overflow: hidden;
+			}
+
+			#next-slide {
+				width: 1280px;
+				height: 1024px;
+				border: none;
+
+				-webkit-transform-origin: 0 0;
+				   -moz-transform-origin: 0 0;
+					-ms-transform-origin: 0 0;
+					 -o-transform-origin: 0 0;
+						transform-origin: 0 0;
+
+				-webkit-transform: scale(0.35);
+				   -moz-transform: scale(0.35);
+					-ms-transform: scale(0.35);
+					 -o-transform: scale(0.35);
+						transform: scale(0.35);
+			}
+
+			.slides {
+				position: relative;
+				margin-bottom: 10px;
+				border: 1px solid black;
+				border-radius: 2px;
+				background: rgb(28, 30, 32);
+			}
+
+			.slides span {
+				position: absolute;
+				top: 3px;
+				left: 3px;
+				font-weight: bold;
+				font-size: 14px;
+				color: rgba( 255, 255, 255, 0.9 );
+			}
+
+			.error {
+				font-weight: bold;
+				color: red;
+				font-size: 1.5em;
+				text-align: center;
+				margin-top: 10%;
+			}
+
+			.error code {
+				font-family: monospace;
+			}
+
+			.time {
+				width: 448px;
+				margin: 30px 0 0 10px;
+				float: left;
+				text-align: center;
+				opacity: 0;
+
+				-webkit-transition: opacity 0.4s;
+				   -moz-transition: opacity 0.4s;
+				     -o-transition: opacity 0.4s;
+				        transition: opacity 0.4s;
+			}
+
+			.elapsed,
+			.clock {
+				color: #333;
+				font-size: 2em;
+				text-align: center;
+				display: inline-block;
+				padding: 0.5em;
+				background-color: #eee;
+				border-radius: 10px;
+			}
+
+			.elapsed h2,
+			.clock h2 {
+				font-size: 0.8em;
+				line-height: 100%;
+				margin: 0;
+				color: #aaa;
+			}
+
+			.elapsed .mute {
+				color: #ddd;
+			}
+
+		</style>
+	</head>
+
+	<body>
+
+		<div id="wrap-current-slide" class="slides">
+			<script>document.write( '<iframe width="1280" height="1024" id="current-slide" src="'+ window.opener.location.href +'"></iframe>' );</script>
+		</div>
+
+		<div id="wrap-next-slide" class="slides">
+			<script>document.write( '<iframe width="640" height="512" id="next-slide" src="'+ window.opener.location.href +'"></iframe>' );</script>
+			<span>UPCOMING:</span>
+		</div>
+
+		<div class="time">
+			<div class="clock">
+				<h2>Time</h2>
+				<span id="clock">0:00:00 AM</span>
+			</div>
+			<div class="elapsed">
+				<h2>Elapsed</h2>
+				<span id="hours">00</span><span id="minutes">:00</span><span id="seconds">:00</span>
+			</div>
+		</div>
+
+		<div id="notes"></div>
+
+		<script src="../../plugin/markdown/showdown.js"></script>
+		<script>
+
+			window.addEventListener( 'load', function() {
+
+				if( window.opener && window.opener.location && window.opener.location.href ) {
+
+					var notes = document.getElementById( 'notes' ),
+						currentSlide = document.getElementById( 'current-slide' ),
+						nextSlide = document.getElementById( 'next-slide' );
+
+					window.addEventListener( 'message', function( event ) {
+						var data = JSON.parse( event.data );
+						// No need for updating the notes in case of fragment changes
+						if ( data.notes !== undefined) {
+							if( data.markdown ) {
+								notes.innerHTML = (new Showdown.converter()).makeHtml( data.notes );
+							}
+							else {
+								notes.innerHTML = data.notes;
+							}
+						}
+
+						// Showing and hiding fragments
+						if( data.fragment === 'next' ) {
+							currentSlide.contentWindow.Reveal.nextFragment();
+						}
+						else if( data.fragment === 'prev' ) {
+							currentSlide.contentWindow.Reveal.prevFragment();
+						}
+						else {
+							// Update the note slides
+							currentSlide.contentWindow.Reveal.slide( data.indexh, data.indexv );
+							nextSlide.contentWindow.Reveal.slide( data.nextindexh, data.nextindexv );
+						}
+
+					}, false );
+
+					var start = new Date(),
+						timeEl = document.querySelector( '.time' ),
+						clockEl = document.getElementById( 'clock' ),
+						hoursEl = document.getElementById( 'hours' ),
+						minutesEl = document.getElementById( 'minutes' ),
+						secondsEl = document.getElementById( 'seconds' );
+
+					setInterval( function() {
+
+						timeEl.style.opacity = 1;
+
+						var diff, hours, minutes, seconds,
+							now = new Date();
+
+						diff = now.getTime() - start.getTime();
+						hours = parseInt( diff / ( 1000 * 60 * 60 ) );
+						minutes = parseInt( ( diff / ( 1000 * 60 ) ) % 60 );
+						seconds = parseInt( ( diff / 1000 ) % 60 );
+
+						clockEl.innerHTML = now.toLocaleTimeString();
+						hoursEl.innerHTML = zeroPadInteger( hours );
+						hoursEl.className = hours > 0 ? "" : "mute";
+						minutesEl.innerHTML = ":" + zeroPadInteger( minutes );
+						minutesEl.className = minutes > 0 ? "" : "mute";
+						secondsEl.innerHTML = ":" + zeroPadInteger( seconds );
+
+					}, 1000 );
+
+					// Navigate the main window when the notes slide changes
+					currentSlide.contentWindow.Reveal.addEventListener( 'slidechanged', function( event ) {
+
+						window.opener.Reveal.slide( event.indexh, event.indexv );
+
+					} );
+
+				}
+				else {
+
+					document.body.innerHTML =  '<p class="error">Unable to access <code>window.opener.location</code>.<br>Make sure the presentation is running on a web server.</p>';
+
+				}
+
+
+			}, false );
+
+			function zeroPadInteger( num ) {
+				var str = "00" + parseInt( num );
+				return str.substring( str.length - 2 );
+			}
+
+		</script>
+	</body>
+</html>

+ 100 - 0
plugin/notes/notes.js

@@ -0,0 +1,100 @@
+/**
+ * Handles opening of and synchronization with the reveal.js
+ * notes window.
+ */
+var RevealNotes = (function() {
+
+	function openNotes() {
+		var jsFileLocation = document.querySelector('script[src$="notes.js"]').src;  // this js file path
+		jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, '');   // the js folder path
+		var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' );
+
+		// Fires when slide is changed
+		Reveal.addEventListener( 'slidechanged', function( event ) {
+			post('slidechanged');
+		} );
+
+		// Fires when a fragment is shown
+		Reveal.addEventListener( 'fragmentshown', function( event ) {
+			post('fragmentshown');
+		} );
+
+		// Fires when a fragment is hidden
+		Reveal.addEventListener( 'fragmenthidden', function( event ) {
+			post('fragmenthidden');
+		} );
+
+		/**
+		 * Posts the current slide data to the notes window
+		 *
+		 * @param {String} eventType Expecting 'slidechanged', 'fragmentshown' 
+		 * or 'fragmenthidden' set in the events above to define the needed 
+		 * slideDate.
+		 */
+		function post( eventType ) {
+			var slideElement = Reveal.getCurrentSlide(),
+				messageData;
+
+			if( eventType === 'slidechanged' ) {
+				var notes = slideElement.querySelector( 'aside.notes' ),
+					indexh = Reveal.getIndices().h,
+					indexv = Reveal.getIndices().v,
+					nextindexh,
+					nextindexv;
+
+				if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) {
+					nextindexh = indexh;
+					nextindexv = indexv + 1;
+				} else {
+					nextindexh = indexh + 1;
+					nextindexv = 0;
+				}
+
+				messageData = {
+					notes : notes ? notes.innerHTML : '',
+					indexh : indexh,
+					indexv : indexv,
+					nextindexh : nextindexh,
+					nextindexv : nextindexv,
+					markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false
+				};
+			}
+			else if( eventType === 'fragmentshown' ) {
+				messageData = {
+					fragment : 'next'
+				};
+			}
+			else if( eventType === 'fragmenthidden' ) {
+				messageData = {
+					fragment : 'prev'
+				};
+			}
+
+			notesPopup.postMessage( JSON.stringify( messageData ), '*' );
+		}
+
+		// Navigate to the current slide when the notes are loaded
+		notesPopup.addEventListener( 'load', function( event ) {
+			post('slidechanged');
+		}, false );
+	}
+
+	// If the there's a 'notes' query set, open directly
+	if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) {
+		openNotes();
+	}
+
+	// Open the notes when the 's' key is hit
+	document.addEventListener( 'keydown', function( event ) {
+		// Disregard the event if the target is editable or a
+		// modifier is present
+		if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return;
+
+		if( event.keyCode === 83 ) {
+			event.preventDefault();
+			openNotes();
+		}
+	}, false );
+
+	return { open: openNotes };
+})();

+ 39 - 0
plugin/postmessage/example.html

@@ -0,0 +1,39 @@
+<html>
+	<body>
+
+		<iframe id="reveal" src="../../index.html" style="border: 0;" width="500" height="500"></iframe>
+
+		<div>
+			<input id="back" type="button" value="go back"/>
+			<input id="ahead" type="button" value="go ahead"/>
+			<input id="slideto" type="button" value="slideto 2-2"/>
+		</div>
+
+		<script>
+
+			(function (){
+
+				var back = document.getElementById( 'back' ),
+						ahead = document.getElementById( 'ahead' ),
+						slideto = document.getElementById( 'slideto' ),
+						reveal =  window.frames[0];
+
+					back.addEventListener( 'click', function () {
+						
+					reveal.postMessage( JSON.stringify({method: 'prev', args: []}), '*' );
+				}, false );
+
+				ahead.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'next', args: []}), '*' );
+				}, false );
+
+				slideto.addEventListener( 'click', function (){
+					reveal.postMessage( JSON.stringify({method: 'slide', args: [2,2]}), '*' );
+				}, false );
+
+			}());
+
+		</script>
+
+	</body>
+</html>

+ 42 - 0
plugin/postmessage/postmessage.js

@@ -0,0 +1,42 @@
+/*
+
+	simple postmessage plugin
+
+	Useful when a reveal slideshow is inside an iframe.
+	It allows to call reveal methods from outside.
+
+	Example:
+		 var reveal =  window.frames[0];
+
+		 // Reveal.prev(); 
+		 reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*');
+		 // Reveal.next(); 
+		 reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*');
+		 // Reveal.slide(2, 2); 
+		 reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*');
+
+	Add to the slideshow:
+
+		dependencies: [
+			...
+			{ src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } }
+		]
+
+*/
+
+(function (){
+
+	window.addEventListener( "message", function ( event ) {
+		var data = JSON.parse( event.data ),
+				method = data.method,
+				args = data.args;
+
+		if( typeof Reveal[method] === 'function' ) {
+			Reveal[method].apply( Reveal, data.args );
+		}
+	}, false);
+
+}());
+
+
+

+ 39 - 0
plugin/print-pdf/print-pdf.js

@@ -0,0 +1,39 @@
+/**
+ * phantomjs script for printing presentations to PDF.
+ *
+ * Example:
+ * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf
+ *
+ * By Manuel Bieh (https://github.com/manuelbieh)
+ */
+
+// html2pdf.js
+var page = new WebPage();
+var system = require( 'system' );
+
+page.paperSize = {
+	format: 'A4',
+	orientation: 'landscape',
+	margin: {
+		left: '0',
+		right: '0',
+		top: '0',
+		bottom: '0'
+	}
+};
+page.zoomFactor = 1.5;
+
+var revealFile = system.args[1] || 'index.html?print-pdf';
+var slideFile = system.args[2] || 'slides.pdf';
+
+if( slideFile.match( /\.pdf$/gi ) === null ) {
+	slideFile += '.pdf';
+}
+
+console.log( 'Printing PDF...' );
+
+page.open( revealFile, function( status ) {
+	console.log( 'Printed succesfully' );
+	page.render( slideFile );
+	phantom.exit();
+} );

+ 30 - 0
plugin/remotes/remotes.js

@@ -0,0 +1,30 @@
+/**
+ * Touch-based remote controller for your presentation courtesy 
+ * of the folks at http://remotes.io
+ */
+
+(function(window){
+
+    /**
+     * Detects if we are dealing with a touch enabled device (with some false positives)
+     * Borrowed from modernizr: https://github.com/Modernizr/Modernizr/blob/master/feature-detects/touch.js   
+     */
+    var hasTouch  = (function(){
+        return ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch;
+    })();
+
+    if(!hasTouch){
+        head.ready( 'remotes.ne.min.js', function() {
+            new Remotes("preview")
+                .on("swipe-left", function(e){ Reveal.right(); })
+                .on("swipe-right", function(e){ Reveal.left(); })
+                .on("swipe-up", function(e){ Reveal.down(); })
+                .on("swipe-down", function(e){ Reveal.up(); })
+                .on("tap", function(e){ 
+                    Reveal.toggleOverview(); 
+                });
+        } );
+
+        head.js('https://raw.github.com/Remotes/Remotes/master/dist/remotes.ne.min.js');
+    }
+})(window);

+ 256 - 0
plugin/zoom-js/zoom.js

@@ -0,0 +1,256 @@
+// Custom reveal.js integration
+(function(){
+	var isEnabled = true;
+
+	document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) {
+		if( event.altKey && isEnabled ) {
+			event.preventDefault();
+			zoom.to({ element: event.target, pan: false });
+		}
+	} );
+
+	Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } );
+	Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } );
+})();
+
+/*!
+ * zoom.js 0.2 (modified version for use with reveal.js)
+ * http://lab.hakim.se/zoom-js
+ * MIT licensed
+ *
+ * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
+ */
+var zoom = (function(){
+
+	// The current zoom level (scale)
+	var level = 1;
+
+	// The current mouse position, used for panning
+	var mouseX = 0,
+		mouseY = 0;
+
+	// Timeout before pan is activated
+	var panEngageTimeout = -1,
+		panUpdateInterval = -1;
+
+	var currentOptions = null;
+
+	// Check for transform support so that we can fallback otherwise
+	var supportsTransforms = 	'WebkitTransform' in document.body.style ||
+								'MozTransform' in document.body.style ||
+								'msTransform' in document.body.style ||
+								'OTransform' in document.body.style ||
+								'transform' in document.body.style;
+
+	if( supportsTransforms ) {
+		// The easing that will be applied when we zoom in/out
+		document.body.style.transition = 'transform 0.8s ease';
+		document.body.style.OTransition = '-o-transform 0.8s ease';
+		document.body.style.msTransition = '-ms-transform 0.8s ease';
+		document.body.style.MozTransition = '-moz-transform 0.8s ease';
+		document.body.style.WebkitTransition = '-webkit-transform 0.8s ease';
+	}
+
+	// Zoom out if the user hits escape
+	document.addEventListener( 'keyup', function( event ) {
+		if( level !== 1 && event.keyCode === 27 ) {
+			zoom.out();
+		}
+	}, false );
+
+	// Monitor mouse movement for panning
+	document.addEventListener( 'mousemove', function( event ) {
+		if( level !== 1 ) {
+			mouseX = event.clientX;
+			mouseY = event.clientY;
+		}
+	}, false );
+
+	/**
+	 * Applies the CSS required to zoom in, prioritizes use of CSS3
+	 * transforms but falls back on zoom for IE.
+	 *
+	 * @param {Number} pageOffsetX
+	 * @param {Number} pageOffsetY
+	 * @param {Number} elementOffsetX
+	 * @param {Number} elementOffsetY
+	 * @param {Number} scale
+	 */
+	function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) {
+
+		if( supportsTransforms ) {
+			var origin = pageOffsetX +'px '+ pageOffsetY +'px',
+				transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')';
+
+			document.body.style.transformOrigin = origin;
+			document.body.style.OTransformOrigin = origin;
+			document.body.style.msTransformOrigin = origin;
+			document.body.style.MozTransformOrigin = origin;
+			document.body.style.WebkitTransformOrigin = origin;
+
+			document.body.style.transform = transform;
+			document.body.style.OTransform = transform;
+			document.body.style.msTransform = transform;
+			document.body.style.MozTransform = transform;
+			document.body.style.WebkitTransform = transform;
+		}
+		else {
+			// Reset all values
+			if( scale === 1 ) {
+				document.body.style.position = '';
+				document.body.style.left = '';
+				document.body.style.top = '';
+				document.body.style.width = '';
+				document.body.style.height = '';
+				document.body.style.zoom = '';
+			}
+			// Apply scale
+			else {
+				document.body.style.position = 'relative';
+				document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px';
+				document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px';
+				document.body.style.width = ( scale * 100 ) + '%';
+				document.body.style.height = ( scale * 100 ) + '%';
+				document.body.style.zoom = scale;
+			}
+		}
+
+		level = scale;
+
+		if( level !== 1 && document.documentElement.classList ) {
+			document.documentElement.classList.add( 'zoomed' );
+		}
+		else {
+			document.documentElement.classList.remove( 'zoomed' );
+		}
+	}
+
+	/**
+	 * Pan the document when the mosue cursor approaches the edges
+	 * of the window.
+	 */
+	function pan() {
+		var range = 0.12,
+			rangeX = window.innerWidth * range,
+			rangeY = window.innerHeight * range,
+			scrollOffset = getScrollOffset();
+
+		// Up
+		if( mouseY < rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) );
+		}
+		// Down
+		else if( mouseY > window.innerHeight - rangeY ) {
+			window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) );
+		}
+
+		// Left
+		if( mouseX < rangeX ) {
+			window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y );
+		}
+		// Right
+		else if( mouseX > window.innerWidth - rangeX ) {
+			window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y );
+		}
+	}
+
+	function getScrollOffset() {
+		return {
+			x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset,
+			y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset
+		}
+	}
+
+	return {
+		/**
+		 * Zooms in on either a rectangle or HTML element.
+		 *
+		 * @param {Object} options
+		 *   - element: HTML element to zoom in on
+		 *   OR
+		 *   - x/y: coordinates in non-transformed space to zoom in on
+		 *   - width/height: the portion of the screen to zoom in on
+		 *   - scale: can be used instead of width/height to explicitly set scale
+		 */
+		to: function( options ) {
+			// Due to an implementation limitation we can't zoom in
+			// to another element without zooming out first
+			if( level !== 1 ) {
+				zoom.out();
+			}
+			else {
+				options.x = options.x || 0;
+				options.y = options.y || 0;
+
+				// If an element is set, that takes precedence
+				if( !!options.element ) {
+					// Space around the zoomed in element to leave on screen
+					var padding = 20;
+
+					options.width = options.element.getBoundingClientRect().width + ( padding * 2 );
+					options.height = options.element.getBoundingClientRect().height + ( padding * 2 );
+					options.x = options.element.getBoundingClientRect().left - padding;
+					options.y = options.element.getBoundingClientRect().top - padding;
+				}
+
+				// If width/height values are set, calculate scale from those values
+				if( options.width !== undefined && options.height !== undefined ) {
+					options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 );
+				}
+
+				if( options.scale > 1 ) {
+					options.x *= options.scale;
+					options.y *= options.scale;
+
+					var scrollOffset = getScrollOffset();
+
+					if( options.element ) {
+						scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2;
+					}
+
+					magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale );
+
+					if( options.pan !== false ) {
+
+						// Wait with engaging panning as it may conflict with the
+						// zoom transition
+						panEngageTimeout = setTimeout( function() {
+							panUpdateInterval = setInterval( pan, 1000 / 60 );
+						}, 800 );
+
+					}
+				}
+
+				currentOptions = options;
+			}
+		},
+
+		/**
+		 * Resets the document zoom state to its default.
+		 */
+		out: function() {
+			clearTimeout( panEngageTimeout );
+			clearInterval( panUpdateInterval );
+
+			var scrollOffset = getScrollOffset();
+
+			if( currentOptions && currentOptions.element ) {
+				scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2;
+			}
+
+			magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 );
+
+			level = 1;
+		},
+
+		// Alias
+		magnify: function( options ) { this.to( options ) },
+		reset: function() { this.out() },
+
+		zoomLevel: function() {
+			return level;
+		}
+	}
+
+})();
+

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.