├── run.bat ├── assets ├── gif │ ├── en.gif │ ├── jidong.gif │ ├── great_job.gif │ ├── let_it_go.gif │ └── inifnite_cat.gif ├── img │ ├── git.png │ ├── learn.jpg │ ├── light.jpg │ ├── storm.jpg │ ├── artisan.png │ ├── github.png │ ├── jet-sky.jpg │ ├── phphub.png │ ├── polygon.jpg │ ├── route1.jpg │ ├── route2.jpg │ ├── route3.jpg │ ├── route4.jpg │ ├── vagrant.png │ ├── background.jpg │ ├── composer.png │ ├── eloquent.png │ ├── l3_drangon.PNG │ ├── resource.png │ ├── sitepoint.jpg │ ├── first_commit.png │ ├── polygon_red.jpg │ ├── current_route.png │ ├── laravel-china.png │ ├── polygon_green.jpg │ ├── sitepoint2013.png │ ├── taylor_family.jpg │ ├── taylor_otwell.jpeg │ └── congruent_pentagon.png ├── font │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── league_gothic-webfont.eot │ ├── league_gothic-webfont.ttf │ ├── league_gothic_license │ └── league_gothic-webfont.woff ├── js │ ├── vendor │ │ ├── html5shiv.js │ │ ├── reveal-plugin │ │ │ ├── markdown │ │ │ │ ├── example.md │ │ │ │ ├── example.html │ │ │ │ ├── markdown.js │ │ │ │ └── marked.js │ │ │ ├── multiplex │ │ │ │ ├── client.js │ │ │ │ ├── master.js │ │ │ │ └── index.js │ │ │ ├── print-pdf │ │ │ │ └── print-pdf.js │ │ │ ├── postmessage │ │ │ │ ├── postmessage.js │ │ │ │ └── example.html │ │ │ ├── remotes │ │ │ │ └── remotes.js │ │ │ ├── math │ │ │ │ └── math.js │ │ │ ├── notes-server │ │ │ │ ├── client.js │ │ │ │ ├── index.js │ │ │ │ └── notes.html │ │ │ ├── notes │ │ │ │ ├── notes.js │ │ │ │ └── notes.html │ │ │ ├── search │ │ │ │ └── search.js │ │ │ ├── zoom-js │ │ │ │ └── zoom.js │ │ │ └── highlight │ │ │ │ └── highlight.pack.js │ │ ├── classList.js │ │ ├── head.min.js │ │ └── reveal │ │ │ └── reveal.min.js │ └── app.js └── css │ ├── custom.css │ └── vendor │ ├── zenburn.css │ ├── hybrid.css │ └── reveal │ └── print │ ├── pdf.css │ └── paper.css ├── slide_start.md ├── slide_part2.md ├── README.md ├── index.html ├── slide_part3.md └── slide_part1.md /run.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | php -S localhost:8000 4 | -------------------------------------------------------------------------------- /assets/gif/en.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/gif/en.gif -------------------------------------------------------------------------------- /assets/img/git.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/git.png -------------------------------------------------------------------------------- /assets/img/learn.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/learn.jpg -------------------------------------------------------------------------------- /assets/img/light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/light.jpg -------------------------------------------------------------------------------- /assets/img/storm.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/storm.jpg -------------------------------------------------------------------------------- /assets/gif/jidong.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/gif/jidong.gif -------------------------------------------------------------------------------- /assets/img/artisan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/artisan.png -------------------------------------------------------------------------------- /assets/img/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/github.png -------------------------------------------------------------------------------- /assets/img/jet-sky.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/jet-sky.jpg -------------------------------------------------------------------------------- /assets/img/phphub.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/phphub.png -------------------------------------------------------------------------------- /assets/img/polygon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/polygon.jpg -------------------------------------------------------------------------------- /assets/img/route1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/route1.jpg -------------------------------------------------------------------------------- /assets/img/route2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/route2.jpg -------------------------------------------------------------------------------- /assets/img/route3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/route3.jpg -------------------------------------------------------------------------------- /assets/img/route4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/route4.jpg -------------------------------------------------------------------------------- /assets/img/vagrant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/vagrant.png -------------------------------------------------------------------------------- /assets/gif/great_job.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/gif/great_job.gif -------------------------------------------------------------------------------- /assets/gif/let_it_go.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/gif/let_it_go.gif -------------------------------------------------------------------------------- /assets/img/background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/background.jpg -------------------------------------------------------------------------------- /assets/img/composer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/composer.png -------------------------------------------------------------------------------- /assets/img/eloquent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/eloquent.png -------------------------------------------------------------------------------- /assets/img/l3_drangon.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/l3_drangon.PNG -------------------------------------------------------------------------------- /assets/img/resource.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/resource.png -------------------------------------------------------------------------------- /assets/img/sitepoint.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/sitepoint.jpg -------------------------------------------------------------------------------- /assets/font/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/FontAwesome.otf -------------------------------------------------------------------------------- /assets/gif/inifnite_cat.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/gif/inifnite_cat.gif -------------------------------------------------------------------------------- /assets/img/first_commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/first_commit.png -------------------------------------------------------------------------------- /assets/img/polygon_red.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/polygon_red.jpg -------------------------------------------------------------------------------- /assets/img/current_route.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/current_route.png -------------------------------------------------------------------------------- /assets/img/laravel-china.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/laravel-china.png -------------------------------------------------------------------------------- /assets/img/polygon_green.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/polygon_green.jpg -------------------------------------------------------------------------------- /assets/img/sitepoint2013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/sitepoint2013.png -------------------------------------------------------------------------------- /assets/img/taylor_family.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/taylor_family.jpg -------------------------------------------------------------------------------- /assets/img/taylor_otwell.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/taylor_otwell.jpeg -------------------------------------------------------------------------------- /assets/font/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/fontawesome-webfont.eot -------------------------------------------------------------------------------- /assets/font/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /assets/img/congruent_pentagon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/img/congruent_pentagon.png -------------------------------------------------------------------------------- /assets/font/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/fontawesome-webfont.woff -------------------------------------------------------------------------------- /assets/font/league_gothic-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/league_gothic-webfont.eot -------------------------------------------------------------------------------- /assets/font/league_gothic-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/league_gothic-webfont.ttf -------------------------------------------------------------------------------- /assets/font/league_gothic_license: -------------------------------------------------------------------------------- 1 | SIL Open Font License (OFL) 2 | http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL 3 | -------------------------------------------------------------------------------- /assets/font/league_gothic-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lifesign/laravel_slide/HEAD/assets/font/league_gothic-webfont.woff -------------------------------------------------------------------------------- /assets/js/vendor/html5shiv.js: -------------------------------------------------------------------------------- 1 | document.createElement('header'); 2 | document.createElement('nav'); 3 | document.createElement('section'); 4 | document.createElement('article'); 5 | document.createElement('aside'); 6 | document.createElement('footer'); 7 | document.createElement('hgroup'); -------------------------------------------------------------------------------- /slide_start.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # LARAVEL与框架二三事 4 | 5 | 6 | ##高锋 7 | ##2014-12-20 @ [四脚猫](http://www.sijiaomao.com) 8 | -------------------------------------------------------------------------------- /slide_part2.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #What's New in laravel5 5 | 6 | - Elixir 7 | - Event Scheduling 8 | - Event Annotations 9 | - Form Request 10 | - FileSystem - Flysystem 11 | - Method Injection 12 | - Route Cache 13 | - Route Annotations 14 | - Socilate 15 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/markdown/example.md: -------------------------------------------------------------------------------- 1 | # Markdown Demo 2 | 3 | 4 | 5 | ## External 1.1 6 | 7 | Content 1.1 8 | 9 | Note: This will only appear in the speaker notes window. 10 | 11 | 12 | ## External 1.2 13 | 14 | Content 1.2 15 | 16 | 17 | 18 | ## External 2 19 | 20 | Content 2.1 21 | 22 | 23 | 24 | ## External 3.1 25 | 26 | Content 3.1 27 | 28 | 29 | ## External 3.2 30 | 31 | Content 3.2 32 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/multiplex/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | var multiplex = Reveal.getConfig().multiplex; 3 | var socketId = multiplex.id; 4 | var socket = io.connect(multiplex.url); 5 | 6 | socket.on(multiplex.id, function(data) { 7 | // ignore data from sockets that aren't ours 8 | if (data.socketId !== socketId) { return; } 9 | if( window.location.host === 'localhost:1947' ) return; 10 | 11 | Reveal.slide(data.indexh, data.indexv, data.indexf, 'remote'); 12 | }); 13 | }()); 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #laravel-slide 2 | 3 | 在四脚猫的一次分享《laravel与框架二三事》 [在线地址](http://lifesign.github.io/laravel_slide/) 4 | 5 | ## How to Run 6 | 7 | 由于使用了[reveal.js](https://github.com/hakimel/reveal.js)中的 External Markdown 所以需要在本地开启 web server , 可参考以下两种方式。 8 | 9 | 1. 如果本地的php版本在5.4以上, 可使用内置的服务器。 `php -S localhost:8000` 10 | 2. 如果本地有nodejs, 可以用nodejs开启 `node server.js` 11 | 3. apache or nginx 12 | 13 | 14 | ## Thanks 15 | 16 | * [reveal.js](https://github.com/hakimel/reveal.js) 17 | * [laravel5-slide](https://github.com/jasteralan/laravel5-slide) 18 | 19 | 20 | ## License 21 | 22 | MIT licensed -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/print-pdf/print-pdf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * phantomjs script for printing presentations to PDF. 3 | * 4 | * Example: 5 | * phantomjs print-pdf.js "http://lab.hakim.se/reveal-js?print-pdf" reveal-demo.pdf 6 | * 7 | * By Manuel Bieh (https://github.com/manuelbieh) 8 | */ 9 | 10 | // html2pdf.js 11 | var page = new WebPage(); 12 | var system = require( 'system' ); 13 | 14 | page.viewportSize = { 15 | width: 1024, 16 | height: 768 17 | }; 18 | 19 | page.paperSize = { 20 | format: 'letter', 21 | orientation: 'landscape', 22 | margin: { 23 | left: '0', 24 | right: '0', 25 | top: '0', 26 | bottom: '0' 27 | } 28 | }; 29 | 30 | var revealFile = system.args[1] || 'index.html?print-pdf'; 31 | var slideFile = system.args[2] || 'slides.pdf'; 32 | 33 | if( slideFile.match( /\.pdf$/gi ) === null ) { 34 | slideFile += '.pdf'; 35 | } 36 | 37 | console.log( 'Printing PDF...' ); 38 | 39 | page.open( revealFile, function( status ) { 40 | console.log( 'Printed succesfully' ); 41 | page.render( slideFile ); 42 | phantom.exit(); 43 | } ); 44 | 45 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/postmessage/postmessage.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | simple postmessage plugin 4 | 5 | Useful when a reveal slideshow is inside an iframe. 6 | It allows to call reveal methods from outside. 7 | 8 | Example: 9 | var reveal = window.frames[0]; 10 | 11 | // Reveal.prev(); 12 | reveal.postMessage(JSON.stringify({method: 'prev', args: []}), '*'); 13 | // Reveal.next(); 14 | reveal.postMessage(JSON.stringify({method: 'next', args: []}), '*'); 15 | // Reveal.slide(2, 2); 16 | reveal.postMessage(JSON.stringify({method: 'slide', args: [2,2]}), '*'); 17 | 18 | Add to the slideshow: 19 | 20 | dependencies: [ 21 | ... 22 | { src: 'plugin/postmessage/postmessage.js', async: true, condition: function() { return !!document.body.classList; } } 23 | ] 24 | 25 | */ 26 | 27 | (function (){ 28 | 29 | window.addEventListener( "message", function ( event ) { 30 | var data = JSON.parse( event.data ), 31 | method = data.method, 32 | args = data.args; 33 | 34 | if( typeof Reveal[method] === 'function' ) { 35 | Reveal[method].apply( Reveal, data.args ); 36 | } 37 | }, false); 38 | 39 | }()); 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/postmessage/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 | 12 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /assets/js/app.js: -------------------------------------------------------------------------------- 1 | Reveal.initialize({ 2 | width: 1440, 3 | height: 1000, 4 | margin: 0.15, 5 | 6 | controls: true, 7 | progress: true, 8 | history: true, 9 | center: true, 10 | 11 | theme: Reveal.getQueryHash().theme, // available themes are in /css/theme 12 | transition: Reveal.getQueryHash().transition || 'default', // default/cube/page/concave/zoom/linear/fade/none 13 | 14 | // Optional libraries used to extend on reveal.js 15 | dependencies: [ 16 | { src: 'assets/js/vendor/classList.js', condition: function() { return !document.body.classList; } }, 17 | { src: 'assets/js/vendor/reveal-plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, 18 | { src: 'assets/js/vendor/reveal-plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } }, 19 | { src: 'assets/js/vendor/reveal-plugin/highlight/highlight.pack.js', async: true, callback: function() { 20 | hljs.configure({ tabReplace: ' ' }); 21 | hljs.initHighlightingOnLoad(); 22 | } }, 23 | { src: 'assets/js/vendor/reveal-plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } }, 24 | { src: 'assets/js/vendor/reveal-plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } } 25 | ] 26 | }); 27 | -------------------------------------------------------------------------------- /assets/js/vendor/classList.js: -------------------------------------------------------------------------------- 1 | /*! @source http://purl.eligrey.com/github/classList.js/blob/master/classList.js*/ 2 | if(typeof document!=="undefined"&&!("classList" in document.createElement("a"))){(function(j){var a="classList",f="prototype",m=(j.HTMLElement||j.Element)[f],b=Object,k=String[f].trim||function(){return this.replace(/^\s+|\s+$/g,"")},c=Array[f].indexOf||function(q){var p=0,o=this.length;for(;p code, .reveal ul li > code { 6 | background: #eee; 7 | color: #f4645f; 8 | padding: 0 5px; 9 | border-radius: 3px; 10 | } 11 | 12 | .self-introduce-wrapper { 13 | 14 | } 15 | .self-introduce-image-wrapper { 16 | width: 25%; 17 | overflow: hidden; 18 | border-radius: 50%; 19 | padding: 40px!important; 20 | float: left; 21 | } 22 | 23 | .self-introduce-content-wrapper { 24 | width: 600px; 25 | padding-top: 50px!important; 26 | margin-left: 260px!important; 27 | text-align: left; 28 | } 29 | 30 | .self-introduce-iam { 31 | font-size: 3em!important; 32 | margin-top: 50px!important; 33 | margin-left: 200px!important; 34 | } 35 | 36 | 37 | /********************************************* 38 | * NAVIGATION CONTROLS 39 | *********************************************/ 40 | /* line 109, ../sass/vendor/reveal/theme/template/_theme.scss */ 41 | .reveal .controls div.navigate-left.enabled { 42 | border-right-color: rgba(82, 199, 190, 0.6); 43 | } 44 | 45 | /* line 114, ../sass/vendor/reveal/theme/template/_theme.scss */ 46 | .reveal .controls div.navigate-right.enabled { 47 | border-left-color: rgba(82, 199, 190, 0.6); 48 | } 49 | 50 | /* line 119, ../sass/vendor/reveal/theme/template/_theme.scss */ 51 | .reveal .controls div.navigate-up.enabled { 52 | border-bottom-color: rgba(82, 199, 190, 0.6); 53 | } 54 | 55 | /* line 124, ../sass/vendor/reveal/theme/template/_theme.scss */ 56 | .reveal .controls div.navigate-down.enabled { 57 | border-top-color: rgba(82, 199, 190, 0.6); 58 | } 59 | 60 | 61 | .reveal h1, 62 | .reveal h2, 63 | .reveal h3, 64 | .reveal h4, 65 | .reveal h5, 66 | .reveal h6 { 67 | color: #F78787; 68 | } -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/multiplex/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var fs = require('fs'); 3 | var io = require('socket.io'); 4 | var crypto = require('crypto'); 5 | 6 | var app = express.createServer(); 7 | var staticDir = express.static; 8 | 9 | io = io.listen(app); 10 | 11 | var opts = { 12 | port: 1948, 13 | baseDir : __dirname + '/../../' 14 | }; 15 | 16 | io.sockets.on('connection', function(socket) { 17 | socket.on('slidechanged', function(slideData) { 18 | if (typeof slideData.secret == 'undefined' || slideData.secret == null || slideData.secret === '') return; 19 | if (createHash(slideData.secret) === slideData.socketId) { 20 | slideData.secret = null; 21 | socket.broadcast.emit(slideData.socketId, slideData); 22 | }; 23 | }); 24 | }); 25 | 26 | app.configure(function() { 27 | [ 'css', 'js', 'plugin', 'lib' ].forEach(function(dir) { 28 | app.use('/' + dir, staticDir(opts.baseDir + dir)); 29 | }); 30 | }); 31 | 32 | app.get("/", function(req, res) { 33 | res.writeHead(200, {'Content-Type': 'text/html'}); 34 | fs.createReadStream(opts.baseDir + '/index.html').pipe(res); 35 | }); 36 | 37 | app.get("/token", function(req,res) { 38 | var ts = new Date().getTime(); 39 | var rand = Math.floor(Math.random()*9999999); 40 | var secret = ts.toString() + rand.toString(); 41 | res.send({secret: secret, socketId: createHash(secret)}); 42 | }); 43 | 44 | var createHash = function(secret) { 45 | var cipher = crypto.createCipher('blowfish', secret); 46 | return(cipher.final('hex')); 47 | }; 48 | 49 | // Actually listen 50 | app.listen(opts.port || null); 51 | 52 | var brown = '\033[33m', 53 | green = '\033[32m', 54 | reset = '\033[0m'; 55 | 56 | console.log( brown + "reveal.js:" + reset + " Multiplex running on port " + green + opts.port + reset ); -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/math/math.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A plugin which enables rendering of math equations inside 3 | * of reveal.js slides. Essentially a thin wrapper for MathJax. 4 | * 5 | * @author Hakim El Hattab 6 | */ 7 | var RevealMath = window.RevealMath || (function(){ 8 | 9 | var options = Reveal.getConfig().math || {}; 10 | options.mathjax = options.mathjax || 'http://cdn.mathjax.org/mathjax/latest/MathJax.js'; 11 | options.config = options.config || 'TeX-AMS_HTML-full'; 12 | 13 | loadScript( options.mathjax + '?config=' + options.config, function() { 14 | 15 | MathJax.Hub.Config({ 16 | messageStyle: 'none', 17 | tex2jax: { inlineMath: [['$','$'],['\\(','\\)']] }, 18 | skipStartupTypeset: true 19 | }); 20 | 21 | // Typeset followed by an immediate reveal.js layout since 22 | // the typesetting process could affect slide height 23 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub ] ); 24 | MathJax.Hub.Queue( Reveal.layout ); 25 | 26 | // Reprocess equations in slides when they turn visible 27 | Reveal.addEventListener( 'slidechanged', function( event ) { 28 | 29 | MathJax.Hub.Queue( [ 'Typeset', MathJax.Hub, event.currentSlide ] ); 30 | 31 | } ); 32 | 33 | } ); 34 | 35 | function loadScript( url, callback ) { 36 | 37 | var head = document.querySelector( 'head' ); 38 | var script = document.createElement( 'script' ); 39 | script.type = 'text/javascript'; 40 | script.src = url; 41 | 42 | // Wrapper for callback to make sure it only fires once 43 | var finish = function() { 44 | if( typeof callback === 'function' ) { 45 | callback.call(); 46 | callback = null; 47 | } 48 | } 49 | 50 | script.onload = finish; 51 | 52 | // IE 53 | script.onreadystatechange = function() { 54 | if ( this.readyState === 'loaded' ) { 55 | finish(); 56 | } 57 | } 58 | 59 | // Normal browsers 60 | head.appendChild( script ); 61 | 62 | } 63 | 64 | })(); 65 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/notes-server/client.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | // don't emit events from inside the previews themselves 3 | if ( window.location.search.match( /receiver/gi ) ) { return; } 4 | 5 | var socket = io.connect(window.location.origin); 6 | var socketId = Math.random().toString().slice(2); 7 | 8 | console.log('View slide notes at ' + window.location.origin + '/notes/' + socketId); 9 | window.open(window.location.origin + '/notes/' + socketId, 'notes-' + socketId); 10 | 11 | // Fires when a fragment is shown 12 | Reveal.addEventListener( 'fragmentshown', function( event ) { 13 | var fragmentData = { 14 | fragment : 'next', 15 | socketId : socketId 16 | }; 17 | socket.emit('fragmentchanged', fragmentData); 18 | } ); 19 | 20 | // Fires when a fragment is hidden 21 | Reveal.addEventListener( 'fragmenthidden', function( event ) { 22 | var fragmentData = { 23 | fragment : 'previous', 24 | socketId : socketId 25 | }; 26 | socket.emit('fragmentchanged', fragmentData); 27 | } ); 28 | 29 | // Fires when slide is changed 30 | Reveal.addEventListener( 'slidechanged', function( event ) { 31 | var nextindexh; 32 | var nextindexv; 33 | var slideElement = event.currentSlide; 34 | 35 | if (slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION') { 36 | nextindexh = event.indexh; 37 | nextindexv = event.indexv + 1; 38 | } else { 39 | nextindexh = event.indexh + 1; 40 | nextindexv = 0; 41 | } 42 | 43 | var notes = slideElement.querySelector('aside.notes'); 44 | var slideData = { 45 | notes : notes ? notes.innerHTML : '', 46 | indexh : event.indexh, 47 | indexv : event.indexv, 48 | nextindexh : nextindexh, 49 | nextindexv : nextindexv, 50 | socketId : socketId, 51 | markdown : notes ? typeof notes.getAttribute('data-markdown') === 'string' : false 52 | 53 | }; 54 | 55 | socket.emit('slidechanged', slideData); 56 | } ); 57 | }()); 58 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/notes-server/index.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var fs = require('fs'); 3 | var io = require('socket.io'); 4 | var _ = require('underscore'); 5 | var Mustache = require('mustache'); 6 | 7 | var app = express.createServer(); 8 | var staticDir = express.static; 9 | 10 | io = io.listen(app); 11 | 12 | var opts = { 13 | port : 1947, 14 | baseDir : __dirname + '/../../' 15 | }; 16 | 17 | io.sockets.on('connection', function(socket) { 18 | socket.on('slidechanged', function(slideData) { 19 | socket.broadcast.emit('slidedata', slideData); 20 | }); 21 | socket.on('fragmentchanged', function(fragmentData) { 22 | socket.broadcast.emit('fragmentdata', fragmentData); 23 | }); 24 | }); 25 | 26 | app.configure(function() { 27 | [ 'css', 'js', 'images', 'plugin', 'lib' ].forEach(function(dir) { 28 | app.use('/' + dir, staticDir(opts.baseDir + dir)); 29 | }); 30 | }); 31 | 32 | app.get("/", function(req, res) { 33 | res.writeHead(200, {'Content-Type': 'text/html'}); 34 | fs.createReadStream(opts.baseDir + '/index.html').pipe(res); 35 | }); 36 | 37 | app.get("/notes/:socketId", function(req, res) { 38 | 39 | fs.readFile(opts.baseDir + 'plugin/notes-server/notes.html', function(err, data) { 40 | res.send(Mustache.to_html(data.toString(), { 41 | socketId : req.params.socketId 42 | })); 43 | }); 44 | // fs.createReadStream(opts.baseDir + 'notes-server/notes.html').pipe(res); 45 | }); 46 | 47 | // Actually listen 48 | app.listen(opts.port || null); 49 | 50 | var brown = '\033[33m', 51 | green = '\033[32m', 52 | reset = '\033[0m'; 53 | 54 | var slidesLocation = "http://localhost" + ( opts.port ? ( ':' + opts.port ) : '' ); 55 | 56 | console.log( brown + "reveal.js - Speaker Notes" + reset ); 57 | console.log( "1. Open the slides at " + green + slidesLocation + reset ); 58 | console.log( "2. Click on the link your JS console to go to the notes page" ); 59 | console.log( "3. Advance through your slides and your notes will advance automatically" ); 60 | -------------------------------------------------------------------------------- /assets/css/vendor/zenburn.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Zenburn style from voldmar.ru (c) Vladimir Epifanov 4 | based on dark.css by Ivan Sagalaev 5 | 6 | */ 7 | 8 | .hljs { 9 | display: block; padding: 0.5em; 10 | background: #3F3F3F; 11 | color: #DCDCDC; 12 | } 13 | 14 | .hljs-keyword, 15 | .hljs-tag, 16 | .css .hljs-class, 17 | .css .hljs-id, 18 | .lisp .hljs-title, 19 | .nginx .hljs-title, 20 | .hljs-request, 21 | .hljs-status, 22 | .clojure .hljs-attribute { 23 | color: #E3CEAB; 24 | } 25 | 26 | .django .hljs-template_tag, 27 | .django .hljs-variable, 28 | .django .hljs-filter .hljs-argument { 29 | color: #DCDCDC; 30 | } 31 | 32 | .hljs-number, 33 | .hljs-date { 34 | color: #8CD0D3; 35 | } 36 | 37 | .dos .hljs-envvar, 38 | .dos .hljs-stream, 39 | .hljs-variable, 40 | .apache .hljs-sqbracket { 41 | color: #EFDCBC; 42 | } 43 | 44 | .dos .hljs-flow, 45 | .diff .hljs-change, 46 | .python .exception, 47 | .python .hljs-built_in, 48 | .hljs-literal, 49 | .tex .hljs-special { 50 | color: #EFEFAF; 51 | } 52 | 53 | .diff .hljs-chunk, 54 | .hljs-subst { 55 | color: #8F8F8F; 56 | } 57 | 58 | .dos .hljs-keyword, 59 | .python .hljs-decorator, 60 | .hljs-title, 61 | .haskell .hljs-type, 62 | .diff .hljs-header, 63 | .ruby .hljs-class .hljs-parent, 64 | .apache .hljs-tag, 65 | .nginx .hljs-built_in, 66 | .tex .hljs-command, 67 | .hljs-prompt { 68 | color: #efef8f; 69 | } 70 | 71 | .dos .hljs-winutils, 72 | .ruby .hljs-symbol, 73 | .ruby .hljs-symbol .hljs-string, 74 | .ruby .hljs-string { 75 | color: #DCA3A3; 76 | } 77 | 78 | .diff .hljs-deletion, 79 | .hljs-string, 80 | .hljs-tag .hljs-value, 81 | .hljs-preprocessor, 82 | .hljs-pragma, 83 | .hljs-built_in, 84 | .sql .hljs-aggregate, 85 | .hljs-javadoc, 86 | .smalltalk .hljs-class, 87 | .smalltalk .hljs-localvars, 88 | .smalltalk .hljs-array, 89 | .css .hljs-rules .hljs-value, 90 | .hljs-attr_selector, 91 | .hljs-pseudo, 92 | .apache .hljs-cbracket, 93 | .tex .hljs-formula, 94 | .coffeescript .hljs-attribute { 95 | color: #CC9393; 96 | } 97 | 98 | .hljs-shebang, 99 | .diff .hljs-addition, 100 | .hljs-comment, 101 | .java .hljs-annotation, 102 | .hljs-template_comment, 103 | .hljs-pi, 104 | .hljs-doctype { 105 | color: #7F9F7F; 106 | } 107 | 108 | .coffeescript .javascript, 109 | .javascript .xml, 110 | .tex .hljs-formula, 111 | .xml .javascript, 112 | .xml .vbscript, 113 | .xml .css, 114 | .xml .hljs-cdata { 115 | opacity: 0.5; 116 | } 117 | 118 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/notes/notes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Handles opening of and synchronization with the reveal.js 3 | * notes window. 4 | */ 5 | var RevealNotes = (function() { 6 | 7 | function openNotes() { 8 | var jsFileLocation = document.querySelector('script[src$="notes.js"]').src; // this js file path 9 | jsFileLocation = jsFileLocation.replace(/notes\.js(\?.*)?$/, ''); // the js folder path 10 | var notesPopup = window.open( jsFileLocation + 'notes.html', 'reveal.js - Notes', 'width=1120,height=850' ); 11 | 12 | // Fires when slide is changed 13 | Reveal.addEventListener( 'slidechanged', post ); 14 | 15 | // Fires when a fragment is shown 16 | Reveal.addEventListener( 'fragmentshown', post ); 17 | 18 | // Fires when a fragment is hidden 19 | Reveal.addEventListener( 'fragmenthidden', post ); 20 | 21 | /** 22 | * Posts the current slide data to the notes window 23 | */ 24 | function post() { 25 | var slideElement = Reveal.getCurrentSlide(), 26 | slideIndices = Reveal.getIndices(), 27 | messageData; 28 | 29 | var notes = slideElement.querySelector( 'aside.notes' ), 30 | nextindexh, 31 | nextindexv; 32 | 33 | if( slideElement.nextElementSibling && slideElement.parentNode.nodeName == 'SECTION' ) { 34 | nextindexh = slideIndices.h; 35 | nextindexv = slideIndices.v + 1; 36 | } else { 37 | nextindexh = slideIndices.h + 1; 38 | nextindexv = 0; 39 | } 40 | 41 | messageData = { 42 | notes : notes ? notes.innerHTML : '', 43 | indexh : slideIndices.h, 44 | indexv : slideIndices.v, 45 | indexf : slideIndices.f, 46 | nextindexh : nextindexh, 47 | nextindexv : nextindexv, 48 | markdown : notes ? typeof notes.getAttribute( 'data-markdown' ) === 'string' : false 49 | }; 50 | 51 | notesPopup.postMessage( JSON.stringify( messageData ), '*' ); 52 | } 53 | 54 | // Navigate to the current slide when the notes are loaded 55 | notesPopup.addEventListener( 'load', function( event ) { 56 | post(); 57 | }, false ); 58 | } 59 | 60 | // If the there's a 'notes' query set, open directly 61 | if( window.location.search.match( /(\?|\&)notes/gi ) !== null ) { 62 | openNotes(); 63 | } 64 | 65 | // Open the notes when the 's' key is hit 66 | document.addEventListener( 'keydown', function( event ) { 67 | // Disregard the event if the target is editable or a 68 | // modifier is present 69 | if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 70 | 71 | if( event.keyCode === 83 ) { 72 | event.preventDefault(); 73 | openNotes(); 74 | } 75 | }, false ); 76 | 77 | return { open: openNotes }; 78 | })(); 79 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | laravel与框架二三事 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | 31 |
34 |
35 | 36 |
39 | 40 |
41 |
42 |
43 |
    44 |
  • 常用ID: 云袭/lifesign
  • 45 |
  • 混迹各大技术社区
  • 46 |
  • lifesign.me
  • 47 |
48 |
49 |
50 | 51 |
52 | 53 |
56 |
57 | 58 |
61 |
62 | 63 |
66 |
67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /assets/js/vendor/head.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | Head JS The only script in your 3 | Copyright Tero Piirainen (tipiirai) 4 | License MIT / http://bit.ly/mit-license 5 | Version 0.96 6 | 7 | http://headjs.com 8 | */(function(a){function z(){d||(d=!0,s(e,function(a){p(a)}))}function y(c,d){var e=a.createElement("script");e.type="text/"+(c.type||"javascript"),e.src=c.src||c,e.async=!1,e.onreadystatechange=e.onload=function(){var a=e.readyState;!d.done&&(!a||/loaded|complete/.test(a))&&(d.done=!0,d())},(a.body||b).appendChild(e)}function x(a,b){if(a.state==o)return b&&b();if(a.state==n)return k.ready(a.name,b);if(a.state==m)return a.onpreload.push(function(){x(a,b)});a.state=n,y(a.url,function(){a.state=o,b&&b(),s(g[a.name],function(a){p(a)}),u()&&d&&s(g.ALL,function(a){p(a)})})}function w(a,b){a.state===undefined&&(a.state=m,a.onpreload=[],y({src:a.url,type:"cache"},function(){v(a)}))}function v(a){a.state=l,s(a.onpreload,function(a){a.call()})}function u(a){a=a||h;var b;for(var c in a){if(a.hasOwnProperty(c)&&a[c].state!=o)return!1;b=!0}return b}function t(a){return Object.prototype.toString.call(a)=="[object Function]"}function s(a,b){if(!!a){typeof a=="object"&&(a=[].slice.call(a));for(var c=0;c 3 | 4 | # 关于学习框架的一些建议 5 | 6 | - 关注web开发领域 7 | - 标准化 8 | - 从最熟悉的开始 9 | - 善用工具 10 | - 阅读经典书籍 11 | 12 | ---- 13 | 14 | 15 | 16 | 17 | # 自我定位 18 | 19 | ---- 20 | 21 | ##建议1. 关注web开发领域 22 | 23 | 1. 不局限在PHP层面 24 | 2. 多关注框架以外的共有的东西 25 | 3. 借鉴、改良、优化 26 | 27 | ---- 28 | 29 | ##建议2. 标准化 30 | 31 | - PSR 32 | - Composer 33 | - Vagrant 34 | 35 | ---- 36 | 37 | ##标准化之PSR 38 | 39 | PSR 是由 [FIG](http://www.php-fig.org/)制定的php规范, 简称PSR。 40 | 41 | 为什么要制定规范? 42 | 43 | `本组织旨在通过讨论我们代码项目的共同点以找出一个协作编程的方法。` 44 | 45 | ---- 46 | 47 | 目前发布的规范如下 48 | 49 | - PSR-0 自动加载(类名中的_会自动转换成目录分隔符) 50 | - PSR-1 基本代码规范(命名、字符编码等) 51 | - PSR-2 代码风格(缩进、括号、关键字位置等) 52 | - PSR-3 日志接口(日志等级) 53 | - PSR-4 自动加载(指定文件路径来自动加载) 54 | 55 | ---- 56 | 57 | 58 | ##标准化之composer 59 | 60 | - 使用composer作为项目的依赖管理工具, 只需要维护 composer.json / composer.lock 61 | - 使用优秀的,遵循标准的类库 62 | - 发布自己的类库, 为开源贡献力量 63 | 64 | ---- 65 | 66 | ##标准化之vagrant 67 | 68 | ![](assets/img/vagrant.png) 69 | 70 | Vagrant 是一款用来构建虚拟开发环境的工具, 非常适合来做 web 开发。 71 | 72 | 我们可以通过 Vagrant 封装一个 Linux的开发环境, 分发给团队成员。成员可以在自己喜欢的桌面系统(Mac/Windows/Linux)上开发程序, 代码却能统一在封装好的环境里运行, 而不用担心由于所在系统环境造成的未知bug。 73 | 74 | ---- 75 | 76 | ##Vagrant Quick Start 77 | 78 | 1. 安装 [virtualbox](https://www.virtualbox.org/wiki/Downloads) 79 | 2. 安装 [vagrantup](http://downloads.vagrantup.com/) 80 | 3. 执行命令 81 | 82 | ``` 83 | $ vagrant init hashicorp/precise32 84 | $ vagrant up 85 | ``` 86 | 87 | ---- 88 | 89 | ##Laravel Way --Homestead 90 | 91 | Laravel 官方定制的 vagrant 包, 包含常用一套完整的开发环境 92 | 93 | - Ubuntu 14.04 94 | - PHP 5.5 95 | - Nginx 96 | - MySQL 97 | - Postgres 98 | - Node (With Bower, Grunt, and Gulp) 99 | - Redis 100 | - Memcached 101 | - Beanstalkd 102 | - Laravel Envoy 103 | - Fabric + HipChat Extension 104 | 105 | ---- 106 | 107 | ## 安装 108 | 109 | - `vagrant box add laravel/homestead` 110 | - `composer global require "laravel/homestead=~2.0"` 配置SSH-key 111 | - `homestead up` 112 | - `homestead ssh` 113 | - `homestead halt` 114 | 115 | ---- 116 | 117 | ##建议3. 从最熟悉的开始 118 | 119 | ---- 120 | 121 | ##了解框架的分类 122 | 123 | - 传统mvc: [Thinkphp], [CI] 124 | - 全栈式: [Laravel], [Phalcon] 125 | - 组件式: [Symfony], [Aura] 126 | - 微框架:[Slim],[Silex] 127 | 128 | ---- 129 | 130 | ##找到适合自己的方法 131 | 132 | - 找一个自己喜欢的 熟悉的钻研源码 133 | - 了解框架生命流程、某个组件的实现 134 | - 尝试自己写一个框架 135 | 136 | ---- 137 | 138 | 139 | ##建议4. 善用工具 140 | 141 | - IDE: PHPstorm/Netbeans/Zend Studio 142 | - Editor: Sublime Text/Atom 143 | - Debug: Whoops/Socketlog 144 | 145 | ---- 146 | 147 | ##建议5. 阅读经典书籍 148 | 149 | - [Head First 设计模式](http://book.douban.com/subject/2243615/) 150 | - [企业应用架构模式](http://book.douban.com/subject/3709632/) 151 | - [重构 改善既有代码的设计](http://book.douban.com/subject/4262627/) 152 | - [PHP核心技术与最佳实践](http://book.douban.com/subject/20370984/) 153 | 154 | ---- 155 | 156 | #总结 157 | 158 | ---- 159 | 160 | ## Thanks 161 | 162 | ![](assets/gif/inifnite_cat.gif) -------------------------------------------------------------------------------- /assets/css/vendor/hybrid.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) 4 | 5 | */ 6 | 7 | /*background color*/ 8 | .hljs { 9 | display: block; 10 | overflow-x: auto; 11 | padding: 0.5em; 12 | background: #1d1f21; 13 | -webkit-text-size-adjust: none; 14 | } 15 | 16 | /*selection color*/ 17 | .hljs::selection, 18 | .hljs span::selection { 19 | background: #373b41; 20 | } 21 | .hljs::-moz-selection, 22 | .hljs span::-moz-selection { 23 | background: #373b41; 24 | } 25 | 26 | /*foreground color*/ 27 | .hljs, 28 | .hljs-setting .hljs-value, 29 | .hljs-expression .hljs-variable, 30 | .hljs-expression .hljs-begin-block, 31 | .hljs-expression .hljs-end-block, 32 | .hljs-class .hljs-params, 33 | .hljs-function .hljs-params, 34 | .hljs-at_rule .hljs-preprocessor { 35 | color: #c5c8c6; 36 | } 37 | 38 | /*color: fg_yellow*/ 39 | .hljs-title, 40 | .hljs-function .hljs-title, 41 | .hljs-keyword .hljs-common, 42 | .hljs-class .hljs-title, 43 | .hljs-decorator, 44 | .hljs-tag .hljs-title, 45 | .hljs-header, 46 | .hljs-sub, 47 | .hljs-function { 48 | color: #f0c674; 49 | } 50 | 51 | /*color: fg_comment*/ 52 | .hljs-comment, 53 | .hljs-javadoc, 54 | .hljs-output .hljs-value, 55 | .hljs-pi, 56 | .hljs-shebang, 57 | .hljs-doctype { 58 | color: #707880; 59 | } 60 | 61 | /*color: fg_red*/ 62 | .hljs-number, 63 | .hljs-symbol, 64 | .hljs-literal, 65 | .hljs-deletion, 66 | .hljs-link_url, 67 | .hljs-symbol .hljs-string, 68 | .hljs-argument, 69 | .hljs-hexcolor, 70 | .hljs-input .hljs-prompt, 71 | .hljs-char { 72 | color: #cc6666 73 | } 74 | 75 | /*color: fg_green*/ 76 | .hljs-string, 77 | .hljs-special, 78 | .hljs-javadoctag, 79 | .hljs-addition, 80 | .hljs-important, 81 | .hljs-tag .hljs-value, 82 | .hljs-at.rule .hljs-keyword, 83 | .hljs-regexp, 84 | .hljs-attr_selector { 85 | color: #b5bd68; 86 | } 87 | 88 | /*color: fg_purple*/ 89 | .hljs-variable, 90 | .hljs-property, 91 | .hljs-envar, 92 | .hljs-code, 93 | .hljs-expression, 94 | .hljs-localvars, 95 | .hljs-id, 96 | .hljs-variable .hljs-filter, 97 | .hljs-variable .hljs-filter .hljs-keyword, 98 | .hljs-template_tag .hljs-filter .hljs-keyword { 99 | color: #b294bb; 100 | } 101 | 102 | /*color: fg_blue*/ 103 | .hljs-statement, 104 | .hljs-label, 105 | .hljs-keyword, 106 | .hljs-xmlDocTag, 107 | .hljs-function .hljs-keyword, 108 | .hljs-chunk, 109 | .hljs-cdata, 110 | .hljs-link_label, 111 | .hljs-bullet, 112 | .hljs-class .hljs-keyword, 113 | .hljs-smartquote, 114 | .hljs-method, 115 | .hljs-list .hljs-title, 116 | .hljs-tag { 117 | color: #81a2be; 118 | } 119 | 120 | /*color: fg_aqua*/ 121 | .hljs-pseudo, 122 | .hljs-exception, 123 | .hljs-annotation, 124 | .hljs-subst, 125 | .hljs-change, 126 | .hljs-cbracket, 127 | .hljs-operator, 128 | .hljs-horizontal_rule, 129 | .hljs-preprocessor .hljs-keyword, 130 | .hljs-typedef, 131 | .hljs-template_tag, 132 | .hljs-variable, 133 | .hljs-variable .hljs-filter .hljs-argument, 134 | .hljs-at_rule, 135 | .hljs-at_rule .hljs-string, 136 | .hljs-at_rule .hljs-keyword { 137 | color: #8abeb7; 138 | } 139 | 140 | 141 | /*color: fg_orange*/ 142 | .hljs-type, 143 | .hljs-typename, 144 | .hljs-inheritance .hljs-parent, 145 | .hljs-constant, 146 | .hljs-built_in, 147 | .hljs-setting, 148 | .hljs-structure, 149 | .hljs-link_reference, 150 | .hljs-attribute, 151 | .hljs-blockquote, 152 | .hljs-quoted, 153 | .hljs-class, 154 | .hljs-header { 155 | color: #de935f; 156 | } 157 | 158 | .hljs-emphasis 159 | { 160 | font-style: italic; 161 | } 162 | 163 | .hljs-strong 164 | { 165 | font-weight: bold; 166 | } 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/notes-server/notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | reveal.js - Slide Notes 9 | 10 | 90 | 91 | 92 | 93 | 94 |
95 | 96 |
97 | 98 |
99 | 100 | UPCOMING: 101 |
102 |
103 | 104 | 105 | 106 | 107 | 140 | 141 | 142 | 143 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/markdown/example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | reveal.js - Markdown Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |
20 | 21 | 22 |
23 | 24 | 25 |
26 | 36 |
37 | 38 | 39 |
40 | 54 |
55 | 56 | 57 |
58 | 69 |
70 | 71 | 72 |
73 | 77 |
78 | 79 | 80 |
81 | 86 |
87 | 88 | 89 |
90 | 100 |
101 | 102 |
103 |
104 | 105 | 106 | 107 | 108 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /assets/css/vendor/reveal/print/pdf.css: -------------------------------------------------------------------------------- 1 | /* Default Print Stylesheet Template 2 | by Rob Glazebrook of CSSnewbie.com 3 | Last Updated: June 4, 2008 4 | 5 | Feel free (nay, compelled) to edit, append, and 6 | manipulate this file as you see fit. */ 7 | 8 | 9 | /* SECTION 1: Set default width, margin, float, and 10 | background. This prevents elements from extending 11 | beyond the edge of the printed page, and prevents 12 | unnecessary background images from printing */ 13 | 14 | * { 15 | -webkit-print-color-adjust: exact; 16 | } 17 | 18 | body { 19 | font-size: 18pt; 20 | width: 297mm; 21 | height: 229mm; 22 | margin: 0 auto !important; 23 | border: 0; 24 | padding: 0; 25 | float: none !important; 26 | overflow: visible; 27 | } 28 | 29 | html { 30 | width: 100%; 31 | height: 100%; 32 | overflow: visible; 33 | } 34 | 35 | @page { 36 | size: letter landscape; 37 | margin: 0; 38 | } 39 | 40 | /* SECTION 2: Remove any elements not needed in print. 41 | This would include navigation, ads, sidebars, etc. */ 42 | .nestedarrow, 43 | .controls, 44 | .reveal .progress, 45 | .reveal.overview, 46 | .fork-reveal, 47 | .share-reveal, 48 | .state-background { 49 | display: none !important; 50 | } 51 | 52 | /* SECTION 3: Set body font face, size, and color. 53 | Consider using a serif font for readability. */ 54 | body, p, td, li, div { 55 | font-size: 18pt; 56 | } 57 | 58 | /* SECTION 4: Set heading font face, sizes, and color. 59 | Differentiate your headings from your body text. 60 | Perhaps use a large sans-serif for distinction. */ 61 | h1,h2,h3,h4,h5,h6 { 62 | text-shadow: 0 0 0 #000 !important; 63 | } 64 | 65 | /* SECTION 5: Make hyperlinks more usable. 66 | Ensure links are underlined, and consider appending 67 | the URL to the end of the link for usability. */ 68 | a:link, 69 | a:visited { 70 | font-weight: normal; 71 | text-decoration: underline; 72 | } 73 | 74 | .reveal pre code { 75 | overflow: hidden !important; 76 | font-family: monospace !important; 77 | } 78 | 79 | 80 | /* SECTION 6: more reveal.js specific additions by @skypanther */ 81 | ul, ol, div, p { 82 | visibility: visible; 83 | position: static; 84 | width: auto; 85 | height: auto; 86 | display: block; 87 | overflow: visible; 88 | margin: auto; 89 | } 90 | .reveal { 91 | width: auto !important; 92 | height: auto !important; 93 | overflow: hidden !important; 94 | } 95 | .reveal .slides { 96 | position: static; 97 | width: 100%; 98 | height: auto; 99 | 100 | left: auto; 101 | top: auto; 102 | margin: 0 !important; 103 | padding: 0 !important; 104 | 105 | overflow: visible; 106 | display: block; 107 | 108 | text-align: center; 109 | 110 | -webkit-perspective: none; 111 | -moz-perspective: none; 112 | -ms-perspective: none; 113 | perspective: none; 114 | 115 | -webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */ 116 | -moz-perspective-origin: 50% 50%; 117 | -ms-perspective-origin: 50% 50%; 118 | perspective-origin: 50% 50%; 119 | } 120 | .reveal .slides section { 121 | 122 | page-break-after: always !important; 123 | 124 | visibility: visible !important; 125 | position: relative !important; 126 | width: 100% !important; 127 | height: 229mm !important; 128 | min-height: 229mm !important; 129 | display: block !important; 130 | overflow: hidden !important; 131 | 132 | left: 0 !important; 133 | top: 0 !important; 134 | margin: 0 !important; 135 | padding: 2cm 2cm 0 2cm !important; 136 | box-sizing: border-box !important; 137 | 138 | opacity: 1 !important; 139 | 140 | -webkit-transform-style: flat !important; 141 | -moz-transform-style: flat !important; 142 | -ms-transform-style: flat !important; 143 | transform-style: flat !important; 144 | 145 | -webkit-transform: none !important; 146 | -moz-transform: none !important; 147 | -ms-transform: none !important; 148 | transform: none !important; 149 | } 150 | .reveal section.stack { 151 | margin: 0 !important; 152 | padding: 0 !important; 153 | page-break-after: avoid !important; 154 | height: auto !important; 155 | min-height: auto !important; 156 | } 157 | .reveal .absolute-element { 158 | margin-left: 2.2cm; 159 | margin-top: 1.8cm; 160 | } 161 | .reveal section .fragment { 162 | opacity: 1 !important; 163 | visibility: visible !important; 164 | 165 | -webkit-transform: none !important; 166 | -moz-transform: none !important; 167 | -ms-transform: none !important; 168 | transform: none !important; 169 | } 170 | .reveal section .slide-background { 171 | position: absolute; 172 | top: 0; 173 | left: 0; 174 | width: 100%; 175 | z-index: 0; 176 | } 177 | .reveal section>* { 178 | position: relative; 179 | z-index: 1; 180 | } 181 | .reveal img { 182 | box-shadow: none; 183 | } 184 | .reveal .roll { 185 | overflow: visible; 186 | line-height: 1em; 187 | } 188 | .reveal small a { 189 | font-size: 16pt !important; 190 | } 191 | -------------------------------------------------------------------------------- /assets/css/vendor/reveal/print/paper.css: -------------------------------------------------------------------------------- 1 | /* Default Print Stylesheet Template 2 | by Rob Glazebrook of CSSnewbie.com 3 | Last Updated: June 4, 2008 4 | 5 | Feel free (nay, compelled) to edit, append, and 6 | manipulate this file as you see fit. */ 7 | 8 | 9 | /* SECTION 1: Set default width, margin, float, and 10 | background. This prevents elements from extending 11 | beyond the edge of the printed page, and prevents 12 | unnecessary background images from printing */ 13 | body { 14 | background: #fff; 15 | font-size: 13pt; 16 | width: auto; 17 | height: auto; 18 | border: 0; 19 | margin: 0 5%; 20 | padding: 0; 21 | float: none !important; 22 | overflow: visible; 23 | } 24 | html { 25 | background: #fff; 26 | width: auto; 27 | height: auto; 28 | overflow: visible; 29 | } 30 | 31 | /* SECTION 2: Remove any elements not needed in print. 32 | This would include navigation, ads, sidebars, etc. */ 33 | .nestedarrow, 34 | .controls, 35 | .reveal .progress, 36 | .reveal.overview, 37 | .fork-reveal, 38 | .share-reveal, 39 | .state-background { 40 | display: none !important; 41 | } 42 | 43 | /* SECTION 3: Set body font face, size, and color. 44 | Consider using a serif font for readability. */ 45 | body, p, td, li, div, a { 46 | font-size: 16pt!important; 47 | font-family: Georgia, "Times New Roman", Times, serif !important; 48 | color: #000; 49 | } 50 | 51 | /* SECTION 4: Set heading font face, sizes, and color. 52 | Differentiate your headings from your body text. 53 | Perhaps use a large sans-serif for distinction. */ 54 | h1,h2,h3,h4,h5,h6 { 55 | color: #000!important; 56 | height: auto; 57 | line-height: normal; 58 | font-family: Georgia, "Times New Roman", Times, serif !important; 59 | text-shadow: 0 0 0 #000 !important; 60 | text-align: left; 61 | letter-spacing: normal; 62 | } 63 | /* Need to reduce the size of the fonts for printing */ 64 | h1 { font-size: 26pt !important; } 65 | h2 { font-size: 22pt !important; } 66 | h3 { font-size: 20pt !important; } 67 | h4 { font-size: 20pt !important; font-variant: small-caps; } 68 | h5 { font-size: 19pt !important; } 69 | h6 { font-size: 18pt !important; font-style: italic; } 70 | 71 | /* SECTION 5: Make hyperlinks more usable. 72 | Ensure links are underlined, and consider appending 73 | the URL to the end of the link for usability. */ 74 | a:link, 75 | a:visited { 76 | color: #000 !important; 77 | font-weight: bold; 78 | text-decoration: underline; 79 | } 80 | /* 81 | .reveal a:link:after, 82 | .reveal a:visited:after { 83 | content: " (" attr(href) ") "; 84 | color: #222 !important; 85 | font-size: 90%; 86 | } 87 | */ 88 | 89 | 90 | /* SECTION 6: more reveal.js specific additions by @skypanther */ 91 | ul, ol, div, p { 92 | visibility: visible; 93 | position: static; 94 | width: auto; 95 | height: auto; 96 | display: block; 97 | overflow: visible; 98 | margin: auto; 99 | text-align: left !important; 100 | } 101 | .reveal .slides { 102 | position: static; 103 | width: auto; 104 | height: auto; 105 | 106 | left: auto; 107 | top: auto; 108 | margin-left: auto; 109 | margin-top: auto; 110 | padding: auto; 111 | 112 | overflow: visible; 113 | display: block; 114 | 115 | text-align: center; 116 | -webkit-perspective: none; 117 | -moz-perspective: none; 118 | -ms-perspective: none; 119 | perspective: none; 120 | 121 | -webkit-perspective-origin: 50% 50%; /* there isn't a none/auto value but 50-50 is the default */ 122 | -moz-perspective-origin: 50% 50%; 123 | -ms-perspective-origin: 50% 50%; 124 | perspective-origin: 50% 50%; 125 | } 126 | .reveal .slides>section, 127 | .reveal .slides>section>section { 128 | 129 | visibility: visible !important; 130 | position: static !important; 131 | width: 90% !important; 132 | height: auto !important; 133 | display: block !important; 134 | overflow: visible !important; 135 | 136 | left: 0% !important; 137 | top: 0% !important; 138 | margin-left: 0px !important; 139 | margin-top: 0px !important; 140 | padding: 20px 0px !important; 141 | 142 | opacity: 1 !important; 143 | 144 | -webkit-transform-style: flat !important; 145 | -moz-transform-style: flat !important; 146 | -ms-transform-style: flat !important; 147 | transform-style: flat !important; 148 | 149 | -webkit-transform: none !important; 150 | -moz-transform: none !important; 151 | -ms-transform: none !important; 152 | transform: none !important; 153 | } 154 | .reveal section { 155 | page-break-after: always !important; 156 | display: block !important; 157 | } 158 | .reveal section .fragment { 159 | opacity: 1 !important; 160 | visibility: visible !important; 161 | 162 | -webkit-transform: none !important; 163 | -moz-transform: none !important; 164 | -ms-transform: none !important; 165 | transform: none !important; 166 | } 167 | .reveal section:last-of-type { 168 | page-break-after: avoid !important; 169 | } 170 | .reveal section img { 171 | display: block; 172 | margin: 15px 0px; 173 | background: rgba(255,255,255,1); 174 | border: 1px solid #666; 175 | box-shadow: none; 176 | } -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/search/search.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Handles finding a text string anywhere in the slides and showing the next occurrence to the user 3 | * by navigatating to that slide and highlighting it. 4 | * 5 | * By Jon Snyder , February 2013 6 | */ 7 | 8 | var RevealSearch = (function() { 9 | 10 | var matchedSlides; 11 | var currentMatchedIndex; 12 | var searchboxDirty; 13 | var myHilitor; 14 | 15 | // Original JavaScript code by Chirp Internet: www.chirp.com.au 16 | // Please acknowledge use of this code by including this header. 17 | // 2/2013 jon: modified regex to display any match, not restricted to word boundaries. 18 | 19 | function Hilitor(id, tag) 20 | { 21 | 22 | var targetNode = document.getElementById(id) || document.body; 23 | var hiliteTag = tag || "EM"; 24 | var skipTags = new RegExp("^(?:" + hiliteTag + "|SCRIPT|FORM|SPAN)$"); 25 | var colors = ["#ff6", "#a0ffff", "#9f9", "#f99", "#f6f"]; 26 | var wordColor = []; 27 | var colorIdx = 0; 28 | var matchRegex = ""; 29 | var matchingSlides = []; 30 | 31 | this.setRegex = function(input) 32 | { 33 | input = input.replace(/^[^\w]+|[^\w]+$/g, "").replace(/[^\w'-]+/g, "|"); 34 | matchRegex = new RegExp("(" + input + ")","i"); 35 | } 36 | 37 | this.getRegex = function() 38 | { 39 | return matchRegex.toString().replace(/^\/\\b\(|\)\\b\/i$/g, "").replace(/\|/g, " "); 40 | } 41 | 42 | // recursively apply word highlighting 43 | this.hiliteWords = function(node) 44 | { 45 | if(node == undefined || !node) return; 46 | if(!matchRegex) return; 47 | if(skipTags.test(node.nodeName)) return; 48 | 49 | if(node.hasChildNodes()) { 50 | for(var i=0; i < node.childNodes.length; i++) 51 | this.hiliteWords(node.childNodes[i]); 52 | } 53 | if(node.nodeType == 3) { // NODE_TEXT 54 | if((nv = node.nodeValue) && (regs = matchRegex.exec(nv))) { 55 | //find the slide's section element and save it in our list of matching slides 56 | var secnode = node.parentNode; 57 | while (secnode.nodeName != 'SECTION') { 58 | secnode = secnode.parentNode; 59 | } 60 | 61 | var slideIndex = Reveal.getIndices(secnode); 62 | var slidelen = matchingSlides.length; 63 | var alreadyAdded = false; 64 | for (var i=0; i < slidelen; i++) { 65 | if ( (matchingSlides[i].h === slideIndex.h) && (matchingSlides[i].v === slideIndex.v) ) { 66 | alreadyAdded = true; 67 | } 68 | } 69 | if (! alreadyAdded) { 70 | matchingSlides.push(slideIndex); 71 | } 72 | 73 | if(!wordColor[regs[0].toLowerCase()]) { 74 | wordColor[regs[0].toLowerCase()] = colors[colorIdx++ % colors.length]; 75 | } 76 | 77 | var match = document.createElement(hiliteTag); 78 | match.appendChild(document.createTextNode(regs[0])); 79 | match.style.backgroundColor = wordColor[regs[0].toLowerCase()]; 80 | match.style.fontStyle = "inherit"; 81 | match.style.color = "#000"; 82 | 83 | var after = node.splitText(regs.index); 84 | after.nodeValue = after.nodeValue.substring(regs[0].length); 85 | node.parentNode.insertBefore(match, after); 86 | } 87 | } 88 | }; 89 | 90 | // remove highlighting 91 | this.remove = function() 92 | { 93 | var arr = document.getElementsByTagName(hiliteTag); 94 | while(arr.length && (el = arr[0])) { 95 | el.parentNode.replaceChild(el.firstChild, el); 96 | } 97 | }; 98 | 99 | // start highlighting at target node 100 | this.apply = function(input) 101 | { 102 | if(input == undefined || !input) return; 103 | this.remove(); 104 | this.setRegex(input); 105 | this.hiliteWords(targetNode); 106 | return matchingSlides; 107 | }; 108 | 109 | } 110 | 111 | function openSearch() { 112 | //ensure the search term input dialog is visible and has focus: 113 | var inputbox = document.getElementById("searchinput"); 114 | inputbox.style.display = "inline"; 115 | inputbox.focus(); 116 | inputbox.select(); 117 | } 118 | 119 | function toggleSearch() { 120 | var inputbox = document.getElementById("searchinput"); 121 | if (inputbox.style.display !== "inline") { 122 | openSearch(); 123 | } 124 | else { 125 | inputbox.style.display = "none"; 126 | myHilitor.remove(); 127 | } 128 | } 129 | 130 | function doSearch() { 131 | //if there's been a change in the search term, perform a new search: 132 | if (searchboxDirty) { 133 | var searchstring = document.getElementById("searchinput").value; 134 | 135 | //find the keyword amongst the slides 136 | myHilitor = new Hilitor("slidecontent"); 137 | matchedSlides = myHilitor.apply(searchstring); 138 | currentMatchedIndex = 0; 139 | } 140 | 141 | //navigate to the next slide that has the keyword, wrapping to the first if necessary 142 | if (matchedSlides.length && (matchedSlides.length <= currentMatchedIndex)) { 143 | currentMatchedIndex = 0; 144 | } 145 | if (matchedSlides.length > currentMatchedIndex) { 146 | Reveal.slide(matchedSlides[currentMatchedIndex].h, matchedSlides[currentMatchedIndex].v); 147 | currentMatchedIndex++; 148 | } 149 | } 150 | 151 | var dom = {}; 152 | dom.wrapper = document.querySelector( '.reveal' ); 153 | 154 | if( !dom.wrapper.querySelector( '.searchbox' ) ) { 155 | var searchElement = document.createElement( 'div' ); 156 | searchElement.id = "searchinputdiv"; 157 | searchElement.classList.add( 'searchdiv' ); 158 | searchElement.style.position = 'absolute'; 159 | searchElement.style.top = '10px'; 160 | searchElement.style.left = '10px'; 161 | //embedded base64 search icon Designed by Sketchdock - http://www.sketchdock.com/: 162 | searchElement.innerHTML = ''; 163 | dom.wrapper.appendChild( searchElement ); 164 | } 165 | 166 | document.getElementById("searchbutton").addEventListener( 'click', function(event) { 167 | doSearch(); 168 | }, false ); 169 | 170 | document.getElementById("searchinput").addEventListener( 'keyup', function( event ) { 171 | switch (event.keyCode) { 172 | case 13: 173 | event.preventDefault(); 174 | doSearch(); 175 | searchboxDirty = false; 176 | break; 177 | default: 178 | searchboxDirty = true; 179 | } 180 | }, false ); 181 | 182 | // Open the search when the 's' key is hit (yes, this conflicts with the notes plugin, disabling for now) 183 | /* 184 | document.addEventListener( 'keydown', function( event ) { 185 | // Disregard the event if the target is editable or a 186 | // modifier is present 187 | if ( document.querySelector( ':focus' ) !== null || event.shiftKey || event.altKey || event.ctrlKey || event.metaKey ) return; 188 | 189 | if( event.keyCode === 83 ) { 190 | event.preventDefault(); 191 | openSearch(); 192 | } 193 | }, false ); 194 | */ 195 | return { open: openSearch }; 196 | })(); 197 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/notes/notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | reveal.js - Slide Notes 7 | 8 | 137 | 138 | 147 | 148 | 149 | 150 | 151 | 158 | 159 |
160 | 161 |
162 | 163 |
164 | 165 | UPCOMING: 166 |
167 | 168 |
169 |
170 |

Time

171 | 0:00:00 AM 172 |
173 |
174 |

Elapsed

175 | 00:00:00 176 |
177 |
178 | 179 |
180 | 181 | 182 | 276 | 277 | 278 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/zoom-js/zoom.js: -------------------------------------------------------------------------------- 1 | // Custom reveal.js integration 2 | (function(){ 3 | var isEnabled = true; 4 | 5 | document.querySelector( '.reveal' ).addEventListener( 'mousedown', function( event ) { 6 | var modifier = ( Reveal.getConfig().zoomKey ? Reveal.getConfig().zoomKey : 'alt' ) + 'Key'; 7 | 8 | if( event[ modifier ] && isEnabled ) { 9 | event.preventDefault(); 10 | zoom.to({ element: event.target, pan: false }); 11 | } 12 | } ); 13 | 14 | Reveal.addEventListener( 'overviewshown', function() { isEnabled = false; } ); 15 | Reveal.addEventListener( 'overviewhidden', function() { isEnabled = true; } ); 16 | })(); 17 | 18 | /*! 19 | * zoom.js 0.2 (modified version for use with reveal.js) 20 | * http://lab.hakim.se/zoom-js 21 | * MIT licensed 22 | * 23 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se 24 | */ 25 | var zoom = (function(){ 26 | 27 | // The current zoom level (scale) 28 | var level = 1; 29 | 30 | // The current mouse position, used for panning 31 | var mouseX = 0, 32 | mouseY = 0; 33 | 34 | // Timeout before pan is activated 35 | var panEngageTimeout = -1, 36 | panUpdateInterval = -1; 37 | 38 | var currentOptions = null; 39 | 40 | // Check for transform support so that we can fallback otherwise 41 | var supportsTransforms = 'WebkitTransform' in document.body.style || 42 | 'MozTransform' in document.body.style || 43 | 'msTransform' in document.body.style || 44 | 'OTransform' in document.body.style || 45 | 'transform' in document.body.style; 46 | 47 | if( supportsTransforms ) { 48 | // The easing that will be applied when we zoom in/out 49 | document.body.style.transition = 'transform 0.8s ease'; 50 | document.body.style.OTransition = '-o-transform 0.8s ease'; 51 | document.body.style.msTransition = '-ms-transform 0.8s ease'; 52 | document.body.style.MozTransition = '-moz-transform 0.8s ease'; 53 | document.body.style.WebkitTransition = '-webkit-transform 0.8s ease'; 54 | } 55 | 56 | // Zoom out if the user hits escape 57 | document.addEventListener( 'keyup', function( event ) { 58 | if( level !== 1 && event.keyCode === 27 ) { 59 | zoom.out(); 60 | } 61 | }, false ); 62 | 63 | // Monitor mouse movement for panning 64 | document.addEventListener( 'mousemove', function( event ) { 65 | if( level !== 1 ) { 66 | mouseX = event.clientX; 67 | mouseY = event.clientY; 68 | } 69 | }, false ); 70 | 71 | /** 72 | * Applies the CSS required to zoom in, prioritizes use of CSS3 73 | * transforms but falls back on zoom for IE. 74 | * 75 | * @param {Number} pageOffsetX 76 | * @param {Number} pageOffsetY 77 | * @param {Number} elementOffsetX 78 | * @param {Number} elementOffsetY 79 | * @param {Number} scale 80 | */ 81 | function magnify( pageOffsetX, pageOffsetY, elementOffsetX, elementOffsetY, scale ) { 82 | 83 | if( supportsTransforms ) { 84 | var origin = pageOffsetX +'px '+ pageOffsetY +'px', 85 | transform = 'translate('+ -elementOffsetX +'px,'+ -elementOffsetY +'px) scale('+ scale +')'; 86 | 87 | document.body.style.transformOrigin = origin; 88 | document.body.style.OTransformOrigin = origin; 89 | document.body.style.msTransformOrigin = origin; 90 | document.body.style.MozTransformOrigin = origin; 91 | document.body.style.WebkitTransformOrigin = origin; 92 | 93 | document.body.style.transform = transform; 94 | document.body.style.OTransform = transform; 95 | document.body.style.msTransform = transform; 96 | document.body.style.MozTransform = transform; 97 | document.body.style.WebkitTransform = transform; 98 | } 99 | else { 100 | // Reset all values 101 | if( scale === 1 ) { 102 | document.body.style.position = ''; 103 | document.body.style.left = ''; 104 | document.body.style.top = ''; 105 | document.body.style.width = ''; 106 | document.body.style.height = ''; 107 | document.body.style.zoom = ''; 108 | } 109 | // Apply scale 110 | else { 111 | document.body.style.position = 'relative'; 112 | document.body.style.left = ( - ( pageOffsetX + elementOffsetX ) / scale ) + 'px'; 113 | document.body.style.top = ( - ( pageOffsetY + elementOffsetY ) / scale ) + 'px'; 114 | document.body.style.width = ( scale * 100 ) + '%'; 115 | document.body.style.height = ( scale * 100 ) + '%'; 116 | document.body.style.zoom = scale; 117 | } 118 | } 119 | 120 | level = scale; 121 | 122 | if( level !== 1 && document.documentElement.classList ) { 123 | document.documentElement.classList.add( 'zoomed' ); 124 | } 125 | else { 126 | document.documentElement.classList.remove( 'zoomed' ); 127 | } 128 | } 129 | 130 | /** 131 | * Pan the document when the mosue cursor approaches the edges 132 | * of the window. 133 | */ 134 | function pan() { 135 | var range = 0.12, 136 | rangeX = window.innerWidth * range, 137 | rangeY = window.innerHeight * range, 138 | scrollOffset = getScrollOffset(); 139 | 140 | // Up 141 | if( mouseY < rangeY ) { 142 | window.scroll( scrollOffset.x, scrollOffset.y - ( 1 - ( mouseY / rangeY ) ) * ( 14 / level ) ); 143 | } 144 | // Down 145 | else if( mouseY > window.innerHeight - rangeY ) { 146 | window.scroll( scrollOffset.x, scrollOffset.y + ( 1 - ( window.innerHeight - mouseY ) / rangeY ) * ( 14 / level ) ); 147 | } 148 | 149 | // Left 150 | if( mouseX < rangeX ) { 151 | window.scroll( scrollOffset.x - ( 1 - ( mouseX / rangeX ) ) * ( 14 / level ), scrollOffset.y ); 152 | } 153 | // Right 154 | else if( mouseX > window.innerWidth - rangeX ) { 155 | window.scroll( scrollOffset.x + ( 1 - ( window.innerWidth - mouseX ) / rangeX ) * ( 14 / level ), scrollOffset.y ); 156 | } 157 | } 158 | 159 | function getScrollOffset() { 160 | return { 161 | x: window.scrollX !== undefined ? window.scrollX : window.pageXOffset, 162 | y: window.scrollY !== undefined ? window.scrollY : window.pageXYffset 163 | } 164 | } 165 | 166 | return { 167 | /** 168 | * Zooms in on either a rectangle or HTML element. 169 | * 170 | * @param {Object} options 171 | * - element: HTML element to zoom in on 172 | * OR 173 | * - x/y: coordinates in non-transformed space to zoom in on 174 | * - width/height: the portion of the screen to zoom in on 175 | * - scale: can be used instead of width/height to explicitly set scale 176 | */ 177 | to: function( options ) { 178 | // Due to an implementation limitation we can't zoom in 179 | // to another element without zooming out first 180 | if( level !== 1 ) { 181 | zoom.out(); 182 | } 183 | else { 184 | options.x = options.x || 0; 185 | options.y = options.y || 0; 186 | 187 | // If an element is set, that takes precedence 188 | if( !!options.element ) { 189 | // Space around the zoomed in element to leave on screen 190 | var padding = 20; 191 | 192 | options.width = options.element.getBoundingClientRect().width + ( padding * 2 ); 193 | options.height = options.element.getBoundingClientRect().height + ( padding * 2 ); 194 | options.x = options.element.getBoundingClientRect().left - padding; 195 | options.y = options.element.getBoundingClientRect().top - padding; 196 | } 197 | 198 | // If width/height values are set, calculate scale from those values 199 | if( options.width !== undefined && options.height !== undefined ) { 200 | options.scale = Math.max( Math.min( window.innerWidth / options.width, window.innerHeight / options.height ), 1 ); 201 | } 202 | 203 | if( options.scale > 1 ) { 204 | options.x *= options.scale; 205 | options.y *= options.scale; 206 | 207 | var scrollOffset = getScrollOffset(); 208 | 209 | if( options.element ) { 210 | scrollOffset.x -= ( window.innerWidth - ( options.width * options.scale ) ) / 2; 211 | } 212 | 213 | magnify( scrollOffset.x, scrollOffset.y, options.x, options.y, options.scale ); 214 | 215 | if( options.pan !== false ) { 216 | 217 | // Wait with engaging panning as it may conflict with the 218 | // zoom transition 219 | panEngageTimeout = setTimeout( function() { 220 | panUpdateInterval = setInterval( pan, 1000 / 60 ); 221 | }, 800 ); 222 | 223 | } 224 | } 225 | 226 | currentOptions = options; 227 | } 228 | }, 229 | 230 | /** 231 | * Resets the document zoom state to its default. 232 | */ 233 | out: function() { 234 | clearTimeout( panEngageTimeout ); 235 | clearInterval( panUpdateInterval ); 236 | 237 | var scrollOffset = getScrollOffset(); 238 | 239 | if( currentOptions && currentOptions.element ) { 240 | scrollOffset.x -= ( window.innerWidth - ( currentOptions.width * currentOptions.scale ) ) / 2; 241 | } 242 | 243 | magnify( scrollOffset.x, scrollOffset.y, 0, 0, 1 ); 244 | 245 | level = 1; 246 | }, 247 | 248 | // Alias 249 | magnify: function( options ) { this.to( options ) }, 250 | reset: function() { this.out() }, 251 | 252 | zoomLevel: function() { 253 | return level; 254 | } 255 | } 256 | 257 | })(); 258 | 259 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/markdown/markdown.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The reveal.js markdown plugin. Handles parsing of 3 | * markdown inside of presentations as well as loading 4 | * of external markdown documents. 5 | */ 6 | (function( root, factory ) { 7 | if( typeof exports === 'object' ) { 8 | module.exports = factory( require( './marked' ) ); 9 | } 10 | else { 11 | // Browser globals (root is window) 12 | root.RevealMarkdown = factory( root.marked ); 13 | root.RevealMarkdown.initialize(); 14 | } 15 | }( this, function( marked ) { 16 | 17 | if( typeof marked === 'undefined' ) { 18 | throw 'The reveal.js Markdown plugin requires marked to be loaded'; 19 | } 20 | 21 | if( typeof hljs !== 'undefined' ) { 22 | marked.setOptions({ 23 | highlight: function( lang, code ) { 24 | return hljs.highlightAuto( lang, code ).value; 25 | } 26 | }); 27 | } 28 | 29 | var DEFAULT_SLIDE_SEPARATOR = '^\n---\n$', 30 | DEFAULT_NOTES_SEPARATOR = 'note:', 31 | DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR = '\\\.element\\\s*?(.+?)$', 32 | DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR = '\\\.slide:\\\s*?(\\\S.+?)$'; 33 | 34 | 35 | /** 36 | * Retrieves the markdown contents of a slide section 37 | * element. Normalizes leading tabs/whitespace. 38 | */ 39 | function getMarkdownFromSlide( section ) { 40 | 41 | var template = section.querySelector( 'script' ); 42 | 43 | // strip leading whitespace so it isn't evaluated as code 44 | var text = ( template || section ).textContent; 45 | 46 | var leadingWs = text.match( /^\n?(\s*)/ )[1].length, 47 | leadingTabs = text.match( /^\n?(\t*)/ )[1].length; 48 | 49 | if( leadingTabs > 0 ) { 50 | text = text.replace( new RegExp('\\n?\\t{' + leadingTabs + '}','g'), '\n' ); 51 | } 52 | else if( leadingWs > 1 ) { 53 | text = text.replace( new RegExp('\\n? {' + leadingWs + '}','g'), '\n' ); 54 | } 55 | 56 | return text; 57 | 58 | } 59 | 60 | /** 61 | * Given a markdown slide section element, this will 62 | * return all arguments that aren't related to markdown 63 | * parsing. Used to forward any other user-defined arguments 64 | * to the output markdown slide. 65 | */ 66 | function getForwardedAttributes( section ) { 67 | 68 | var attributes = section.attributes; 69 | var result = []; 70 | 71 | for( var i = 0, len = attributes.length; i < len; i++ ) { 72 | var name = attributes[i].name, 73 | value = attributes[i].value; 74 | 75 | // disregard attributes that are used for markdown loading/parsing 76 | if( /data\-(markdown|separator|vertical|notes)/gi.test( name ) ) continue; 77 | 78 | if( value ) { 79 | result.push( name + '=' + value ); 80 | } 81 | else { 82 | result.push( name ); 83 | } 84 | } 85 | 86 | return result.join( ' ' ); 87 | 88 | } 89 | 90 | /** 91 | * Inspects the given options and fills out default 92 | * values for what's not defined. 93 | */ 94 | function getSlidifyOptions( options ) { 95 | 96 | options = options || {}; 97 | options.separator = options.separator || DEFAULT_SLIDE_SEPARATOR; 98 | options.notesSeparator = options.notesSeparator || DEFAULT_NOTES_SEPARATOR; 99 | options.attributes = options.attributes || ''; 100 | 101 | return options; 102 | 103 | } 104 | 105 | /** 106 | * Helper function for constructing a markdown slide. 107 | */ 108 | function createMarkdownSlide( content, options ) { 109 | 110 | options = getSlidifyOptions( options ); 111 | 112 | var notesMatch = content.split( new RegExp( options.notesSeparator, 'mgi' ) ); 113 | 114 | if( notesMatch.length === 2 ) { 115 | content = notesMatch[0] + ''; 116 | } 117 | 118 | return ''; 119 | 120 | } 121 | 122 | /** 123 | * Parses a data string into multiple slides based 124 | * on the passed in separator arguments. 125 | */ 126 | function slidify( markdown, options ) { 127 | 128 | options = getSlidifyOptions( options ); 129 | 130 | var separatorRegex = new RegExp( options.separator + ( options.verticalSeparator ? '|' + options.verticalSeparator : '' ), 'mg' ), 131 | horizontalSeparatorRegex = new RegExp( options.separator ); 132 | 133 | var matches, 134 | lastIndex = 0, 135 | isHorizontal, 136 | wasHorizontal = true, 137 | content, 138 | sectionStack = []; 139 | 140 | // iterate until all blocks between separators are stacked up 141 | while( matches = separatorRegex.exec( markdown ) ) { 142 | notes = null; 143 | 144 | // determine direction (horizontal by default) 145 | isHorizontal = horizontalSeparatorRegex.test( matches[0] ); 146 | 147 | if( !isHorizontal && wasHorizontal ) { 148 | // create vertical stack 149 | sectionStack.push( [] ); 150 | } 151 | 152 | // pluck slide content from markdown input 153 | content = markdown.substring( lastIndex, matches.index ); 154 | 155 | if( isHorizontal && wasHorizontal ) { 156 | // add to horizontal stack 157 | sectionStack.push( content ); 158 | } 159 | else { 160 | // add to vertical stack 161 | sectionStack[sectionStack.length-1].push( content ); 162 | } 163 | 164 | lastIndex = separatorRegex.lastIndex; 165 | wasHorizontal = isHorizontal; 166 | } 167 | 168 | // add the remaining slide 169 | ( wasHorizontal ? sectionStack : sectionStack[sectionStack.length-1] ).push( markdown.substring( lastIndex ) ); 170 | 171 | var markdownSections = ''; 172 | 173 | // flatten the hierarchical stack, and insert
tags 174 | for( var i = 0, len = sectionStack.length; i < len; i++ ) { 175 | // vertical 176 | if( sectionStack[i] instanceof Array ) { 177 | markdownSections += '
'; 178 | 179 | sectionStack[i].forEach( function( child ) { 180 | markdownSections += '
' + createMarkdownSlide( child, options ) + '
'; 181 | } ); 182 | 183 | markdownSections += '
'; 184 | } 185 | else { 186 | markdownSections += '
' + createMarkdownSlide( sectionStack[i], options ) + '
'; 187 | } 188 | } 189 | 190 | return markdownSections; 191 | 192 | } 193 | 194 | /** 195 | * Parses any current data-markdown slides, splits 196 | * multi-slide markdown into separate sections and 197 | * handles loading of external markdown. 198 | */ 199 | function processSlides() { 200 | 201 | var sections = document.querySelectorAll( '[data-markdown]'), 202 | section; 203 | 204 | for( var i = 0, len = sections.length; i < len; i++ ) { 205 | 206 | section = sections[i]; 207 | 208 | if( section.getAttribute( 'data-markdown' ).length ) { 209 | 210 | var xhr = new XMLHttpRequest(), 211 | url = section.getAttribute( 'data-markdown' ); 212 | 213 | datacharset = section.getAttribute( 'data-charset' ); 214 | 215 | // see https://developer.mozilla.org/en-US/docs/Web/API/element.getAttribute#Notes 216 | if( datacharset != null && datacharset != '' ) { 217 | xhr.overrideMimeType( 'text/html; charset=' + datacharset ); 218 | } 219 | 220 | xhr.onreadystatechange = function() { 221 | if( xhr.readyState === 4 ) { 222 | if ( xhr.status >= 200 && xhr.status < 300 ) { 223 | 224 | section.outerHTML = slidify( xhr.responseText, { 225 | separator: section.getAttribute( 'data-separator' ), 226 | verticalSeparator: section.getAttribute( 'data-vertical' ), 227 | notesSeparator: section.getAttribute( 'data-notes' ), 228 | attributes: getForwardedAttributes( section ) 229 | }); 230 | 231 | } 232 | else { 233 | 234 | section.outerHTML = '
' + 235 | 'ERROR: The attempt to fetch ' + url + ' failed with HTTP status ' + xhr.status + '.' + 236 | 'Check your browser\'s JavaScript console for more details.' + 237 | '

Remember that you need to serve the presentation HTML from a HTTP server.

' + 238 | '
'; 239 | 240 | } 241 | } 242 | }; 243 | 244 | xhr.open( 'GET', url, false ); 245 | 246 | try { 247 | xhr.send(); 248 | } 249 | catch ( e ) { 250 | alert( '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 ); 251 | } 252 | 253 | } 254 | else if( section.getAttribute( 'data-separator' ) || section.getAttribute( 'data-vertical' ) || section.getAttribute( 'data-notes' ) ) { 255 | 256 | section.outerHTML = slidify( getMarkdownFromSlide( section ), { 257 | separator: section.getAttribute( 'data-separator' ), 258 | verticalSeparator: section.getAttribute( 'data-vertical' ), 259 | notesSeparator: section.getAttribute( 'data-notes' ), 260 | attributes: getForwardedAttributes( section ) 261 | }); 262 | 263 | } 264 | else { 265 | section.innerHTML = createMarkdownSlide( getMarkdownFromSlide( section ) ); 266 | } 267 | } 268 | 269 | } 270 | 271 | /** 272 | * Check if a node value has the attributes pattern. 273 | * If yes, extract it and add that value as one or several attributes 274 | * the the terget element. 275 | * 276 | * You need Cache Killer on Chrome to see the effect on any FOM transformation 277 | * directly on refresh (F5) 278 | * http://stackoverflow.com/questions/5690269/disabling-chrome-cache-for-website-development/7000899#answer-11786277 279 | */ 280 | function addAttributeInElement( node, elementTarget, separator ) { 281 | 282 | var mardownClassesInElementsRegex = new RegExp( separator, 'mg' ); 283 | var mardownClassRegex = new RegExp( "([^\"= ]+?)=\"([^\"=]+?)\"", 'mg' ); 284 | var nodeValue = node.nodeValue; 285 | if( matches = mardownClassesInElementsRegex.exec( nodeValue ) ) { 286 | 287 | var classes = matches[1]; 288 | nodeValue = nodeValue.substring( 0, matches.index ) + nodeValue.substring( mardownClassesInElementsRegex.lastIndex ); 289 | node.nodeValue = nodeValue; 290 | while( matchesClass = mardownClassRegex.exec( classes ) ) { 291 | elementTarget.setAttribute( matchesClass[1], matchesClass[2] ); 292 | } 293 | return true; 294 | } 295 | return false; 296 | } 297 | 298 | /** 299 | * Add attributes to the parent element of a text node, 300 | * or the element of an attribute node. 301 | */ 302 | function addAttributes( section, element, previousElement, separatorElementAttributes, separatorSectionAttributes ) { 303 | 304 | if ( element != null && element.childNodes != undefined && element.childNodes.length > 0 ) { 305 | previousParentElement = element; 306 | for( var i = 0; i < element.childNodes.length; i++ ) { 307 | childElement = element.childNodes[i]; 308 | if ( i > 0 ) { 309 | j = i - 1; 310 | while ( j >= 0 ) { 311 | aPreviousChildElement = element.childNodes[j]; 312 | if ( typeof aPreviousChildElement.setAttribute == 'function' && aPreviousChildElement.tagName != "BR" ) { 313 | previousParentElement = aPreviousChildElement; 314 | break; 315 | } 316 | j = j - 1; 317 | } 318 | } 319 | parentSection = section; 320 | if( childElement.nodeName == "section" ) { 321 | parentSection = childElement ; 322 | previousParentElement = childElement ; 323 | } 324 | if ( typeof childElement.setAttribute == 'function' || childElement.nodeType == Node.COMMENT_NODE ) { 325 | addAttributes( parentSection, childElement, previousParentElement, separatorElementAttributes, separatorSectionAttributes ); 326 | } 327 | } 328 | } 329 | 330 | if ( element.nodeType == Node.COMMENT_NODE ) { 331 | if ( addAttributeInElement( element, previousElement, separatorElementAttributes ) == false ) { 332 | addAttributeInElement( element, section, separatorSectionAttributes ); 333 | } 334 | } 335 | } 336 | 337 | /** 338 | * Converts any current data-markdown slides in the 339 | * DOM to HTML. 340 | */ 341 | function convertSlides() { 342 | 343 | var sections = document.querySelectorAll( '[data-markdown]'); 344 | 345 | for( var i = 0, len = sections.length; i < len; i++ ) { 346 | 347 | var section = sections[i]; 348 | 349 | // Only parse the same slide once 350 | if( !section.getAttribute( 'data-markdown-parsed' ) ) { 351 | 352 | section.setAttribute( 'data-markdown-parsed', true ) 353 | 354 | var notes = section.querySelector( 'aside.notes' ); 355 | var markdown = getMarkdownFromSlide( section ); 356 | 357 | section.innerHTML = marked( markdown ); 358 | addAttributes( section, section, null, section.getAttribute( 'data-element-attributes' ) || 359 | section.parentNode.getAttribute( 'data-element-attributes' ) || 360 | DEFAULT_ELEMENT_ATTRIBUTES_SEPARATOR, 361 | section.getAttribute( 'data-attributes' ) || 362 | section.parentNode.getAttribute( 'data-attributes' ) || 363 | DEFAULT_SLIDE_ATTRIBUTES_SEPARATOR); 364 | 365 | // If there were notes, we need to re-add them after 366 | // having overwritten the section's HTML 367 | if( notes ) { 368 | section.appendChild( notes ); 369 | } 370 | 371 | } 372 | 373 | } 374 | 375 | } 376 | 377 | // API 378 | return { 379 | 380 | initialize: function() { 381 | processSlides(); 382 | convertSlides(); 383 | }, 384 | 385 | // TODO: Do these belong in the API? 386 | processSlides: processSlides, 387 | convertSlides: convertSlides, 388 | slidify: slidify 389 | 390 | }; 391 | 392 | })); 393 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/markdown/marked.js: -------------------------------------------------------------------------------- 1 | /** 2 | * marked - a markdown parser 3 | * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed) 4 | * https://github.com/chjj/marked 5 | */ 6 | 7 | (function(){var block={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:noop,hr:/^( *[-*_]){3,} *(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)/,nptable:noop,lheading:/^([^\n]+)\n *(=|-){3,} *\n*/,blockquote:/^( *>[^\n]+(\n[^\n]+)*\n*)+/,list:/^( *)(bull) [\s\S]+?(?:hr|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:/^ *(?:comment|closed|closing) *(?:\n{2,}|\s*$)/,def:/^ *\[([^\]]+)\]: *]+)>?(?: +["(]([^\n]+)[")])? *(?:\n+|$)/,table:noop,paragraph:/^((?:[^\n]+\n?(?!hr|heading|lheading|blockquote|tag|def))+)\n*/, 8 | text:/^[^\n]+/};block.bullet=/(?:[*+-]|\d+\.)/;block.item=/^( *)(bull) [^\n]*(?:\n(?!\1bull )[^\n]*)*/;block.item=replace(block.item,"gm")(/bull/g,block.bullet)();block.list=replace(block.list)(/bull/g,block.bullet)("hr",/\n+(?=(?: *[-*_]){3,} *(?:\n+|$))/)();block._tag="(?!(?:"+"a|em|strong|small|s|cite|q|dfn|abbr|data|time|code"+"|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo"+"|span|br|wbr|ins|del|img)\\b)\\w+(?!:/|@)\\b";block.html=replace(block.html)("comment",/\x3c!--[\s\S]*?--\x3e/)("closed", 9 | /<(tag)[\s\S]+?<\/\1>/)("closing",/])*?>/)(/tag/g,block._tag)();block.paragraph=replace(block.paragraph)("hr",block.hr)("heading",block.heading)("lheading",block.lheading)("blockquote",block.blockquote)("tag","<"+block._tag)("def",block.def)();block.normal=merge({},block);block.gfm=merge({},block.normal,{fences:/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n+|$)/,paragraph:/^/});block.gfm.paragraph=replace(block.paragraph)("(?!","(?!"+block.gfm.fences.source.replace("\\1", 10 | "\\2")+"|")();block.tables=merge({},block.gfm,{nptable:/^ *(\S.*\|.*)\n *([-:]+ *\|[-| :]*)\n((?:.*\|.*(?:\n|$))*)\n*/,table:/^ *\|(.+)\n *\|( *[-:]+[-| :]*)\n((?: *\|.*(?:\n|$))*)\n*/});function Lexer(options){this.tokens=[];this.tokens.links={};this.options=options||marked.defaults;this.rules=block.normal;if(this.options.gfm)if(this.options.tables)this.rules=block.tables;else this.rules=block.gfm}Lexer.rules=block;Lexer.lex=function(src,options){var lexer=new Lexer(options);return lexer.lex(src)}; 11 | Lexer.prototype.lex=function(src){src=src.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n");return this.token(src,true)};Lexer.prototype.token=function(src,top){var src=src.replace(/^ +$/gm,""),next,loose,cap,bull,b,item,space,i,l;while(src){if(cap=this.rules.newline.exec(src)){src=src.substring(cap[0].length);if(cap[0].length>1)this.tokens.push({type:"space"})}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);cap=cap[0].replace(/^ {4}/gm, 12 | "");this.tokens.push({type:"code",text:!this.options.pedantic?cap.replace(/\n+$/,""):cap});continue}if(cap=this.rules.fences.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"code",lang:cap[2],text:cap[3]});continue}if(cap=this.rules.heading.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:"heading",depth:cap[1].length,text:cap[2]});continue}if(top&&(cap=this.rules.nptable.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g, 13 | "").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/\n$/,"").split("\n")};for(i=0;i ?/gm,"");this.token(cap,top);this.tokens.push({type:"blockquote_end"});continue}if(cap=this.rules.list.exec(src)){src=src.substring(cap[0].length); 15 | bull=cap[2];this.tokens.push({type:"list_start",ordered:bull.length>1});cap=cap[0].match(this.rules.item);next=false;l=cap.length;i=0;for(;i1&&b.length>1)){src=cap.slice(i+ 16 | 1).join("\n")+src;i=l-1}}loose=next||/\n\n(?!\s*$)/.test(item);if(i!==l-1){next=item[item.length-1]==="\n";if(!loose)loose=next}this.tokens.push({type:loose?"loose_item_start":"list_item_start"});this.token(item,false);this.tokens.push({type:"list_item_end"})}this.tokens.push({type:"list_end"});continue}if(cap=this.rules.html.exec(src)){src=src.substring(cap[0].length);this.tokens.push({type:this.options.sanitize?"paragraph":"html",pre:cap[1]==="pre"||cap[1]==="script",text:cap[0]});continue}if(top&& 17 | (cap=this.rules.def.exec(src))){src=src.substring(cap[0].length);this.tokens.links[cap[1].toLowerCase()]={href:cap[2],title:cap[3]};continue}if(top&&(cap=this.rules.table.exec(src))){src=src.substring(cap[0].length);item={type:"table",header:cap[1].replace(/^ *| *\| *$/g,"").split(/ *\| */),align:cap[2].replace(/^ *|\| *$/g,"").split(/ *\| */),cells:cap[3].replace(/(?: *\| *)?\n$/,"").split("\n")};for(i=0;i])/,autolink:/^<([^ >]+(@|:\/)[^ >]+)>/,url:noop,tag:/^\x3c!--[\s\S]*?--\x3e|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,link:/^!?\[(inside)\]\(href\)/,reflink:/^!?\[(inside)\]\s*\[([^\]]*)\]/,nolink:/^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,strong:/^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,em:/^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, 20 | code:/^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,br:/^ {2,}\n(?!\s*$)/,del:noop,text:/^[\s\S]+?(?=[\\?(?:\s+['"]([\s\S]*?)['"])?\s*/;inline.link=replace(inline.link)("inside",inline._inside)("href",inline._href)();inline.reflink=replace(inline.reflink)("inside",inline._inside)();inline.normal=merge({},inline);inline.pedantic=merge({},inline.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/, 21 | em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/});inline.gfm=merge({},inline.normal,{escape:replace(inline.escape)("])","~|])")(),url:/^(https?:\/\/[^\s<]+[^<.,:;"')\]\s])/,del:/^~~(?=\S)([\s\S]*?\S)~~/,text:replace(inline.text)("]|","~]|")("|","|https?://|")()});inline.breaks=merge({},inline.gfm,{br:replace(inline.br)("{2,}","*")(),text:replace(inline.gfm.text)("{2,}","*")()});function InlineLexer(links,options){this.options=options||marked.defaults;this.links=links;this.rules=inline.normal; 22 | if(!this.links)throw new Error("Tokens array requires a `links` property.");if(this.options.gfm)if(this.options.breaks)this.rules=inline.breaks;else this.rules=inline.gfm;else if(this.options.pedantic)this.rules=inline.pedantic}InlineLexer.rules=inline;InlineLexer.output=function(src,links,options){var inline=new InlineLexer(links,options);return inline.output(src)};InlineLexer.prototype.output=function(src){var out="",link,text,href,cap;while(src){if(cap=this.rules.escape.exec(src)){src=src.substring(cap[0].length); 23 | out+=cap[1];continue}if(cap=this.rules.autolink.exec(src)){src=src.substring(cap[0].length);if(cap[2]==="@"){text=cap[1][6]===":"?this.mangle(cap[1].substring(7)):this.mangle(cap[1]);href=this.mangle("mailto:")+text}else{text=escape(cap[1]);href=text}out+=''+text+"";continue}if(cap=this.rules.url.exec(src)){src=src.substring(cap[0].length);text=escape(cap[1]);href=text;out+=''+text+"";continue}if(cap=this.rules.tag.exec(src)){src=src.substring(cap[0].length); 24 | out+=this.options.sanitize?escape(cap[0]):cap[0];continue}if(cap=this.rules.link.exec(src)){src=src.substring(cap[0].length);out+=this.outputLink(cap,{href:cap[2],title:cap[3]});continue}if((cap=this.rules.reflink.exec(src))||(cap=this.rules.nolink.exec(src))){src=src.substring(cap[0].length);link=(cap[2]||cap[1]).replace(/\s+/g," ");link=this.links[link.toLowerCase()];if(!link||!link.href){out+=cap[0][0];src=cap[0].substring(1)+src;continue}out+=this.outputLink(cap,link);continue}if(cap=this.rules.strong.exec(src)){src= 25 | src.substring(cap[0].length);out+=""+this.output(cap[2]||cap[1])+"";continue}if(cap=this.rules.em.exec(src)){src=src.substring(cap[0].length);out+=""+this.output(cap[2]||cap[1])+"";continue}if(cap=this.rules.code.exec(src)){src=src.substring(cap[0].length);out+=""+escape(cap[2],true)+"";continue}if(cap=this.rules.br.exec(src)){src=src.substring(cap[0].length);out+="
";continue}if(cap=this.rules.del.exec(src)){src=src.substring(cap[0].length);out+=""+ 26 | this.output(cap[1])+"";continue}if(cap=this.rules.text.exec(src)){src=src.substring(cap[0].length);out+=escape(cap[0]);continue}if(src)throw new Error("Infinite loop on byte: "+src.charCodeAt(0));}return out};InlineLexer.prototype.outputLink=function(cap,link){if(cap[0][0]!=="!")return'"+this.output(cap[1])+"";else return''+escape(cap[1])+'"};InlineLexer.prototype.smartypants=function(text){if(!this.options.smartypants)return text;return text.replace(/--/g,"\u2014").replace(/'([^']*)'/g,"\u2018$1\u2019").replace(/"([^"]*)"/g,"\u201c$1\u201d").replace(/\.{3}/g,"\u2026")};InlineLexer.prototype.mangle=function(text){var out="",l=text.length,i=0,ch;for(;i0.5)ch="x"+ch.toString(16);out+="&#"+ch+";"}return out};function Parser(options){this.tokens=[];this.token=null; 28 | this.options=options||marked.defaults}Parser.parse=function(src,options){var parser=new Parser(options);return parser.parse(src)};Parser.prototype.parse=function(src){this.inline=new InlineLexer(src.links,this.options);this.tokens=src.reverse();var out="";while(this.next())out+=this.tok();return out};Parser.prototype.next=function(){return this.token=this.tokens.pop()};Parser.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0};Parser.prototype.parseText=function(){var body=this.token.text; 29 | while(this.peek().type==="text")body+="\n"+this.next().text;return this.inline.output(body)};Parser.prototype.tok=function(){switch(this.token.type){case "space":return"";case "hr":return"
\n";case "heading":return""+this.inline.output(this.token.text)+"\n";case "code":if(this.options.highlight){var code=this.options.highlight(this.token.text,this.token.lang);if(code!=null&&code!==this.token.text){this.token.escaped=true;this.token.text=code}}if(!this.token.escaped)this.token.text= 30 | escape(this.token.text,true);return"
"+this.token.text+"
\n";case "table":var body="",heading,i,row,cell,j;body+="\n\n";for(i=0;i'+heading+"\n":""+heading+"\n"}body+="\n\n";body+="\n";for(i=0;i'+cell+"\n":""+cell+"\n"}body+="\n"}body+="\n";return"\n"+body+"
\n";case "blockquote_start":var body="";while(this.next().type!=="blockquote_end")body+=this.tok();return"
\n"+body+"
\n";case "list_start":var type=this.token.ordered?"ol":"ul",body="";while(this.next().type!=="list_end")body+= 32 | this.tok();return"<"+type+">\n"+body+"\n";case "list_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.token.type==="text"?this.parseText():this.tok();return"
  • "+body+"
  • \n";case "loose_item_start":var body="";while(this.next().type!=="list_item_end")body+=this.tok();return"
  • "+body+"
  • \n";case "html":return!this.token.pre&&!this.options.pedantic?this.inline.output(this.token.text):this.token.text;case "paragraph":return"

    "+this.inline.output(this.token.text)+ 33 | "

    \n";case "text":return"

    "+this.parseText()+"

    \n"}};function escape(html,encode){return html.replace(!encode?/&(?!#?\w+;)/g:/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function replace(regex,opt){regex=regex.source;opt=opt||"";return function self(name,val){if(!name)return new RegExp(regex,opt);val=val.source||val;val=val.replace(/(^|[^\[])\^/g,"$1");regex=regex.replace(name,val);return self}}function noop(){}noop.exec=noop;function merge(obj){var i= 34 | 1,target,key;for(;iAn error occured:

    "+escape(e.message+"",true)+"
    ";throw e;}}marked.options=marked.setOptions=function(opt){merge(marked.defaults,opt);return marked};marked.defaults={gfm:true,tables:true,breaks:false,pedantic:false,sanitize:false,smartLists:false,silent:false,highlight:null,langPrefix:""};marked.Parser=Parser;marked.parser=Parser.parse;marked.Lexer=Lexer;marked.lexer=Lexer.lex;marked.InlineLexer=InlineLexer;marked.inlineLexer=InlineLexer.output; 37 | marked.parse=marked;if(typeof exports==="object")module.exports=marked;else if(typeof define==="function"&&define.amd)define(function(){return marked});else this.marked=marked}).call(function(){return this||(typeof window!=="undefined"?window:global)}()); 38 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal-plugin/highlight/highlight.pack.js: -------------------------------------------------------------------------------- 1 | // START CUSTOM REVEAL.JS INTEGRATION 2 | (function() { 3 | if( typeof window.addEventListener === 'function' ) { 4 | var hljs_nodes = document.querySelectorAll( 'pre code' ); 5 | 6 | for( var i = 0, len = hljs_nodes.length; i < len; i++ ) { 7 | var element = hljs_nodes[i]; 8 | 9 | // trim whitespace if data-trim attribute is present 10 | if( element.hasAttribute( 'data-trim' ) && typeof element.innerHTML.trim === 'function' ) { 11 | element.innerHTML = element.innerHTML.trim(); 12 | } 13 | 14 | // Now escape html unless prevented by author 15 | if( ! element.hasAttribute( 'data-noescape' )) { 16 | element.innerHTML = element.innerHTML.replace(//g,">"); 17 | } 18 | 19 | // filename marker 20 | if( element.hasAttribute( 'data-filename' ) ) { 21 | var filename = element.getAttribute('data-filename'); 22 | element.insertAdjacentHTML('beforebegin', '' + 23 | ' ' + filename + 24 | ''); 25 | } 26 | 27 | 28 | // re-highlight when focus is lost (for edited code) 29 | element.addEventListener( 'focusout', function( event ) { 30 | hljs.highlightBlock( event.currentTarget ); 31 | }, false ); 32 | } 33 | } 34 | })(); 35 | // END CUSTOM REVEAL.JS INTEGRATION 36 | 37 | var hljs=new function(){function k(v){return v.replace(/&/gm,"&").replace(//gm,">")}function t(v){return v.nodeName.toLowerCase()}function i(w,x){var v=w&&w.exec(x);return v&&v.index==0}function d(v){return Array.prototype.map.call(v.childNodes,function(w){if(w.nodeType==3){return b.useBR?w.nodeValue.replace(/\n/g,""):w.nodeValue}if(t(w)=="br"){return"\n"}return d(w)}).join("")}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^language-/,"")});return v.filter(function(x){return j(x)||x=="no-highlight"})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(t(A)=="br"){z+=1}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset"}function E(G){F+=""}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=k(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+k(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};function E(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})}if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b=D.bK.split(" ").join("|")}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?\\b("+F.b+")\\b\\.?":F.b}).concat([D.tE]).concat([D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}};D.continuation={}}x(y)}function c(S,L,J,R){function v(U,V){for(var T=0;T";U+=Z+'">';return U+X+Y}function N(){var U=k(C);if(!I.k){return U}var T="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(U);while(V){T+=U.substr(X,V.index-X);var W=E(I,V);if(W){H+=W[1];T+=w(W[0],V[0])}else{T+=V[0]}X=I.lR.lastIndex;V=I.lR.exec(U)}return T+U.substr(X)}function F(){if(I.sL&&!f[I.sL]){return k(C)}var T=I.sL?c(I.sL,C,true,I.continuation.top):g(C);if(I.r>0){H+=T.r}if(I.subLanguageMode=="continuous"){I.continuation.top=T.top}return w(T.language,T.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(V,U){var T=V.cN?w(V.cN,"",true):"";if(V.rB){D+=T;C=""}else{if(V.eB){D+=k(U)+T;C=""}else{D+=T;C=U}}I=Object.create(V,{parent:{value:I}})}function G(T,X){C+=T;if(X===undefined){D+=Q();return 0}var V=v(X,I);if(V){D+=Q();P(V,X);return V.rB?0:X.length}var W=z(I,X);if(W){var U=I;if(!(U.rE||U.eE)){C+=X}D+=Q();do{if(I.cN){D+=""}H+=I.r;I=I.parent}while(I!=W.parent);if(U.eE){D+=k(X)}C="";if(W.starts){P(W.starts,"")}return U.rE?0:X.length}if(A(X,I)){throw new Error('Illegal lexeme "'+X+'" for mode "'+(I.cN||"")+'"')}C+=X;return X.length||1}var M=j(S);if(!M){throw new Error('Unknown language: "'+S+'"')}m(M);var I=R||M;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,D,true)}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+=""}}return{r:H,value:D,language:S,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:k(L)}}else{throw O}}}function g(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:k(y)};var w=v;x.forEach(function(z){if(!j(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function h(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"
    ")}return v}function p(z){var y=d(z);var A=r(z);if(A=="no-highlight"){return}var v=A?c(A,y,true):g(y);var w=u(z);if(w.length){var x=document.createElementNS("http://www.w3.org/1999/xhtml","pre");x.innerHTML=v.value;v.value=q(w,u(x),y)}v.value=h(v.value);z.innerHTML=v.value;z.className+=" hljs "+(!A&&v.language||"");z.result={language:v.language,re:v.r};if(v.second_best){z.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function e(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function j(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=g;this.fixMarkup=h;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=e;this.getLanguage=j;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("bash",function(b){var a={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)\}/}]};var d={cN:"string",b:/"/,e:/"/,c:[b.BE,a,{cN:"variable",b:/\$\(/,e:/\)/,c:[b.BE]}]};var c={cN:"string",b:/'/,e:/'/};return{l:/-?[a-z\.]+/,k:{keyword:"if then else elif fi for break continue while in do done exit return set declare case esac export exec",literal:"true false",built_in:"printf echo read cd pwd pushd popd dirs let eval unset typeset readonly getopts source shopt caller type hash bind help sudo",operator:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"shebang",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:true,c:[b.inherit(b.TM,{b:/\w[\w\d_]*/})],r:0},b.HCM,b.NM,d,c,a]}});hljs.registerLanguage("diff",function(a){return{c:[{cN:"chunk",r:10,v:[{b:/^\@\@ +\-\d+,\d+ +\+\d+,\d+ +\@\@$/},{b:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{b:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{cN:"header",v:[{b:/Index: /,e:/$/},{b:/=====/,e:/=====$/},{b:/^\-\-\-/,e:/$/},{b:/^\*{3} /,e:/$/},{b:/^\+\+\+/,e:/$/},{b:/\*{5}/,e:/\*{5}$/}]},{cN:"addition",b:"^\\+",e:"$"},{cN:"deletion",b:"^\\-",e:"$"},{cN:"change",b:"^\\!",e:"$"}]}});hljs.registerLanguage("javascript",function(a){return{aliases:["js"],k:{keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require"},c:[{cN:"pi",b:/^\s*('|")use strict('|")/,r:10},a.ASM,a.QSM,a.CLCM,a.CBLCLM,a.CNM,{b:"("+a.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[a.CLCM,a.CBLCLM,a.REGEXP_MODE,{b:/;/,r:0,sL:"xml"}],r:0},{cN:"function",bK:"function",e:/\{/,c:[a.inherit(a.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,c:[a.CLCM,a.CBLCLM],i:/["'\(]/}],i:/\[|%/},{b:/\$[(.]/},{b:"\\."+a.IR,r:0}]}});hljs.registerLanguage("xml",function(a){var c="[A-Za-z0-9\\._:-]+";var d={b:/<\?(php)?(?!\w)/,e:/\?>/,sL:"php",subLanguageMode:"continuous"};var b={eW:true,i:/]+/}]}]}]};return{aliases:["html"],cI:true,c:[{cN:"doctype",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},{cN:"comment",b:"",r:10},{cN:"cdata",b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"tag",b:"|$)",e:">",k:{title:"style"},c:[b],starts:{e:"",rE:true,sL:"css"}},{cN:"tag",b:"|$)",e:">",k:{title:"script"},c:[b],starts:{e:"<\/script>",rE:true,sL:"javascript"}},{b:"<%",e:"%>",sL:"vbscript"},d,{cN:"pi",b:/<\?\w+/,e:/\?>/,r:10},{cN:"tag",b:"",c:[{cN:"title",b:"[^ /><]+",r:0},b]}]}});hljs.registerLanguage("markdown",function(a){return{c:[{cN:"header",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"blockquote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{cN:"horizontal_rule",b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].+?[\\)\\]]",rB:true,c:[{cN:"link_label",b:"\\[",e:"\\]",eB:true,rE:true,r:0},{cN:"link_url",b:"\\]\\(",e:"\\)",eB:true,eE:true},{cN:"link_reference",b:"\\]\\[",e:"\\]",eB:true,eE:true,}],r:10},{b:"^\\[.+\\]:",e:"$",rB:true,c:[{cN:"link_reference",b:"\\[",e:"\\]",eB:true,eE:true},{cN:"link_url",b:"\\s",e:"$"}]}]}});hljs.registerLanguage("css",function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});hljs.registerLanguage("http",function(a){return{i:"\\S",c:[{cN:"status",b:"^HTTP/[0-9\\.]+",e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{cN:"request",b:"^[A-Z]+ (.*?) HTTP/[0-9\\.]+$",rB:true,e:"$",c:[{cN:"string",b:" ",e:" ",eB:true,eE:true}]},{cN:"attribute",b:"^\\w",e:": ",eE:true,i:"\\n|\\s|=",starts:{cN:"string",e:"$"}},{b:"\\n\\n",starts:{sL:"",eW:true}}]}});hljs.registerLanguage("php",function(b){var e={cN:"variable",b:"\\$+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*"};var a={cN:"preprocessor",b:/<\?(php)?|\?>/};var c={cN:"string",c:[b.BE,a],v:[{b:'b"',e:'"'},{b:"b'",e:"'"},b.inherit(b.ASM,{i:null}),b.inherit(b.QSM,{i:null})]};var d={v:[b.BNM,b.CNM]};return{cI:true,k:"and include_once list abstract global private echo interface as static endswitch array null if endwhile or const for endforeach self var while isset public protected exit foreach throw elseif include __FILE__ empty require_once do xor return parent clone use __CLASS__ __LINE__ else break print eval new catch __METHOD__ case exception default die require __FUNCTION__ enddeclare final try switch continue endfor endif declare unset true false trait goto instanceof insteadof __DIR__ __NAMESPACE__ yield finally",c:[b.CLCM,b.HCM,{cN:"comment",b:"/\\*",e:"\\*/",c:[{cN:"phpdoc",b:"\\s@[A-Za-z]+"},a]},{cN:"comment",b:"__halt_compiler.+?;",eW:true,k:"__halt_compiler",l:b.UIR},{cN:"string",b:"<<<['\"]?\\w+['\"]?$",e:"^\\w+;",c:[b.BE]},a,e,{cN:"function",bK:"function",e:/[;{]/,i:"\\$|\\[|%",c:[b.UTM,{cN:"params",b:"\\(",e:"\\)",c:["self",e,b.CBLCLM,c,d]}]},{cN:"class",bK:"class interface",e:"{",i:/[:\(\$"]/,c:[{bK:"extends implements",r:10},b.UTM]},{bK:"namespace",e:";",i:/[\.']/,c:[b.UTM]},{bK:"use",e:";",c:[b.UTM]},{b:"=>"},c,d]}});hljs.registerLanguage("sql",function(a){return{cI:true,i:/[<>]/,c:[{cN:"operator",b:"\\b(begin|end|start|commit|rollback|savepoint|lock|alter|create|drop|rename|call|delete|do|handler|insert|load|replace|select|truncate|update|set|show|pragma|grant|merge)\\b(?!:)",e:";",eW:true,k:{keyword:"all partial global month current_timestamp using go revoke smallint indicator end-exec disconnect zone with character assertion to add current_user usage input local alter match collate real then rollback get read timestamp session_user not integer bit unique day minute desc insert execute like ilike|2 level decimal drop continue isolation found where constraints domain right national some module transaction relative second connect escape close system_user for deferred section cast current sqlstate allocate intersect deallocate numeric public preserve full goto initially asc no key output collation group by union session both last language constraint column of space foreign deferrable prior connection unknown action commit view or first into float year primary cascaded except restrict set references names table outer open select size are rows from prepare distinct leading create only next inner authorization schema corresponding option declare precision immediate else timezone_minute external varying translation true case exception join hour default double scroll value cursor descriptor values dec fetch procedure delete and false int is describe char as at in varchar null trailing any absolute current_time end grant privileges when cross check write current_date pad begin temporary exec time update catalog user sql date on identity timezone_hour natural whenever interval work order cascade diagnostics nchar having left call do handler load replace truncate start lock show pragma exists number trigger if before after each row merge matched database",aggregate:"count sum min max avg"},c:[{cN:"string",b:"'",e:"'",c:[a.BE,{b:"''"}]},{cN:"string",b:'"',e:'"',c:[a.BE,{b:'""'}]},{cN:"string",b:"`",e:"`",c:[a.BE]},a.CNM]},a.CBLCLM,{cN:"comment",b:"--",e:"$"}]}});hljs.registerLanguage("nginx",function(c){var b={cN:"variable",v:[{b:/\$\d+/},{b:/\$\{/,e:/}/},{b:"[\\$\\@]"+c.UIR}]};var a={eW:true,l:"[a-z/_]+",k:{built_in:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},r:0,i:"=>",c:[c.HCM,{cN:"string",c:[c.BE,b],v:[{b:/"/,e:/"/},{b:/'/,e:/'/}]},{cN:"url",b:"([a-z]+):/",e:"\\s",eW:true,eE:true},{cN:"regexp",c:[c.BE,b],v:[{b:"\\s\\^",e:"\\s|{|;",rE:true},{b:"~\\*?\\s+",e:"\\s|{|;",rE:true},{b:"\\*(\\.[a-z\\-]+)+"},{b:"([a-z\\-]+\\.)+\\*"}]},{cN:"number",b:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{cN:"number",b:"\\b\\d+[kKmMgGdshdwy]*\\b",r:0},b]};return{c:[c.HCM,{b:c.UIR+"\\s",e:";|{",rB:true,c:[c.inherit(c.UTM,{starts:a})],r:0}],i:"[^\\s\\}]"}});hljs.registerLanguage("json",function(a){var e={literal:"true false null"};var d=[a.QSM,a.CNM];var c={cN:"value",e:",",eW:true,eE:true,c:d,k:e};var b={b:"{",e:"}",c:[{cN:"attribute",b:'\\s*"',e:'"\\s*:\\s*',eB:true,eE:true,c:[a.BE],i:"\\n",starts:c}],i:"\\S"};var f={b:"\\[",e:"\\]",c:[a.inherit(c,{cN:null})],i:"\\S"};d.splice(d.length,0,b,f);return{c:d,k:e,i:"\\S"}});hljs.registerLanguage("apache",function(a){var b={cN:"number",b:"[\\$%]\\d+"};return{cI:true,c:[a.HCM,{cN:"tag",b:""},{cN:"keyword",b:/\w+/,r:0,k:{common:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"sqbracket",b:"\\s\\[",e:"\\]$"},{cN:"cbracket",b:"[\\$%]\\{",e:"\\}",c:["self",b]},b,a.QSM]}}],i:/\S/}}); -------------------------------------------------------------------------------- /slide_part1.md: -------------------------------------------------------------------------------- 1 | ## [PHPhub](http://phphub.org) 社区 2 | 3 | ![](assets/img/phphub.png) 4 | 5 | ---- 6 | 7 | ## [Laravel-china.org](http://laravel-china.org) 8 | 9 | ![](assets/img/laravel-china.png) 10 | 11 | ---- 12 | 13 | ## laravel 现状 14 | 15 | 2014年php开发框架流行度排名 16 | 17 | ![](assets/img/sitepoint2013.png) 18 | 19 | ---- 20 | 21 | Github Star 22 | 23 | ![](assets/img/git.png) 24 | 25 | ---- 26 | 27 | First Commit 28 | 29 | ![](assets/img/first_commit.png) 30 | 31 | ---- 32 | 33 | Author: Taylor Otwell 34 | 35 | ![](assets/img/taylor_otwell.jpeg) 36 | 37 | ---- 38 | 39 | 40 | 41 | ###发布里程 42 | 43 | - 2011年6月 1.0.0 Beta 44 | - 2011年11月 2.0发布 45 | - 2013年5月 3.2发布 46 | - 2013年12月 4.0发布 47 | - 到目前为止最新版本是4.2.11 48 | 49 | .... 50 | 51 | ---- 52 | 53 | ## 2015年1月 laravel5 54 | ![](assets/gif/jidong.gif) 55 | 56 | ---- 57 | 58 | 59 | ## 「Laravel特点」 60 | 61 |
    62 | “Laravel是一个简单优雅的PHP Web开发框架,可以将开发者从意大利面条式的代码中解放出来,通过简单、高雅、表达式语法开发出很棒的Web应用,Laravel拥有更富有表现力的语法、高质量的文档、丰富的扩展包,被称为“巨匠级PHP开发框架”。” 63 |
    64 | 65 | ---- 66 | 67 | ![](assets/gif/en.gif) 68 | 69 | ---- 70 | 71 | ## 特色简介 72 | 73 | ---- 74 | 75 | 76 | 77 | - 强大的路由系统 78 | - 合理的 ORM model 层, Eloquent ORM 79 | - Blade 模板引擎 80 | - migration 数据库版本系统 和 seeding 81 | - artisan命令行工具, 高度自动化 82 | - 使用包管理器 Composer 扩展 83 | - 强调测试驱动, 高质量代码 84 | 85 | ---- 86 | 87 | 88 | 89 | ##Route System 90 | 91 | - Routing for basic static pages 92 | - Passing parameters to functions 93 | - Using named routes to make URLs easier to use 94 | - Filtering routes for Auth or anything else 95 | - Group routing 96 | - Routing to Controller 97 | - Resource Route 98 | 99 | ---- 100 | 101 | ## 先来一个最基本的路由 102 | 103 | ``` 104 | // app/routes.php 105 | Route::get('/', function(){ 106 | return View::make('hello'); 107 | }) 108 | ``` 109 | 110 | 其他请求呢? 111 | 112 | ``` 113 | Route::post('foo/bar', function(){ 114 | return 'Post Request'; 115 | }) 116 | 117 | Route::any('foo', function(){ 118 | return 'Any Request'; 119 | }); 120 | ``` 121 | 122 | 123 | ---- 124 | 125 | ## 路由参数 126 | 127 | 很多时候往往路由不是静态的地址, 而是带有动态的参数. 比如`blog/{$category}` 128 | 129 | ``` 130 | Route::get('blog/{category}', function($category){ 131 | return "Finding Post in {$category}"; 132 | }); 133 | ``` 134 | 135 | 可选参数 136 | 137 | ``` 138 | Route::get('blog/{category?}', function($category = null){ 139 | if ($category) 140 | //fetch blogs in this category 141 | else 142 | //fetch all blogs 143 | 144 | return View::make('blog', /* $blogs */); 145 | }); 146 | ``` 147 | 148 | 149 | ---- 150 | 151 | 152 | ##命名路由 153 | 顾名思义是给路由进行命名, 有什么好处呢? 154 | 155 | ``` 156 | Route::get('user/{id}', ['as' => 'user.detail', function($id){ 157 | // 158 | }]); 159 | 160 | ``` 161 | 162 | 163 | - 生成重定向跳转 164 | `Redirect::route('user.detail', $id);` 165 | - 生成 url 166 | `route('user.detail', $id)` -> "http://domain/user/$id" 167 | 168 | ---- 169 | 170 | ##路由过滤 171 | 172 | ``` 173 | //define filter 174 | Route::filter('login', function() 175 | { 176 | // Some Logic check if the current user is login 177 | }); 178 | ``` 179 | 180 | 在特定的路由前进行过滤 使用 before 关键字 181 | ``` 182 | Route::get('money', ['before' => 'login', function(){ 183 | // see user's money 184 | }]); 185 | ``` 186 | 187 | ---- 188 | 189 | ##群组路由 190 | 191 | 如果不想为每个路由定义相同的过滤器, 我们可以采用群组路由的方式 192 | 193 | ``` 194 | Route::group(['before' => 'csrf'], function(){ 195 | 196 | Route::post('login', function(){}); 197 | 198 | Route::post('user/profile', function(){}); 199 | }); 200 | 201 | ``` 202 | 203 | ---- 204 | 205 | ##控制器路由 206 | 207 | ``` 208 | Route::get('user/{id}', 'UserController@showProfile'); 209 | 210 | ``` 211 | 212 | 控制器 213 | 214 | ``` 215 | class UserController extends BaseController { 216 | 217 | /** 218 | * Show the profile for the given user. 219 | */ 220 | public function showProfile($id) 221 | { 222 | $user = User::find($id); 223 | 224 | return View::make('user.profile', ['user' => $user]); 225 | } 226 | 227 | } 228 | ``` 229 | 230 | ---- 231 | 232 | ##资源控制器 233 | 234 | `Route::resource('photo', 'PhotoController');` 235 | 236 | ![](assets/img/resource.png) 237 | 238 | ---- 239 | 240 | 241 | ## Eloquent ORM 242 | 243 |
    244 | Laravel 的 Eloquent ORM 提供了漂亮、简洁的 ActiveRecord 实现来和数据库的互动。 每个数据库表会和一个对应的「模型」互动。 245 |
    246 | 247 | 248 | ---- 249 | 250 | ## Eloquent ORM ——CRUD Example 251 | 252 | 253 | ``` 254 | // 获取所有任务记录 255 | $tasks = Task::all(); 256 | 257 | // 获取ID为1的任务 258 | $task = Task::find(1); 259 | 260 | // 更新ID为1的task 261 | $task = Task::find(1); 262 | $task->title = 'Finish Homework'; 263 | $task->save(); 264 | 265 | // 创建一条任务 266 | Task::create([ 267 | 'title' => 'Write article' 268 | ]); 269 | 270 | // 删除任务 271 | Task::find(1)->delete(); 272 | 273 | ``` 274 | 275 | ---- 276 | 277 | ## Eloquent ORM 278 | ### Relationship 279 | 280 | - 一对一 281 | - 一对多 282 | - 多对多 283 | 284 | ---- 285 | 286 | One To One Example 287 | 288 | ``` 289 | class User extends Eloquent { 290 | 291 | public function phone() 292 | { 293 | return $this->hasOne('Phone'); 294 | } 295 | 296 | } 297 | 298 | $phone = User::find(1)->phone; 299 | 300 | ``` 301 |


    302 | SQL执行 303 | 304 | ``` 305 | select * from users where id = 1 306 | 307 | select * from phones where user_id = 1 308 | ``` 309 | 310 | ---- 311 | 312 | One To Many Example 313 | 314 | ``` 315 | class Task extends Eloquent { 316 | 317 | public function user() 318 | { 319 | return $this->belongsTo('User'); 320 | } 321 | 322 | } 323 | ``` 324 | 325 | ``` 326 | class User extends Eloquent { 327 | 328 | public function tasks() 329 | { 330 | return $this->hasMany('Task'); 331 | } 332 | 333 | } 334 | ``` 335 | 336 | ``` 337 | // Get all tasks by the author with an id of 1 338 | $tasks = User::find(1)->tasks; 339 | 340 | // Get the author of a task 341 | $author = Task::find(5)->user()->username; 342 | 343 | // Insert a new task by author 344 | $task = new Task([ title: 'Go to store.' ]); 345 | User::find(1)->tasks()->insert($task); 346 | ``` 347 | 348 | ---- 349 | 350 | ## Eloquent ORM ——Mass-assignment 351 | 352 | 353 | 354 | ``` 355 | //需要手动指定一堆的键值 为的是预防多余字段插入 356 | News::create([ 357 | 'title' => Input::get('title'), 358 | 'slug' => Input::get('slug'), 359 | 'content' => Input::get('content'), 360 | 'published_at' => Input::get('published_at'), 361 | ]) 362 | 363 | ``` 364 | 一个常见的场景 365 | 366 | ---- 367 | 368 | 有没有更简单直观的做法呢? 369 | 370 | ![](assets/gif/let_it_go.gif) 371 | 372 | ---- 373 | 374 | 通过定义fillable属性 - "白名单" 375 | 376 | ``` 377 | class News extends Eloquent { 378 | 379 | protected $fillable = array('title', 'slug', 'content', 'published_at'); 380 | 381 | } 382 | ``` 383 | 384 | 385 | 386 | 定义Guarded属性 - "黑名单" 387 | 388 | ``` 389 | class News extends Eloquent { 390 | 391 | protected $guarded = array('id'); 392 | 393 | } 394 | ``` 395 | 396 | 397 | 398 | Finally: 399 | 400 | ``` 401 | News::create(Input::get()); 402 | 403 | ``` 404 | 405 | 406 | ---- 407 | 408 | ![](assets/gif/great_job.gif) 409 | 410 | ---- 411 | 412 | ##Model Events 413 | 414 | - Eloquent 模型中定义了很多的事件, 使得我们可以在模型操作的生命周期的不同时间点, 通过以下方法绑定事件`creating` 、 `created` 、 `updating` 、 `updated` 、 `saving` 、 `saved`、 `deleting` 、 `deleted` 、 `restoring` 、 `restored` 。 415 | - 当一个对象被创建时, `creating` 和 `created` 事件会被触发。如果是更新对象, `updating` / `updated` 事件会被触发。而两者的 `saving` / `saved` 事件都会触发。 416 | 417 | ---- 418 | 419 | ###Model Events Example 420 | 421 | `Eloquent_Model_Name::Event_Name(callback)` 422 | 423 | ``` 424 | //创建或者修改post模型的时候自动加入编辑的人的id 425 | 426 | Post::creating(function($post) 427 | { 428 | $post->created_by = Auth::user()->id; 429 | $post->updated_by = Auth::user()->id; 430 | }); 431 | 432 | Post::updating(function($post) 433 | { 434 | $post->updated_by = Auth::user()->id; 435 | }); 436 | 437 | //删除图片 438 | Image::deleting(function($image) 439 | { 440 | if (count($image->galleries)) return false; 441 | }); 442 | 443 | ``` 444 | 445 | ---- 446 | 447 | 448 | ###Model Observer Example 449 | 450 |

    451 | 如果我们对一个模型注册了很多的事件, 可以为这个模型单独注册一个模型的观察者。 452 |

    453 | 454 | 455 | ``` 456 | class UserObserver { 457 | public function creating($model) {} 458 | public function updating($model) {} 459 | public function saved($model) {} 460 | } 461 | 462 | ``` 463 | 464 |

    465 | 使用 `observe` 方法注册一个观察者的实例 `User::observe(new UserObserver)` 466 |

    467 | 468 | 469 | ---- 470 | 471 | ## Setter And Getter 472 | 473 | `允许动态的对模型进行获取和修改` 474 | 475 | ### Getter 476 | ``` 477 | class User extends Eloquent { 478 | 479 | public function getFirstNameAttribute($value) 480 | { 481 | return ucfirst($value); 482 | } 483 | 484 | } 485 | 486 | echo User::find(1)->firstName; // jack->Jack 487 | 488 | ``` 489 | 490 | ### Setter 491 | 492 | ``` 493 | class User extends Eloquent { 494 | 495 | public function setPasswordAttribute() 496 | { 497 | return md5( $this->password ); 498 | } 499 | } 500 | 501 | ``` 502 | 503 | ---- 504 | 505 | ##更多用法 506 | 507 | [官方文档](http://laravel-china.org/docs/eloquent) 508 | 509 | ![](assets/img/eloquent.png) 510 | 511 | ---- 512 | 513 | 514 | ##Blade模板引擎 515 | 516 |

    517 | "Laravel 所提供的一个简单却又非常强大的模板引擎。Blade 是使用 模板继承(template inheritance) 及 区块(sections) 来创建出视图。所有的 Blade 模板的后缀名都要命名为 .blade.php。" 518 |

    519 | 520 | 521 | 522 | ### 一个简单的layout 523 | 524 | ``` 525 | 526 | 527 | 528 | 529 | @include('layouts.partial.nav') 530 | 531 | @section('sidebar') 532 | This is the master sidebar. 533 | @show 534 | 535 |
    536 | @yield('content') 537 |
    538 | 539 | 540 | ``` 541 | 542 | ---- 543 | 544 | ##继承布局 545 | 546 | ``` 547 | @extends('layouts.master') 548 | 549 | @section('sidebar') 550 | 551 | @parent 552 | 553 |

    This is appended to the master sidebar.

    554 | @stop 555 | 556 | @section('content') 557 | 558 | Hello, {{ $name }}. {{{age}}} 559 |

    This is my body content.

    560 | @stop 561 | 562 | ``` 563 | 564 | ---- 565 | 566 | ##其他控制语法 567 | 568 | ``` 569 | @if (count($records) === 1) 570 | I have one record! 571 | @elseif (count($records) > 1) 572 | I have multiple records! 573 | @else 574 | No Records. 575 | @endif 576 | 577 | 578 | @for ($i = 0; $i < 10; $i++) 579 | The current value is {{ $i }} 580 | @endfor 581 | 582 | @foreach ($users as $user) 583 |

    This is user {{ $user->id }}

    584 | @endforeach 585 | 586 | @while (true) 587 |

    looping forever.

    588 | @endwhile 589 | 590 | ``` 591 | 592 | ---- 593 | 594 | ## Migrations & Seeds 595 | 596 | - `Migrations: 数据库的版本控制` 597 | - `Seeds: 数据导入` 598 | 599 | ---- 600 | 601 | 602 | 来个栗子 603 | 604 | `php artisan migrate:make create_users_table --table=users --create` 605 | 606 | 607 | ``` 608 | 609 | increments('id'); 622 | $table->string('name'); 623 | $table->integer('age'); 624 | $table->timestamps(); 625 | }); 626 | } 627 | 628 | public function down() 629 | { 630 | Schema::drop('users'); 631 | } 632 | 633 | } 634 | 635 | ``` 636 | 637 | 638 | 执行操作 `php artisan migrate` 639 | 640 | 执行回滚 `php artisan rollback` 641 | 642 | 重置操作 `php artisan reset` 643 | 644 | 645 | ---- 646 | 647 | ##Seed Example 648 | 649 | ``` 650 | //入口 651 | class DatabaseSeeder extends Seeder { 652 | 653 | public function run() 654 | { 655 | //调用UserTableSeeder的run方法 一个表一个seeder 656 | $this->call('UserTableSeeder'); 657 | // $this->call('OtherTableSeeder'); 658 | 659 | $this->command->info('User table seeded!'); 660 | } 661 | 662 | } 663 | 664 | //使用faker作为假数据生成器 665 | use Faker\Factory as Faker; 666 | 667 | class UserTableSeeder extends Seeder { 668 | 669 | public function run() 670 | { 671 | $faker = Faker::create(); 672 | 673 | foreach(range(1, 50) as $index) 674 | { 675 | User::create([ 676 | 'github_id' => $index, 677 | 'github_url' => $faker->url(), 678 | 'city' => $faker->city(), 679 | 'name' => $faker->userName(), 680 | 'introduction' => $faker->sentence(), 681 | 'email' => $faker->email(), 682 | ]); 683 | } 684 | } 685 | 686 | } 687 | 688 | ``` 689 | 690 |

    执行: `php artisan db:seed`

    691 | 692 | 693 | ---- 694 | 695 | ## Artisan 命令行工具 696 | 697 | ![](assets/img/artisan.png) 698 | 699 | ---- 700 | 701 | ### 查看当前路由 702 | 703 | 704 | `php artisan route` 705 | 706 | ![](assets/img/current_route.png) 707 | 708 | ---- 709 | 710 | ##Other Useful Command 711 | - `php artisan down` 进入维护模式 (`php artisan up` 可恢复) 712 | - `php artisan tinker` 内置的repl模式 可以直接进行数据库操作 713 | - `php artisan serve` 开启内置server 714 | - `php artisan tail` 实时查看laravel的log 715 | 716 | ---- 717 | 718 | ![](assets/img/composer.png) 719 | ## [使用Composer扩展](http://getcomposer.org) 720 | 721 |
    722 | 是 PHP 用来管理依赖(dependency)关系的工具。你可以在自己的项目中声明所依赖的外部工具库(libraries),Composer 会帮你安装这些依赖的库文件。 723 |
    724 | 725 | ---- 726 | 727 | ## 关于安装 728 | 729 | ``` 730 | php >= 5.3.2 openssl √ (win下使用php套件的同学注意多个php.ini问题) 731 | 732 | $ curl -sS https://getcomposer.org/installer | php 733 | $ mv composer.phar /usr/local/bin/composer 734 | $ composer 735 | 736 | / ____/___ ____ ___ ____ ____ ________ _____ 737 | / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/ 738 | / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ / 739 | \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/ 740 | /_/ 741 | Composer version d79f2b0fd33ee9b89f3d9f1969f43dc3d570a33a 2014-09-10 15:11:05 742 | 743 | Usage: 744 | [options] command [arguments] 745 | ... 746 | 747 | ``` 748 | 749 | ---- 750 | 751 | 752 | ## 简明三步教程 753 | 754 | ###在项目目录中创建 composer.json 文件, 比如 [Monnolog](https://github.com/Seldaek/monolog) 755 | 756 | 757 | ``` 758 | { 759 | "require": { 760 | "monolog/monolog": "1.2.*" 761 | } 762 | } 763 | ``` 764 | 765 | ###安装依赖 766 | 767 | 在项目目录中执行 `composer install` 768 | 769 | ###引入自动加载 770 | 771 | 在代码初始化的部分引入下面的代码: 772 | 773 | `require 'vendor/autoload.php'` 774 | 775 | ---- 776 | 777 | ##Other Thing 778 | 779 | 1. [packagist.org](https://packagist.org/) 是 [Composer](http://getcomposer.org) 的官方仓库, 一些知名的PHP库都能在其中找到, 也可以提交自己的类库。 780 | 2. 被墙可以考虑使用[Composer国内镜像](http://pkg.phpcomposer.com/) 781 | 3. 公司内部可使用[Satis](https://github.com/composer/satis) 782 | 4. 使用[Toran](https://toranproxy.com/)自建镜像 783 | 784 | ---- 785 | 786 | 787 | ## What Else? 788 | 789 | - [官方文档](http://laravel.com/docs) 790 | - [中文文档](http://laravel-china.org/docs) 791 | - [交流社区](http://phphub.org) 792 | - [问答社区](http://wenda.golaravel.com) 793 | - [项目源码参考](https://phphub.org/topics/8) 794 | - [视频集锦](https://phphub.org/topics/14) 795 | - [相关站点](https://phphub.org/topics/13) 796 | -------------------------------------------------------------------------------- /assets/js/vendor/reveal/reveal.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * reveal.js 2.6.1 (2014-03-18, 11:48) 3 | * http://lab.hakim.se/reveal-js 4 | * MIT licensed 5 | * 6 | * Copyright (C) 2013 Hakim El Hattab, http://hakim.se 7 | * Slide Theme Copyright (C) 2014 Colin Viebrock, http://viebrock.ca 8 | */ 9 | 10 | var Reveal=function(){"use strict";function a(a){if(b(),!ec.transforms2d&&!ec.transforms3d)return void document.body.setAttribute("class","no-transforms");window.addEventListener("load",A,!1);var d=Reveal.getQueryHash();"undefined"!=typeof d.dependencies&&delete d.dependencies,k(_b,a),k(_b,d),r(),c()}function b(){ec.transforms3d="WebkitPerspective"in document.body.style||"MozPerspective"in document.body.style||"msPerspective"in document.body.style||"OPerspective"in document.body.style||"perspective"in document.body.style,ec.transforms2d="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,ec.requestAnimationFrameMethod=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame,ec.requestAnimationFrame="function"==typeof ec.requestAnimationFrameMethod,ec.canvas=!!document.createElement("canvas").getContext,Vb=navigator.userAgent.match(/(iphone|ipod|android)/gi)}function c(){function a(){e.length&&head.js.apply(null,e),d()}function b(b){head.ready(b.src.match(/([\w\d_\-]*)\.?js$|[^\\\/]*$/i)[0],function(){"function"==typeof b.callback&&b.callback.apply(this),0===--f&&a()})}for(var c=[],e=[],f=0,g=0,h=_b.dependencies.length;h>g;g++){var i=_b.dependencies[g];(!i.condition||i.condition())&&(i.async?e.push(i.src):c.push(i.src),b(i))}c.length?(f=c.length,head.js.apply(null,c)):a()}function d(){e(),Q(),h(),cb(),X(!0),setTimeout(function(){dc.slides.classList.remove("no-transition"),ac=!0,t("ready",{indexh:Qb,indexv:Rb,currentSlide:Tb})},1)}function e(){dc.theme=document.querySelector("#theme"),dc.wrapper=document.querySelector(".reveal"),dc.slides=document.querySelector(".reveal .slides"),dc.slides.classList.add("no-transition"),dc.background=f(dc.wrapper,"div","backgrounds",null),dc.progress=f(dc.wrapper,"div","progress",""),dc.progressbar=dc.progress.querySelector("span"),f(dc.wrapper,"aside","controls",''),dc.slideNumber=f(dc.wrapper,"div","slide-number",""),f(dc.wrapper,"div","state-background",null),f(dc.wrapper,"div","pause-overlay",null),dc.controls=document.querySelector(".reveal .controls"),dc.controlsLeft=l(document.querySelectorAll(".navigate-left")),dc.controlsRight=l(document.querySelectorAll(".navigate-right")),dc.controlsUp=l(document.querySelectorAll(".navigate-up")),dc.controlsDown=l(document.querySelectorAll(".navigate-down")),dc.controlsPrev=l(document.querySelectorAll(".navigate-prev")),dc.controlsNext=l(document.querySelectorAll(".navigate-next"))}function f(a,b,c,d){var e=a.querySelector("."+c);return e||(e=document.createElement(b),e.classList.add(c),null!==d&&(e.innerHTML=d),a.appendChild(e)),e}function g(){function a(a,b){var c={background:a.getAttribute("data-background"),backgroundSize:a.getAttribute("data-background-size"),backgroundImage:a.getAttribute("data-background-image"),backgroundColor:a.getAttribute("data-background-color"),backgroundRepeat:a.getAttribute("data-background-repeat"),backgroundPosition:a.getAttribute("data-background-position"),backgroundTransition:a.getAttribute("data-background-transition")},d=document.createElement("div");return d.className="slide-background",c.background&&(/^(http|file|\/\/)/gi.test(c.background)||/\.(svg|png|jpg|jpeg|gif|bmp)$/gi.test(c.background)?d.style.backgroundImage="url("+c.background+")":d.style.background=c.background),(c.background||c.backgroundColor||c.backgroundImage)&&d.setAttribute("data-background-hash",c.background+c.backgroundSize+c.backgroundImage+c.backgroundColor+c.backgroundRepeat+c.backgroundPosition+c.backgroundTransition),c.backgroundSize&&(d.style.backgroundSize=c.backgroundSize),c.backgroundImage&&(d.style.backgroundImage='url("'+c.backgroundImage+'")'),c.backgroundColor&&(d.style.backgroundColor=c.backgroundColor),c.backgroundRepeat&&(d.style.backgroundRepeat=c.backgroundRepeat),c.backgroundPosition&&(d.style.backgroundPosition=c.backgroundPosition),c.backgroundTransition&&d.setAttribute("data-background-transition",c.backgroundTransition),b.appendChild(d),d}q()&&document.body.classList.add("print-pdf"),dc.background.innerHTML="",dc.background.classList.add("no-transition"),l(document.querySelectorAll(Yb)).forEach(function(b){var c;c=q()?a(b,b):a(b,dc.background),l(b.querySelectorAll("section")).forEach(function(b){q()?a(b,b):a(b,c)})}),_b.parallaxBackgroundImage?(dc.background.style.backgroundImage='url("'+_b.parallaxBackgroundImage+'")',dc.background.style.backgroundSize=_b.parallaxBackgroundSize,setTimeout(function(){dc.wrapper.classList.add("has-parallax-background")},1)):(dc.background.style.backgroundImage="",dc.wrapper.classList.remove("has-parallax-background"))}function h(a){var b=document.querySelectorAll(Xb).length;if(dc.wrapper.classList.remove(_b.transition),"object"==typeof a&&k(_b,a),ec.transforms3d===!1&&(_b.transition="linear"),dc.wrapper.classList.add(_b.transition),dc.wrapper.setAttribute("data-transition-speed",_b.transitionSpeed),dc.wrapper.setAttribute("data-background-transition",_b.backgroundTransition),dc.controls.style.display=_b.controls?"block":"none",dc.progress.style.display=_b.progress?"block":"none",_b.rtl?dc.wrapper.classList.add("rtl"):dc.wrapper.classList.remove("rtl"),_b.center?dc.wrapper.classList.add("center"):dc.wrapper.classList.remove("center"),_b.mouseWheel?(document.addEventListener("DOMMouseScroll",Bb,!1),document.addEventListener("mousewheel",Bb,!1)):(document.removeEventListener("DOMMouseScroll",Bb,!1),document.removeEventListener("mousewheel",Bb,!1)),_b.rollingLinks?u():v(),_b.previewLinks?w():(x(),w("[data-preview-link]")),b>1&&_b.autoSlide&&_b.autoSlideStoppable&&ec.canvas&&ec.requestAnimationFrame?(Wb=new Pb(dc.wrapper,function(){return Math.min(Math.max((Date.now()-mc)/kc,0),1)}),Wb.on("click",Ob),nc=!1):Wb&&(Wb.destroy(),Wb=null),_b.theme&&dc.theme){var c=dc.theme.getAttribute("href"),d=/[^\/]*?(?=\.css)/,e=c.match(d)[0];_b.theme!==e&&(c=c.replace(d,_b.theme),dc.theme.setAttribute("href",c))}P()}function i(){if(jc=!0,window.addEventListener("hashchange",Jb,!1),window.addEventListener("resize",Kb,!1),_b.touch&&(dc.wrapper.addEventListener("touchstart",vb,!1),dc.wrapper.addEventListener("touchmove",wb,!1),dc.wrapper.addEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.addEventListener("MSPointerDown",yb,!1),dc.wrapper.addEventListener("MSPointerMove",zb,!1),dc.wrapper.addEventListener("MSPointerUp",Ab,!1))),_b.keyboard&&document.addEventListener("keydown",ub,!1),_b.progress&&dc.progress&&dc.progress.addEventListener("click",Cb,!1),_b.focusBodyOnPageVisiblityChange){var a;"hidden"in document?a="visibilitychange":"msHidden"in document?a="msvisibilitychange":"webkitHidden"in document&&(a="webkitvisibilitychange"),a&&document.addEventListener(a,Lb,!1)}["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.addEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.addEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.addEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.addEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.addEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.addEventListener(a,Ib,!1)})})}function j(){jc=!1,document.removeEventListener("keydown",ub,!1),window.removeEventListener("hashchange",Jb,!1),window.removeEventListener("resize",Kb,!1),dc.wrapper.removeEventListener("touchstart",vb,!1),dc.wrapper.removeEventListener("touchmove",wb,!1),dc.wrapper.removeEventListener("touchend",xb,!1),window.navigator.msPointerEnabled&&(dc.wrapper.removeEventListener("MSPointerDown",yb,!1),dc.wrapper.removeEventListener("MSPointerMove",zb,!1),dc.wrapper.removeEventListener("MSPointerUp",Ab,!1)),_b.progress&&dc.progress&&dc.progress.removeEventListener("click",Cb,!1),["touchstart","click"].forEach(function(a){dc.controlsLeft.forEach(function(b){b.removeEventListener(a,Db,!1)}),dc.controlsRight.forEach(function(b){b.removeEventListener(a,Eb,!1)}),dc.controlsUp.forEach(function(b){b.removeEventListener(a,Fb,!1)}),dc.controlsDown.forEach(function(b){b.removeEventListener(a,Gb,!1)}),dc.controlsPrev.forEach(function(b){b.removeEventListener(a,Hb,!1)}),dc.controlsNext.forEach(function(b){b.removeEventListener(a,Ib,!1)})})}function k(a,b){for(var c in b)a[c]=b[c]}function l(a){return Array.prototype.slice.call(a)}function m(a,b){var c=a.x-b.x,d=a.y-b.y;return Math.sqrt(c*c+d*d)}function n(a,b){a.style.WebkitTransform=b,a.style.MozTransform=b,a.style.msTransform=b,a.style.OTransform=b,a.style.transform=b}function o(a){var b=0;if(a){var c=0;l(a.childNodes).forEach(function(a){"number"==typeof a.offsetTop&&a.style&&("absolute"===a.style.position&&(c+=1),b=Math.max(b,a.offsetTop+a.offsetHeight))}),0===c&&(b=a.offsetHeight)}return b}function p(a,b){if(b=b||0,a){var c=a.parentNode,d=c.childNodes;l(d).forEach(function(c){if("number"==typeof c.offsetHeight&&c!==a){var d=window.getComputedStyle(c),e=parseInt(d.marginTop,10),f=parseInt(d.marginBottom,10);b-=c.offsetHeight+e+f}});var e=window.getComputedStyle(a);b-=parseInt(e.marginTop,10)+parseInt(e.marginBottom,10)}return b}function q(){return/print-pdf/gi.test(window.location.search)}function r(){_b.hideAddressBar&&Vb&&(window.addEventListener("load",s,!1),window.addEventListener("orientationchange",s,!1))}function s(){setTimeout(function(){window.scrollTo(0,1)},10)}function t(a,b){var c=document.createEvent("HTMLEvents",1,2);c.initEvent(a,!0,!0),k(c,b),dc.wrapper.dispatchEvent(c)}function u(){if(ec.transforms3d&&!("msPerspective"in document.body.style))for(var a=document.querySelectorAll(Xb+" a:not(.image)"),b=0,c=a.length;c>b;b++){var d=a[b];if(!(!d.textContent||d.querySelector("*")||d.className&&d.classList.contains(d,"roll"))){var e=document.createElement("span");e.setAttribute("data-title",d.text),e.innerHTML=d.innerHTML,d.classList.add("roll"),d.innerHTML="",d.appendChild(e)}}}function v(){for(var a=document.querySelectorAll(Xb+" a.roll"),b=0,c=a.length;c>b;b++){var d=a[b],e=d.querySelector("span");e&&(d.classList.remove("roll"),d.innerHTML=e.innerHTML)}}function w(a){var b=l(document.querySelectorAll(a?a:"a"));b.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.addEventListener("click",Nb,!1)})}function x(){var a=l(document.querySelectorAll("a"));a.forEach(function(a){/^(http|www)/gi.test(a.getAttribute("href"))&&a.removeEventListener("click",Nb,!1)})}function y(a){z(),dc.preview=document.createElement("div"),dc.preview.classList.add("preview-link-overlay"),dc.wrapper.appendChild(dc.preview),dc.preview.innerHTML=["
    ",'','',"
    ",'
    ','
    ','',"
    "].join(""),dc.preview.querySelector("iframe").addEventListener("load",function(){dc.preview.classList.add("loaded")},!1),dc.preview.querySelector(".close").addEventListener("click",function(a){z(),a.preventDefault()},!1),dc.preview.querySelector(".external").addEventListener("click",function(){z()},!1),setTimeout(function(){dc.preview.classList.add("visible")},1)}function z(){dc.preview&&(dc.preview.setAttribute("src",""),dc.preview.parentNode.removeChild(dc.preview),dc.preview=null)}function A(){if(dc.wrapper&&!q()){var a=dc.wrapper.offsetWidth,b=dc.wrapper.offsetHeight;a-=b*_b.margin,b-=b*_b.margin;var c=_b.width,d=_b.height,e=20;B(_b.width,_b.height,e),"string"==typeof c&&/%$/.test(c)&&(c=parseInt(c,10)/100*a),"string"==typeof d&&/%$/.test(d)&&(d=parseInt(d,10)/100*b),dc.slides.style.width=c+"px",dc.slides.style.height=d+"px",cc=Math.min(a/c,b/d),cc=Math.max(cc,_b.minScale),cc=Math.min(cc,_b.maxScale),"undefined"==typeof dc.slides.style.zoom||navigator.userAgent.match(/(iphone|ipod|ipad|android)/gi)?n(dc.slides,"translate(-50%, -50%) scale("+cc+") translate(50%, 50%)"):dc.slides.style.zoom=cc;for(var f=l(document.querySelectorAll(Xb)),g=0,h=f.length;h>g;g++){var i=f[g];"none"!==i.style.display&&(i.style.top=_b.center||i.classList.contains("center")?i.classList.contains("stack")?0:Math.max(-(o(i)/2)-e,-d/2)+"px":"")}U(),Y()}}function B(a,b,c){l(dc.slides.querySelectorAll("section > .stretch")).forEach(function(d){var e=p(d,b-2*c);if(/(img|video)/gi.test(d.nodeName)){var f=d.naturalWidth||d.videoWidth,g=d.naturalHeight||d.videoHeight,h=Math.min(a/f,e/g);d.style.width=f*h+"px",d.style.height=g*h+"px"}else d.style.width=a+"px",d.style.height=e+"px"})}function C(a,b){"object"==typeof a&&"function"==typeof a.setAttribute&&a.setAttribute("data-previous-indexv",b||0)}function D(a){if("object"==typeof a&&"function"==typeof a.setAttribute&&a.classList.contains("stack")){var b=a.hasAttribute("data-start-indexv")?"data-start-indexv":"data-previous-indexv";return parseInt(a.getAttribute(b)||0,10)}return 0}function E(){if(_b.overview){kb();var a=dc.wrapper.classList.contains("overview"),b=window.innerWidth<400?1e3:2500;dc.wrapper.classList.add("overview"),dc.wrapper.classList.remove("overview-deactivating"),clearTimeout(hc),clearTimeout(ic),hc=setTimeout(function(){for(var c=document.querySelectorAll(Yb),d=0,e=c.length;e>d;d++){var f=c[d],g=_b.rtl?-105:105;if(f.setAttribute("data-index-h",d),n(f,"translateZ(-"+b+"px) translate("+(d-Qb)*g+"%, 0%)"),f.classList.contains("stack"))for(var h=f.querySelectorAll("section"),i=0,j=h.length;j>i;i++){var k=d===Qb?Rb:D(f),l=h[i];l.setAttribute("data-index-h",d),l.setAttribute("data-index-v",i),n(l,"translate(0%, "+105*(i-k)+"%)"),l.addEventListener("click",Mb,!0)}else f.addEventListener("click",Mb,!0)}T(),A(),a||t("overviewshown",{indexh:Qb,indexv:Rb,currentSlide:Tb})},10)}}function F(){_b.overview&&(clearTimeout(hc),clearTimeout(ic),dc.wrapper.classList.remove("overview"),dc.wrapper.classList.add("overview-deactivating"),ic=setTimeout(function(){dc.wrapper.classList.remove("overview-deactivating")},1),l(document.querySelectorAll(Xb)).forEach(function(a){n(a,""),a.removeEventListener("click",Mb,!0)}),O(Qb,Rb),jb(),t("overviewhidden",{indexh:Qb,indexv:Rb,currentSlide:Tb}))}function G(a){"boolean"==typeof a?a?E():F():H()?F():E()}function H(){return dc.wrapper.classList.contains("overview")}function I(a){return a=a?a:Tb,a&&a.parentNode&&!!a.parentNode.nodeName.match(/section/i)}function J(){var a=document.body,b=a.requestFullScreen||a.webkitRequestFullscreen||a.webkitRequestFullScreen||a.mozRequestFullScreen||a.msRequestFullScreen;b&&b.apply(a)}function K(){var a=dc.wrapper.classList.contains("paused");kb(),dc.wrapper.classList.add("paused"),a===!1&&t("paused")}function L(){var a=dc.wrapper.classList.contains("paused");dc.wrapper.classList.remove("paused"),jb(),a&&t("resumed")}function M(){N()?L():K()}function N(){return dc.wrapper.classList.contains("paused")}function O(a,b,c,d){Sb=Tb;var e=document.querySelectorAll(Yb);void 0===b&&(b=D(e[a])),Sb&&Sb.parentNode&&Sb.parentNode.classList.contains("stack")&&C(Sb.parentNode,Rb);var f=bc.concat();bc.length=0;var g=Qb||0,h=Rb||0;Qb=S(Yb,void 0===a?Qb:a),Rb=S(Zb,void 0===b?Rb:b),T(),A();a:for(var i=0,j=bc.length;j>i;i++){for(var k=0;k0&&(a.classList.remove("present"),a.classList.remove("past"),a.classList.add("future"))})})}function R(){var a=l(document.querySelectorAll(Yb));a.forEach(function(a){var b=l(a.querySelectorAll("section"));b.forEach(function(a){fb(a.querySelectorAll(".fragment"))}),0===b.length&&fb(a.querySelectorAll(".fragment"))})}function S(a,b){var c=l(document.querySelectorAll(a)),d=c.length;if(d){_b.loop&&(b%=d,0>b&&(b=d+b)),b=Math.max(Math.min(b,d-1),0);for(var e=0;d>e;e++){var f=c[e],g=_b.rtl&&!I(f);if(f.classList.remove("past"),f.classList.remove("present"),f.classList.remove("future"),f.setAttribute("hidden",""),b>e){f.classList.add(g?"future":"past");for(var h=l(f.querySelectorAll(".fragment"));h.length;){var i=h.pop();i.classList.add("visible"),i.classList.remove("current-fragment")}}else if(e>b){f.classList.add(g?"past":"future");for(var j=l(f.querySelectorAll(".fragment.visible"));j.length;){var k=j.pop();k.classList.remove("visible"),k.classList.remove("current-fragment")}}f.querySelector("section")&&f.classList.add("stack")}c[b].classList.add("present"),c[b].removeAttribute("hidden");var m=c[b].getAttribute("data-state");m&&(bc=bc.concat(m.split(" ")))}else b=0;return b}function T(){var a,b,c=l(document.querySelectorAll(Yb)),d=c.length;if(d){var e=H()?10:_b.viewDistance;Vb&&(e=H()?6:1);for(var f=0;d>f;f++){var g=c[f],h=l(g.querySelectorAll("section")),i=h.length;if(a=Math.abs((Qb-f)%(d-e))||0,g.style.display=a>e?"none":"block",i)for(var j=D(g),k=0;i>k;k++){var m=h[k];b=Math.abs(f===Qb?Rb-k:k-j),m.style.display=a+b>e?"none":"block"}}}}function U(){if(_b.progress&&dc.progress){var a=l(document.querySelectorAll(Yb)),b=document.querySelectorAll(Xb+":not(.stack)").length,c=0;a:for(var d=0;d0&&(a+=" - "+Rb),dc.slideNumber.innerHTML=a}}function W(){var a=Z(),b=$();dc.controlsLeft.concat(dc.controlsRight).concat(dc.controlsUp).concat(dc.controlsDown).concat(dc.controlsPrev).concat(dc.controlsNext).forEach(function(a){a.classList.remove("enabled"),a.classList.remove("fragmented")}),a.left&&dc.controlsLeft.forEach(function(a){a.classList.add("enabled")}),a.right&&dc.controlsRight.forEach(function(a){a.classList.add("enabled")}),a.up&&dc.controlsUp.forEach(function(a){a.classList.add("enabled")}),a.down&&dc.controlsDown.forEach(function(a){a.classList.add("enabled")}),(a.left||a.up)&&dc.controlsPrev.forEach(function(a){a.classList.add("enabled")}),(a.right||a.down)&&dc.controlsNext.forEach(function(a){a.classList.add("enabled")}),Tb&&(b.prev&&dc.controlsPrev.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsNext.forEach(function(a){a.classList.add("fragmented","enabled")}),I(Tb)?(b.prev&&dc.controlsUp.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsDown.forEach(function(a){a.classList.add("fragmented","enabled")})):(b.prev&&dc.controlsLeft.forEach(function(a){a.classList.add("fragmented","enabled")}),b.next&&dc.controlsRight.forEach(function(a){a.classList.add("fragmented","enabled")})))}function X(a){var b=null,c=_b.rtl?"future":"past",d=_b.rtl?"past":"future";if(l(dc.background.childNodes).forEach(function(e,f){Qb>f?e.className="slide-background "+c:f>Qb?e.className="slide-background "+d:(e.className="slide-background present",b=e),(a||f===Qb)&&l(e.childNodes).forEach(function(a,c){Rb>c?a.className="slide-background past":c>Rb?a.className="slide-background future":(a.className="slide-background present",f===Qb&&(b=a))})}),b){var e=Ub?Ub.getAttribute("data-background-hash"):null,f=b.getAttribute("data-background-hash");f&&f===e&&b!==Ub&&dc.background.classList.add("no-transition"),Ub=b}setTimeout(function(){dc.background.classList.remove("no-transition")},1)}function Y(){if(_b.parallaxBackgroundImage){var a,b,c=document.querySelectorAll(Yb),d=document.querySelectorAll(Zb),e=dc.background.style.backgroundSize.split(" ");1===e.length?a=b=parseInt(e[0],10):(a=parseInt(e[0],10),b=parseInt(e[1],10));var f=dc.background.offsetWidth,g=c.length,h=-(a-f)/(g-1)*Qb,i=dc.background.offsetHeight,j=d.length,k=j>0?-(b-i)/(j-1)*Rb:0;dc.background.style.backgroundPosition=h+"px "+k+"px"}}function Z(){var a=document.querySelectorAll(Yb),b=document.querySelectorAll(Zb),c={left:Qb>0||_b.loop,right:Qb0,down:Rb0,next:!!b.length}}return{prev:!1,next:!1}}function _(a){a&&!bb()&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&a.play()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:start","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-autoplay")&&a.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")}))}function ab(a){a&&(l(a.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-ignore")||a.pause()}),l(a.querySelectorAll("iframe")).forEach(function(a){a.contentWindow.postMessage("slide:stop","*")}),l(a.querySelectorAll('iframe[src*="youtube.com/embed/"]')).forEach(function(a){a.hasAttribute("data-ignore")||"function"!=typeof a.contentWindow.postMessage||a.contentWindow.postMessage('{"event":"command","func":"pauseVideo","args":""}',"*")}))}function bb(){return!!window.location.search.match(/receiver/gi)}function cb(){var a=window.location.hash,b=a.slice(2).split("/"),c=a.replace(/#|\//gi,"");if(isNaN(parseInt(b[0],10))&&c.length){var d=document.querySelector("#"+c);if(d){var e=Reveal.getIndices(d);O(e.h,e.v)}else O(Qb||0,Rb||0)}else{var f=parseInt(b[0],10)||0,g=parseInt(b[1],10)||0;(f!==Qb||g!==Rb)&&O(f,g)}}function db(a){if(_b.history)if(clearTimeout(gc),"number"==typeof a)gc=setTimeout(db,a);else{var b="/";Tb&&"string"==typeof Tb.getAttribute("id")?b="/"+Tb.getAttribute("id"):((Qb>0||Rb>0)&&(b+=Qb),Rb>0&&(b+="/"+Rb)),window.location.hash=b}}function eb(a){var b,c=Qb,d=Rb;if(a){var e=I(a),f=e?a.parentNode:a,g=l(document.querySelectorAll(Yb));c=Math.max(g.indexOf(f),0),e&&(d=Math.max(l(a.parentNode.querySelectorAll("section")).indexOf(a),0))}if(!a&&Tb){var h=Tb.querySelectorAll(".fragment").length>0;if(h){var i=Tb.querySelectorAll(".fragment.visible");b=i.length-1}}return{h:c,v:d,f:b}}function fb(a){a=l(a);var b=[],c=[],d=[];a.forEach(function(a){if(a.hasAttribute("data-fragment-index")){var d=parseInt(a.getAttribute("data-fragment-index"),10);b[d]||(b[d]=[]),b[d].push(a)}else c.push([a])}),b=b.concat(c);var e=0;return b.forEach(function(a){a.forEach(function(a){d.push(a),a.setAttribute("data-fragment-index",e)}),e++}),d}function gb(a,b){if(Tb&&_b.fragments){var c=fb(Tb.querySelectorAll(".fragment"));if(c.length){if("number"!=typeof a){var d=fb(Tb.querySelectorAll(".fragment.visible")).pop();a=d?parseInt(d.getAttribute("data-fragment-index")||0,10):-1}"number"==typeof b&&(a+=b);var e=[],f=[];return l(c).forEach(function(b,c){b.hasAttribute("data-fragment-index")&&(c=parseInt(b.getAttribute("data-fragment-index"),10)),a>=c?(b.classList.contains("visible")||e.push(b),b.classList.add("visible"),b.classList.remove("current-fragment"),c===a&&b.classList.add("current-fragment")):(b.classList.contains("visible")&&f.push(b),b.classList.remove("visible"),b.classList.remove("current-fragment"))}),f.length&&t("fragmenthidden",{fragment:f[0],fragments:f}),e.length&&t("fragmentshown",{fragment:e[0],fragments:e}),W(),!(!e.length&&!f.length)}}return!1}function hb(){return gb(null,1)}function ib(){return gb(null,-1)}function jb(){if(kb(),Tb){var a=Tb.parentNode?Tb.parentNode.getAttribute("data-autoslide"):null,b=Tb.getAttribute("data-autoslide");kc=b?parseInt(b,10):a?parseInt(a,10):_b.autoSlide,l(Tb.querySelectorAll("video, audio")).forEach(function(a){a.hasAttribute("data-autoplay")&&kc&&1e3*a.duration>kc&&(kc=1e3*a.duration+1e3)}),!kc||nc||N()||H()||Reveal.isLastSlide()&&_b.loop!==!0||(lc=setTimeout(sb,kc),mc=Date.now()),Wb&&Wb.setPlaying(-1!==lc)}}function kb(){clearTimeout(lc),lc=-1}function lb(){nc=!0,clearTimeout(lc),Wb&&Wb.setPlaying(!1)}function mb(){nc=!1,jb()}function nb(){_b.rtl?(H()||hb()===!1)&&Z().left&&O(Qb+1):(H()||ib()===!1)&&Z().left&&O(Qb-1)}function ob(){_b.rtl?(H()||ib()===!1)&&Z().right&&O(Qb-1):(H()||hb()===!1)&&Z().right&&O(Qb+1)}function pb(){(H()||ib()===!1)&&Z().up&&O(Qb,Rb-1)}function qb(){(H()||hb()===!1)&&Z().down&&O(Qb,Rb+1)}function rb(){if(ib()===!1)if(Z().up)pb();else{var a=document.querySelector(Yb+".past:nth-child("+Qb+")");if(a){var b=a.querySelectorAll("section").length-1||void 0,c=Qb-1;O(c,b)}}}function sb(){hb()===!1&&(Z().down?qb():ob()),jb()}function tb(){_b.autoSlideStoppable&&lb()}function ub(a){tb(a);var b=(document.activeElement,!(!document.activeElement||!document.activeElement.type&&!document.activeElement.href&&"inherit"===document.activeElement.contentEditable));if(!(b||a.shiftKey&&32!==a.keyCode||a.altKey||a.ctrlKey||a.metaKey)){if(N()&&-1===[66,190,191].indexOf(a.keyCode))return!1;var c=!1;if("object"==typeof _b.keyboard)for(var d in _b.keyboard)if(parseInt(d,10)===a.keyCode){var e=_b.keyboard[d];"function"==typeof e?e.apply(null,[a]):"string"==typeof e&&"function"==typeof Reveal[e]&&Reveal[e].call(),c=!0}if(c===!1)switch(c=!0,a.keyCode){case 80:case 33:rb();break;case 78:case 34:sb();break;case 72:case 37:nb();break;case 76:case 39:ob();break;case 75:case 38:pb();break;case 74:case 40:qb();break;case 36:O(0);break;case 35:O(Number.MAX_VALUE);break;case 32:H()?F():a.shiftKey?rb():sb();break;case 13:H()?F():c=!1;break;case 66:case 190:case 191:M();break;case 70:J();break;default:c=!1}c?a.preventDefault():27!==a.keyCode&&79!==a.keyCode||!ec.transforms3d||(dc.preview?z():G(),a.preventDefault()),jb()}}function vb(a){oc.startX=a.touches[0].clientX,oc.startY=a.touches[0].clientY,oc.startCount=a.touches.length,2===a.touches.length&&_b.overview&&(oc.startSpan=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY}))}function wb(a){if(oc.captured)navigator.userAgent.match(/android/gi)&&a.preventDefault();else{tb(a);var b=a.touches[0].clientX,c=a.touches[0].clientY;if(2===a.touches.length&&2===oc.startCount&&_b.overview){var d=m({x:a.touches[1].clientX,y:a.touches[1].clientY},{x:oc.startX,y:oc.startY});Math.abs(oc.startSpan-d)>oc.threshold&&(oc.captured=!0,doc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,nb()):e<-oc.threshold&&Math.abs(e)>Math.abs(f)?(oc.captured=!0,ob()):f>oc.threshold?(oc.captured=!0,pb()):f<-oc.threshold&&(oc.captured=!0,qb()),_b.embedded?(oc.captured||I(Tb))&&a.preventDefault():a.preventDefault()}}}function xb(){oc.captured=!1}function yb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],vb(a))}function zb(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],wb(a))}function Ab(a){a.pointerType===a.MSPOINTER_TYPE_TOUCH&&(a.touches=[{clientX:a.clientX,clientY:a.clientY}],xb(a))}function Bb(a){if(Date.now()-fc>600){fc=Date.now();var b=a.detail||-a.wheelDelta;b>0?sb():rb()}}function Cb(a){tb(a),a.preventDefault();var b=l(document.querySelectorAll(Yb)).length,c=Math.floor(a.clientX/dc.wrapper.offsetWidth*b);O(c)}function Db(a){a.preventDefault(),tb(),nb()}function Eb(a){a.preventDefault(),tb(),ob()}function Fb(a){a.preventDefault(),tb(),pb()}function Gb(a){a.preventDefault(),tb(),qb()}function Hb(a){a.preventDefault(),tb(),rb()}function Ib(a){a.preventDefault(),tb(),sb()}function Jb(){cb()}function Kb(){A()}function Lb(){var a=document.webkitHidden||document.msHidden||document.hidden;a===!1&&document.activeElement!==document.body&&(document.activeElement.blur(),document.body.focus())}function Mb(a){if(jc&&H()){a.preventDefault();for(var b=a.target;b&&!b.nodeName.match(/section/gi);)b=b.parentNode;if(b&&!b.classList.contains("disabled")&&(F(),b.nodeName.match(/section/gi))){var c=parseInt(b.getAttribute("data-index-h"),10),d=parseInt(b.getAttribute("data-index-v"),10);O(c,d)}}}function Nb(a){var b=a.target.getAttribute("href");b&&(y(b),a.preventDefault())}function Ob(){Reveal.isLastSlide()&&_b.loop===!1?(O(0,0),mb()):nc?mb():lb()}function Pb(a,b){this.diameter=50,this.thickness=3,this.playing=!1,this.progress=0,this.progressOffset=1,this.container=a,this.progressCheck=b,this.canvas=document.createElement("canvas"),this.canvas.className="playback",this.canvas.width=this.diameter,this.canvas.height=this.diameter,this.context=this.canvas.getContext("2d"),this.container.appendChild(this.canvas),this.render()}var Qb,Rb,Sb,Tb,Ub,Vb,Wb,Xb=".reveal .slides section",Yb=".reveal .slides>section",Zb=".reveal .slides>section.present>section",$b=".reveal .slides>section:first-of-type",_b={width:960,height:700,margin:.1,minScale:.2,maxScale:1,controls:!0,progress:!0,slideNumber:!1,history:!1,keyboard:!0,overview:!0,center:!0,touch:!0,loop:!1,rtl:!1,fragments:!0,embedded:!1,autoSlide:0,autoSlideStoppable:!0,mouseWheel:!1,rollingLinks:!1,hideAddressBar:!0,previewLinks:!1,focusBodyOnPageVisiblityChange:!0,theme:null,transition:"default",transitionSpeed:"default",backgroundTransition:"default",parallaxBackgroundImage:"",parallaxBackgroundSize:"",viewDistance:3,dependencies:[]},ac=!1,bc=[],cc=1,dc={},ec={},fc=0,gc=0,hc=0,ic=0,jc=!1,kc=0,lc=0,mc=-1,nc=!1,oc={startX:0,startY:0,startSpan:0,startCount:0,captured:!1,threshold:40};return Pb.prototype.setPlaying=function(a){var b=this.playing;this.playing=a,!b&&this.playing?this.animate():this.render()},Pb.prototype.animate=function(){var a=this.progress;this.progress=this.progressCheck(),a>.8&&this.progress<.2&&(this.progressOffset=this.progress),this.render(),this.playing&&ec.requestAnimationFrameMethod.call(window,this.animate.bind(this))},Pb.prototype.render=function(){var a=this.playing?this.progress:0,b=this.diameter/2-this.thickness,c=this.diameter/2,d=this.diameter/2,e=14;this.progressOffset+=.1*(1-this.progressOffset);var f=-Math.PI/2+2*a*Math.PI,g=-Math.PI/2+2*this.progressOffset*Math.PI;this.context.save(),this.context.clearRect(0,0,this.diameter,this.diameter),this.context.beginPath(),this.context.arc(c,d,b+2,0,2*Math.PI,!1),this.context.fillStyle="rgba( 0, 0, 0, 0.4 )",this.context.fill(),this.context.beginPath(),this.context.arc(c,d,b,0,2*Math.PI,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#666",this.context.stroke(),this.playing&&(this.context.beginPath(),this.context.arc(c,d,b,g,f,!1),this.context.lineWidth=this.thickness,this.context.strokeStyle="#fff",this.context.stroke()),this.context.translate(c-e/2,d-e/2),this.playing?(this.context.fillStyle="#fff",this.context.fillRect(0,0,e/2-2,e),this.context.fillRect(e/2+2,0,e/2-2,e)):(this.context.beginPath(),this.context.translate(2,0),this.context.moveTo(0,0),this.context.lineTo(e-2,e/2),this.context.lineTo(0,e),this.context.fillStyle="#fff",this.context.fill()),this.context.restore()},Pb.prototype.on=function(a,b){this.canvas.addEventListener(a,b,!1)},Pb.prototype.off=function(a,b){this.canvas.removeEventListener(a,b,!1)},Pb.prototype.destroy=function(){this.playing=!1,this.canvas.parentNode&&this.container.removeChild(this.canvas)},{initialize:a,configure:h,sync:P,slide:O,left:nb,right:ob,up:pb,down:qb,prev:rb,next:sb,navigateFragment:gb,prevFragment:ib,nextFragment:hb,navigateTo:O,navigateLeft:nb,navigateRight:ob,navigateUp:pb,navigateDown:qb,navigatePrev:rb,navigateNext:sb,layout:A,availableRoutes:Z,availableFragments:$,toggleOverview:G,togglePause:M,isOverview:H,isPaused:N,addEventListeners:i,removeEventListeners:j,getIndices:eb,getSlide:function(a,b){var c=document.querySelectorAll(Yb)[a],d=c&&c.querySelectorAll("section"); 11 | return"undefined"!=typeof b?d?d[b]:void 0:c},getPreviousSlide:function(){return Sb},getCurrentSlide:function(){return Tb},getScale:function(){return cc},getConfig:function(){return _b},getQueryHash:function(){var a={};location.search.replace(/[A-Z0-9]+?=([\w\.%-]*)/gi,function(b){a[b.split("=").shift()]=b.split("=").pop()});for(var b in a){var c=a[b];a[b]=unescape(c),"null"===c?a[b]=null:"true"===c?a[b]=!0:"false"===c?a[b]=!1:c.match(/^\d+$/)&&(a[b]=parseFloat(c))}return a},isFirstSlide:function(){return null==document.querySelector(Xb+".past")?!0:!1},isLastSlide:function(){return Tb?Tb.nextElementSibling?!1:I(Tb)&&Tb.parentNode.nextElementSibling?!1:!0:!1},isReady:function(){return ac},addEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).addEventListener(a,b,c)},removeEventListener:function(a,b,c){"addEventListener"in window&&(dc.wrapper||document.querySelector(".reveal")).removeEventListener(a,b,c)}}}(); --------------------------------------------------------------------------------