mirror of
https://github.com/zrgn/zrgn.github.io
synced 2024-12-26 00:26:33 +00:00
Add framework for creating reveal.js presentations.
This commit is contained in:
parent
08053c05d8
commit
80850677e1
58 changed files with 6582 additions and 34 deletions
19
Gruntfile.js
19
Gruntfile.js
|
@ -9,14 +9,23 @@ module.exports = function (grunt) {
|
||||||
options: { destPrefix: '_sass/vendor' },
|
options: { destPrefix: '_sass/vendor' },
|
||||||
files: {
|
files: {
|
||||||
'bulma/sass': 'bulma/sass',
|
'bulma/sass': 'bulma/sass',
|
||||||
'bulma/bulma.sass': 'bulma/bulma.sass'
|
'bulma/bulma.sass': 'bulma/bulma.sass',
|
||||||
|
'reveal': 'reveal.js/css',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
js: {
|
jquery: {
|
||||||
options: { destPrefix: 'assets/vendor/js' },
|
options: { destPrefix: 'assets/vendor/jquery' },
|
||||||
files: {
|
files: {
|
||||||
'jquery/jquery.min.js': 'jquery/dist/jquery.min.js',
|
'jquery.min.js': 'jquery/dist/jquery.min.js',
|
||||||
'jquery/jquery.min.map': 'jquery/dist/jquery.min.map'
|
'jquery.min.map': 'jquery/dist/jquery.min.map',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
reveal: {
|
||||||
|
options: { destPrefix: 'assets/vendor/reveal' },
|
||||||
|
files: {
|
||||||
|
'reveal.js': 'reveal.js/dist/reveal.js',
|
||||||
|
'reveal.css': 'reveal.js/dist/reveal.css',
|
||||||
|
'plugin': 'reveal.js/plugin',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,5 +23,11 @@ exclude:
|
||||||
- Gruntfile.js
|
- Gruntfile.js
|
||||||
- .eslintrc.json
|
- .eslintrc.json
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
- scope:
|
||||||
|
path: "presentations"
|
||||||
|
values:
|
||||||
|
layout: "presentation"
|
||||||
|
|
||||||
kramdown:
|
kramdown:
|
||||||
hard_wrap: false
|
hard_wrap: false
|
||||||
|
|
56
_layouts/presentation.html
Normal file
56
_layouts/presentation.html
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
{% capture reveal_home %}{{ site.baseurl }}/assets/vendor/reveal{% endcapture %}
|
||||||
|
{% assign theme = page.theme %}
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>{{ page.title }}</title>
|
||||||
|
|
||||||
|
<meta name="description" content=" {{ page.description }} "/>
|
||||||
|
<meta name="author" content="{{ page.author }}">
|
||||||
|
|
||||||
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="{{ reveal_home }}/reveal.css">
|
||||||
|
<link rel="stylesheet" href="{{ site.baseurl }}/assets/{{ theme }}" id="theme"/>
|
||||||
|
|
||||||
|
<!-- Printing and PDF exports -->
|
||||||
|
<script type="text/javascript">
|
||||||
|
var link = document.createElement( 'link' );
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.type = 'text/css';
|
||||||
|
link.href = window.location.search.match( /print-pdf/gi ) ? '{{ site.baseurl }}/assets/pdf.css' : '{{ site.baseurl }}/assets/paper.css';
|
||||||
|
document.getElementsByTagName( 'head' )[0].appendChild( link );
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" src="{{ reveal_home }}/reveal.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ reveal_home }}/plugin/markdown/markdown.js"></script>
|
||||||
|
<script type="text/javascript" src="{{ reveal_home }}/plugin/notes/notes.js"></script>
|
||||||
|
|
||||||
|
<div class="reveal">
|
||||||
|
<div class="slides">
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// Full list of configuration options available at:
|
||||||
|
// https://github.com/hakimel/reveal.js#configuration
|
||||||
|
Reveal.initialize({
|
||||||
|
controls: true,
|
||||||
|
progress: true,
|
||||||
|
history: true,
|
||||||
|
center: true,
|
||||||
|
width: 1600,
|
||||||
|
height: 900,
|
||||||
|
transition: 'slide', // none/fade/slide/convex/concave/zoom
|
||||||
|
plugins: [ RevealMarkdown, RevealNotes ]
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
151
_sass/_solarized.scss
Normal file
151
_sass/_solarized.scss
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
/*
|
||||||
|
A SCSS style-sheet for Pygments using the Solarized color-scheme
|
||||||
|
|
||||||
|
Information on Solarized is at http://ethanschoonover.com/solarized
|
||||||
|
|
||||||
|
Two mixins, solarized-dark and solarized-light are provided for convenience
|
||||||
|
and if you wish to use your own primary and secondary colors, you may call the
|
||||||
|
solarized mixin and provide parameters for the primary and secondary values.
|
||||||
|
|
||||||
|
The CSS class names are derived from the CSS classes that Pygments uses when
|
||||||
|
you generate a CSS file based on a style. E.g. pygmentize -S vim -f html
|
||||||
|
|
||||||
|
An explanation of the Pygments token types is at http://pygments.org/docs/tokens/
|
||||||
|
*/
|
||||||
|
|
||||||
|
$solarized-yellow: #b58900;
|
||||||
|
$solarized-orange: #cb4b16;
|
||||||
|
$solarized-red: #dc322f;
|
||||||
|
$solarized-magenta: #d33682;
|
||||||
|
$solarized-violet: #6c71c4;
|
||||||
|
$solarized-blue: #268bd2;
|
||||||
|
$solarized-cyan: #2aa198;
|
||||||
|
$solarized-green: #859900;
|
||||||
|
|
||||||
|
$solarized-base03: #002b36;
|
||||||
|
$solarized-base02: #073642;
|
||||||
|
$solarized-base01: #586e75;
|
||||||
|
$solarized-base00: #657b83;
|
||||||
|
$solarized-base0: #839496;
|
||||||
|
$solarized-base1: #93a1a1;
|
||||||
|
$solarized-base2: #eee8d5;
|
||||||
|
$solarized-base3: #fdf6e3;
|
||||||
|
|
||||||
|
$solarized-dark-primary: $solarized-base0;
|
||||||
|
$solarized-dark-secondary: $solarized-base01;
|
||||||
|
$solarized-dark-bg: $solarized-base03;
|
||||||
|
|
||||||
|
$solarized-light-primary: $solarized-base00;
|
||||||
|
$solarized-light-secondary: $solarized-base1;
|
||||||
|
$solarized-light-bg: $solarized-base3;
|
||||||
|
|
||||||
|
@mixin solarized($solarized-primary, $solarized-secondary) {
|
||||||
|
// Cyan
|
||||||
|
.m, // Literal.Number
|
||||||
|
.s, // Literal.String
|
||||||
|
.mf, // Literal.Number.Float
|
||||||
|
.mh, // Literal.Number.Hex
|
||||||
|
.mi, // Literal.Number.Integer
|
||||||
|
.mo, // Literal.Number.Oct
|
||||||
|
.sc, // Literal.String.Char
|
||||||
|
.s2, // Literal.String.Double
|
||||||
|
.si, // Literal.String.Interpol
|
||||||
|
.sx, // Literal.String.Other
|
||||||
|
.s1, // Literal.String.Single
|
||||||
|
.ss, // Literal.String.Symbol
|
||||||
|
.il, // Literal.Number.Integer.Long
|
||||||
|
.gd // Generic.Deleted
|
||||||
|
{ color: $solarized-cyan; }
|
||||||
|
|
||||||
|
// Green
|
||||||
|
.k, // Keyword
|
||||||
|
.o, // Operator
|
||||||
|
.ow, // Operator.Word
|
||||||
|
.cp, // Comment.Preproc
|
||||||
|
.cs, // Comment.Special
|
||||||
|
.gi, // Generic.Inserted
|
||||||
|
.kn, // Keyword.Namespace
|
||||||
|
.kp // Keyword.Pseudo
|
||||||
|
{ color: $solarized-green; }
|
||||||
|
|
||||||
|
// Orange
|
||||||
|
.x, // Other
|
||||||
|
.gh, // Generic.Heading
|
||||||
|
.gu, // Generic.Subheading
|
||||||
|
.kc, // Keyword.Constant
|
||||||
|
.no, // Name.Constant
|
||||||
|
.ni, // Name.Entity
|
||||||
|
.ne, // Name.Exception
|
||||||
|
.se // Literal.String.Escape
|
||||||
|
{ color: $solarized-orange; }
|
||||||
|
|
||||||
|
// Blue
|
||||||
|
.kd, // Keyword.Declaration
|
||||||
|
.kr, // Keyword.Reserved
|
||||||
|
.nc, // Name.Class
|
||||||
|
.nd, // Name.Decorator
|
||||||
|
.nf, // Name.Function
|
||||||
|
.nt, // Name.Tag
|
||||||
|
.nv, // Name.Variable
|
||||||
|
.bp, // Name.Builtin.Pseudo
|
||||||
|
.vc, // Name.Variable.Class
|
||||||
|
.vg, // Name.Variable.Global
|
||||||
|
.vi // Name.Variable.Instance
|
||||||
|
{ color: $solarized-blue; }
|
||||||
|
|
||||||
|
// Red
|
||||||
|
.gr, // Generic.Error
|
||||||
|
.kt, // Keyword.Type
|
||||||
|
.sr, // Literal.String.Regex
|
||||||
|
.err // Error
|
||||||
|
{ color: $solarized-red; }
|
||||||
|
|
||||||
|
// Yellow
|
||||||
|
.nb // Name.Builtin
|
||||||
|
{ color: $solarized-yellow; }
|
||||||
|
|
||||||
|
// Comments
|
||||||
|
.c, // Comment
|
||||||
|
.cm, // Comment.Multiline
|
||||||
|
.c1, // Comment.Single
|
||||||
|
.sb // Literal.String.Backtick
|
||||||
|
{ color: $solarized-secondary; }
|
||||||
|
|
||||||
|
// Default
|
||||||
|
.g, // Generic
|
||||||
|
.l, // Literal
|
||||||
|
.n, // Name
|
||||||
|
.p, // Punctuation
|
||||||
|
.w, // Text.Whitespace
|
||||||
|
.go, // Generic.Output
|
||||||
|
.gp, // Generic.Prompt
|
||||||
|
.gt, // Generic.Traceback
|
||||||
|
.na, // Name.Attribute
|
||||||
|
.nl, // Name.Label
|
||||||
|
.nn, // Name.Namespace
|
||||||
|
.nx, // Name.Other
|
||||||
|
.py, // Name.Property
|
||||||
|
.ld, // Literal.Date
|
||||||
|
.sd // Literal.String.Doc
|
||||||
|
{ color: $solarized-primary; }
|
||||||
|
|
||||||
|
.ge // Generic.Emph
|
||||||
|
{ color: $solarized-primary; font-style: italic; }
|
||||||
|
|
||||||
|
.gs // Generic.Strong
|
||||||
|
{ color: $solarized-primary; font-weight: bold; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarized-dark {
|
||||||
|
@include solarized($solarized-dark-primary, $solarized-dark-secondary);
|
||||||
|
background-color: $solarized-dark-bg;
|
||||||
|
color: $solarized-dark-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.solarized-light {
|
||||||
|
@include solarized($solarized-light-primary, $solarized-light-secondary);
|
||||||
|
background-color: $solarized-light-bg;
|
||||||
|
color: $solarized-light-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
57
_sass/vendor/reveal/layout.scss
vendored
Normal file
57
_sass/vendor/reveal/layout.scss
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* Layout helpers.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Stretch an element vertically based on available space
|
||||||
|
.reveal .stretch,
|
||||||
|
.reveal .r-stretch {
|
||||||
|
max-width: none;
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre.stretch code,
|
||||||
|
.reveal pre.r-stretch code {
|
||||||
|
height: 100%;
|
||||||
|
max-height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stack multiple elements on top of each other
|
||||||
|
.reveal .r-stack {
|
||||||
|
display: grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .r-stack > * {
|
||||||
|
grid-area: 1/1;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Horizontal and vertical stacks
|
||||||
|
.reveal .r-vstack,
|
||||||
|
.reveal .r-hstack {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .r-vstack {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .r-hstack {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Naming based on tailwindcss
|
||||||
|
.reveal .items-stretch { align-items: stretch; }
|
||||||
|
.reveal .items-start { align-items: flex-start; }
|
||||||
|
.reveal .items-center { align-items: center; }
|
||||||
|
.reveal .items-end { align-items: flex-end; }
|
||||||
|
|
||||||
|
.reveal .justify-between { justify-content: space-between; }
|
||||||
|
.reveal .justify-around { justify-content: space-around; }
|
||||||
|
.reveal .justify-start { justify-content: flex-start; }
|
||||||
|
.reveal .justify-center { justify-content: center; }
|
||||||
|
.reveal .justify-end { justify-content: flex-end; }
|
173
_sass/vendor/reveal/print/paper.scss
vendored
Normal file
173
_sass/vendor/reveal/print/paper.scss
vendored
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
/* 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. */
|
||||||
|
|
||||||
|
@media print {
|
||||||
|
html:not(.print-pdf) {
|
||||||
|
|
||||||
|
background: #fff;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
overflow: visible;
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #fff;
|
||||||
|
font-size: 20pt;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
border: 0;
|
||||||
|
margin: 0 5%;
|
||||||
|
padding: 0;
|
||||||
|
overflow: visible;
|
||||||
|
float: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nestedarrow,
|
||||||
|
.controls,
|
||||||
|
.fork-reveal,
|
||||||
|
.share-reveal,
|
||||||
|
.state-background,
|
||||||
|
.reveal .progress,
|
||||||
|
.reveal .backgrounds,
|
||||||
|
.reveal .slide-number {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
body, p, td, li {
|
||||||
|
font-size: 20pt!important;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1,h2,h3,h4,h5,h6 {
|
||||||
|
color: #000!important;
|
||||||
|
height: auto;
|
||||||
|
line-height: normal;
|
||||||
|
text-align: left;
|
||||||
|
letter-spacing: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Need to reduce the size of the fonts for printing */
|
||||||
|
h1 { font-size: 28pt !important; }
|
||||||
|
h2 { font-size: 24pt !important; }
|
||||||
|
h3 { font-size: 22pt !important; }
|
||||||
|
h4 { font-size: 22pt !important; font-variant: small-caps; }
|
||||||
|
h5 { font-size: 21pt !important; }
|
||||||
|
h6 { font-size: 20pt !important; font-style: italic; }
|
||||||
|
|
||||||
|
a:link,
|
||||||
|
a:visited {
|
||||||
|
color: #000 !important;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul, ol, div, p {
|
||||||
|
visibility: visible;
|
||||||
|
position: static;
|
||||||
|
width: auto;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
overflow: visible;
|
||||||
|
margin: 0;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
.reveal pre,
|
||||||
|
.reveal table {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.reveal pre code {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.reveal blockquote {
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.reveal .slides {
|
||||||
|
position: static !important;
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
|
||||||
|
left: 0 !important;
|
||||||
|
top: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
zoom: 1 !important;
|
||||||
|
transform: none !important;
|
||||||
|
|
||||||
|
overflow: visible !important;
|
||||||
|
display: block !important;
|
||||||
|
|
||||||
|
text-align: left !important;
|
||||||
|
perspective: none;
|
||||||
|
|
||||||
|
perspective-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
.reveal .slides section {
|
||||||
|
visibility: visible !important;
|
||||||
|
position: static !important;
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
display: block !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
|
||||||
|
left: 0 !important;
|
||||||
|
top: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
padding: 60px 20px !important;
|
||||||
|
z-index: auto !important;
|
||||||
|
|
||||||
|
opacity: 1 !important;
|
||||||
|
|
||||||
|
page-break-after: always !important;
|
||||||
|
|
||||||
|
transform-style: flat !important;
|
||||||
|
transform: none !important;
|
||||||
|
transition: none !important;
|
||||||
|
}
|
||||||
|
.reveal .slides section.stack {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
.reveal section:last-of-type {
|
||||||
|
page-break-after: avoid !important;
|
||||||
|
}
|
||||||
|
.reveal section .fragment {
|
||||||
|
opacity: 1 !important;
|
||||||
|
visibility: visible !important;
|
||||||
|
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
.reveal section img {
|
||||||
|
display: block;
|
||||||
|
margin: 15px 0px;
|
||||||
|
background: rgba(255,255,255,1);
|
||||||
|
border: 1px solid #666;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal section small {
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .hljs {
|
||||||
|
max-height: 100%;
|
||||||
|
white-space: pre-wrap;
|
||||||
|
word-wrap: break-word;
|
||||||
|
word-break: break-word;
|
||||||
|
font-size: 15pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .hljs .hljs-ln-numbers {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .hljs td {
|
||||||
|
font-size: inherit !important;
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
156
_sass/vendor/reveal/print/pdf.scss
vendored
Normal file
156
_sass/vendor/reveal/print/pdf.scss
vendored
Normal file
|
@ -0,0 +1,156 @@
|
||||||
|
/**
|
||||||
|
* This stylesheet is used to print reveal.js
|
||||||
|
* presentations to PDF.
|
||||||
|
*
|
||||||
|
* https://revealjs.revealjs.com/pdf-export/
|
||||||
|
*/
|
||||||
|
|
||||||
|
html.print-pdf {
|
||||||
|
* {
|
||||||
|
-webkit-print-color-adjust: exact;
|
||||||
|
}
|
||||||
|
|
||||||
|
& {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0 auto !important;
|
||||||
|
border: 0;
|
||||||
|
padding: 0;
|
||||||
|
float: none !important;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove any elements not needed in print. */
|
||||||
|
.nestedarrow,
|
||||||
|
.reveal .controls,
|
||||||
|
.reveal .progress,
|
||||||
|
.reveal .playback,
|
||||||
|
.reveal.overview,
|
||||||
|
.state-background {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
overflow: hidden !important;
|
||||||
|
font-family: Courier, 'Courier New', monospace !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
width: auto !important;
|
||||||
|
height: auto !important;
|
||||||
|
overflow: hidden !important;
|
||||||
|
}
|
||||||
|
.reveal .slides {
|
||||||
|
position: static;
|
||||||
|
width: 100% !important;
|
||||||
|
height: auto !important;
|
||||||
|
zoom: 1 !important;
|
||||||
|
pointer-events: initial;
|
||||||
|
|
||||||
|
left: auto;
|
||||||
|
top: auto;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
|
||||||
|
overflow: visible;
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
perspective: none;
|
||||||
|
perspective-origin: 50% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides .pdf-page {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
page-break-after: always;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section {
|
||||||
|
visibility: visible !important;
|
||||||
|
display: block !important;
|
||||||
|
position: absolute !important;
|
||||||
|
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
box-sizing: border-box !important;
|
||||||
|
min-height: 1px;
|
||||||
|
|
||||||
|
opacity: 1 !important;
|
||||||
|
|
||||||
|
transform-style: flat !important;
|
||||||
|
transform: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal section.stack {
|
||||||
|
position: relative !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
padding: 0 !important;
|
||||||
|
page-break-after: avoid !important;
|
||||||
|
height: auto !important;
|
||||||
|
min-height: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Slide backgrounds are placed inside of their slide when exporting to PDF */
|
||||||
|
.reveal .backgrounds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.reveal .slide-background {
|
||||||
|
display: block !important;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display slide speaker notes when 'showNotes' is enabled */
|
||||||
|
.reveal.show-notes {
|
||||||
|
max-width: none;
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
.reveal .speaker-notes-pdf {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
max-height: none;
|
||||||
|
top: auto;
|
||||||
|
right: auto;
|
||||||
|
bottom: auto;
|
||||||
|
left: auto;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layout option which makes notes appear on a separate page */
|
||||||
|
.reveal .speaker-notes-pdf[data-layout="separate-page"] {
|
||||||
|
position: relative;
|
||||||
|
color: inherit;
|
||||||
|
background-color: transparent;
|
||||||
|
padding: 20px;
|
||||||
|
page-break-after: always;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Display slide numbers when 'slideNumber' is enabled */
|
||||||
|
.reveal .slide-number-pdf {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This accessibility tool is not useful in PDF and breaks it visually */
|
||||||
|
.aria-status {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
1822
_sass/vendor/reveal/reveal.scss
vendored
Normal file
1822
_sass/vendor/reveal/reveal.scss
vendored
Normal file
File diff suppressed because it is too large
Load diff
21
_sass/vendor/reveal/theme/README.md
vendored
Normal file
21
_sass/vendor/reveal/theme/README.md
vendored
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Themes are written using Sass to keep things modular and reduce the need for repeated selectors across files. Make sure that you have the reveal.js development environment installed before proceeding: https://revealjs.revealjs.com/installation/#full-setup
|
||||||
|
|
||||||
|
## Creating a Theme
|
||||||
|
|
||||||
|
To create your own theme, start by duplicating a ```.scss``` file in [/css/theme/source](https://github.com/hakimel/reveal.js/blob/master/css/theme/source). It will be automatically compiled from Sass to CSS (see the [gulpfile](https://github.com/hakimel/reveal.js/blob/master/gulpfile.js)) when you run `npm run build -- css-themes`.
|
||||||
|
|
||||||
|
Each theme file 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 any selectors and styles you please.
|
||||||
|
|
||||||
|
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.
|
39
_sass/vendor/reveal/theme/source/beige.scss
vendored
Normal file
39
_sass/vendor/reveal/theme/source/beige.scss
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
@import url(fonts/league-gothic/league-gothic.css);
|
||||||
|
@import url(https://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";
|
||||||
|
// ---------------------------------------------
|
49
_sass/vendor/reveal/theme/source/black.scss
vendored
Normal file
49
_sass/vendor/reveal/theme/source/black.scss
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* Black theme for reveal.js. This is the opposite of the 'white' theme.
|
||||||
|
*
|
||||||
|
* By Hakim El Hattab, http://hakim.se
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$backgroundColor: #191919;
|
||||||
|
|
||||||
|
$mainColor: #fff;
|
||||||
|
$headingColor: #fff;
|
||||||
|
|
||||||
|
$mainFontSize: 42px;
|
||||||
|
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingLetterSpacing: normal;
|
||||||
|
$headingTextTransform: uppercase;
|
||||||
|
$headingFontWeight: 600;
|
||||||
|
$linkColor: #42affa;
|
||||||
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
|
$heading1Size: 2.5em;
|
||||||
|
$heading2Size: 1.6em;
|
||||||
|
$heading3Size: 1.3em;
|
||||||
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
|
section.has-light-background {
|
||||||
|
&, h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
78
_sass/vendor/reveal/theme/source/blood.scss
vendored
Normal file
78
_sass/vendor/reveal/theme/source/blood.scss
vendored
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* Blood theme for reveal.js
|
||||||
|
* Author: Walther http://github.com/Walther
|
||||||
|
*
|
||||||
|
* Designed to be used with highlight.js theme
|
||||||
|
* "monokai_sublime.css" available from
|
||||||
|
* https://github.com/isagalaev/highlight.js/
|
||||||
|
*
|
||||||
|
* For other themes, change $codeBackground accordingly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,700,300italic,700italic);
|
||||||
|
|
||||||
|
// Colors used in the theme
|
||||||
|
$blood: #a23;
|
||||||
|
$coal: #222;
|
||||||
|
$codeBackground: #23241f;
|
||||||
|
|
||||||
|
$backgroundColor: $coal;
|
||||||
|
|
||||||
|
// Main text
|
||||||
|
$mainFont: Ubuntu, 'sans-serif';
|
||||||
|
$mainColor: #eee;
|
||||||
|
|
||||||
|
// Headings
|
||||||
|
$headingFont: Ubuntu, 'sans-serif';
|
||||||
|
$headingTextShadow: 2px 2px 2px $coal;
|
||||||
|
|
||||||
|
// h1 shadow, borrowed humbly from
|
||||||
|
// (c) Default theme by Hakim El Hattab
|
||||||
|
$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);
|
||||||
|
|
||||||
|
// Links
|
||||||
|
$linkColor: $blood;
|
||||||
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
|
||||||
|
// Text selection
|
||||||
|
$selectionBackgroundColor: $blood;
|
||||||
|
$selectionColor: #fff;
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
// some overrides after theme template import
|
||||||
|
|
||||||
|
.reveal p {
|
||||||
|
font-weight: 300;
|
||||||
|
text-shadow: 1px 1px $coal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal p code {
|
||||||
|
background-color: $codeBackground;
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small code {
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
34
_sass/vendor/reveal/theme/source/league.scss
vendored
Normal file
34
_sass/vendor/reveal/theme/source/league.scss
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* League theme for reveal.js.
|
||||||
|
*
|
||||||
|
* This was the default theme pre-3.0.0.
|
||||||
|
*
|
||||||
|
* 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(fonts/league-gothic/league-gothic.css);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$headingTextShadow: 0px 0px 6px rgba(0,0,0,0.2);
|
||||||
|
$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";
|
||||||
|
// ---------------------------------------------
|
57
_sass/vendor/reveal/theme/source/moon.scss
vendored
Normal file
57
_sass/vendor/reveal/theme/source/moon.scss
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/**
|
||||||
|
* Solarized Dark theme for reveal.js.
|
||||||
|
* Author: Achim Staebler
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(fonts/league-gothic/league-gothic.css);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solarized colors by Ethan Schoonover
|
||||||
|
*/
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solarized colors
|
||||||
|
$base03: #002b36;
|
||||||
|
$base02: #073642;
|
||||||
|
$base01: #586e75;
|
||||||
|
$base00: #657b83;
|
||||||
|
$base0: #839496;
|
||||||
|
$base1: #93a1a1;
|
||||||
|
$base2: #eee8d5;
|
||||||
|
$base3: #fdf6e3;
|
||||||
|
$yellow: #b58900;
|
||||||
|
$orange: #cb4b16;
|
||||||
|
$red: #dc322f;
|
||||||
|
$magenta: #d33682;
|
||||||
|
$violet: #6c71c4;
|
||||||
|
$blue: #268bd2;
|
||||||
|
$cyan: #2aa198;
|
||||||
|
$green: #859900;
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$mainColor: $base1;
|
||||||
|
$headingColor: $base2;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$backgroundColor: $base03;
|
||||||
|
$linkColor: $blue;
|
||||||
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
$selectionBackgroundColor: $magenta;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
34
_sass/vendor/reveal/theme/source/night.scss
vendored
Normal file
34
_sass/vendor/reveal/theme/source/night.scss
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
/**
|
||||||
|
* 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(https://fonts.googleapis.com/css?family=Montserrat:700);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$backgroundColor: #111;
|
||||||
|
|
||||||
|
$mainFont: 'Open Sans', sans-serif;
|
||||||
|
$linkColor: #e7ad52;
|
||||||
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
$headingFont: 'Montserrat', Impact, sans-serif;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingLetterSpacing: -0.03em;
|
||||||
|
$headingTextTransform: none;
|
||||||
|
$selectionBackgroundColor: #e7ad52;
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
35
_sass/vendor/reveal/theme/source/serif.scss
vendored
Normal file
35
_sass/vendor/reveal/theme/source/serif.scss
vendored
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/**
|
||||||
|
* A simple theme for reveal.js presentations, similar
|
||||||
|
* to the default theme. The accent color is brown.
|
||||||
|
*
|
||||||
|
* This theme is Copyright (C) 2012-2013 Owen Versteeg, http://owenversteeg.com - it is MIT licensed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
.reveal a {
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
43
_sass/vendor/reveal/theme/source/simple.scss
vendored
Normal file
43
_sass/vendor/reveal/theme/source/simple.scss
vendored
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* 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(https://fonts.googleapis.com/css?family=News+Cycle:400,700);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$mainFont: 'Lato', sans-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);
|
||||||
|
|
||||||
|
section.has-dark-background {
|
||||||
|
&, h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
46
_sass/vendor/reveal/theme/source/sky.scss
vendored
Normal file
46
_sass/vendor/reveal/theme/source/sky.scss
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* 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(https://fonts.googleapis.com/css?family=Quicksand:400,700,400italic,700italic);
|
||||||
|
@import url(https://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;
|
||||||
|
|
||||||
|
// Fix links so they are not cut off
|
||||||
|
.reveal a {
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Background generator
|
||||||
|
@mixin bodyBackground() {
|
||||||
|
@include radial-gradient( #add9e4, #f7fbfc );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
63
_sass/vendor/reveal/theme/source/solarized.scss
vendored
Normal file
63
_sass/vendor/reveal/theme/source/solarized.scss
vendored
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* Solarized Light theme for reveal.js.
|
||||||
|
* Author: Achim Staebler
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(fonts/league-gothic/league-gothic.css);
|
||||||
|
@import url(https://fonts.googleapis.com/css?family=Lato:400,700,400italic,700italic);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solarized colors by Ethan Schoonover
|
||||||
|
*/
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solarized colors
|
||||||
|
$base03: #002b36;
|
||||||
|
$base02: #073642;
|
||||||
|
$base01: #586e75;
|
||||||
|
$base00: #657b83;
|
||||||
|
$base0: #839496;
|
||||||
|
$base1: #93a1a1;
|
||||||
|
$base2: #eee8d5;
|
||||||
|
$base3: #fdf6e3;
|
||||||
|
$yellow: #b58900;
|
||||||
|
$orange: #cb4b16;
|
||||||
|
$red: #dc322f;
|
||||||
|
$magenta: #d33682;
|
||||||
|
$violet: #6c71c4;
|
||||||
|
$blue: #268bd2;
|
||||||
|
$cyan: #2aa198;
|
||||||
|
$green: #859900;
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$mainColor: $base00;
|
||||||
|
$headingColor: $base01;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$backgroundColor: $base3;
|
||||||
|
$linkColor: $blue;
|
||||||
|
$linkColorHover: lighten( $linkColor, 20% );
|
||||||
|
$selectionBackgroundColor: $magenta;
|
||||||
|
|
||||||
|
// Background generator
|
||||||
|
// @mixin bodyBackground() {
|
||||||
|
// @include radial-gradient( rgba($base3,1), rgba(lighten($base3, 20%),1) );
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
49
_sass/vendor/reveal/theme/source/white.scss
vendored
Normal file
49
_sass/vendor/reveal/theme/source/white.scss
vendored
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/**
|
||||||
|
* White theme for reveal.js. This is the opposite of the 'black' theme.
|
||||||
|
*
|
||||||
|
* By Hakim El Hattab, http://hakim.se
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// Default mixins and settings -----------------
|
||||||
|
@import "../template/mixins";
|
||||||
|
@import "../template/settings";
|
||||||
|
// ---------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Include theme-specific fonts
|
||||||
|
@import url(fonts/source-sans-pro/source-sans-pro.css);
|
||||||
|
|
||||||
|
|
||||||
|
// Override theme settings (see ../template/settings.scss)
|
||||||
|
$backgroundColor: #fff;
|
||||||
|
|
||||||
|
$mainColor: #222;
|
||||||
|
$headingColor: #222;
|
||||||
|
|
||||||
|
$mainFontSize: 42px;
|
||||||
|
$mainFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingFont: 'Source Sans Pro', Helvetica, sans-serif;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingLetterSpacing: normal;
|
||||||
|
$headingTextTransform: uppercase;
|
||||||
|
$headingFontWeight: 600;
|
||||||
|
$linkColor: #2a76dd;
|
||||||
|
$linkColorHover: lighten( $linkColor, 15% );
|
||||||
|
$selectionBackgroundColor: lighten( $linkColor, 25% );
|
||||||
|
|
||||||
|
$heading1Size: 2.5em;
|
||||||
|
$heading2Size: 1.6em;
|
||||||
|
$heading3Size: 1.3em;
|
||||||
|
$heading4Size: 1.0em;
|
||||||
|
|
||||||
|
section.has-dark-background {
|
||||||
|
&, h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Theme template ------------------------------
|
||||||
|
@import "../template/theme";
|
||||||
|
// ---------------------------------------------
|
27
_sass/vendor/reveal/theme/template/exposer.scss
vendored
Normal file
27
_sass/vendor/reveal/theme/template/exposer.scss
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// Exposes theme's variables for easy re-use in CSS for plugin authors
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--background-color: #{$backgroundColor};
|
||||||
|
--main-font: #{$mainFont};
|
||||||
|
--main-font-size: #{$mainFontSize};
|
||||||
|
--main-color: #{$mainColor};
|
||||||
|
--block-margin: #{$blockMargin};
|
||||||
|
--heading-margin: #{$headingMargin};
|
||||||
|
--heading-font: #{$headingFont};
|
||||||
|
--heading-color: #{$headingColor};
|
||||||
|
--heading-line-height: #{$headingLineHeight};
|
||||||
|
--heading-letter-spacing: #{$headingLetterSpacing};
|
||||||
|
--heading-text-transform: #{$headingTextTransform};
|
||||||
|
--heading-text-shadow: #{$headingTextShadow};
|
||||||
|
--heading-font-weight: #{$headingFontWeight};
|
||||||
|
--heading1-text-shadow: #{$heading1TextShadow};
|
||||||
|
--heading1-size: #{$heading1Size};
|
||||||
|
--heading2-size: #{$heading2Size};
|
||||||
|
--heading3-size: #{$heading3Size};
|
||||||
|
--heading4-size: #{$heading4Size};
|
||||||
|
--code-font: #{$codeFont};
|
||||||
|
--link-color: #{$linkColor};
|
||||||
|
--link-color-hover: #{$linkColorHover};
|
||||||
|
--selection-background-color: #{$selectionBackgroundColor};
|
||||||
|
--selection-color: #{$selectionColor};
|
||||||
|
}
|
29
_sass/vendor/reveal/theme/template/mixins.scss
vendored
Normal file
29
_sass/vendor/reveal/theme/template/mixins.scss
vendored
Normal file
|
@ -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% );
|
||||||
|
}
|
45
_sass/vendor/reveal/theme/template/settings.scss
vendored
Normal file
45
_sass/vendor/reveal/theme/template/settings.scss
vendored
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
// 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', sans-serif;
|
||||||
|
$mainFontSize: 40px;
|
||||||
|
$mainColor: #eee;
|
||||||
|
|
||||||
|
// Vertical spacing between blocks of text
|
||||||
|
$blockMargin: 20px;
|
||||||
|
|
||||||
|
// Headings
|
||||||
|
$headingMargin: 0 0 $blockMargin 0;
|
||||||
|
$headingFont: 'League Gothic', Impact, sans-serif;
|
||||||
|
$headingColor: #eee;
|
||||||
|
$headingLineHeight: 1.2;
|
||||||
|
$headingLetterSpacing: normal;
|
||||||
|
$headingTextTransform: uppercase;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$headingFontWeight: normal;
|
||||||
|
$heading1TextShadow: $headingTextShadow;
|
||||||
|
|
||||||
|
$heading1Size: 3.77em;
|
||||||
|
$heading2Size: 2.11em;
|
||||||
|
$heading3Size: 1.55em;
|
||||||
|
$heading4Size: 1.00em;
|
||||||
|
|
||||||
|
$codeFont: monospace;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
310
_sass/vendor/reveal/theme/template/theme.scss
vendored
Normal file
310
_sass/vendor/reveal/theme/template/theme.scss
vendored
Normal file
|
@ -0,0 +1,310 @@
|
||||||
|
// Base theme template for reveal.js
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* GLOBAL STYLES
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
@import "./exposer";
|
||||||
|
|
||||||
|
.reveal-viewport {
|
||||||
|
@include bodyBackground();
|
||||||
|
background-color: $backgroundColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal {
|
||||||
|
font-family: $mainFont;
|
||||||
|
font-size: $mainFontSize;
|
||||||
|
font-weight: normal;
|
||||||
|
color: $mainColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::selection {
|
||||||
|
color: $selectionColor;
|
||||||
|
background: $selectionBackgroundColor;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ::-moz-selection {
|
||||||
|
color: $selectionColor;
|
||||||
|
background: $selectionBackgroundColor;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides section,
|
||||||
|
.reveal .slides section>section {
|
||||||
|
line-height: 1.3;
|
||||||
|
font-weight: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* HEADERS
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal h1,
|
||||||
|
.reveal h2,
|
||||||
|
.reveal h3,
|
||||||
|
.reveal h4,
|
||||||
|
.reveal h5,
|
||||||
|
.reveal h6 {
|
||||||
|
margin: $headingMargin;
|
||||||
|
color: $headingColor;
|
||||||
|
|
||||||
|
font-family: $headingFont;
|
||||||
|
font-weight: $headingFontWeight;
|
||||||
|
line-height: $headingLineHeight;
|
||||||
|
letter-spacing: $headingLetterSpacing;
|
||||||
|
|
||||||
|
text-transform: $headingTextTransform;
|
||||||
|
text-shadow: $headingTextShadow;
|
||||||
|
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal h1 {font-size: $heading1Size; }
|
||||||
|
.reveal h2 {font-size: $heading2Size; }
|
||||||
|
.reveal h3 {font-size: $heading3Size; }
|
||||||
|
.reveal h4 {font-size: $heading4Size; }
|
||||||
|
|
||||||
|
.reveal h1 {
|
||||||
|
text-shadow: $heading1TextShadow;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* OTHER
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal p {
|
||||||
|
margin: $blockMargin 0;
|
||||||
|
line-height: 1.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ensure certain elements are never larger than the slide itself */
|
||||||
|
.reveal img,
|
||||||
|
.reveal video,
|
||||||
|
.reveal iframe {
|
||||||
|
max-width: 95%;
|
||||||
|
max-height: 95%;
|
||||||
|
}
|
||||||
|
.reveal strong,
|
||||||
|
.reveal b {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal em {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol,
|
||||||
|
.reveal dl,
|
||||||
|
.reveal ul {
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
margin: 0 0 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ol {
|
||||||
|
list-style-type: decimal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul {
|
||||||
|
list-style-type: disc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul {
|
||||||
|
list-style-type: square;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul ul {
|
||||||
|
list-style-type: circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal ul ul,
|
||||||
|
.reveal ul ol,
|
||||||
|
.reveal ol ol,
|
||||||
|
.reveal ol ul {
|
||||||
|
display: block;
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dt {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal dd {
|
||||||
|
margin-left: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal blockquote {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 70%;
|
||||||
|
margin: $blockMargin auto;
|
||||||
|
padding: 5px;
|
||||||
|
|
||||||
|
font-style: italic;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
box-shadow: 0px 0px 2px rgba(0,0,0,0.2);
|
||||||
|
}
|
||||||
|
.reveal blockquote p:first-child,
|
||||||
|
.reveal blockquote p:last-child {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal q {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 90%;
|
||||||
|
margin: $blockMargin auto;
|
||||||
|
|
||||||
|
text-align: left;
|
||||||
|
font-size: 0.55em;
|
||||||
|
font-family: $codeFont;
|
||||||
|
line-height: 1.2em;
|
||||||
|
|
||||||
|
word-wrap: break-word;
|
||||||
|
|
||||||
|
box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal code {
|
||||||
|
font-family: $codeFont;
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal pre code {
|
||||||
|
display: block;
|
||||||
|
padding: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 400px;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table {
|
||||||
|
margin: auto;
|
||||||
|
border-collapse: collapse;
|
||||||
|
border-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th,
|
||||||
|
.reveal table td {
|
||||||
|
text-align: left;
|
||||||
|
padding: 0.2em 0.5em 0.2em 0.5em;
|
||||||
|
border-bottom: 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align="center"],
|
||||||
|
.reveal table td[align="center"] {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table th[align="right"],
|
||||||
|
.reveal table td[align="right"] {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal table tbody tr:last-child th,
|
||||||
|
.reveal table tbody tr:last-child td {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal sup {
|
||||||
|
vertical-align: super;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
.reveal sub {
|
||||||
|
vertical-align: sub;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.6em;
|
||||||
|
line-height: 1.2em;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal small * {
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal img {
|
||||||
|
margin: $blockMargin 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* LINKS
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal a {
|
||||||
|
color: $linkColor;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: color .15s ease;
|
||||||
|
}
|
||||||
|
.reveal a:hover {
|
||||||
|
color: $linkColorHover;
|
||||||
|
text-shadow: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .roll span:after {
|
||||||
|
color: #fff;
|
||||||
|
background: darken( $linkColor, 15% );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Frame helper
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal .r-frame {
|
||||||
|
border: 4px solid $mainColor;
|
||||||
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a .r-frame {
|
||||||
|
transition: all .15s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal a:hover .r-frame {
|
||||||
|
border-color: $linkColor;
|
||||||
|
box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* NAVIGATION CONTROLS
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal .controls {
|
||||||
|
color: $linkColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PROGRESS BAR
|
||||||
|
*********************************************/
|
||||||
|
|
||||||
|
.reveal .progress {
|
||||||
|
background: rgba(0,0,0,0.2);
|
||||||
|
color: $linkColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* PRINT BACKGROUND
|
||||||
|
*********************************************/
|
||||||
|
@media print {
|
||||||
|
.backgrounds {
|
||||||
|
background-color: $backgroundColor;
|
||||||
|
}
|
||||||
|
}
|
3
assets/paper.scss
Normal file
3
assets/paper.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
@import "vendor/reveal/print/paper";
|
3
assets/pdf.scss
Normal file
3
assets/pdf.scss
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
@import "vendor/reveal/print/pdf";
|
223
assets/presentation-dark.scss
Normal file
223
assets/presentation-dark.scss
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
@import "solarized";
|
||||||
|
|
||||||
|
@import "vendor/reveal/theme/template/mixins";
|
||||||
|
@import "vendor/reveal/theme/template/settings";
|
||||||
|
|
||||||
|
// Override Reveal.js variables
|
||||||
|
$mainColor: $solarized-dark-primary;
|
||||||
|
$headingColor: $solarized-dark-secondary;
|
||||||
|
$backgroundColor: $solarized-dark-bg;
|
||||||
|
$selectionBackgroundColor: $solarized-magenta;
|
||||||
|
$linkColor: $solarized-blue;
|
||||||
|
$linkColorHover: lighten($linkColor, 20%);
|
||||||
|
|
||||||
|
$mainFont: sans-serif;
|
||||||
|
$mainFontSize: 37px;
|
||||||
|
|
||||||
|
$headingFont: sans-serif;
|
||||||
|
$headingTextTransform: none;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$heading1Size: 70px;
|
||||||
|
$heading2Size: 60px;
|
||||||
|
$heading3Size: 50px;
|
||||||
|
$heading4Size: 40px;
|
||||||
|
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides {
|
||||||
|
top: 45% !important;
|
||||||
|
|
||||||
|
section, section > section {
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: transparentize($solarized-dark-bg, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > pre {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > code {
|
||||||
|
max-height: 750px;
|
||||||
|
background-color: transparentize($solarized-dark-bg, 0.3);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > p {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul, & > ol {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.two_column {
|
||||||
|
float: left;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.left_float {
|
||||||
|
float: left;
|
||||||
|
margin-left: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.right_float {
|
||||||
|
float: right;
|
||||||
|
margin-right: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.action_block {
|
||||||
|
margin-top: 50px;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
& > pre, & > img {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
display: inline;
|
||||||
|
float: left;
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > pre > code {
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid $solarized-dark-secondary;
|
||||||
|
background-color: $solarized-dark-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead tr, tr:nth-child(even) {
|
||||||
|
background-color: lighten($solarized-dark-bg, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syntax highlighting.
|
||||||
|
// See http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html
|
||||||
|
.hljs, .hljs .none {
|
||||||
|
padding: 10px;
|
||||||
|
background: $solarized-dark-bg;
|
||||||
|
color: $solarized-dark-primary;
|
||||||
|
font-family: monospace;
|
||||||
|
overflow-x: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs :not(.none) {
|
||||||
|
.hljs-function .hljs-params {
|
||||||
|
color: $solarized-dark-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.diff .hljs-header,
|
||||||
|
.hljs-doctype,
|
||||||
|
.hljs-pi,
|
||||||
|
.hljs-javadoc {
|
||||||
|
color: $solarized-dark-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition,
|
||||||
|
.css .hljs-tag,
|
||||||
|
.hljs-request,
|
||||||
|
.hljs-status {
|
||||||
|
color: $solarized-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-tag .hljs-value,
|
||||||
|
.hljs-rules .hljs-value,
|
||||||
|
.hljs-hexcolor,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-link_url {
|
||||||
|
color: $solarized-cyan;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-command,
|
||||||
|
.hljs-localvars,
|
||||||
|
.hljs-chunk,
|
||||||
|
.hljs-decorator,
|
||||||
|
.hljs-annotation,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-class .hljs-title,
|
||||||
|
.hljs-parent,
|
||||||
|
.hljs-id,
|
||||||
|
.hljs-keyword,
|
||||||
|
.method,
|
||||||
|
.hljs-function {
|
||||||
|
color: $solarized-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-preprocessor,
|
||||||
|
.hljs-preprocessor .hljs-keyword,
|
||||||
|
.hljs-pragma,
|
||||||
|
.hljs-shebang,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-symbol .hljs-string,
|
||||||
|
.diff .hljs-change,
|
||||||
|
.hljs-special,
|
||||||
|
.hljs-attr_selector,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-cdata,
|
||||||
|
.hljs-constant,
|
||||||
|
.css .hljs-pseudo,
|
||||||
|
.hljs-header {
|
||||||
|
color: $solarized-orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-important {
|
||||||
|
color: $solarized-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link_label {
|
||||||
|
color: $solarized-violet;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link_reference {
|
||||||
|
color: $solarized-yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "vendor/reveal/theme/template/theme";
|
223
assets/presentation.scss
Normal file
223
assets/presentation.scss
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
---
|
||||||
|
---
|
||||||
|
@import "solarized";
|
||||||
|
|
||||||
|
@import "vendor/reveal/theme/template/mixins";
|
||||||
|
@import "vendor/reveal/theme/template/settings";
|
||||||
|
|
||||||
|
// Override Reveal.js variables
|
||||||
|
$mainColor: $solarized-light-primary;
|
||||||
|
$headingColor: $solarized-light-secondary;
|
||||||
|
$backgroundColor: $solarized-light-bg;
|
||||||
|
$selectionBackgroundColor: $solarized-magenta;
|
||||||
|
$linkColor: $solarized-blue;
|
||||||
|
$linkColorHover: lighten($linkColor, 20%);
|
||||||
|
|
||||||
|
$mainFont: sans-serif;
|
||||||
|
$mainFontSize: 37px;
|
||||||
|
|
||||||
|
$headingFont: sans-serif;
|
||||||
|
$headingTextTransform: none;
|
||||||
|
$headingTextShadow: none;
|
||||||
|
$heading1Size: 70px;
|
||||||
|
$heading2Size: 60px;
|
||||||
|
$heading3Size: 50px;
|
||||||
|
$heading4Size: 40px;
|
||||||
|
|
||||||
|
html * {
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reveal .slides {
|
||||||
|
top: 45% !important;
|
||||||
|
|
||||||
|
section, section > section {
|
||||||
|
padding-top: 5px;
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
background-color: transparentize($solarized-light-bg, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
& > pre {
|
||||||
|
margin-top: 30px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
pre > code {
|
||||||
|
max-height: 750px;
|
||||||
|
background-color: transparentize($solarized-dark-bg, 0.3);
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > p {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul, & > ol {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.two_column {
|
||||||
|
float: left;
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.left_float {
|
||||||
|
float: left;
|
||||||
|
margin-left: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.right_float {
|
||||||
|
float: right;
|
||||||
|
margin-right: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.action_block {
|
||||||
|
margin-top: 50px;
|
||||||
|
vertical-align: middle;
|
||||||
|
|
||||||
|
& > pre, & > img {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
display: inline;
|
||||||
|
float: left;
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > pre > code {
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
margin-top: 30px;
|
||||||
|
|
||||||
|
tr {
|
||||||
|
border-bottom: 1px solid $solarized-light-secondary;
|
||||||
|
background-color: $solarized-light-bg;
|
||||||
|
}
|
||||||
|
|
||||||
|
thead tr, tr:nth-child(even) {
|
||||||
|
background-color: lighten($solarized-light-bg, 5%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Syntax highlighting.
|
||||||
|
// See http://highlightjs.readthedocs.org/en/latest/css-classes-reference.html
|
||||||
|
.hljs, .hljs .none {
|
||||||
|
padding: 10px;
|
||||||
|
background: $solarized-light-bg;
|
||||||
|
color: $solarized-light-primary;
|
||||||
|
font-family: monospace;
|
||||||
|
overflow-x: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs :not(.none) {
|
||||||
|
.hljs-function .hljs-params {
|
||||||
|
color: $solarized-light-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.diff .hljs-header,
|
||||||
|
.hljs-doctype,
|
||||||
|
.hljs-pi,
|
||||||
|
.hljs-javadoc {
|
||||||
|
color: $solarized-light-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition,
|
||||||
|
.css .hljs-tag,
|
||||||
|
.hljs-request,
|
||||||
|
.hljs-status {
|
||||||
|
color: $solarized-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-tag .hljs-value,
|
||||||
|
.hljs-rules .hljs-value,
|
||||||
|
.hljs-hexcolor,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-link_url {
|
||||||
|
color: $solarized-cyan;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-command,
|
||||||
|
.hljs-localvars,
|
||||||
|
.hljs-chunk,
|
||||||
|
.hljs-decorator,
|
||||||
|
.hljs-annotation,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-class .hljs-title,
|
||||||
|
.hljs-parent,
|
||||||
|
.hljs-id,
|
||||||
|
.hljs-keyword,
|
||||||
|
.method,
|
||||||
|
.hljs-function {
|
||||||
|
color: $solarized-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-preprocessor,
|
||||||
|
.hljs-preprocessor .hljs-keyword,
|
||||||
|
.hljs-pragma,
|
||||||
|
.hljs-shebang,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-symbol .hljs-string,
|
||||||
|
.diff .hljs-change,
|
||||||
|
.hljs-special,
|
||||||
|
.hljs-attr_selector,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-cdata,
|
||||||
|
.hljs-constant,
|
||||||
|
.css .hljs-pseudo,
|
||||||
|
.hljs-header {
|
||||||
|
color: $solarized-orange;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-important {
|
||||||
|
color: $solarized-red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link_label {
|
||||||
|
color: $solarized-violet;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-link_reference {
|
||||||
|
color: $solarized-yellow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "vendor/reveal/theme/template/theme";
|
2
assets/vendor/jquery/jquery.min.js
vendored
Normal file
2
assets/vendor/jquery/jquery.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/vendor/jquery/jquery.min.map
vendored
Normal file
1
assets/vendor/jquery/jquery.min.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
assets/vendor/js/jquery/jquery.min.js
vendored
2
assets/vendor/js/jquery/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
1
assets/vendor/js/jquery/jquery.min.map
vendored
1
assets/vendor/js/jquery/jquery.min.map
vendored
File diff suppressed because one or more lines are too long
5
assets/vendor/reveal/plugin/highlight/highlight.esm.js
vendored
Normal file
5
assets/vendor/reveal/plugin/highlight/highlight.esm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
5
assets/vendor/reveal/plugin/highlight/highlight.js
vendored
Normal file
5
assets/vendor/reveal/plugin/highlight/highlight.js
vendored
Normal file
File diff suppressed because one or more lines are too long
71
assets/vendor/reveal/plugin/highlight/monokai.css
vendored
Normal file
71
assets/vendor/reveal/plugin/highlight/monokai.css
vendored
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
Monokai style - ported by Luigi Maselli - http://grigio.org
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
background: #272822;
|
||||||
|
color: #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-tag,
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-strong,
|
||||||
|
.hljs-name {
|
||||||
|
color: #f92672;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-code {
|
||||||
|
color: #66d9ef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-class .hljs-title {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-regexp,
|
||||||
|
.hljs-link {
|
||||||
|
color: #bf79db;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-subst,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-emphasis,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-builtin-name,
|
||||||
|
.hljs-selector-attr,
|
||||||
|
.hljs-selector-pseudo,
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-tag,
|
||||||
|
.hljs-template-variable {
|
||||||
|
color: #a6e22e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-meta {
|
||||||
|
color: #75715e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-doctag,
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-type,
|
||||||
|
.hljs-selector-id {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
419
assets/vendor/reveal/plugin/highlight/plugin.js
vendored
Normal file
419
assets/vendor/reveal/plugin/highlight/plugin.js
vendored
Normal file
|
@ -0,0 +1,419 @@
|
||||||
|
import hljs from 'highlight.js'
|
||||||
|
|
||||||
|
/* highlightjs-line-numbers.js 2.6.0 | (C) 2018 Yauheni Pakala | MIT License | github.com/wcoder/highlightjs-line-numbers.js */
|
||||||
|
/* Edited by Hakim for reveal.js; removed async timeout */
|
||||||
|
!function(n,e){"use strict";function t(){var n=e.createElement("style");n.type="text/css",n.innerHTML=g(".{0}{border-collapse:collapse}.{0} td{padding:0}.{1}:before{content:attr({2})}",[v,L,b]),e.getElementsByTagName("head")[0].appendChild(n)}function r(t){"interactive"===e.readyState||"complete"===e.readyState?i(t):n.addEventListener("DOMContentLoaded",function(){i(t)})}function i(t){try{var r=e.querySelectorAll("code.hljs,code.nohighlight");for(var i in r)r.hasOwnProperty(i)&&l(r[i],t)}catch(o){n.console.error("LineNumbers error: ",o)}}function l(n,e){"object"==typeof n&&f(function(){n.innerHTML=s(n,e)})}function o(n,e){if("string"==typeof n){var t=document.createElement("code");return t.innerHTML=n,s(t,e)}}function s(n,e){e=e||{singleLine:!1};var t=e.singleLine?0:1;return c(n),a(n.innerHTML,t)}function a(n,e){var t=u(n);if(""===t[t.length-1].trim()&&t.pop(),t.length>e){for(var r="",i=0,l=t.length;i<l;i++)r+=g('<tr><td class="{0}"><div class="{1} {2}" {3}="{5}"></div></td><td class="{4}"><div class="{1}">{6}</div></td></tr>',[j,m,L,b,p,i+1,t[i].length>0?t[i]:" "]);return g('<table class="{0}">{1}</table>',[v,r])}return n}function c(n){var e=n.childNodes;for(var t in e)if(e.hasOwnProperty(t)){var r=e[t];h(r.textContent)>0&&(r.childNodes.length>0?c(r):d(r.parentNode))}}function d(n){var e=n.className;if(/hljs-/.test(e)){for(var t=u(n.innerHTML),r=0,i="";r<t.length;r++){var l=t[r].length>0?t[r]:" ";i+=g('<span class="{0}">{1}</span>\n',[e,l])}n.innerHTML=i.trim()}}function u(n){return 0===n.length?[]:n.split(y)}function h(n){return(n.trim().match(y)||[]).length}function f(e){e()}function g(n,e){return n.replace(/\{(\d+)\}/g,function(n,t){return e[t]?e[t]:n})}var v="hljs-ln",m="hljs-ln-line",p="hljs-ln-code",j="hljs-ln-numbers",L="hljs-ln-n",b="data-line-number",y=/\r\n|\r|\n/g;hljs?(hljs.initLineNumbersOnLoad=r,hljs.lineNumbersBlock=l,hljs.lineNumbersValue=o,t()):n.console.error("highlight.js not detected!")}(window,document);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* reveal.js plugin that adds syntax highlight support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Plugin = {
|
||||||
|
|
||||||
|
id: 'highlight',
|
||||||
|
|
||||||
|
HIGHLIGHT_STEP_DELIMITER: '|',
|
||||||
|
HIGHLIGHT_LINE_DELIMITER: ',',
|
||||||
|
HIGHLIGHT_LINE_RANGE_DELIMITER: '-',
|
||||||
|
|
||||||
|
hljs: hljs,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlights code blocks withing the given deck.
|
||||||
|
*
|
||||||
|
* Note that this can be called multiple times if
|
||||||
|
* there are multiple presentations on one page.
|
||||||
|
*
|
||||||
|
* @param {Reveal} reveal the reveal.js instance
|
||||||
|
*/
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
// Read the plugin config options and provide fallbacks
|
||||||
|
var config = reveal.getConfig().highlight || {};
|
||||||
|
config.highlightOnLoad = typeof config.highlightOnLoad === 'boolean' ? config.highlightOnLoad : true;
|
||||||
|
config.escapeHTML = typeof config.escapeHTML === 'boolean' ? config.escapeHTML : true;
|
||||||
|
|
||||||
|
[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code' ) ).forEach( function( block ) {
|
||||||
|
|
||||||
|
// Trim whitespace if the "data-trim" attribute is present
|
||||||
|
if( block.hasAttribute( 'data-trim' ) && typeof block.innerHTML.trim === 'function' ) {
|
||||||
|
block.innerHTML = betterTrim( block );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape HTML tags unless the "data-noescape" attrbute is present
|
||||||
|
if( config.escapeHTML && !block.hasAttribute( 'data-noescape' )) {
|
||||||
|
block.innerHTML = block.innerHTML.replace( /</g,"<").replace(/>/g, '>' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-highlight when focus is lost (for contenteditable code)
|
||||||
|
block.addEventListener( 'focusout', function( event ) {
|
||||||
|
hljs.highlightBlock( event.currentTarget );
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
if( config.highlightOnLoad ) {
|
||||||
|
Plugin.highlightBlock( block );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
// If we're printing to PDF, scroll the code highlights of
|
||||||
|
// all blocks in the deck into view at once
|
||||||
|
reveal.on( 'pdf-ready', function() {
|
||||||
|
[].slice.call( reveal.getRevealElement().querySelectorAll( 'pre code[data-line-numbers].current-fragment' ) ).forEach( function( block ) {
|
||||||
|
Plugin.scrollHighlightedLineIntoView( block, {}, true );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlights a code block. If the <code> node has the
|
||||||
|
* 'data-line-numbers' attribute we also generate slide
|
||||||
|
* numbers.
|
||||||
|
*
|
||||||
|
* If the block contains multiple line highlight steps,
|
||||||
|
* we clone the block and create a fragment for each step.
|
||||||
|
*/
|
||||||
|
highlightBlock: function( block ) {
|
||||||
|
|
||||||
|
hljs.highlightBlock( block );
|
||||||
|
|
||||||
|
// Don't generate line numbers for empty code blocks
|
||||||
|
if( block.innerHTML.trim().length === 0 ) return;
|
||||||
|
|
||||||
|
if( block.hasAttribute( 'data-line-numbers' ) ) {
|
||||||
|
hljs.lineNumbersBlock( block, { singleLine: true } );
|
||||||
|
|
||||||
|
var scrollState = { currentBlock: block };
|
||||||
|
|
||||||
|
// If there is at least one highlight step, generate
|
||||||
|
// fragments
|
||||||
|
var highlightSteps = Plugin.deserializeHighlightSteps( block.getAttribute( 'data-line-numbers' ) );
|
||||||
|
if( highlightSteps.length > 1 ) {
|
||||||
|
|
||||||
|
// If the original code block has a fragment-index,
|
||||||
|
// each clone should follow in an incremental sequence
|
||||||
|
var fragmentIndex = parseInt( block.getAttribute( 'data-fragment-index' ), 10 );
|
||||||
|
|
||||||
|
if( typeof fragmentIndex !== 'number' || isNaN( fragmentIndex ) ) {
|
||||||
|
fragmentIndex = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate fragments for all steps except the original block
|
||||||
|
highlightSteps.slice(1).forEach( function( highlight ) {
|
||||||
|
|
||||||
|
var fragmentBlock = block.cloneNode( true );
|
||||||
|
fragmentBlock.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlight ] ) );
|
||||||
|
fragmentBlock.classList.add( 'fragment' );
|
||||||
|
block.parentNode.appendChild( fragmentBlock );
|
||||||
|
Plugin.highlightLines( fragmentBlock );
|
||||||
|
|
||||||
|
if( typeof fragmentIndex === 'number' ) {
|
||||||
|
fragmentBlock.setAttribute( 'data-fragment-index', fragmentIndex );
|
||||||
|
fragmentIndex += 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
fragmentBlock.removeAttribute( 'data-fragment-index' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll highlights into view as we step through them
|
||||||
|
fragmentBlock.addEventListener( 'visible', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock, scrollState ) );
|
||||||
|
fragmentBlock.addEventListener( 'hidden', Plugin.scrollHighlightedLineIntoView.bind( Plugin, fragmentBlock.previousSibling, scrollState ) );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
block.removeAttribute( 'data-fragment-index' )
|
||||||
|
block.setAttribute( 'data-line-numbers', Plugin.serializeHighlightSteps( [ highlightSteps[0] ] ) );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll the first highlight into view when the slide
|
||||||
|
// becomes visible. Note supported in IE11 since it lacks
|
||||||
|
// support for Element.closest.
|
||||||
|
var slide = typeof block.closest === 'function' ? block.closest( 'section:not(.stack)' ) : null;
|
||||||
|
if( slide ) {
|
||||||
|
var scrollFirstHighlightIntoView = function() {
|
||||||
|
Plugin.scrollHighlightedLineIntoView( block, scrollState, true );
|
||||||
|
slide.removeEventListener( 'visible', scrollFirstHighlightIntoView );
|
||||||
|
}
|
||||||
|
slide.addEventListener( 'visible', scrollFirstHighlightIntoView );
|
||||||
|
}
|
||||||
|
|
||||||
|
Plugin.highlightLines( block );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates scrolling to the first highlighted line
|
||||||
|
* in the given code block.
|
||||||
|
*/
|
||||||
|
scrollHighlightedLineIntoView: function( block, scrollState, skipAnimation ) {
|
||||||
|
|
||||||
|
cancelAnimationFrame( scrollState.animationFrameID );
|
||||||
|
|
||||||
|
// Match the scroll position of the currently visible
|
||||||
|
// code block
|
||||||
|
if( scrollState.currentBlock ) {
|
||||||
|
block.scrollTop = scrollState.currentBlock.scrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember the current code block so that we can match
|
||||||
|
// its scroll position when showing/hiding fragments
|
||||||
|
scrollState.currentBlock = block;
|
||||||
|
|
||||||
|
var highlightBounds = this.getHighlightedLineBounds( block )
|
||||||
|
var viewportHeight = block.offsetHeight;
|
||||||
|
|
||||||
|
// Subtract padding from the viewport height
|
||||||
|
var blockStyles = getComputedStyle( block );
|
||||||
|
viewportHeight -= parseInt( blockStyles.paddingTop ) + parseInt( blockStyles.paddingBottom );
|
||||||
|
|
||||||
|
// Scroll position which centers all highlights
|
||||||
|
var startTop = block.scrollTop;
|
||||||
|
var targetTop = highlightBounds.top + ( Math.min( highlightBounds.bottom - highlightBounds.top, viewportHeight ) - viewportHeight ) / 2;
|
||||||
|
|
||||||
|
// Account for offsets in position applied to the
|
||||||
|
// <table> that holds our lines of code
|
||||||
|
var lineTable = block.querySelector( '.hljs-ln' );
|
||||||
|
if( lineTable ) targetTop += lineTable.offsetTop - parseInt( blockStyles.paddingTop );
|
||||||
|
|
||||||
|
// Make sure the scroll target is within bounds
|
||||||
|
targetTop = Math.max( Math.min( targetTop, block.scrollHeight - viewportHeight ), 0 );
|
||||||
|
|
||||||
|
if( skipAnimation === true || startTop === targetTop ) {
|
||||||
|
block.scrollTop = targetTop;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Don't attempt to scroll if there is no overflow
|
||||||
|
if( block.scrollHeight <= viewportHeight ) return;
|
||||||
|
|
||||||
|
var time = 0;
|
||||||
|
var animate = function() {
|
||||||
|
time = Math.min( time + 0.02, 1 );
|
||||||
|
|
||||||
|
// Update our eased scroll position
|
||||||
|
block.scrollTop = startTop + ( targetTop - startTop ) * Plugin.easeInOutQuart( time );
|
||||||
|
|
||||||
|
// Keep animating unless we've reached the end
|
||||||
|
if( time < 1 ) {
|
||||||
|
scrollState.animationFrameID = requestAnimationFrame( animate );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
animate();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The easing function used when scrolling.
|
||||||
|
*/
|
||||||
|
easeInOutQuart: function( t ) {
|
||||||
|
|
||||||
|
// easeInOutQuart
|
||||||
|
return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t;
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
getHighlightedLineBounds: function( block ) {
|
||||||
|
|
||||||
|
var highlightedLines = block.querySelectorAll( '.highlight-line' );
|
||||||
|
if( highlightedLines.length === 0 ) {
|
||||||
|
return { top: 0, bottom: 0 };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var firstHighlight = highlightedLines[0];
|
||||||
|
var lastHighlight = highlightedLines[ highlightedLines.length -1 ];
|
||||||
|
|
||||||
|
return {
|
||||||
|
top: firstHighlight.offsetTop,
|
||||||
|
bottom: lastHighlight.offsetTop + lastHighlight.offsetHeight
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Visually emphasize specific lines within a code block.
|
||||||
|
* This only works on blocks with line numbering turned on.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} block a <code> block
|
||||||
|
* @param {String} [linesToHighlight] The lines that should be
|
||||||
|
* highlighted in this format:
|
||||||
|
* "1" = highlights line 1
|
||||||
|
* "2,5" = highlights lines 2 & 5
|
||||||
|
* "2,5-7" = highlights lines 2, 5, 6 & 7
|
||||||
|
*/
|
||||||
|
highlightLines: function( block, linesToHighlight ) {
|
||||||
|
|
||||||
|
var highlightSteps = Plugin.deserializeHighlightSteps( linesToHighlight || block.getAttribute( 'data-line-numbers' ) );
|
||||||
|
|
||||||
|
if( highlightSteps.length ) {
|
||||||
|
|
||||||
|
highlightSteps[0].forEach( function( highlight ) {
|
||||||
|
|
||||||
|
var elementsToHighlight = [];
|
||||||
|
|
||||||
|
// Highlight a range
|
||||||
|
if( typeof highlight.end === 'number' ) {
|
||||||
|
elementsToHighlight = [].slice.call( block.querySelectorAll( 'table tr:nth-child(n+'+highlight.start+'):nth-child(-n+'+highlight.end+')' ) );
|
||||||
|
}
|
||||||
|
// Highlight a single line
|
||||||
|
else if( typeof highlight.start === 'number' ) {
|
||||||
|
elementsToHighlight = [].slice.call( block.querySelectorAll( 'table tr:nth-child('+highlight.start+')' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( elementsToHighlight.length ) {
|
||||||
|
elementsToHighlight.forEach( function( lineElement ) {
|
||||||
|
lineElement.classList.add( 'highlight-line' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
block.classList.add( 'has-highlights' );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses and formats a user-defined string of line
|
||||||
|
* numbers to highlight.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* Plugin.deserializeHighlightSteps( '1,2|3,5-10' )
|
||||||
|
* // [
|
||||||
|
* // [ { start: 1 }, { start: 2 } ],
|
||||||
|
* // [ { start: 3 }, { start: 5, end: 10 } ]
|
||||||
|
* // ]
|
||||||
|
*/
|
||||||
|
deserializeHighlightSteps: function( highlightSteps ) {
|
||||||
|
|
||||||
|
// Remove whitespace
|
||||||
|
highlightSteps = highlightSteps.replace( /\s/g, '' );
|
||||||
|
|
||||||
|
// Divide up our line number groups
|
||||||
|
highlightSteps = highlightSteps.split( Plugin.HIGHLIGHT_STEP_DELIMITER );
|
||||||
|
|
||||||
|
return highlightSteps.map( function( highlights ) {
|
||||||
|
|
||||||
|
return highlights.split( Plugin.HIGHLIGHT_LINE_DELIMITER ).map( function( highlight ) {
|
||||||
|
|
||||||
|
// Parse valid line numbers
|
||||||
|
if( /^[\d-]+$/.test( highlight ) ) {
|
||||||
|
|
||||||
|
highlight = highlight.split( Plugin.HIGHLIGHT_LINE_RANGE_DELIMITER );
|
||||||
|
|
||||||
|
var lineStart = parseInt( highlight[0], 10 ),
|
||||||
|
lineEnd = parseInt( highlight[1], 10 );
|
||||||
|
|
||||||
|
if( isNaN( lineEnd ) ) {
|
||||||
|
return {
|
||||||
|
start: lineStart
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return {
|
||||||
|
start: lineStart,
|
||||||
|
end: lineEnd
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// If no line numbers are provided, no code will be highlighted
|
||||||
|
else {
|
||||||
|
|
||||||
|
return {};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes parsed line number data into a string so
|
||||||
|
* that we can store it in the DOM.
|
||||||
|
*/
|
||||||
|
serializeHighlightSteps: function( highlightSteps ) {
|
||||||
|
|
||||||
|
return highlightSteps.map( function( highlights ) {
|
||||||
|
|
||||||
|
return highlights.map( function( highlight ) {
|
||||||
|
|
||||||
|
// Line range
|
||||||
|
if( typeof highlight.end === 'number' ) {
|
||||||
|
return highlight.start + Plugin.HIGHLIGHT_LINE_RANGE_DELIMITER + highlight.end;
|
||||||
|
}
|
||||||
|
// Single line
|
||||||
|
else if( typeof highlight.start === 'number' ) {
|
||||||
|
return highlight.start;
|
||||||
|
}
|
||||||
|
// All lines
|
||||||
|
else {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
} ).join( Plugin.HIGHLIGHT_LINE_DELIMITER );
|
||||||
|
|
||||||
|
} ).join( Plugin.HIGHLIGHT_STEP_DELIMITER );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to perform a better "data-trim" on code snippets
|
||||||
|
// Will slice an indentation amount on each line of the snippet (amount based on the line having the lowest indentation length)
|
||||||
|
function betterTrim(snippetEl) {
|
||||||
|
// Helper functions
|
||||||
|
function trimLeft(val) {
|
||||||
|
// Adapted from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
|
||||||
|
return val.replace(/^[\s\uFEFF\xA0]+/g, '');
|
||||||
|
}
|
||||||
|
function trimLineBreaks(input) {
|
||||||
|
var lines = input.split('\n');
|
||||||
|
|
||||||
|
// Trim line-breaks from the beginning
|
||||||
|
for (var i = 0; i < lines.length; i++) {
|
||||||
|
if (lines[i].trim() === '') {
|
||||||
|
lines.splice(i--, 1);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trim line-breaks from the end
|
||||||
|
for (var i = lines.length-1; i >= 0; i--) {
|
||||||
|
if (lines[i].trim() === '') {
|
||||||
|
lines.splice(i, 1);
|
||||||
|
} else break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lines.join('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main function for betterTrim()
|
||||||
|
return (function(snippetEl) {
|
||||||
|
var content = trimLineBreaks(snippetEl.innerHTML);
|
||||||
|
var lines = content.split('\n');
|
||||||
|
// Calculate the minimum amount to remove on each line start of the snippet (can be 0)
|
||||||
|
var pad = lines.reduce(function(acc, line) {
|
||||||
|
if (line.length > 0 && trimLeft(line).length > 0 && acc > line.length - trimLeft(line).length) {
|
||||||
|
return line.length - trimLeft(line).length;
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, Number.POSITIVE_INFINITY);
|
||||||
|
// Slice each line with this amount
|
||||||
|
return lines.map(function(line, index) {
|
||||||
|
return line.slice(pad);
|
||||||
|
})
|
||||||
|
.join('\n');
|
||||||
|
})(snippetEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => Plugin;
|
80
assets/vendor/reveal/plugin/highlight/zenburn.css
vendored
Normal file
80
assets/vendor/reveal/plugin/highlight/zenburn.css
vendored
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Zenburn style from voldmar.ru (c) Vladimir Epifanov <voldmar@voldmar.ru>
|
||||||
|
based on dark.css by Ivan Sagalaev
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
.hljs {
|
||||||
|
display: block;
|
||||||
|
overflow-x: auto;
|
||||||
|
padding: 0.5em;
|
||||||
|
background: #3f3f3f;
|
||||||
|
color: #dcdcdc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-tag {
|
||||||
|
color: #e3ceab;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-template-tag {
|
||||||
|
color: #dcdcdc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-number {
|
||||||
|
color: #8cd0d3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-template-variable,
|
||||||
|
.hljs-attribute {
|
||||||
|
color: #efdcbc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-literal {
|
||||||
|
color: #efefaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-subst {
|
||||||
|
color: #8f8f8f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-selector-id,
|
||||||
|
.hljs-selector-class,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-type {
|
||||||
|
color: #efef8f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-symbol,
|
||||||
|
.hljs-bullet,
|
||||||
|
.hljs-link {
|
||||||
|
color: #dca3a3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-deletion,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-built_in,
|
||||||
|
.hljs-builtin-name {
|
||||||
|
color: #cc9393;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-addition,
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote,
|
||||||
|
.hljs-meta {
|
||||||
|
color: #7f9f7f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.hljs-emphasis {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hljs-strong {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
1
assets/vendor/reveal/plugin/markdown/markdown.esm.js
vendored
Normal file
1
assets/vendor/reveal/plugin/markdown/markdown.esm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/vendor/reveal/plugin/markdown/markdown.js
vendored
Normal file
1
assets/vendor/reveal/plugin/markdown/markdown.js
vendored
Normal file
File diff suppressed because one or more lines are too long
451
assets/vendor/reveal/plugin/markdown/plugin.js
vendored
Normal file
451
assets/vendor/reveal/plugin/markdown/plugin.js
vendored
Normal file
|
@ -0,0 +1,451 @@
|
||||||
|
/*!
|
||||||
|
* The reveal.js markdown plugin. Handles parsing of
|
||||||
|
* markdown inside of presentations as well as loading
|
||||||
|
* of external markdown documents.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import marked from 'marked'
|
||||||
|
|
||||||
|
const DEFAULT_SLIDE_SEPARATOR = '^\r?\n---\r?\n$',
|
||||||
|
DEFAULT_NOTES_SEPARATOR = 'notes?:',
|
||||||
|
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$',
|
||||||
|
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$';
|
||||||
|
|
||||||
|
const SCRIPT_END_PLACEHOLDER = '__SCRIPT_END__';
|
||||||
|
|
||||||
|
const CODE_LINE_NUMBER_REGEX = /\[([\s\d,|-]*)\]/;
|
||||||
|
|
||||||
|
const Plugin = () => {
|
||||||
|
|
||||||
|
// The reveal.js instance this plugin is attached to
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the markdown contents of a slide section
|
||||||
|
* element. Normalizes leading tabs/whitespace.
|
||||||
|
*/
|
||||||
|
function getMarkdownFromSlide( section ) {
|
||||||
|
|
||||||
|
// look for a <script> or <textarea data-template> wrapper
|
||||||
|
var template = section.querySelector( '[data-template]' ) || section.querySelector( 'script' );
|
||||||
|
|
||||||
|
// strip leading whitespace so it isn't evaluated as code
|
||||||
|
var text = ( template || section ).textContent;
|
||||||
|
|
||||||
|
// restore script end tags
|
||||||
|
text = text.replace( new RegExp( SCRIPT_END_PLACEHOLDER, 'g' ), '</script>' );
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a markdown slide section element, this will
|
||||||
|
* return all arguments that aren't related to markdown
|
||||||
|
* parsing. Used to forward any other user-defined arguments
|
||||||
|
* to the output markdown slide.
|
||||||
|
*/
|
||||||
|
function getForwardedAttributes( section ) {
|
||||||
|
|
||||||
|
var attributes = section.attributes;
|
||||||
|
var result = [];
|
||||||
|
|
||||||
|
for( var i = 0, len = attributes.length; i < len; i++ ) {
|
||||||
|
var name = attributes[i].name,
|
||||||
|
value = attributes[i].value;
|
||||||
|
|
||||||
|
// disregard attributes that are used for markdown loading/parsing
|
||||||
|
if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue;
|
||||||
|
|
||||||
|
if( value ) {
|
||||||
|
result.push( name + '="' + value + '"' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.push( name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.join( ' ' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inspects the given options and fills out default
|
||||||
|
* values for what's not defined.
|
||||||
|
*/
|
||||||
|
function getSlidifyOptions( options ) {
|
||||||
|
|
||||||
|
options = options || {};
|
||||||
|
options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR;
|
||||||
|
options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR;
|
||||||
|
options.attributes = options.attributes || '';
|
||||||
|
|
||||||
|
return options;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for constructing a markdown slide.
|
||||||
|
*/
|
||||||
|
function createMarkdownSlide( content, options ) {
|
||||||
|
|
||||||
|
options = getSlidifyOptions( options );
|
||||||
|
|
||||||
|
var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) );
|
||||||
|
|
||||||
|
if( notesMatch.length === 2 ) {
|
||||||
|
content = notesMatch[0] + '<aside class="notes">' + marked(notesMatch[1].trim()) + '</aside>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent script end tags in the content from interfering
|
||||||
|
// with parsing
|
||||||
|
content = content.replace( /<\/script>/g, SCRIPT_END_PLACEHOLDER );
|
||||||
|
|
||||||
|
return '<script type="text/template">' + content + '</script>';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses a data string into multiple slides based
|
||||||
|
* on the passed in separator arguments.
|
||||||
|
*/
|
||||||
|
function slidify( markdown, options ) {
|
||||||
|
|
||||||
|
options = getSlidifyOptions( options );
|
||||||
|
|
||||||
|
var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ),
|
||||||
|
horizontalSeparatorRegex = new RegExp( options.separator );
|
||||||
|
|
||||||
|
var matches,
|
||||||
|
lastIndex = 0,
|
||||||
|
isHorizontal,
|
||||||
|
wasHorizontal = true,
|
||||||
|
content,
|
||||||
|
sectionStack = [];
|
||||||
|
|
||||||
|
// iterate until all blocks between separators are stacked up
|
||||||
|
while( matches = separatorRegex.exec( markdown ) ) {
|
||||||
|
var notes = null;
|
||||||
|
|
||||||
|
// determine direction (horizontal by default)
|
||||||
|
isHorizontal = horizontalSeparatorRegex.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 = separatorRegex.lastIndex;
|
||||||
|
wasHorizontal = isHorizontal;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the remaining slide
|
||||||
|
( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) );
|
||||||
|
|
||||||
|
var markdownSections = '';
|
||||||
|
|
||||||
|
// flatten the hierarchical stack, and insert <section data-markdown> tags
|
||||||
|
for( var i = 0, len = sectionStack.length; i < len; i++ ) {
|
||||||
|
// vertical
|
||||||
|
if( sectionStack[i] instanceof Array ) {
|
||||||
|
markdownSections += '<section '+ options.attributes +'>';
|
||||||
|
|
||||||
|
sectionStack[i].forEach( function( child ) {
|
||||||
|
markdownSections += '<section data-markdown>' + createMarkdownSlide( child, options ) + '</section>';
|
||||||
|
} );
|
||||||
|
|
||||||
|
markdownSections += '</section>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
markdownSections += '<section '+ options.attributes +' data-markdown>' + createMarkdownSlide( sectionStack[i], options ) + '</section>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return markdownSections;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses any current data-markdown slides, splits
|
||||||
|
* multi-slide markdown into separate sections and
|
||||||
|
* handles loading of external markdown.
|
||||||
|
*/
|
||||||
|
function processSlides( scope ) {
|
||||||
|
|
||||||
|
return new Promise( function( resolve ) {
|
||||||
|
|
||||||
|
var externalPromises = [];
|
||||||
|
|
||||||
|
[].slice.call( scope.querySelectorAll( '[data-markdown]:not([data-markdown-parsed])') ).forEach( function( section, i ) {
|
||||||
|
|
||||||
|
if( section.getAttribute( 'data-markdown' ).length ) {
|
||||||
|
|
||||||
|
externalPromises.push( loadExternalMarkdown( section ).then(
|
||||||
|
|
||||||
|
// Finished loading external file
|
||||||
|
function( xhr, url ) {
|
||||||
|
section.outerHTML = slidify( xhr.responseText, {
|
||||||
|
separator: section.getAttribute( 'data-separator' ),
|
||||||
|
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
|
||||||
|
notesSeparator: section.getAttribute( 'data-separator-notes' ),
|
||||||
|
attributes: getForwardedAttributes( section )
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// Failed to load markdown
|
||||||
|
function( xhr, url ) {
|
||||||
|
section.outerHTML = '<section data-state="alert">' +
|
||||||
|
'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' +
|
||||||
|
'Check your browser\'s JavaScript console for more details.' +
|
||||||
|
'<p>Remember that you need to serve the presentation HTML from a HTTP server.</p>' +
|
||||||
|
'</section>';
|
||||||
|
}
|
||||||
|
|
||||||
|
) );
|
||||||
|
|
||||||
|
}
|
||||||
|
else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-separator-vertical' ) || section.getAttribute( 'data-separator-notes' ) ) {
|
||||||
|
|
||||||
|
section.outerHTML = slidify( getMarkdownFromSlide( section ), {
|
||||||
|
separator: section.getAttribute( 'data-separator' ),
|
||||||
|
verticalSeparator: section.getAttribute( 'data-separator-vertical' ),
|
||||||
|
notesSeparator: section.getAttribute( 'data-separator-notes' ),
|
||||||
|
attributes: getForwardedAttributes( section )
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all( externalPromises ).then( resolve );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadExternalMarkdown( section ) {
|
||||||
|
|
||||||
|
return new Promise( function( resolve, reject ) {
|
||||||
|
|
||||||
|
var xhr = new XMLHttpRequest(),
|
||||||
|
url = section.getAttribute( 'data-markdown' );
|
||||||
|
|
||||||
|
var datacharset = section.getAttribute( 'data-charset' );
|
||||||
|
|
||||||
|
// see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes
|
||||||
|
if( datacharset != null && datacharset != '' ) {
|
||||||
|
xhr.overrideMimeType( 'text/html; charset=' + datacharset );
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.onreadystatechange = function( section, xhr ) {
|
||||||
|
if( xhr.readyState === 4 ) {
|
||||||
|
// file protocol yields status code 0 (useful for local debug, mobile applications etc.)
|
||||||
|
if ( ( xhr.status >= 200 && xhr.status < 300 ) || xhr.status === 0 ) {
|
||||||
|
|
||||||
|
resolve( xhr, url );
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
reject( xhr, url );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.bind( this, section, xhr );
|
||||||
|
|
||||||
|
xhr.open( 'GET', url, true );
|
||||||
|
|
||||||
|
try {
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
catch ( e ) {
|
||||||
|
console.warn( 'Failed to get the Markdown file ' + url + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + e );
|
||||||
|
resolve( xhr, url );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a node value has the attributes pattern.
|
||||||
|
* If yes, extract it and add that value as one or several attributes
|
||||||
|
* to the target element.
|
||||||
|
*
|
||||||
|
* You need Cache Killer on Chrome to see the effect on any FOM transformation
|
||||||
|
* directly on refresh (F5)
|
||||||
|
* http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277
|
||||||
|
*/
|
||||||
|
function addAttributeInElement( node, elementTarget, separator ) {
|
||||||
|
|
||||||
|
var mardownClassesInElementsRegex = new RegExp( separator, 'mg' );
|
||||||
|
var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"]+?)\"|(data-[^\"= ]+?)(?=[\" ])", 'mg' );
|
||||||
|
var nodeValue = node.nodeValue;
|
||||||
|
var matches,
|
||||||
|
matchesClass;
|
||||||
|
if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) {
|
||||||
|
|
||||||
|
var classes = matches[1];
|
||||||
|
nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex );
|
||||||
|
node.nodeValue = nodeValue;
|
||||||
|
while( matchesClass = mardownClassRegex.exec( classes ) ) {
|
||||||
|
if( matchesClass[2] ) {
|
||||||
|
elementTarget.setAttribute( matchesClass[1], matchesClass[2] );
|
||||||
|
} else {
|
||||||
|
elementTarget.setAttribute( matchesClass[3], "" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add attributes to the parent element of a text node,
|
||||||
|
* or the element of an attribute node.
|
||||||
|
*/
|
||||||
|
function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) {
|
||||||
|
|
||||||
|
if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) {
|
||||||
|
var previousParentElement = element;
|
||||||
|
for( var i = 0; i < element.childNodes.length; i++ ) {
|
||||||
|
var childElement = element.childNodes[i];
|
||||||
|
if ( i > 0 ) {
|
||||||
|
var j = i - 1;
|
||||||
|
while ( j >= 0 ) {
|
||||||
|
var aPreviousChildElement = element.childNodes[j];
|
||||||
|
if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) {
|
||||||
|
previousParentElement = aPreviousChildElement;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
j = j - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var parentSection = section;
|
||||||
|
if( childElement.nodeName == "section" ) {
|
||||||
|
parentSection = childElement ;
|
||||||
|
previousParentElement = childElement ;
|
||||||
|
}
|
||||||
|
if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) {
|
||||||
|
addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( element.nodeType == Node.COMMENT_NODE ) {
|
||||||
|
if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) {
|
||||||
|
addAttributeInElement( element, section, separatorSectionAttributes );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts any current data-markdown slides in the
|
||||||
|
* DOM to HTML.
|
||||||
|
*/
|
||||||
|
function convertSlides() {
|
||||||
|
|
||||||
|
var sections = deck.getRevealElement().querySelectorAll( '[data-markdown]:not([data-markdown-parsed])');
|
||||||
|
|
||||||
|
[].slice.call( sections ).forEach( function( section ) {
|
||||||
|
|
||||||
|
section.setAttribute( 'data-markdown-parsed', true )
|
||||||
|
|
||||||
|
var notes = section.querySelector( 'aside.notes' );
|
||||||
|
var markdown = getMarkdownFromSlide( section );
|
||||||
|
|
||||||
|
section.innerHTML = marked( markdown );
|
||||||
|
addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) ||
|
||||||
|
section.parentNode.getAttribute( 'data-element-attributes' ) ||
|
||||||
|
DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR,
|
||||||
|
section.getAttribute( 'data-attributes' ) ||
|
||||||
|
section.parentNode.getAttribute( 'data-attributes' ) ||
|
||||||
|
DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR);
|
||||||
|
|
||||||
|
// If there were notes, we need to re-add them after
|
||||||
|
// having overwritten the section's HTML
|
||||||
|
if( notes ) {
|
||||||
|
section.appendChild( notes );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'markdown',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts processing and converting Markdown within the
|
||||||
|
* current reveal.js deck.
|
||||||
|
*/
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
let renderer = new marked.Renderer();
|
||||||
|
|
||||||
|
renderer.code = ( code, language ) => {
|
||||||
|
|
||||||
|
// Off by default
|
||||||
|
let lineNumbers = '';
|
||||||
|
|
||||||
|
// Users can opt in to show line numbers and highlight
|
||||||
|
// specific lines.
|
||||||
|
// ```javascript [] show line numbers
|
||||||
|
// ```javascript [1,4-8] highlights lines 1 and 4-8
|
||||||
|
if( CODE_LINE_NUMBER_REGEX.test( language ) ) {
|
||||||
|
lineNumbers = language.match( CODE_LINE_NUMBER_REGEX )[1].trim();
|
||||||
|
lineNumbers = `data-line-numbers="${lineNumbers}"`;
|
||||||
|
language = language.replace( CODE_LINE_NUMBER_REGEX, '' ).trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
return `<pre><code ${lineNumbers} class="${language}">${code}</code></pre>`;
|
||||||
|
};
|
||||||
|
|
||||||
|
marked.setOptions( {
|
||||||
|
renderer,
|
||||||
|
...deck.getConfig().markdown
|
||||||
|
} );
|
||||||
|
|
||||||
|
return processSlides( deck.getRevealElement() ).then( convertSlides );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: Do these belong in the API?
|
||||||
|
processSlides: processSlides,
|
||||||
|
convertSlides: convertSlides,
|
||||||
|
slidify: slidify,
|
||||||
|
marked: marked
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Plugin;
|
1
assets/vendor/reveal/plugin/math/math.esm.js
vendored
Normal file
1
assets/vendor/reveal/plugin/math/math.esm.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(n){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?t(Object(a),!0).forEach((function(t){e(n,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach((function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(a,e))}))}return n}export default function(){var e,t={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=n(n({},t),a),c=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=n(n({},t.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(c,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}
|
1
assets/vendor/reveal/plugin/math/math.js
vendored
Normal file
1
assets/vendor/reveal/plugin/math/math.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RevealMath=t()}(this,(function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function n(n){for(var r=1;r<arguments.length;r++){var a=null!=arguments[r]?arguments[r]:{};r%2?t(Object(a),!0).forEach((function(t){e(n,t,a[t])})):Object.getOwnPropertyDescriptors?Object.defineProperties(n,Object.getOwnPropertyDescriptors(a)):t(Object(a)).forEach((function(e){Object.defineProperty(n,e,Object.getOwnPropertyDescriptor(a,e))}))}return n}return function(){var e,t={messageStyle:"none",tex2jax:{inlineMath:[["$","$"],["\\(","\\)"]],skipTags:["script","noscript","style","textarea","pre"]},skipStartupTypeset:!0};return{id:"math",init:function(r){var a=(e=r).getConfig().math||{},o=n(n({},t),a),c=(o.mathjax||"https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js")+"?config="+(o.config||"TeX-AMS_HTML-full");o.tex2jax=n(n({},t.tex2jax),a.tex2jax),o.mathjax=o.config=null,function(e,t){var n=this,r=document.querySelector("head"),a=document.createElement("script");a.type="text/javascript",a.src=e;var o=function(){"function"==typeof t&&(t.call(),t=null)};a.onload=o,a.onreadystatechange=function(){"loaded"===n.readyState&&o()},r.appendChild(a)}(c,(function(){MathJax.Hub.Config(o),MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.getRevealElement()]),MathJax.Hub.Queue(e.layout),e.on("slidechanged",(function(e){MathJax.Hub.Queue(["Typeset",MathJax.Hub,e.currentSlide])}))}))}}}}));
|
91
assets/vendor/reveal/plugin/math/plugin.js
vendored
Normal file
91
assets/vendor/reveal/plugin/math/plugin.js
vendored
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
/**
|
||||||
|
* A plugin which enables rendering of math equations inside
|
||||||
|
* of reveal.js slides. Essentially a thin wrapper for MathJax.
|
||||||
|
*
|
||||||
|
* @author Hakim El Hattab
|
||||||
|
*/
|
||||||
|
const Plugin = () => {
|
||||||
|
|
||||||
|
// The reveal.js instance this plugin is attached to
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
let defaultOptions = {
|
||||||
|
messageStyle: 'none',
|
||||||
|
tex2jax: {
|
||||||
|
inlineMath: [ [ '$', '$' ], [ '\\(', '\\)' ] ],
|
||||||
|
skipTags: [ 'script', 'noscript', 'style', 'textarea', 'pre' ]
|
||||||
|
},
|
||||||
|
skipStartupTypeset: true
|
||||||
|
};
|
||||||
|
|
||||||
|
function loadScript( url, callback ) {
|
||||||
|
|
||||||
|
let head = document.querySelector( 'head' );
|
||||||
|
let script = document.createElement( 'script' );
|
||||||
|
script.type = 'text/javascript';
|
||||||
|
script.src = url;
|
||||||
|
|
||||||
|
// Wrapper for callback to make sure it only fires once
|
||||||
|
let finish = () => {
|
||||||
|
if( typeof callback === 'function' ) {
|
||||||
|
callback.call();
|
||||||
|
callback = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
script.onload = finish;
|
||||||
|
|
||||||
|
// IE
|
||||||
|
script.onreadystatechange = () => {
|
||||||
|
if ( this.readyState === 'loaded' ) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normal browsers
|
||||||
|
head.appendChild( script );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'math',
|
||||||
|
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
let revealOptions = deck.getConfig().math || {};
|
||||||
|
|
||||||
|
let options = { ...defaultOptions, ...revealOptions };
|
||||||
|
let mathjax = options.mathjax || 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js';
|
||||||
|
let config = options.config || 'TeX-AMS_HTML-full';
|
||||||
|
let url = mathjax + '?config=' + config;
|
||||||
|
|
||||||
|
options.tex2jax = { ...defaultOptions.tex2jax, ...revealOptions.tex2jax };
|
||||||
|
|
||||||
|
options.mathjax = options.config = null;
|
||||||
|
|
||||||
|
loadScript( url, function() {
|
||||||
|
|
||||||
|
MathJax.Hub.Config( options );
|
||||||
|
|
||||||
|
// Typeset followed by an immediate reveal.js layout since
|
||||||
|
// the typesetting process could affect slide height
|
||||||
|
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, deck.getRevealElement() ] );
|
||||||
|
MathJax.Hub.Queue( deck.layout );
|
||||||
|
|
||||||
|
// Reprocess equations in slides when they turn visible
|
||||||
|
deck.on( 'slidechanged', function( event ) {
|
||||||
|
|
||||||
|
MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Plugin;
|
1
assets/vendor/reveal/plugin/notes/notes.esm.js
vendored
Normal file
1
assets/vendor/reveal/plugin/notes/notes.esm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/vendor/reveal/plugin/notes/notes.js
vendored
Normal file
1
assets/vendor/reveal/plugin/notes/notes.js
vendored
Normal file
File diff suppressed because one or more lines are too long
184
assets/vendor/reveal/plugin/notes/plugin.js
vendored
Normal file
184
assets/vendor/reveal/plugin/notes/plugin.js
vendored
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
import speakerViewHTML from './speaker-view.html';
|
||||||
|
|
||||||
|
import marked from 'marked';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles opening of and synchronization with the reveal.js
|
||||||
|
* notes window.
|
||||||
|
*
|
||||||
|
* Handshake process:
|
||||||
|
* 1. This window posts 'connect' to notes window
|
||||||
|
* - Includes URL of presentation to show
|
||||||
|
* 2. Notes window responds with 'connected' when it is available
|
||||||
|
* 3. This window proceeds to send the current presentation state
|
||||||
|
* to the notes window
|
||||||
|
*/
|
||||||
|
const Plugin = () => {
|
||||||
|
|
||||||
|
let popup = null;
|
||||||
|
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
function openNotes() {
|
||||||
|
|
||||||
|
if (popup && !popup.closed) {
|
||||||
|
popup.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
popup = window.open( 'about:blank', 'reveal.js - Notes', 'width=1100,height=700' );
|
||||||
|
popup.marked = marked;
|
||||||
|
popup.document.write( speakerViewHTML );
|
||||||
|
|
||||||
|
if( !popup ) {
|
||||||
|
alert( 'Speaker view popup failed to open. Please make sure popups are allowed and reopen the speaker view.' );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connect to the notes window through a postmessage handshake.
|
||||||
|
* Using postmessage enables us to work in situations where the
|
||||||
|
* origins differ, such as a presentation being opened from the
|
||||||
|
* file system.
|
||||||
|
*/
|
||||||
|
function connect() {
|
||||||
|
// Keep trying to connect until we get a 'connected' message back
|
||||||
|
let connectInterval = setInterval( function() {
|
||||||
|
popup.postMessage( JSON.stringify( {
|
||||||
|
namespace: 'reveal-notes',
|
||||||
|
type: 'connect',
|
||||||
|
url: window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.search,
|
||||||
|
state: deck.getState()
|
||||||
|
} ), '*' );
|
||||||
|
}, 500 );
|
||||||
|
|
||||||
|
window.addEventListener( 'message', function( event ) {
|
||||||
|
let data = JSON.parse( event.data );
|
||||||
|
if( data && data.namespace === 'reveal-notes' && data.type === 'connected' ) {
|
||||||
|
clearInterval( connectInterval );
|
||||||
|
onConnected();
|
||||||
|
}
|
||||||
|
if( data && data.namespace === 'reveal-notes' && data.type === 'call' ) {
|
||||||
|
callRevealApi( data.methodName, data.arguments, data.callId );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the specified Reveal.js method with the provided argument
|
||||||
|
* and then pushes the result to the notes frame.
|
||||||
|
*/
|
||||||
|
function callRevealApi( methodName, methodArguments, callId ) {
|
||||||
|
|
||||||
|
let result = deck[methodName].apply( deck, methodArguments );
|
||||||
|
popup.postMessage( JSON.stringify( {
|
||||||
|
namespace: 'reveal-notes',
|
||||||
|
type: 'return',
|
||||||
|
result: result,
|
||||||
|
callId: callId
|
||||||
|
} ), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Posts the current slide data to the notes window
|
||||||
|
*/
|
||||||
|
function post( event ) {
|
||||||
|
|
||||||
|
let slideElement = deck.getCurrentSlide(),
|
||||||
|
notesElement = slideElement.querySelector( 'aside.notes' ),
|
||||||
|
fragmentElement = slideElement.querySelector( '.current-fragment' );
|
||||||
|
|
||||||
|
let messageData = {
|
||||||
|
namespace: 'reveal-notes',
|
||||||
|
type: 'state',
|
||||||
|
notes: '',
|
||||||
|
markdown: false,
|
||||||
|
whitespace: 'normal',
|
||||||
|
state: deck.getState()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Look for notes defined in a slide attribute
|
||||||
|
if( slideElement.hasAttribute( 'data-notes' ) ) {
|
||||||
|
messageData.notes = slideElement.getAttribute( 'data-notes' );
|
||||||
|
messageData.whitespace = 'pre-wrap';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for notes defined in a fragment
|
||||||
|
if( fragmentElement ) {
|
||||||
|
let fragmentNotes = fragmentElement.querySelector( 'aside.notes' );
|
||||||
|
if( fragmentNotes ) {
|
||||||
|
notesElement = fragmentNotes;
|
||||||
|
}
|
||||||
|
else if( fragmentElement.hasAttribute( 'data-notes' ) ) {
|
||||||
|
messageData.notes = fragmentElement.getAttribute( 'data-notes' );
|
||||||
|
messageData.whitespace = 'pre-wrap';
|
||||||
|
|
||||||
|
// In case there are slide notes
|
||||||
|
notesElement = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look for notes defined in an aside element
|
||||||
|
if( notesElement ) {
|
||||||
|
messageData.notes = notesElement.innerHTML;
|
||||||
|
messageData.markdown = typeof notesElement.getAttribute( 'data-markdown' ) === 'string';
|
||||||
|
}
|
||||||
|
|
||||||
|
popup.postMessage( JSON.stringify( messageData ), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called once we have established a connection to the notes
|
||||||
|
* window.
|
||||||
|
*/
|
||||||
|
function onConnected() {
|
||||||
|
|
||||||
|
// Monitor events that trigger a change in state
|
||||||
|
deck.on( 'slidechanged', post );
|
||||||
|
deck.on( 'fragmentshown', post );
|
||||||
|
deck.on( 'fragmenthidden', post );
|
||||||
|
deck.on( 'overviewhidden', post );
|
||||||
|
deck.on( 'overviewshown', post );
|
||||||
|
deck.on( 'paused', post );
|
||||||
|
deck.on( 'resumed', post );
|
||||||
|
|
||||||
|
// Post the initial state
|
||||||
|
post();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
connect();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'notes',
|
||||||
|
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
|
||||||
|
if( !/receiver/i.test( window.location.search ) ) {
|
||||||
|
|
||||||
|
// 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
|
||||||
|
deck.addKeyBinding({keyCode: 83, key: 'S', description: 'Speaker notes view'}, function() {
|
||||||
|
openNotes();
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
open: openNotes
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Plugin;
|
852
assets/vendor/reveal/plugin/notes/speaker-view.html
vendored
Normal file
852
assets/vendor/reveal/plugin/notes/speaker-view.html
vendored
Normal file
|
@ -0,0 +1,852 @@
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
|
||||||
|
<title>reveal.js - Speaker View</title>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Helvetica;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#current-slide,
|
||||||
|
#upcoming-slide,
|
||||||
|
#speaker-controls {
|
||||||
|
padding: 6px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#current-slide iframe,
|
||||||
|
#upcoming-slide iframe {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
#current-slide .label,
|
||||||
|
#upcoming-slide .label {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
left: 10px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connection-status {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 20;
|
||||||
|
padding: 30% 20% 20% 20%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #222;
|
||||||
|
background: #fff;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-element {
|
||||||
|
height: 34px;
|
||||||
|
line-height: 34px;
|
||||||
|
padding: 0 10px;
|
||||||
|
text-shadow: none;
|
||||||
|
background: rgba( 220, 220, 220, 0.8 );
|
||||||
|
color: #222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay-element.interactive:hover {
|
||||||
|
background: rgba( 220, 220, 220, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#current-slide {
|
||||||
|
position: absolute;
|
||||||
|
width: 60%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#upcoming-slide {
|
||||||
|
position: absolute;
|
||||||
|
width: 40%;
|
||||||
|
height: 40%;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Speaker controls */
|
||||||
|
#speaker-controls {
|
||||||
|
position: absolute;
|
||||||
|
top: 40%;
|
||||||
|
right: 0;
|
||||||
|
width: 40%;
|
||||||
|
height: 60%;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time.hidden,
|
||||||
|
.speaker-controls-notes.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .label,
|
||||||
|
.speaker-controls-pace .label,
|
||||||
|
.speaker-controls-notes .label {
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: normal;
|
||||||
|
font-size: 0.66em;
|
||||||
|
color: #666;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time, .speaker-controls-pace {
|
||||||
|
border-bottom: 1px solid rgba( 200, 200, 200, 0.5 );
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 10px 16px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .reset-button {
|
||||||
|
opacity: 0;
|
||||||
|
float: right;
|
||||||
|
color: #666;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.speaker-controls-time:hover .reset-button {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .timer,
|
||||||
|
.speaker-controls-time .clock {
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .timer,
|
||||||
|
.speaker-controls-time .clock,
|
||||||
|
.speaker-controls-time .pacing .hours-value,
|
||||||
|
.speaker-controls-time .pacing .minutes-value,
|
||||||
|
.speaker-controls-time .pacing .seconds-value {
|
||||||
|
font-size: 1.9em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .timer {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .clock {
|
||||||
|
float: right;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time span.mute {
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .pacing-title {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .pacing.ahead {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .pacing.on-track {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-time .pacing.behind {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-notes {
|
||||||
|
padding: 10px 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.speaker-controls-notes .value {
|
||||||
|
margin-top: 5px;
|
||||||
|
line-height: 1.4;
|
||||||
|
font-size: 1.2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Layout selector */
|
||||||
|
#speaker-layout {
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
color: #222;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
#speaker-layout select {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
border: 0;
|
||||||
|
box-shadow: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0;
|
||||||
|
|
||||||
|
font-size: 1em;
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#speaker-layout select:focus {
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Speaker layout: Wide */
|
||||||
|
body[data-speaker-layout="wide"] #current-slide,
|
||||||
|
body[data-speaker-layout="wide"] #upcoming-slide {
|
||||||
|
width: 50%;
|
||||||
|
height: 45%;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="wide"] #current-slide {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="wide"] #upcoming-slide {
|
||||||
|
top: 0;
|
||||||
|
left: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="wide"] #speaker-controls {
|
||||||
|
top: 45%;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 50%;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Speaker layout: Tall */
|
||||||
|
body[data-speaker-layout="tall"] #current-slide,
|
||||||
|
body[data-speaker-layout="tall"] #upcoming-slide {
|
||||||
|
width: 45%;
|
||||||
|
height: 50%;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="tall"] #current-slide {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="tall"] #upcoming-slide {
|
||||||
|
top: 50%;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="tall"] #speaker-controls {
|
||||||
|
padding-top: 40px;
|
||||||
|
top: 0;
|
||||||
|
left: 45%;
|
||||||
|
width: 55%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Speaker layout: Notes only */
|
||||||
|
body[data-speaker-layout="notes-only"] #current-slide,
|
||||||
|
body[data-speaker-layout="notes-only"] #upcoming-slide {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-speaker-layout="notes-only"] #speaker-controls {
|
||||||
|
padding-top: 40px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1080px) {
|
||||||
|
body[data-speaker-layout="default"] #speaker-controls {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 900px) {
|
||||||
|
body[data-speaker-layout="default"] #speaker-controls {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) {
|
||||||
|
body[data-speaker-layout="default"] #speaker-controls {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="connection-status">Loading speaker view...</div>
|
||||||
|
|
||||||
|
<div id="current-slide"></div>
|
||||||
|
<div id="upcoming-slide"><span class="overlay-element label">Upcoming</span></div>
|
||||||
|
<div id="speaker-controls">
|
||||||
|
<div class="speaker-controls-time">
|
||||||
|
<h4 class="label">Time <span class="reset-button">Click to Reset</span></h4>
|
||||||
|
<div class="clock">
|
||||||
|
<span class="clock-value">0:00 AM</span>
|
||||||
|
</div>
|
||||||
|
<div class="timer">
|
||||||
|
<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
|
||||||
|
</div>
|
||||||
|
<div class="clear"></div>
|
||||||
|
|
||||||
|
<h4 class="label pacing-title" style="display: none">Pacing – Time to finish current slide</h4>
|
||||||
|
<div class="pacing" style="display: none">
|
||||||
|
<span class="hours-value">00</span><span class="minutes-value">:00</span><span class="seconds-value">:00</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="speaker-controls-notes hidden">
|
||||||
|
<h4 class="label">Notes</h4>
|
||||||
|
<div class="value"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="speaker-layout" class="overlay-element interactive">
|
||||||
|
<span class="speaker-layout-label"></span>
|
||||||
|
<select class="speaker-layout-dropdown"></select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
var notes,
|
||||||
|
notesValue,
|
||||||
|
currentState,
|
||||||
|
currentSlide,
|
||||||
|
upcomingSlide,
|
||||||
|
layoutLabel,
|
||||||
|
layoutDropdown,
|
||||||
|
pendingCalls = {},
|
||||||
|
lastRevealApiCallId = 0,
|
||||||
|
connected = false;
|
||||||
|
|
||||||
|
var SPEAKER_LAYOUTS = {
|
||||||
|
'default': 'Default',
|
||||||
|
'wide': 'Wide',
|
||||||
|
'tall': 'Tall',
|
||||||
|
'notes-only': 'Notes only'
|
||||||
|
};
|
||||||
|
|
||||||
|
setupLayout();
|
||||||
|
|
||||||
|
var connectionStatus = document.querySelector( '#connection-status' );
|
||||||
|
var connectionTimeout = setTimeout( function() {
|
||||||
|
connectionStatus.innerHTML = 'Error connecting to main window.<br>Please try closing and reopening the speaker view.';
|
||||||
|
}, 5000 );
|
||||||
|
|
||||||
|
window.addEventListener( 'message', function( event ) {
|
||||||
|
|
||||||
|
clearTimeout( connectionTimeout );
|
||||||
|
connectionStatus.style.display = 'none';
|
||||||
|
|
||||||
|
var data = JSON.parse( event.data );
|
||||||
|
|
||||||
|
// The overview mode is only useful to the reveal.js instance
|
||||||
|
// where navigation occurs so we don't sync it
|
||||||
|
if( data.state ) delete data.state.overview;
|
||||||
|
|
||||||
|
// Messages sent by the notes plugin inside of the main window
|
||||||
|
if( data && data.namespace === 'reveal-notes' ) {
|
||||||
|
if( data.type === 'connect' ) {
|
||||||
|
handleConnectMessage( data );
|
||||||
|
}
|
||||||
|
else if( data.type === 'state' ) {
|
||||||
|
handleStateMessage( data );
|
||||||
|
}
|
||||||
|
else if( data.type === 'return' ) {
|
||||||
|
pendingCalls[data.callId](data.result);
|
||||||
|
delete pendingCalls[data.callId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Messages sent by the reveal.js inside of the current slide preview
|
||||||
|
else if( data && data.namespace === 'reveal' ) {
|
||||||
|
if( /ready/.test( data.eventName ) ) {
|
||||||
|
// Send a message back to notify that the handshake is complete
|
||||||
|
window.opener.postMessage( JSON.stringify({ namespace: 'reveal-notes', type: 'connected'} ), '*' );
|
||||||
|
}
|
||||||
|
else if( /slidechanged|fragmentshown|fragmenthidden|paused|resumed/.test( data.eventName ) && currentState !== JSON.stringify( data.state ) ) {
|
||||||
|
|
||||||
|
window.opener.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ]} ), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asynchronously calls the Reveal.js API of the main frame.
|
||||||
|
*/
|
||||||
|
function callRevealApi( methodName, methodArguments, callback ) {
|
||||||
|
|
||||||
|
var callId = ++lastRevealApiCallId;
|
||||||
|
pendingCalls[callId] = callback;
|
||||||
|
window.opener.postMessage( JSON.stringify( {
|
||||||
|
namespace: 'reveal-notes',
|
||||||
|
type: 'call',
|
||||||
|
callId: callId,
|
||||||
|
methodName: methodName,
|
||||||
|
arguments: methodArguments
|
||||||
|
} ), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the main window is trying to establish a
|
||||||
|
* connection.
|
||||||
|
*/
|
||||||
|
function handleConnectMessage( data ) {
|
||||||
|
|
||||||
|
if( connected === false ) {
|
||||||
|
connected = true;
|
||||||
|
|
||||||
|
setupIframes( data );
|
||||||
|
setupKeyboard();
|
||||||
|
setupNotes();
|
||||||
|
setupTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the main window sends an updated state.
|
||||||
|
*/
|
||||||
|
function handleStateMessage( data ) {
|
||||||
|
|
||||||
|
// Store the most recently set state to avoid circular loops
|
||||||
|
// applying the same state
|
||||||
|
currentState = JSON.stringify( data.state );
|
||||||
|
|
||||||
|
// No need for updating the notes in case of fragment changes
|
||||||
|
if ( data.notes ) {
|
||||||
|
notes.classList.remove( 'hidden' );
|
||||||
|
notesValue.style.whiteSpace = data.whitespace;
|
||||||
|
if( data.markdown ) {
|
||||||
|
notesValue.innerHTML = marked( data.notes );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
notesValue.innerHTML = data.notes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
notes.classList.add( 'hidden' );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the note slides
|
||||||
|
currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
|
||||||
|
upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'setState', args: [ data.state ] }), '*' );
|
||||||
|
upcomingSlide.contentWindow.postMessage( JSON.stringify({ method: 'next' }), '*' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Limit to max one state update per X ms
|
||||||
|
handleStateMessage = debounce( handleStateMessage, 200 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward keyboard events to the current slide window.
|
||||||
|
* This enables keyboard events to work even if focus
|
||||||
|
* isn't set on the current slide iframe.
|
||||||
|
*
|
||||||
|
* Block F5 default handling, it reloads and disconnects
|
||||||
|
* the speaker notes window.
|
||||||
|
*/
|
||||||
|
function setupKeyboard() {
|
||||||
|
|
||||||
|
document.addEventListener( 'keydown', function( event ) {
|
||||||
|
if( event.keyCode === 116 || ( event.metaKey && event.keyCode === 82 ) ) {
|
||||||
|
event.preventDefault();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
currentSlide.contentWindow.postMessage( JSON.stringify({ method: 'triggerKey', args: [ event.keyCode ] }), '*' );
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the preview iframes.
|
||||||
|
*/
|
||||||
|
function setupIframes( data ) {
|
||||||
|
|
||||||
|
var params = [
|
||||||
|
'receiver',
|
||||||
|
'progress=false',
|
||||||
|
'history=false',
|
||||||
|
'transition=none',
|
||||||
|
'autoSlide=0',
|
||||||
|
'backgroundTransition=none'
|
||||||
|
].join( '&' );
|
||||||
|
|
||||||
|
var urlSeparator = /\?/.test(data.url) ? '&' : '?';
|
||||||
|
var hash = '#/' + data.state.indexh + '/' + data.state.indexv;
|
||||||
|
var currentURL = data.url + urlSeparator + params + '&postMessageEvents=true' + hash;
|
||||||
|
var upcomingURL = data.url + urlSeparator + params + '&controls=false' + hash;
|
||||||
|
|
||||||
|
currentSlide = document.createElement( 'iframe' );
|
||||||
|
currentSlide.setAttribute( 'width', 1280 );
|
||||||
|
currentSlide.setAttribute( 'height', 1024 );
|
||||||
|
currentSlide.setAttribute( 'src', currentURL );
|
||||||
|
document.querySelector( '#current-slide' ).appendChild( currentSlide );
|
||||||
|
|
||||||
|
upcomingSlide = document.createElement( 'iframe' );
|
||||||
|
upcomingSlide.setAttribute( 'width', 640 );
|
||||||
|
upcomingSlide.setAttribute( 'height', 512 );
|
||||||
|
upcomingSlide.setAttribute( 'src', upcomingURL );
|
||||||
|
document.querySelector( '#upcoming-slide' ).appendChild( upcomingSlide );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup the notes UI.
|
||||||
|
*/
|
||||||
|
function setupNotes() {
|
||||||
|
|
||||||
|
notes = document.querySelector( '.speaker-controls-notes' );
|
||||||
|
notesValue = document.querySelector( '.speaker-controls-notes .value' );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTimings( callback ) {
|
||||||
|
|
||||||
|
callRevealApi( 'getSlidesAttributes', [], function ( slideAttributes ) {
|
||||||
|
callRevealApi( 'getConfig', [], function ( config ) {
|
||||||
|
var totalTime = config.totalTime;
|
||||||
|
var minTimePerSlide = config.minimumTimePerSlide || 0;
|
||||||
|
var defaultTiming = config.defaultTiming;
|
||||||
|
if ((defaultTiming == null) && (totalTime == null)) {
|
||||||
|
callback(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Setting totalTime overrides defaultTiming
|
||||||
|
if (totalTime) {
|
||||||
|
defaultTiming = 0;
|
||||||
|
}
|
||||||
|
var timings = [];
|
||||||
|
for ( var i in slideAttributes ) {
|
||||||
|
var slide = slideAttributes[ i ];
|
||||||
|
var timing = defaultTiming;
|
||||||
|
if( slide.hasOwnProperty( 'data-timing' )) {
|
||||||
|
var t = slide[ 'data-timing' ];
|
||||||
|
timing = parseInt(t);
|
||||||
|
if( isNaN(timing) ) {
|
||||||
|
console.warn("Could not parse timing '" + t + "' of slide " + i + "; using default of " + defaultTiming);
|
||||||
|
timing = defaultTiming;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
timings.push(timing);
|
||||||
|
}
|
||||||
|
if ( totalTime ) {
|
||||||
|
// After we've allocated time to individual slides, we summarize it and
|
||||||
|
// subtract it from the total time
|
||||||
|
var remainingTime = totalTime - timings.reduce( function(a, b) { return a + b; }, 0 );
|
||||||
|
// The remaining time is divided by the number of slides that have 0 seconds
|
||||||
|
// allocated at the moment, giving the average time-per-slide on the remaining slides
|
||||||
|
var remainingSlides = (timings.filter( function(x) { return x == 0 }) ).length
|
||||||
|
var timePerSlide = Math.round( remainingTime / remainingSlides, 0 )
|
||||||
|
// And now we replace every zero-value timing with that average
|
||||||
|
timings = timings.map( function(x) { return (x==0 ? timePerSlide : x) } );
|
||||||
|
}
|
||||||
|
var slidesUnderMinimum = timings.filter( function(x) { return (x < minTimePerSlide) } ).length
|
||||||
|
if ( slidesUnderMinimum ) {
|
||||||
|
message = "The pacing time for " + slidesUnderMinimum + " slide(s) is under the configured minimum of " + minTimePerSlide + " seconds. Check the data-timing attribute on individual slides, or consider increasing the totalTime or minimumTimePerSlide configuration options (or removing some slides).";
|
||||||
|
alert(message);
|
||||||
|
}
|
||||||
|
callback( timings );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number of seconds allocated for presenting
|
||||||
|
* all slides up to and including this one.
|
||||||
|
*/
|
||||||
|
function getTimeAllocated( timings, callback ) {
|
||||||
|
|
||||||
|
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||||
|
var allocated = 0;
|
||||||
|
for (var i in timings.slice(0, currentSlide + 1)) {
|
||||||
|
allocated += timings[i];
|
||||||
|
}
|
||||||
|
callback( allocated );
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the timer and clock and start updating them
|
||||||
|
* at an interval.
|
||||||
|
*/
|
||||||
|
function setupTimer() {
|
||||||
|
|
||||||
|
var start = new Date(),
|
||||||
|
timeEl = document.querySelector( '.speaker-controls-time' ),
|
||||||
|
clockEl = timeEl.querySelector( '.clock-value' ),
|
||||||
|
hoursEl = timeEl.querySelector( '.hours-value' ),
|
||||||
|
minutesEl = timeEl.querySelector( '.minutes-value' ),
|
||||||
|
secondsEl = timeEl.querySelector( '.seconds-value' ),
|
||||||
|
pacingTitleEl = timeEl.querySelector( '.pacing-title' ),
|
||||||
|
pacingEl = timeEl.querySelector( '.pacing' ),
|
||||||
|
pacingHoursEl = pacingEl.querySelector( '.hours-value' ),
|
||||||
|
pacingMinutesEl = pacingEl.querySelector( '.minutes-value' ),
|
||||||
|
pacingSecondsEl = pacingEl.querySelector( '.seconds-value' );
|
||||||
|
|
||||||
|
var timings = null;
|
||||||
|
getTimings( function ( _timings ) {
|
||||||
|
|
||||||
|
timings = _timings;
|
||||||
|
if (_timings !== null) {
|
||||||
|
pacingTitleEl.style.removeProperty('display');
|
||||||
|
pacingEl.style.removeProperty('display');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update once directly
|
||||||
|
_updateTimer();
|
||||||
|
|
||||||
|
// Then update every second
|
||||||
|
setInterval( _updateTimer, 1000 );
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
function _resetTimer() {
|
||||||
|
|
||||||
|
if (timings == null) {
|
||||||
|
start = new Date();
|
||||||
|
_updateTimer();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Reset timer to beginning of current slide
|
||||||
|
getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
|
||||||
|
var slideEndTiming = slideEndTimingSeconds * 1000;
|
||||||
|
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||||
|
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||||
|
var previousSlidesTiming = slideEndTiming - currentSlideTiming;
|
||||||
|
var now = new Date();
|
||||||
|
start = new Date(now.getTime() - previousSlidesTiming);
|
||||||
|
_updateTimer();
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
timeEl.addEventListener( 'click', function() {
|
||||||
|
_resetTimer();
|
||||||
|
return false;
|
||||||
|
} );
|
||||||
|
|
||||||
|
function _displayTime( hrEl, minEl, secEl, time) {
|
||||||
|
|
||||||
|
var sign = Math.sign(time) == -1 ? "-" : "";
|
||||||
|
time = Math.abs(Math.round(time / 1000));
|
||||||
|
var seconds = time % 60;
|
||||||
|
var minutes = Math.floor( time / 60 ) % 60 ;
|
||||||
|
var hours = Math.floor( time / ( 60 * 60 )) ;
|
||||||
|
hrEl.innerHTML = sign + zeroPadInteger( hours );
|
||||||
|
if (hours == 0) {
|
||||||
|
hrEl.classList.add( 'mute' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hrEl.classList.remove( 'mute' );
|
||||||
|
}
|
||||||
|
minEl.innerHTML = ':' + zeroPadInteger( minutes );
|
||||||
|
if (hours == 0 && minutes == 0) {
|
||||||
|
minEl.classList.add( 'mute' );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
minEl.classList.remove( 'mute' );
|
||||||
|
}
|
||||||
|
secEl.innerHTML = ':' + zeroPadInteger( seconds );
|
||||||
|
}
|
||||||
|
|
||||||
|
function _updateTimer() {
|
||||||
|
|
||||||
|
var diff, hours, minutes, seconds,
|
||||||
|
now = new Date();
|
||||||
|
|
||||||
|
diff = now.getTime() - start.getTime();
|
||||||
|
|
||||||
|
clockEl.innerHTML = now.toLocaleTimeString( 'en-US', { hour12: true, hour: '2-digit', minute:'2-digit' } );
|
||||||
|
_displayTime( hoursEl, minutesEl, secondsEl, diff );
|
||||||
|
if (timings !== null) {
|
||||||
|
_updatePacing(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function _updatePacing(diff) {
|
||||||
|
|
||||||
|
getTimeAllocated( timings, function ( slideEndTimingSeconds ) {
|
||||||
|
var slideEndTiming = slideEndTimingSeconds * 1000;
|
||||||
|
|
||||||
|
callRevealApi( 'getSlidePastCount', [], function ( currentSlide ) {
|
||||||
|
var currentSlideTiming = timings[currentSlide] * 1000;
|
||||||
|
var timeLeftCurrentSlide = slideEndTiming - diff;
|
||||||
|
if (timeLeftCurrentSlide < 0) {
|
||||||
|
pacingEl.className = 'pacing behind';
|
||||||
|
}
|
||||||
|
else if (timeLeftCurrentSlide < currentSlideTiming) {
|
||||||
|
pacingEl.className = 'pacing on-track';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pacingEl.className = 'pacing ahead';
|
||||||
|
}
|
||||||
|
_displayTime( pacingHoursEl, pacingMinutesEl, pacingSecondsEl, timeLeftCurrentSlide );
|
||||||
|
} );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets up the speaker view layout and layout selector.
|
||||||
|
*/
|
||||||
|
function setupLayout() {
|
||||||
|
|
||||||
|
layoutDropdown = document.querySelector( '.speaker-layout-dropdown' );
|
||||||
|
layoutLabel = document.querySelector( '.speaker-layout-label' );
|
||||||
|
|
||||||
|
// Render the list of available layouts
|
||||||
|
for( var id in SPEAKER_LAYOUTS ) {
|
||||||
|
var option = document.createElement( 'option' );
|
||||||
|
option.setAttribute( 'value', id );
|
||||||
|
option.textContent = SPEAKER_LAYOUTS[ id ];
|
||||||
|
layoutDropdown.appendChild( option );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Monitor the dropdown for changes
|
||||||
|
layoutDropdown.addEventListener( 'change', function( event ) {
|
||||||
|
|
||||||
|
setLayout( layoutDropdown.value );
|
||||||
|
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
// Restore any currently persisted layout
|
||||||
|
setLayout( getLayout() );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a new speaker view layout. The layout is persisted
|
||||||
|
* in local storage.
|
||||||
|
*/
|
||||||
|
function setLayout( value ) {
|
||||||
|
|
||||||
|
var title = SPEAKER_LAYOUTS[ value ];
|
||||||
|
|
||||||
|
layoutLabel.innerHTML = 'Layout' + ( title ? ( ': ' + title ) : '' );
|
||||||
|
layoutDropdown.value = value;
|
||||||
|
|
||||||
|
document.body.setAttribute( 'data-speaker-layout', value );
|
||||||
|
|
||||||
|
// Persist locally
|
||||||
|
if( supportsLocalStorage() ) {
|
||||||
|
window.localStorage.setItem( 'reveal-speaker-layout', value );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID of the most recently set speaker layout
|
||||||
|
* or our default layout if none has been set.
|
||||||
|
*/
|
||||||
|
function getLayout() {
|
||||||
|
|
||||||
|
if( supportsLocalStorage() ) {
|
||||||
|
var layout = window.localStorage.getItem( 'reveal-speaker-layout' );
|
||||||
|
if( layout ) {
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to the first record in the layouts hash
|
||||||
|
for( var id in SPEAKER_LAYOUTS ) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function supportsLocalStorage() {
|
||||||
|
|
||||||
|
try {
|
||||||
|
localStorage.setItem('test', 'test');
|
||||||
|
localStorage.removeItem('test');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch( e ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function zeroPadInteger( num ) {
|
||||||
|
|
||||||
|
var str = '00' + parseInt( num );
|
||||||
|
return str.substring( str.length - 2 );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limits the frequency at which a function can be called.
|
||||||
|
*/
|
||||||
|
function debounce( fn, ms ) {
|
||||||
|
|
||||||
|
var lastTime = 0,
|
||||||
|
timeout;
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
|
||||||
|
var args = arguments;
|
||||||
|
var context = this;
|
||||||
|
|
||||||
|
clearTimeout( timeout );
|
||||||
|
|
||||||
|
var timeSinceLastCall = Date.now() - lastTime;
|
||||||
|
if( timeSinceLastCall > ms ) {
|
||||||
|
fn.apply( context, args );
|
||||||
|
lastTime = Date.now();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
timeout = setTimeout( function() {
|
||||||
|
fn.apply( context, args );
|
||||||
|
lastTime = Date.now();
|
||||||
|
}, ms - timeSinceLastCall );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
243
assets/vendor/reveal/plugin/search/plugin.js
vendored
Normal file
243
assets/vendor/reveal/plugin/search/plugin.js
vendored
Normal file
|
@ -0,0 +1,243 @@
|
||||||
|
/*!
|
||||||
|
* Handles finding a text string anywhere in the slides and showing the next occurrence to the user
|
||||||
|
* by navigatating to that slide and highlighting it.
|
||||||
|
*
|
||||||
|
* @author Jon Snyder <snyder.jon@gmail.com>, February 2013
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Plugin = () => {
|
||||||
|
|
||||||
|
// The reveal.js instance this plugin is attached to
|
||||||
|
let deck;
|
||||||
|
|
||||||
|
let searchElement;
|
||||||
|
let searchButton;
|
||||||
|
let searchInput;
|
||||||
|
|
||||||
|
let matchedSlides;
|
||||||
|
let currentMatchedIndex;
|
||||||
|
let searchboxDirty;
|
||||||
|
let hilitor;
|
||||||
|
|
||||||
|
function render() {
|
||||||
|
|
||||||
|
searchElement = document.createElement( 'div' );
|
||||||
|
searchElement.classList.add( 'searchbox' );
|
||||||
|
searchElement.style.position = 'absolute';
|
||||||
|
searchElement.style.top = '10px';
|
||||||
|
searchElement.style.right = '10px';
|
||||||
|
searchElement.style.zIndex = 10;
|
||||||
|
|
||||||
|
//embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/:
|
||||||
|
searchElement.innerHTML = `<input type="search" class="searchinput" placeholder="Search..." style="vertical-align: top;"/>
|
||||||
|
</span>`;
|
||||||
|
|
||||||
|
searchInput = searchElement.querySelector( '.searchinput' );
|
||||||
|
searchInput.style.width = '240px';
|
||||||
|
searchInput.style.fontSize = '14px';
|
||||||
|
searchInput.style.padding = '4px 6px';
|
||||||
|
searchInput.style.color = '#000';
|
||||||
|
searchInput.style.background = '#fff';
|
||||||
|
searchInput.style.borderRadius = '2px';
|
||||||
|
searchInput.style.border = '0';
|
||||||
|
searchInput.style.outline = '0';
|
||||||
|
searchInput.style.boxShadow = '0 2px 18px rgba(0, 0, 0, 0.2)';
|
||||||
|
searchInput.style['-webkit-appearance'] = 'none';
|
||||||
|
|
||||||
|
deck.getRevealElement().appendChild( searchElement );
|
||||||
|
|
||||||
|
// searchButton.addEventListener( 'click', function(event) {
|
||||||
|
// doSearch();
|
||||||
|
// }, false );
|
||||||
|
|
||||||
|
searchInput.addEventListener( 'keyup', function( event ) {
|
||||||
|
switch (event.keyCode) {
|
||||||
|
case 13:
|
||||||
|
event.preventDefault();
|
||||||
|
doSearch();
|
||||||
|
searchboxDirty = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
searchboxDirty = true;
|
||||||
|
}
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
closeSearch();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function openSearch() {
|
||||||
|
if( !searchElement ) render();
|
||||||
|
|
||||||
|
searchElement.style.display = 'inline';
|
||||||
|
searchInput.focus();
|
||||||
|
searchInput.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSearch() {
|
||||||
|
if( !searchElement ) render();
|
||||||
|
|
||||||
|
searchElement.style.display = 'none';
|
||||||
|
if(hilitor) hilitor.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleSearch() {
|
||||||
|
if( !searchElement ) render();
|
||||||
|
|
||||||
|
if (searchElement.style.display !== 'inline') {
|
||||||
|
openSearch();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
closeSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function doSearch() {
|
||||||
|
//if there's been a change in the search term, perform a new search:
|
||||||
|
if (searchboxDirty) {
|
||||||
|
var searchstring = searchInput.value;
|
||||||
|
|
||||||
|
if (searchstring === '') {
|
||||||
|
if(hilitor) hilitor.remove();
|
||||||
|
matchedSlides = null;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
//find the keyword amongst the slides
|
||||||
|
hilitor = new Hilitor("slidecontent");
|
||||||
|
matchedSlides = hilitor.apply(searchstring);
|
||||||
|
currentMatchedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedSlides) {
|
||||||
|
//navigate to the next slide that has the keyword, wrapping to the first if necessary
|
||||||
|
if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) {
|
||||||
|
currentMatchedIndex = 0;
|
||||||
|
}
|
||||||
|
if (matchedSlides.length > currentMatchedIndex) {
|
||||||
|
deck.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v);
|
||||||
|
currentMatchedIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original JavaScript code by Chirp Internet: www.chirp.com.au
|
||||||
|
// Please acknowledge use of this code by including this header.
|
||||||
|
// 2/2013 jon: modified regex to display any match, not restricted to word boundaries.
|
||||||
|
function Hilitor(id, tag) {
|
||||||
|
|
||||||
|
var targetNode = document.getElementById(id) || document.body;
|
||||||
|
var hiliteTag = tag || "EM";
|
||||||
|
var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM)$");
|
||||||
|
var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"];
|
||||||
|
var wordColor = [];
|
||||||
|
var colorIdx = 0;
|
||||||
|
var matchRegex = "";
|
||||||
|
var matchingSlides = [];
|
||||||
|
|
||||||
|
this.setRegex = function(input)
|
||||||
|
{
|
||||||
|
input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|");
|
||||||
|
matchRegex = new RegExp("(" + input + ")","i");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getRegex = function()
|
||||||
|
{
|
||||||
|
return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
// recursively apply word highlighting
|
||||||
|
this.hiliteWords = function(node)
|
||||||
|
{
|
||||||
|
if(node == undefined || !node) return;
|
||||||
|
if(!matchRegex) return;
|
||||||
|
if(skipTags.test(node.nodeName)) return;
|
||||||
|
|
||||||
|
if(node.hasChildNodes()) {
|
||||||
|
for(var i=0; i < node.childNodes.length; i++)
|
||||||
|
this.hiliteWords(node.childNodes[i]);
|
||||||
|
}
|
||||||
|
if(node.nodeType == 3) { // NODE_TEXT
|
||||||
|
var nv, regs;
|
||||||
|
if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) {
|
||||||
|
//find the slide's section element and save it in our list of matching slides
|
||||||
|
var secnode = node;
|
||||||
|
while (secnode != null && secnode.nodeName != 'SECTION') {
|
||||||
|
secnode = secnode.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slideIndex = deck.getIndices(secnode);
|
||||||
|
var slidelen = matchingSlides.length;
|
||||||
|
var alreadyAdded = false;
|
||||||
|
for (var i=0; i < slidelen; i++) {
|
||||||
|
if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) {
|
||||||
|
alreadyAdded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! alreadyAdded) {
|
||||||
|
matchingSlides.push(slideIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!wordColor[regs[0].toLowerCase()]) {
|
||||||
|
wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length];
|
||||||
|
}
|
||||||
|
|
||||||
|
var match = document.createElement(hiliteTag);
|
||||||
|
match.appendChild(document.createTextNode(regs[0]));
|
||||||
|
match.style.backgroundColor = wordColor[regs[0].toLowerCase()];
|
||||||
|
match.style.fontStyle = "inherit";
|
||||||
|
match.style.color = "#000";
|
||||||
|
|
||||||
|
var after = node.splitText(regs.index);
|
||||||
|
after.nodeValue = after.nodeValue.substring(regs[0].length);
|
||||||
|
node.parentNode.insertBefore(match, after);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// remove highlighting
|
||||||
|
this.remove = function()
|
||||||
|
{
|
||||||
|
var arr = document.getElementsByTagName(hiliteTag);
|
||||||
|
var el;
|
||||||
|
while(arr.length && (el = arr[0])) {
|
||||||
|
el.parentNode.replaceChild(el.firstChild, el);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// start highlighting at target node
|
||||||
|
this.apply = function(input)
|
||||||
|
{
|
||||||
|
if(input == undefined || !input) return;
|
||||||
|
this.remove();
|
||||||
|
this.setRegex(input);
|
||||||
|
this.hiliteWords(targetNode);
|
||||||
|
return matchingSlides;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
|
||||||
|
id: 'search',
|
||||||
|
|
||||||
|
init: reveal => {
|
||||||
|
|
||||||
|
deck = reveal;
|
||||||
|
deck.registerKeyboardShortcut( 'CTRL + Shift + F', 'Search' );
|
||||||
|
|
||||||
|
document.addEventListener( 'keydown', function( event ) {
|
||||||
|
if( event.key == "F" && (event.ctrlKey || event.metaKey) ) { //Control+Shift+f
|
||||||
|
event.preventDefault();
|
||||||
|
toggleSearch();
|
||||||
|
}
|
||||||
|
}, false );
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
open: openSearch
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Plugin;
|
1
assets/vendor/reveal/plugin/search/search.esm.js
vendored
Normal file
1
assets/vendor/reveal/plugin/search/search.esm.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
assets/vendor/reveal/plugin/search/search.js
vendored
Normal file
1
assets/vendor/reveal/plugin/search/search.js
vendored
Normal file
File diff suppressed because one or more lines are too long
279
assets/vendor/reveal/plugin/zoom/plugin.js
vendored
Normal file
279
assets/vendor/reveal/plugin/zoom/plugin.js
vendored
Normal file
|
@ -0,0 +1,279 @@
|
||||||
|
/*!
|
||||||
|
* reveal.js Zoom plugin
|
||||||
|
*/
|
||||||
|
const Plugin = {
|
||||||
|
|
||||||
|
id: 'zoom',
|
||||||
|
|
||||||
|
init: function( reveal ) {
|
||||||
|
|
||||||
|
reveal.getRevealElement().addEventListener( 'mousedown', function( event ) {
|
||||||
|
var defaultModifier = /Linux/.test( window.navigator.platform ) ? 'ctrl' : 'alt';
|
||||||
|
|
||||||
|
var modifier = ( reveal.getConfig().zoomKey ? reveal.getConfig().zoomKey : defaultModifier ) + 'Key';
|
||||||
|
var zoomLevel = ( reveal.getConfig().zoomLevel ? reveal.getConfig().zoomLevel : 2 );
|
||||||
|
|
||||||
|
if( event[ modifier ] && !reveal.isOverview() ) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
zoom.to({
|
||||||
|
x: event.clientX,
|
||||||
|
y: event.clientY,
|
||||||
|
scale: zoomLevel,
|
||||||
|
pan: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default () => Plugin;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* zoom.js 0.3 (modified for use with reveal.js)
|
||||||
|
* http://lab.hakim.se/zoom-js
|
||||||
|
* MIT licensed
|
||||||
|
*
|
||||||
|
* Copyright (C) 2011-2014 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;
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
// Monitor mouse movement for panning
|
||||||
|
document.addEventListener( 'mousemove', function( event ) {
|
||||||
|
if( level !== 1 ) {
|
||||||
|
mouseX = event.clientX;
|
||||||
|
mouseY = event.clientY;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies the CSS required to zoom in, prefers the use of CSS3
|
||||||
|
* transforms but falls back on zoom for IE.
|
||||||
|
*
|
||||||
|
* @param {Object} rect
|
||||||
|
* @param {Number} scale
|
||||||
|
*/
|
||||||
|
function magnify( rect, scale ) {
|
||||||
|
|
||||||
|
var scrollOffset = getScrollOffset();
|
||||||
|
|
||||||
|
// Ensure a width/height is set
|
||||||
|
rect.width = rect.width || 1;
|
||||||
|
rect.height = rect.height || 1;
|
||||||
|
|
||||||
|
// Center the rect within the zoomed viewport
|
||||||
|
rect.x -= ( window.innerWidth - ( rect.width * scale ) ) / 2;
|
||||||
|
rect.y -= ( window.innerHeight - ( rect.height * scale ) ) / 2;
|
||||||
|
|
||||||
|
if( supportsTransforms ) {
|
||||||
|
// Reset
|
||||||
|
if( scale === 1 ) {
|
||||||
|
document.body.style.transform = '';
|
||||||
|
document.body.style.OTransform = '';
|
||||||
|
document.body.style.msTransform = '';
|
||||||
|
document.body.style.MozTransform = '';
|
||||||
|
document.body.style.WebkitTransform = '';
|
||||||
|
}
|
||||||
|
// Scale
|
||||||
|
else {
|
||||||
|
var origin = scrollOffset.x +'px '+ scrollOffset.y +'px',
|
||||||
|
transform = 'translate('+ -rect.x +'px,'+ -rect.y +'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
|
||||||
|
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 = '';
|
||||||
|
}
|
||||||
|
// Scale
|
||||||
|
else {
|
||||||
|
document.body.style.position = 'relative';
|
||||||
|
document.body.style.left = ( - ( scrollOffset.x + rect.x ) / scale ) + 'px';
|
||||||
|
document.body.style.top = ( - ( scrollOffset.y + rect.y ) / scale ) + 'px';
|
||||||
|
document.body.style.width = ( scale * 100 ) + '%';
|
||||||
|
document.body.style.height = ( scale * 100 ) + '%';
|
||||||
|
document.body.style.zoom = scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
level = scale;
|
||||||
|
|
||||||
|
if( document.documentElement.classList ) {
|
||||||
|
if( level !== 1 ) {
|
||||||
|
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.pageYOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
var bounds = options.element.getBoundingClientRect();
|
||||||
|
|
||||||
|
options.x = bounds.left - padding;
|
||||||
|
options.y = bounds.top - padding;
|
||||||
|
options.width = bounds.width + ( padding * 2 );
|
||||||
|
options.height = bounds.height + ( padding * 2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
magnify( options, 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 );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the document zoom state to its default.
|
||||||
|
*/
|
||||||
|
out: function() {
|
||||||
|
clearTimeout( panEngageTimeout );
|
||||||
|
clearInterval( panUpdateInterval );
|
||||||
|
|
||||||
|
magnify( { x: 0, y: 0 }, 1 );
|
||||||
|
|
||||||
|
level = 1;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Alias
|
||||||
|
magnify: function( options ) { this.to( options ) },
|
||||||
|
reset: function() { this.out() },
|
||||||
|
|
||||||
|
zoomLevel: function() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
4
assets/vendor/reveal/plugin/zoom/zoom.esm.js
vendored
Normal file
4
assets/vendor/reveal/plugin/zoom/zoom.esm.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/*!
|
||||||
|
* reveal.js Zoom plugin
|
||||||
|
*/
|
||||||
|
var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="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;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(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"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();export default function(){return e}
|
4
assets/vendor/reveal/plugin/zoom/zoom.js
vendored
Normal file
4
assets/vendor/reveal/plugin/zoom/zoom.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).RevealZoom=t()}(this,(function(){"use strict";
|
||||||
|
/*!
|
||||||
|
* reveal.js Zoom plugin
|
||||||
|
*/var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(o){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;o[i]&&!e.isOverview()&&(o.preventDefault(),t.to({x:o.clientX,y:o.clientY,scale:d,pan:!1}))}))}},t=function(){var e=1,o=0,n=0,i=-1,d=-1,s="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;function r(t,o){var n=y();if(t.width=t.width||1,t.height=t.height||1,t.x-=(window.innerWidth-t.width*o)/2,t.y-=(window.innerHeight-t.height*o)/2,s)if(1===o)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-t.x+"px,"+-t.y+"px) scale("+o+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===o?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+t.x)/o+"px",document.body.style.top=-(n.y+t.y)/o+"px",document.body.style.width=100*o+"%",document.body.style.height=100*o+"%",document.body.style.zoom=o);e=o,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var t=.12*window.innerWidth,i=.12*window.innerHeight,d=y();n<i?window.scroll(d.x,d.y-14/e*(1-n/i)):n>window.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),o<t?window.scroll(d.x-14/e*(1-o/t),d.y):o>window.innerWidth-t&&window.scroll(d.x+(1-(window.innerWidth-o)/t)*(14/e),d.y)}function y(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(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"),document.addEventListener("keyup",(function(o){1!==e&&27===o.keyCode&&t.out()})),document.addEventListener("mousemove",(function(t){1!==e&&(o=t.clientX,n=t.clientY)})),{to:function(o){if(1!==e)t.out();else{if(o.x=o.x||0,o.y=o.y||0,o.element){var n=o.element.getBoundingClientRect();o.x=n.left-20,o.y=n.top-20,o.width=n.width+40,o.height=n.height+40}void 0!==o.width&&void 0!==o.height&&(o.scale=Math.max(Math.min(window.innerWidth/o.width,window.innerHeight/o.height),1)),o.scale>1&&(o.x*=o.scale,o.y*=o.scale,r(o,o.scale),!1!==o.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
|
8
assets/vendor/reveal/reveal.css
vendored
Normal file
8
assets/vendor/reveal/reveal.css
vendored
Normal file
File diff suppressed because one or more lines are too long
9
assets/vendor/reveal/reveal.js
vendored
Normal file
9
assets/vendor/reveal/reveal.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "zargon-now.github.io",
|
"name": "zrgn.github.io",
|
||||||
"homepage": "https://github.com/zargon-now/zargon-now.github.io",
|
"homepage": "https://github.com/zrgn/zrgn.github.io",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Patrick Connelly <patrick@deadlypenguin.com>"
|
"Patrick Connelly <patrick@deadlypenguin.com>"
|
||||||
],
|
],
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jquery": "^3.4.1",
|
"jquery": "^3.4.1",
|
||||||
"bulma": "^0.7.4"
|
"bulma": "^0.7.4",
|
||||||
|
"reveal.js": "^4.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
package-lock.json
generated
37
package-lock.json
generated
|
@ -648,42 +648,35 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grunt-bowercopy": {
|
"grunt-bowercopy": {
|
||||||
"version": "1.2.4",
|
"version": "1.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/grunt-bowercopy/-/grunt-bowercopy-1.2.4.tgz",
|
"resolved": "https://registry.npmjs.org/grunt-bowercopy/-/grunt-bowercopy-1.2.5.tgz",
|
||||||
"integrity": "sha1-DCafaBs4u9+hOwHayBJInvMiTFc=",
|
"integrity": "sha512-add3pqWmE5vt2o+TkgV4hr6jQLCZRtupuGXgDGDzfQAzka+EGMPsjGmVC8wUYhoAC+6j46zUIc3cv4dMmXC3zA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"bower": "^1.3.5",
|
"bower": "^1.3.5",
|
||||||
"glob": "^4.3.5",
|
"glob": "^7.1.6",
|
||||||
"lodash": "^3.1.0"
|
"lodash": "^4.17.15"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": {
|
"glob": {
|
||||||
"version": "4.5.3",
|
"version": "7.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
|
||||||
"integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
|
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"fs.realpath": "^1.0.0",
|
||||||
"inflight": "^1.0.4",
|
"inflight": "^1.0.4",
|
||||||
"inherits": "2",
|
"inherits": "2",
|
||||||
"minimatch": "^2.0.1",
|
"minimatch": "^3.0.4",
|
||||||
"once": "^1.3.0"
|
"once": "^1.3.0",
|
||||||
|
"path-is-absolute": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "3.10.1",
|
"version": "4.17.19",
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
|
||||||
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
|
"integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
|
||||||
"minimatch": {
|
|
||||||
"version": "2.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
|
|
||||||
"integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^1.0.0"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "^5.16.0",
|
"eslint": "^5.16.0",
|
||||||
"grunt": "^1.0.4",
|
"grunt": "^1.0.4",
|
||||||
"grunt-bowercopy": "^1.2.3",
|
"grunt-bowercopy": "^1.2.5",
|
||||||
"grunt-contrib-clean": "^2.0.0"
|
"grunt-contrib-clean": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {}
|
"dependencies": {}
|
||||||
|
|
Loading…
Reference in a new issue