├── .gitignore
├── commitlint.config.js
├── .husky
└── commit-msg
├── frontend
├── public
│ ├── robots.txt
│ ├── favicon.ico
│ ├── logo192.png
│ ├── logo512.png
│ ├── manifest.json
│ └── index.html
├── src
│ ├── utils
│ │ └── api.js
│ ├── setupTests.js
│ ├── App.test.js
│ ├── index.css
│ ├── reportWebVitals.js
│ ├── index.js
│ ├── App.js
│ ├── App.css
│ └── logo.svg
├── Dockerfile
├── .gitignore
├── package.json
└── README.md
├── backend
├── Dockerfile
├── database
│ ├── connection.js
│ └── mysql-seeder
│ │ └── languages.sql
├── .eslintrc.json
├── index.js
└── package.json
├── .vscode
└── settings.json
├── .github
└── workflows
│ └── main.yml
├── apresentacao
├── export
│ ├── libs
│ │ ├── reveal.js
│ │ │ └── 4.1.3
│ │ │ │ ├── plugin
│ │ │ │ ├── anything
│ │ │ │ │ ├── d3.patch.js
│ │ │ │ │ ├── d3
│ │ │ │ │ │ ├── queue.v1.min.js
│ │ │ │ │ │ └── topojson.v1.min.js
│ │ │ │ │ └── plugin.js
│ │ │ │ ├── chalkboard
│ │ │ │ │ └── style.css
│ │ │ │ ├── fullscreen
│ │ │ │ │ └── plugin.js
│ │ │ │ ├── math
│ │ │ │ │ └── math.js
│ │ │ │ ├── embed-tweet
│ │ │ │ │ └── plugin.js
│ │ │ │ ├── customcontrols
│ │ │ │ │ └── plugin.js
│ │ │ │ ├── zoom
│ │ │ │ │ └── zoom.js
│ │ │ │ ├── chart
│ │ │ │ │ └── plugin.js
│ │ │ │ └── animate
│ │ │ │ │ └── plugin.js
│ │ │ │ ├── reset.css
│ │ │ │ ├── theme
│ │ │ │ └── night.css
│ │ │ │ └── reveal.css
│ │ ├── highlight.js
│ │ │ └── 11.3.1
│ │ │ │ └── styles
│ │ │ │ └── monokai.min.css
│ │ └── styles
│ │ │ └── tasklist.css
│ └── index.html
└── slides.md
├── docker-compose.yml
├── package.json
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = { extends: ['@commitlint/config-conventional'] };
2 |
--------------------------------------------------------------------------------
/.husky/commit-msg:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | npx --no -- commitlint --edit $1
5 |
--------------------------------------------------------------------------------
/frontend/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/frontend/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Thiago-Mariotto/project-config-base/HEAD/frontend/public/favicon.ico
--------------------------------------------------------------------------------
/frontend/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Thiago-Mariotto/project-config-base/HEAD/frontend/public/logo192.png
--------------------------------------------------------------------------------
/frontend/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Thiago-Mariotto/project-config-base/HEAD/frontend/public/logo512.png
--------------------------------------------------------------------------------
/frontend/src/utils/api.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 |
3 | const api = axios.create({
4 | baseURL: 'http://localhost:3333'
5 |
6 | });
7 |
8 | export default api;
--------------------------------------------------------------------------------
/backend/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14-alpine
2 |
3 | WORKDIR /app/api
4 |
5 | COPY package*.json ./
6 |
7 | RUN npm install
8 |
9 | COPY . .
10 |
11 | EXPOSE 3333
12 |
13 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/frontend/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14-alpine
2 |
3 | WORKDIR /app/web
4 |
5 | COPY package*.json ./
6 |
7 | RUN npm install
8 |
9 | COPY . .
10 |
11 | EXPOSE 3000
12 |
13 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/backend/database/connection.js:
--------------------------------------------------------------------------------
1 | const mysql = require('mysql2/promise');
2 |
3 | const connection = mysql.createPool({
4 | host: 'database',
5 | user: 'root',
6 | password: 'root',
7 | port: '3306',
8 | });
9 |
10 | module.exports = connection;
11 |
--------------------------------------------------------------------------------
/frontend/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/frontend/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/backend/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "commonjs": true,
4 | "es2021": true,
5 | "node": true
6 | },
7 | "extends": [
8 | "airbnb-base"
9 | ],
10 | "parserOptions": {
11 | "ecmaVersion": "latest"
12 | },
13 | "rules": {}
14 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnPaste": true,
3 | "editor.formatOnSave": true,
4 | "editor.formatOnSaveMode": "file",
5 | "editor.formatOnType": true,
6 | "editor.tabSize": 2,
7 | "editor.codeActionsOnSave": {
8 | "source.fixAll": true,
9 | "source.organizeImports": true
10 | // ...
11 | }
12 | }
--------------------------------------------------------------------------------
/frontend/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/frontend/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/frontend/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/backend/database/mysql-seeder/languages.sql:
--------------------------------------------------------------------------------
1 | CREATE DATABASE IF NOT EXISTS technology DEFAULT CHARACTER SET = 'utf8';
2 | USE technology;
3 | CREATE TABLE IF NOT EXISTS `language` (name VARCHAR(25), creator VARCHAR(25));
4 | INSERT INTO
5 | `language` (name, creator)
6 | VALUES
7 | ('Java', 'James Gosling'),
8 | ('Javascript', 'Brendan Eich'),
9 | ('PHP', 'Rasmus Lerdorf'),
10 | ('Python', 'Guido van Rossum'),
11 | ('C#', 'Anders Hejlsberg')
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | on:
2 | pull_request:
3 | types: [opened, synchronize]
4 |
5 | jobs:
6 | eslint:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v2
10 |
11 | - uses: actions/setup-node@v2
12 | with:
13 | node-version: 14
14 |
15 | - name: Install back-end modules
16 | run: npm i --prefix backend
17 |
18 | - name: Run linter on back-end
19 | run: npm run lint --prefix backend
20 |
--------------------------------------------------------------------------------
/frontend/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/backend/index.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const cors = require('cors');
3 | const connection = require('./database/connection');
4 |
5 | const app = express();
6 | const PORT = process.env.PORT || 3333;
7 |
8 | app.use(cors());
9 |
10 | app.get('/', async (_req, res) => {
11 | try {
12 | const [instructors] = await connection.execute(
13 | 'SELECT * FROM technology.language',
14 | );
15 |
16 | // HI
17 |
18 | return res.status(200).json(instructors);
19 | } catch (e) {
20 | return res.status(500).send(e);
21 | }
22 | });
23 |
24 | app.listen(PORT);
25 |
--------------------------------------------------------------------------------
/frontend/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/anything/d3.patch.js:
--------------------------------------------------------------------------------
1 | (function(d3) {
2 | document.scaleX = 1;
3 | document.scaleY = 1;
4 | function d3_eventSource() {
5 | var e = d3.event, s;
6 | while (s = e.sourceEvent) e = s;
7 | return e;
8 | }
9 |
10 | d3.mouse = function(container) {
11 | return d3_mousePoint(container, d3_eventSource());
12 | };
13 |
14 | function d3_mousePoint(container, e) {
15 | var rect = container.getBoundingClientRect();
16 | return [ (e.clientX - rect.left - container.clientLeft)/document.scaleX, (e.clientY - rect.top - container.clientTop)/document.scaleY];
17 | };
18 | })(d3);
19 |
20 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.1'
2 |
3 | services:
4 | # containers
5 | database:
6 | image: mysql:5.7
7 | container_name: mysql_compose
8 | ports:
9 | - 3306:3306
10 | environment:
11 | - MYSQL_ROOT_PASSWORD=root
12 | volumes:
13 | - ./backend/database/mysql-seeder:/docker-entrypoint-initdb.d
14 |
15 | api:
16 | build: ./backend
17 | container_name: backend_compose
18 | ports:
19 | - 3333:3333
20 | depends_on:
21 | - database
22 |
23 | web:
24 | build: ./frontend
25 | container_name: frontend_compose
26 | ports:
27 | - 3000:3000
28 | depends_on:
29 | - api
30 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "project-config",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "prepare": "husky install",
9 | "commit": "cz"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "@commitlint/cli": "^16.2.3",
16 | "@commitlint/config-conventional": "^16.2.1",
17 | "commitizen": "^4.2.4",
18 | "cz-conventional-changelog": "^3.3.0",
19 | "husky": "^7.0.4"
20 | },
21 | "config": {
22 | "commitizen": {
23 | "path": "./node_modules/cz-conventional-changelog"
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/frontend/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react';
2 | import './App.css';
3 | import api from './utils/api';
4 |
5 | function App() {
6 |
7 | const [instructors, setInstructors] = useState([]);
8 |
9 | useEffect(() => {
10 | api.get('/').then(response => { setInstructors(response.data) });
11 | }, []);
12 |
13 |
14 | return (
15 |
16 |
17 |
Proggraming Languages
18 | {
19 | instructors.map(p => (
20 |
{p.name} - {p.creator}
21 | ))}
22 |
23 |
24 | );
25 | }
26 |
27 | export default App;
28 |
--------------------------------------------------------------------------------
/backend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backend",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "lint": "eslint --no-inline-config --no-error-on-unmatched-pattern -c .eslintrc.json .",
9 | "start": "node index.js"
10 | },
11 | "keywords": [],
12 | "author": "",
13 | "license": "ISC",
14 | "devDependencies": {
15 | "eslint": "^8.12.0",
16 | "eslint-config-airbnb-base": "^15.0.0",
17 | "eslint-plugin-import": "^2.26.0"
18 | },
19 | "dependencies": {
20 | "cors": "^2.8.5",
21 | "express": "^4.17.3",
22 | "mysql2": "^2.3.3"
23 | }
24 | }
--------------------------------------------------------------------------------
/frontend/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/highlight.js/11.3.1/styles/monokai.min.css:
--------------------------------------------------------------------------------
1 | pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#272822;color:#ddd}.hljs-keyword,.hljs-literal,.hljs-name,.hljs-selector-tag,.hljs-strong,.hljs-tag{color:#f92672}.hljs-code{color:#66d9ef}.hljs-attribute,.hljs-link,.hljs-regexp,.hljs-symbol{color:#bf79db}.hljs-addition,.hljs-built_in,.hljs-bullet,.hljs-emphasis,.hljs-section,.hljs-selector-attr,.hljs-selector-pseudo,.hljs-string,.hljs-subst,.hljs-template-tag,.hljs-template-variable,.hljs-title,.hljs-type,.hljs-variable{color:#a6e22e}.hljs-class .hljs-title,.hljs-title.class_{color:#fff}.hljs-comment,.hljs-deletion,.hljs-meta,.hljs-quote{color:#75715e}.hljs-doctag,.hljs-keyword,.hljs-literal,.hljs-section,.hljs-selector-id,.hljs-selector-tag,.hljs-title,.hljs-type{font-weight:700}
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/chalkboard/style.css:
--------------------------------------------------------------------------------
1 | div.palette, div.boardhandle {
2 | position: absolute;
3 | /*
4 | height: 260px;
5 | margin: -130px 0 0 0px;
6 | */
7 | top: 50%;
8 | transform: translateY(-50%);
9 | font-size: 24px;
10 | border-radius: 10px;
11 | border-top: 4px solid #222;
12 | border-right: 4px solid #222;
13 | border-bottom: 4px solid #222;
14 | background: black;
15 | transition: transform 0.3s;
16 | }
17 |
18 | div.palette {
19 | left: -10px;
20 | padding-left:10px;
21 | }
22 |
23 | div.boardhandle {
24 | right: -10px;
25 | padding-right:10px;
26 | }
27 |
28 | div.palette > ul,
29 | div.boardhandle > ul {
30 | list-style-type: none;
31 | margin: 0;
32 | padding: 0;
33 | }
34 |
35 | div.palette > ul > li,
36 | div.boardhandle > ul > li {
37 | margin: 10px;
38 | }
39 |
40 | @media print {
41 | div.palette, div.boardhandle, .chalkboard-button {
42 | display: none!important;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/frontend/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "frontend",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.4",
7 | "@testing-library/react": "^12.1.4",
8 | "@testing-library/user-event": "^13.5.0",
9 | "axios": "^0.26.1",
10 | "react": "^18.0.0",
11 | "react-dom": "^18.0.0",
12 | "react-scripts": "5.0.0",
13 | "web-vitals": "^2.1.4"
14 | },
15 | "scripts": {
16 | "start": "react-scripts start",
17 | "build": "react-scripts build",
18 | "test": "react-scripts test",
19 | "eject": "react-scripts eject"
20 | },
21 | "eslintConfig": {
22 | "extends": [
23 | "react-app",
24 | "react-app/jest"
25 | ]
26 | },
27 | "browserslist": {
28 | "production": [
29 | ">0.2%",
30 | "not dead",
31 | "not op_mini all"
32 | ],
33 | "development": [
34 | "last 1 chrome version",
35 | "last 1 firefox version",
36 | "last 1 safari version"
37 | ]
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/reset.css:
--------------------------------------------------------------------------------
1 | /* http://meyerweb.com/eric/tools/css/reset/
2 | v4.0 | 20180602
3 | License: none (public domain)
4 | */
5 |
6 | html, body, div, span, applet, object, iframe,
7 | h1, h2, h3, h4, h5, h6, p, blockquote, pre,
8 | a, abbr, acronym, address, big, cite, code,
9 | del, dfn, em, img, ins, kbd, q, s, samp,
10 | small, strike, strong, sub, sup, tt, var,
11 | b, u, i, center,
12 | dl, dt, dd, ol, ul, li,
13 | fieldset, form, label, legend,
14 | table, caption, tbody, tfoot, thead, tr, th, td,
15 | article, aside, canvas, details, embed,
16 | figure, figcaption, footer, header, hgroup,
17 | main, menu, nav, output, ruby, section, summary,
18 | time, mark, audio, video {
19 | margin: 0;
20 | padding: 0;
21 | border: 0;
22 | font-size: 100%;
23 | font: inherit;
24 | vertical-align: baseline;
25 | }
26 | /* HTML5 display-role reset for older browsers */
27 | article, aside, details, figcaption, figure,
28 | footer, header, hgroup, main, menu, nav, section {
29 | display: block;
30 | }
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/anything/d3/queue.v1.min.js:
--------------------------------------------------------------------------------
1 | !function(n,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define("queue",r):n.queue=r()}(this,function(){"use strict";function n(){}function r(r){function t(){if(!h)try{l()}catch(n){s[v+y-1]&&i(n)}}function l(){for(;h=d&&r>y;){var n=v+y,t=s[n],u=t.length-1,o=t[u];t[u]=f(n),--d,++y,t=o.apply(null,t),s[n]&&(s[n]=t||e)}}function f(n){return function(r,u){s[n]&&(--y,++v,s[n]=null,null==p&&(null!=r?i(r):(w[n]=u,d?t():y||c())))}}function i(n){var r,t=s.length;for(p=n,w=null,d=NaN;--t>=0;)if((r=s[t])&&(s[t]=null,r.abort))try{r.abort()}catch(n){}y=NaN,c()}function c(){null!=p?b(p):g?b(null,w):b.apply(null,o.concat(w))}if(!(r>=1))throw new Error;var a,h,p,s=[],w=[],d=0,y=0,v=0,b=n,g=!0;return a={defer:function(r){if(b!==n)throw new Error;if(null!=p)return a;var e=u.call(arguments,1);return e.push(r),++d,s.push(e),t(),a},abort:function(){return null==p&&i(new Error("abort")),a},await:function(r){if(b!==n)throw new Error;return b=r,g=!1,y||c(),a},awaitAll:function(r){if(b!==n)throw new Error;return b=r,g=!0,y||c(),a}}}function t(n){return r(arguments.length?+n:1/0)}var u=[].slice,e={},o=[null];return t.version="1.2.1",t});
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/fullscreen/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | **
4 | ** A plugin allowing slides to use the full window size.
5 | **
6 | ** Version: 1.0.0
7 | **
8 | ** License: MIT license (see LICENSE.md)
9 | **
10 | ******************************************************************/
11 |
12 | window.RevealFullscreen = window.RevealFullscreen || {
13 | id: 'RevealFullscreen',
14 | init: function(deck) {
15 | initFullscreen(deck);
16 | }
17 | };
18 |
19 | const initFullscreen = function(Reveal){
20 | var config = null;
21 | var ready = false;
22 |
23 | Reveal.addEventListener( 'ready', function( event ) {
24 | ready = true;
25 | config = { width: Reveal.getConfig().width, height: Reveal.getConfig().height, margin: Reveal.getConfig().margin };
26 | if ( Reveal.getCurrentSlide().hasAttribute("data-fullscreen") ) {
27 | Reveal.configure( { width: window.innerWidth, height: window.innerHeight, margin: 0 } );
28 | }
29 | } );
30 |
31 | Reveal.addEventListener( 'slidechanged', function( event ) {
32 | if ( Reveal.getCurrentSlide().hasAttribute("data-fullscreen") ) {
33 | Reveal.configure( { width: window.innerWidth, height: window.innerHeight, margin: 0 } );
34 | }
35 | else {
36 | Reveal.configure( config );
37 | }
38 | } );
39 |
40 | window.addEventListener( 'resize', function( event ) {
41 | if ( ready && Reveal.getCurrentSlide().hasAttribute("data-fullscreen") ) {
42 | Reveal.configure( { width: window.innerWidth, height: window.innerHeight, margin: 0 } );
43 | }
44 | } );
45 |
46 | };
47 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/math/math.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealMath=t()}(this,(function(){"use strict";function e(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function t(t){for(var r=1;r
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/embed-tweet/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | **
4 | ** A plugin for embedding tweets.
5 | **
6 | ** Version: 1.0.0
7 | **
8 | ** License: MIT license (see LICENSE.md)
9 | **
10 | ******************************************************************/
11 |
12 | window.RevealEmbedTweet = window.RevealEmbedTweet || {
13 | id: 'RevealEmbedTweet',
14 | init: function(deck) {
15 | initEmbedTweet(deck);
16 | }
17 | };
18 |
19 | const initEmbedTweet = function(Reveal){
20 | var ready = false;
21 | window.twttr = (function(d, s, id) {
22 | var js, fjs = d.getElementsByTagName(s)[0],
23 | t = window.twttr || {};
24 | if (d.getElementById(id)) return t;
25 | js = d.createElement(s);
26 | js.id = id;
27 | js.src = "https://platform.twitter.com/widgets.js";
28 | fjs.parentNode.insertBefore(js, fjs);
29 |
30 | t._e = [];
31 | t.ready = function(f) {
32 | t._e.push(f);
33 | };
34 | }(document, "script", "twitter-wjs"));
35 |
36 |
37 | function load() {
38 | if ( twttr != undefined && !document.querySelector('section[data-markdown]:not([data-markdown-parsed])') ) {
39 | tweets = document.querySelectorAll(".tweet");
40 | for (i = 0; i < tweets.length; ++i) {
41 | tweets[i].style.cssText = "margin: 0;position: absolute; left: 50%;transform: translate(-50%,0%);" + tweets[i].style.cssText;
42 | tweets[i].innerHTML = '';
43 | }
44 | twttr.widgets.load()
45 | }
46 | else {
47 | // wait for markdown to be loaded and parsed
48 | setTimeout( load, 100 );
49 | }
50 | }
51 |
52 | Reveal.addEventListener( 'ready', function( event ) {
53 | load();
54 | } );
55 |
56 | this.refresh = load;
57 |
58 | return this;
59 | };
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/styles/tasklist.css:
--------------------------------------------------------------------------------
1 | [class*=task-list-item] {
2 | min-height: 22px;
3 | margin-top: 6px!important;
4 | margin-bottom: 6px!important;
5 | padding-left: 0;
6 | list-style: none;
7 | }
8 |
9 | [class*=task-list-item]>input:first-child {
10 | position: absolute!important;
11 | opacity: 0;
12 | margin: 0;
13 | }
14 | [class*=task-list-item]>label {
15 | padding-left: 29px!important;
16 | min-height: 22px;
17 | line-height: 22px;
18 | display: inline-block;
19 | position: relative;
20 | vertical-align: top;
21 | margin-bottom: 0;
22 | font-weight: 400;
23 | cursor: pointer;
24 | }
25 |
26 | .task-list-item>input:first-child:checked+input[type=hidden]+label::before, .task-list-item>input:first-child:checked+label::before {
27 | background-color: #ecf0f1;
28 | border-color: #ecf0f1;
29 | }
30 |
31 | [class*=task-list-item]>input:first-child+input[type=hidden]+label::before, [class*=task-list-item]>input:first-child+label::before {
32 | content: "";
33 | display: inline-block;
34 | position: absolute;
35 | width: 22px;
36 | height: 22px;
37 | border: 1px solid #D3CFC8;
38 | border-radius: 0;
39 | margin-left: -29px;
40 | }
41 |
42 |
43 | [class*=task-list-item]>input:first-child:checked+input[type=hidden]+label::after, [class*=task-list-item]>input:first-child:checked+label::after {
44 | content: "";
45 | display: inline-block;
46 | position: absolute;
47 | top: 0;
48 | left: 0;
49 | width: 7px;
50 | height: 10px;
51 | border: 2px solid #fff;
52 | border-left: none;
53 | border-top: none;
54 | transform: translate(7.75px,4.5px) rotate(45deg);
55 | -ms-transform: translate(7.75px,4.5px) rotate(45deg);
56 | }
57 |
58 |
59 | .task-list-item>input:first-child:checked+input[type=hidden]+label::after, .task-list-item>input:first-child:checked+label::after {
60 | border-bottom-color: #95a5a6;
61 | border-right-color: #95a5a6;
62 | }
63 |
64 |
65 |
66 | .reveal .container{
67 | display: grid;
68 | grid-auto-flow: column;
69 | }
70 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Configurações iniciais de um projeto
2 |
3 | ## Boas vindas
4 |
5 | Este é um exemplo de como utilizar o [Docker Compose](https://docs.docker.com/compose/install/) para iniciar três aplicações containerizadas, sendo elas:
6 | 1. [MySQL](https://www.mysql.com/)
7 | 2. [API com Node.js](https://nodejs.org/en/)
8 | 3. [SPA com React.js](https://reactjs.org/)
9 |
10 | ### Pré requisitos
11 |
12 | Você precisa das seguintes ferramentas instaladas
13 |
14 | - [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
15 | - [Docker](https://docs.docker.com/engine/install/ubuntu/)
16 | - [Docker Compose](https://docs.docker.com/compose/install/)
17 |
18 | ### Instalação
19 |
20 | Siga este passo a passo para testar este repositório.
21 |
22 | Clone o repositório para sua máquina local
23 |
24 | ```
25 | $ git clone git@github.com:Thiago-Mariotto/docker-compose-example.git
26 | ```
27 |
28 | Acesse a pasta
29 |
30 | ```
31 | $ cd docker-compose-example
32 | ```
33 |
34 | Inicie a aplicação com o Docker Compose
35 |
36 | ```
37 | $ docker-compose up --build
38 | ```
39 | O comando acima realiza o build do arquivo `docker-compose.yml` construindo todas as imagens necessárias e inicializa todos os containers configurados.
40 |
41 | ## Como utilizar?
42 |
43 | 1. Cetifique-se de seguir todos os passos de instação.
44 | 2. Verifique se todos os containers foram iniciados.
45 |
46 | ```sh
47 | $ docker ps
48 | ```
49 |
50 | O retorno deve conter 3 containers ativos `frontend` | `backend` | `mysql`.
51 |
52 | ### Acessando o frontend
53 |
54 | A página do frontend deve ser renderizado no endereço `http://localhost:3000`, sua página inicial renderiza os dados retornados da api.
55 |
56 | ### Acessando o backend
57 |
58 | A API estará sendo executada na porta 3333, é possível verificar o acesso em uma rota GET `http://localhost:3333` o retorno é um Array de pessoas instrutoras e suas frases.
59 |
60 | ### Acessando o banco de dados
61 |
62 | O banco de dados é populado com um script que está localizado na pasta `backend/mysql-dump` quando o container é inicializado.
63 |
64 | É possível acessa-lo pela porta `3306` do seu `localhost` ou `127.0.0.1` a senha de acesso é `docker`.
65 |
66 | ### Realizando pull request
67 |
68 | Certifique-se de executar `npm run lint` na pasta do backend, existe uma action de validação.
69 |
70 |
71 | ## Aproveite :)
72 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/customcontrols/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | **
4 | ** A plugin replacing the default controls by custom controls.
5 | **
6 | ** Version: 2.0.0
7 | **
8 | ** License: MIT license (see LICENSE.md)
9 | **
10 | ******************************************************************/
11 | window.RevealCustomControls = window.RevealCustomControls || {
12 | id: 'RevealCustomControls',
13 | init: function(deck) {
14 | initCustomControls(deck);
15 | }
16 | };
17 |
18 | const initCustomControls = function(Reveal){
19 | var config = Reveal.getConfig().customcontrols || {};
20 |
21 | var collapseIcon = config.collapseIcon || ' ';
22 | var expandIcon = config.expandIcon || ' ';
23 | var tooltip = config.tooltip || 'Show/hide controls';
24 |
25 | var div = document.createElement( 'div' );
26 | div.id = 'customcontrols';
27 |
28 | var toggleButton = document.createElement( 'button' );
29 | toggleButton.title = tooltip;
30 | toggleButton.innerHTML = '' + collapseIcon + ' ' + '' + expandIcon + ' ';
31 |
32 | toggleButton.addEventListener('click', function( event ) {
33 | var div = document.querySelector("div#customcontrols");
34 | if ( div.classList.contains('collapsed') ) {
35 | div.classList.remove('collapsed');
36 | }
37 | else {
38 | div.classList.add('collapsed');
39 | }
40 | });
41 |
42 | div.appendChild(toggleButton);
43 |
44 | var controls = document.createElement( 'ul' );
45 | for (var i = 0; i < config.controls.length; i++ ) {
46 | var control = document.createElement( 'li' );
47 | if ( config.controls[i].id ) {
48 | control.id = config.controls[i].id;
49 | }
50 | control.innerHTML = '' + config.controls[i].icon + ' ';
51 | controls.appendChild( control );
52 | }
53 | div.appendChild( controls );
54 |
55 |
56 | document.querySelector(".reveal").appendChild( div );
57 |
58 | document.addEventListener( 'resize', function( event ) {
59 | // expand controls to make sure they are visible
60 | var div = document.querySelector("div#customcontrols.collapsed");
61 | if ( div ) {
62 | div.classList.remove('collapsed');
63 | }
64 | } );
65 |
66 | return this;
67 |
68 | };
69 |
70 |
--------------------------------------------------------------------------------
/frontend/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/anything/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | **
4 | ** A plugin for reveal.js allowing to easily integrate any content
5 | **
6 | ** Version: 1.0.1
7 | **
8 | ** License: MIT license (see LICENSE.md)
9 | **
10 | ******************************************************************/
11 |
12 | window.RevealAnything = window.RevealAnything || {
13 | id: 'RevealAnything',
14 | init: function(deck) {
15 | if ( Reveal.getConfig().anything ) initAnything(deck);
16 | }
17 | };
18 |
19 | const initAnything = function(Reveal){
20 | function parseJSON(str) {
21 | str = str.replace(/(\r\n|\n|\r|\t)/gm,""); // remove line breaks and tabs
22 | var json;
23 | try {
24 | json = JSON.parse(str, function (key, value) {
25 | if (value && (typeof value === 'string') && value.indexOf("function") === 0) {
26 | // we can only pass a function as string in JSON ==> doing a real function
27 | // eval("var jsFunc = " + value);
28 | var jsFunc = new Function('return ' + value)();
29 | return jsFunc;
30 | }
31 | return value;
32 | });
33 | } catch (e) {
34 | return null;
35 | }
36 | return json;
37 | }
38 |
39 | /*
40 | * Recursively merge properties of two objects without overwriting the first
41 | */
42 | function mergeRecursive(obj1, obj2) {
43 |
44 | for (var p in obj2) {
45 | try {
46 | // Property in destination object set; update its value.
47 | if ( obj1[p] !== null && typeof obj1[p] === 'object' && typeof obj2[p] === 'object' ) {
48 | obj1[p] = mergeRecursive(obj1[p], obj2[p]);
49 | }
50 | else {
51 | obj1[p] = obj2[p];
52 | }
53 | } catch(e) {
54 | // Property in destination object not set; create it and set its value.
55 | obj1[p] = obj2[p];
56 | }
57 | }
58 |
59 | return obj1;
60 | }
61 |
62 |
63 | var config = Reveal.getConfig().anything;
64 |
65 | Reveal.addEventListener( 'ready', function( event ) {
66 | for (var i = 0; i < config.length; i++ ){
67 | // Get all elements of the class
68 | var elements = document.getElementsByClassName(config[i].className);
69 | var initialize = config[i].initialize;
70 | // deprecated parameters
71 | if ( !initialize && config[i].f ) {
72 | initialize = config[i].f;
73 | console.warn('Setting parameter "f" is deprecated! Use "initialize" instead. ');
74 | }
75 |
76 | for (var j = 0; j < elements.length; j++ ){
77 | var options = config[i].defaults;
78 | var comments = elements[j].innerHTML.trim().match(//g);
79 | if ( comments !== null ) for (var k = 0; k < comments.length; k++ ){
80 | comments[k] = comments[k].replace(//,'');
82 | mergeRecursive( options, config[i].defaults);
83 | options = parseJSON(comments[k]);
84 | if ( options ) {
85 | mergeRecursive( options, config[i].defaults);
86 | break;
87 | }
88 | }
89 | // console.log(config[i].className + " options: " + JSON.stringify(options))
90 | initialize(elements[j], options);
91 | // console.log(elements[j].outerHTML)
92 | }
93 | }
94 | } );
95 |
96 |
97 | };
98 |
99 |
100 |
--------------------------------------------------------------------------------
/frontend/README.md:
--------------------------------------------------------------------------------
1 | # Getting Started with Create React App
2 |
3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
4 |
5 | ## Available Scripts
6 |
7 | In the project directory, you can run:
8 |
9 | ### `npm start`
10 |
11 | Runs the app in the development mode.\
12 | Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
13 |
14 | The page will reload when you make changes.\
15 | You may also see any lint errors in the console.
16 |
17 | ### `npm test`
18 |
19 | Launches the test runner in the interactive watch mode.\
20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
21 |
22 | ### `npm run build`
23 |
24 | Builds the app for production to the `build` folder.\
25 | It correctly bundles React in production mode and optimizes the build for the best performance.
26 |
27 | The build is minified and the filenames include the hashes.\
28 | Your app is ready to be deployed!
29 |
30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
31 |
32 | ### `npm run eject`
33 |
34 | **Note: this is a one-way operation. Once you `eject`, you can't go back!**
35 |
36 | If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
37 |
38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
39 |
40 | You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
41 |
42 | ## Learn More
43 |
44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
45 |
46 | To learn React, check out the [React documentation](https://reactjs.org/).
47 |
48 | ### Code Splitting
49 |
50 | This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
51 |
52 | ### Analyzing the Bundle Size
53 |
54 | This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
55 |
56 | ### Making a Progressive Web App
57 |
58 | This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
59 |
60 | ### Advanced Configuration
61 |
62 | This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
63 |
64 | ### Deployment
65 |
66 | This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
67 |
68 | ### `npm run build` fails to minify
69 |
70 | This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
71 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/zoom/zoom.js:
--------------------------------------------------------------------------------
1 | !function(e,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(e="undefined"!=typeof globalThis?globalThis:e||self).RevealZoom=o()}(this,(function(){"use strict";
2 | /*!
3 | * reveal.js Zoom plugin
4 | */var e={id:"zoom",init:function(e){e.getRevealElement().addEventListener("mousedown",(function(t){var n=/Linux/.test(window.navigator.platform)?"ctrl":"alt",i=(e.getConfig().zoomKey?e.getConfig().zoomKey:n)+"Key",d=e.getConfig().zoomLevel?e.getConfig().zoomLevel:2;t[i]&&!e.isOverview()&&(t.preventDefault(),o.to({x:t.clientX,y:t.clientY,scale:d,pan:!1}))}))}},o=function(){var e=1,t=0,n=0,i=-1,d=-1,s="WebkitTransform"in document.body.style||"MozTransform"in document.body.style||"msTransform"in document.body.style||"OTransform"in document.body.style||"transform"in document.body.style;function r(o,t){var n=l();if(o.width=o.width||1,o.height=o.height||1,o.x-=(window.innerWidth-o.width*t)/2,o.y-=(window.innerHeight-o.height*t)/2,s)if(1===t)document.body.style.transform="",document.body.style.OTransform="",document.body.style.msTransform="",document.body.style.MozTransform="",document.body.style.WebkitTransform="";else{var i=n.x+"px "+n.y+"px",d="translate("+-o.x+"px,"+-o.y+"px) scale("+t+")";document.body.style.transformOrigin=i,document.body.style.OTransformOrigin=i,document.body.style.msTransformOrigin=i,document.body.style.MozTransformOrigin=i,document.body.style.WebkitTransformOrigin=i,document.body.style.transform=d,document.body.style.OTransform=d,document.body.style.msTransform=d,document.body.style.MozTransform=d,document.body.style.WebkitTransform=d}else 1===t?(document.body.style.position="",document.body.style.left="",document.body.style.top="",document.body.style.width="",document.body.style.height="",document.body.style.zoom=""):(document.body.style.position="relative",document.body.style.left=-(n.x+o.x)/t+"px",document.body.style.top=-(n.y+o.y)/t+"px",document.body.style.width=100*t+"%",document.body.style.height=100*t+"%",document.body.style.zoom=t);e=t,document.documentElement.classList&&(1!==e?document.documentElement.classList.add("zoomed"):document.documentElement.classList.remove("zoomed"))}function m(){var o=.12*window.innerWidth,i=.12*window.innerHeight,d=l();nwindow.innerHeight-i&&window.scroll(d.x,d.y+(1-(window.innerHeight-n)/i)*(14/e)),twindow.innerWidth-o&&window.scroll(d.x+(1-(window.innerWidth-t)/o)*(14/e),d.y)}function l(){return{x:void 0!==window.scrollX?window.scrollX:window.pageXOffset,y:void 0!==window.scrollY?window.scrollY:window.pageYOffset}}return s&&(document.body.style.transition="transform 0.8s ease",document.body.style.OTransition="-o-transform 0.8s ease",document.body.style.msTransition="-ms-transform 0.8s ease",document.body.style.MozTransition="-moz-transform 0.8s ease",document.body.style.WebkitTransition="-webkit-transform 0.8s ease"),document.addEventListener("keyup",(function(t){1!==e&&27===t.keyCode&&o.out()})),document.addEventListener("mousemove",(function(o){1!==e&&(t=o.clientX,n=o.clientY)})),{to:function(t){if(1!==e)o.out();else{if(t.x=t.x||0,t.y=t.y||0,t.element){var n=t.element.getBoundingClientRect();t.x=n.left-20,t.y=n.top-20,t.width=n.width+40,t.height=n.height+40}void 0!==t.width&&void 0!==t.height&&(t.scale=Math.max(Math.min(window.innerWidth/t.width,window.innerHeight/t.height),1)),t.scale>1&&(t.x*=t.scale,t.y*=t.scale,r(t,t.scale),!1!==t.pan&&(i=setTimeout((function(){d=setInterval(m,1e3/60)}),800)))}},out:function(){clearTimeout(i),clearInterval(d),r({x:0,y:0},1),e=1},magnify:function(e){this.to(e)},reset:function(){this.out()},zoomLevel:function(){return e}}}();return function(){return e}}));
5 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/anything/d3/topojson.v1.min.js:
--------------------------------------------------------------------------------
1 | !function(){function n(n,t){function r(t){var r,e=n.arcs[0>t?~t:t],o=e[0];return n.transform?(r=[0,0],e.forEach(function(n){r[0]+=n[0],r[1]+=n[1]})):r=e[e.length-1],0>t?[r,o]:[o,r]}function e(n,t){for(var r in n){var e=n[r];delete t[e.start],delete e.start,delete e.end,e.forEach(function(n){o[0>n?~n:n]=1}),f.push(e)}}var o={},i={},u={},f=[],c=-1;return t.forEach(function(r,e){var o,i=n.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++c],t[c]=r,t[e]=o)}),t.forEach(function(n){var t,e,o=r(n),f=o[0],c=o[1];if(t=u[f])if(delete u[t.end],t.push(n),t.end=c,e=i[c]){delete i[e.start];var a=e===t?t:t.concat(e);i[a.start=t.start]=u[a.end=e.end]=a}else i[t.start]=u[t.end]=t;else if(t=i[c])if(delete i[t.start],t.unshift(n),t.start=f,e=u[f]){delete u[e.end];var s=e===t?t:e.concat(t);i[s.start=e.start]=u[s.end=t.end]=s}else i[t.start]=u[t.end]=t;else t=[n],i[t.start=f]=u[t.end=c]=t}),e(u,i),e(i,u),t.forEach(function(n){o[0>n?~n:n]||f.push([n])}),f}function t(t,r,e){function o(n){var t=0>n?~n:n;(s[t]||(s[t]=[])).push({i:n,g:a})}function i(n){n.forEach(o)}function u(n){n.forEach(i)}function f(n){"GeometryCollection"===n.type?n.geometries.forEach(f):n.type in l&&(a=n,l[n.type](n.arcs))}var c=[];if(arguments.length>1){var a,s=[],l={LineString:i,MultiLineString:u,Polygon:u,MultiPolygon:function(n){n.forEach(u)}};f(r),s.forEach(arguments.length<3?function(n){c.push(n[0].i)}:function(n){e(n[0].g,n[n.length-1].g)&&c.push(n[0].i)})}else for(var h=0,p=t.arcs.length;p>h;++h)c.push(h);return{type:"MultiLineString",arcs:n(t,c)}}function r(t,r){function e(n){n.forEach(function(t){t.forEach(function(t){(u[t=0>t?~t:t]||(u[t]=[])).push(n)})}),f.push(n)}function o(n){return s(i(t,{type:"Polygon",arcs:[n]}).coordinates[0])>0}var u={},f=[],c=[];return r.forEach(function(n){"Polygon"===n.type?e(n.arcs):"MultiPolygon"===n.type&&n.arcs.forEach(e)}),f.forEach(function(n){if(!n._){var t=[],r=[n];for(n._=1,c.push(t);n=r.pop();)t.push(n),n.forEach(function(n){n.forEach(function(n){u[0>n?~n:n].forEach(function(n){n._||(n._=1,r.push(n))})})})}}),f.forEach(function(n){delete n._}),{type:"MultiPolygon",arcs:c.map(function(r){var e,i=[];if(r.forEach(function(n){n.forEach(function(n){n.forEach(function(n){u[0>n?~n:n].length<2&&i.push(n)})})}),i=n(t,i),(e=i.length)>1)for(var f,c=o(r[0][0]),a=0;e>a;++a)if(c===o(i[a])){f=i[0],i[0]=i[a],i[a]=f;break}return i})}}function e(n,t){return"GeometryCollection"===t.type?{type:"FeatureCollection",features:t.geometries.map(function(t){return o(n,t)})}:o(n,t)}function o(n,t){var r={type:"Feature",id:t.id,properties:t.properties||{},geometry:i(n,t)};return null==t.id&&delete r.id,r}function i(n,t){function r(n,t){t.length&&t.pop();for(var r,e=s[0>n?~n:n],o=0,i=e.length;i>o;++o)t.push(r=e[o].slice()),a(r,o);0>n&&u(t,i)}function e(n){return n=n.slice(),a(n,0),n}function o(n){for(var t=[],e=0,o=n.length;o>e;++e)r(n[e],t);return t.length<2&&t.push(t[0].slice()),t}function i(n){for(var t=o(n);t.length<4;)t.push(t[0].slice());return t}function f(n){return n.map(i)}function c(n){var t=n.type;return"GeometryCollection"===t?{type:t,geometries:n.geometries.map(c)}:t in l?{type:t,coordinates:l[t](n)}:null}var a=g(n.transform),s=n.arcs,l={Point:function(n){return e(n.coordinates)},MultiPoint:function(n){return n.coordinates.map(e)},LineString:function(n){return o(n.arcs)},MultiLineString:function(n){return n.arcs.map(o)},Polygon:function(n){return f(n.arcs)},MultiPolygon:function(n){return n.arcs.map(f)}};return c(t)}function u(n,t){for(var r,e=n.length,o=e-t;o<--e;)r=n[o],n[o++]=n[e],n[e]=r}function f(n,t){for(var r=0,e=n.length;e>r;){var o=r+e>>>1;n[o]n&&(n=~n);var r=o[n];r?r.push(t):o[n]=[t]})}function r(n,r){n.forEach(function(n){t(n,r)})}function e(n,t){"GeometryCollection"===n.type?n.geometries.forEach(function(n){e(n,t)}):n.type in u&&u[n.type](n.arcs,t)}var o={},i=n.map(function(){return[]}),u={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(n,t){n.forEach(function(n){r(n,t)})}};n.forEach(e);for(var c in o)for(var a=o[c],s=a.length,l=0;s>l;++l)for(var h=l+1;s>h;++h){var p,g=a[l],v=a[h];(p=i[g])[c=f(p,v)]!==v&&p.splice(c,0,v),(p=i[v])[c=f(p,g)]!==g&&p.splice(c,0,g)}return i}function a(n,t){function r(n){i.remove(n),n[1][2]=t(n),i.push(n)}var e=g(n.transform),o=v(n.transform),i=p();return t||(t=l),n.arcs.forEach(function(n){for(var u,f,c=[],a=0,s=0,l=n.length;l>s;++s)f=n[s],e(n[s]=[f[0],f[1],1/0],s);for(var s=1,l=n.length-1;l>s;++s)u=n.slice(s-1,s+2),u[1][2]=t(u),c.push(u),i.push(u);for(var s=0,l=c.length;l>s;++s)u=c[s],u.previous=c[s-1],u.next=c[s+1];for(;u=i.pop();){var h=u.previous,p=u.next;u[1][2]0;){var r=(t+1>>1)-1,o=e[r];if(h(n,o)>=0)break;e[o._=t]=o,e[n._=t=r]=n}}function t(n,t){for(;;){var r=t+1<<1,i=r-1,u=t,f=e[u];if(o>i&&h(e[i],f)<0&&(f=e[u=i]),o>r&&h(e[r],f)<0&&(f=e[u=r]),u===t)break;e[f._=t]=f,e[n._=t=u]=n}}var r={},e=[],o=0;return r.push=function(t){return n(e[t._=o]=t,o++),o},r.pop=function(){if(!(0>=o)){var n,r=e[0];return--o>0&&(n=e[o],t(e[n._=0]=n,0)),r}},r.remove=function(r){var i,u=r._;if(e[u]===r)return u!==--o&&(i=e[o],(h(i,r)<0?n:t)(e[i._=u]=i,u)),u},r}function g(n){if(!n)return m;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0),n[0]=(t+=n[0])*e+i,n[1]=(r+=n[1])*o+u}}function v(n){if(!n)return m;var t,r,e=n.scale[0],o=n.scale[1],i=n.translate[0],u=n.translate[1];return function(n,f){f||(t=r=0);var c=(n[0]-i)/e|0,a=(n[1]-u)/o|0;n[0]=c-t,n[1]=a-r,t=c,r=a}}function m(){}var y={version:"1.6.20",mesh:function(n){return i(n,t.apply(this,arguments))},meshArcs:t,merge:function(n){return i(n,r.apply(this,arguments))},mergeArcs:r,feature:e,neighbors:c,presimplify:a};"function"==typeof define&&define.amd?define(y):"object"==typeof module&&module.exports?module.exports=y:this.topojson=y}();
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/chart/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | ** Fixed for Reveal4: kotborealis@awooo.ru
4 | **
5 | ** A plugin for reveal.js allowing to integrate Chart.js
6 | **
7 | ** Version: 1.3.1
8 | **
9 | ** License: MIT license (see LICENSE.md)
10 | **
11 | ******************************************************************/
12 |
13 | /**
14 | * Reveal Plugin
15 | * https://revealjs.com/creating-plugins/
16 | */
17 | window.RevealChart = window.RevealChart || {
18 | id: 'RevealChart',
19 | init: function(deck) {
20 | initChart(deck);
21 | },
22 | update: function(canvas, idx, data) { update(canvas, idx, data); },
23 | };
24 |
25 | const initChart = function(Reveal){
26 | function parseJSON(str) {
27 | var json;
28 | try {
29 | json = JSON.parse(str);
30 | } catch (e) {
31 | return null;
32 | }
33 | return json;
34 | }
35 |
36 | /*
37 | * Recursively merge properties of two objects
38 | */
39 | function mergeRecursive(obj1, obj2) {
40 |
41 | for (var p in obj2) {
42 | try {
43 | // Property in destination object set; update its value.
44 | if ( obj1[p] !== null && typeof obj1[p] === 'object' && typeof obj2[p] === 'object' ) {
45 | obj1[p] = mergeRecursive(obj1[p], obj2[p]);
46 | }
47 | else {
48 | obj1[p] = obj2[p];
49 | }
50 | } catch(e) {
51 | // Property in destination object not set; create it and set its value.
52 | obj1[p] = obj2[p];
53 | }
54 | }
55 |
56 | return obj1;
57 | }
58 |
59 |
60 | function createChart(canvas, CSV, comments) {
61 | canvas.chart = null;
62 | var ctx = canvas.getContext("2d");
63 | var chartOptions = { responsive: true, maintainAspectRatio: false };
64 | var chartData = { labels: null, datasets: []};
65 | if ( comments !== null ) for (var j = 0; j < comments.length; j++ ){
66 | comments[j] = comments[j].replace(//,'');
68 | var config = parseJSON(comments[j]);
69 | if ( config ) {
70 | if ( config.data ) {
71 | mergeRecursive( chartData, config.data);
72 | }
73 | if ( config.options ) {
74 | mergeRecursive( chartOptions, config.options);
75 | }
76 | }
77 | }
78 |
79 | var lines = CSV.split('\n').filter(function(v){return v!==''});
80 | // if labels are not defined, get them from first line
81 | if ( chartData.labels === null && lines.length > 0 ) {
82 | chartData.labels = lines[0].split(',');
83 | chartData.labels.shift();
84 | lines.shift();
85 | }
86 | // get data values
87 | for (var j = 0; j < lines.length; j++ ){
88 | if (chartData.datasets.length <= j) chartData.datasets[j] = {};
89 | chartData.datasets[j].data = lines[j].split(','); //.filter(function(v){return v!==''});
90 | chartData.datasets[j].label = chartData.datasets[j].data[0];
91 | chartData.datasets[j].data.shift();
92 | for (var k = 0; k < chartData.datasets[j].data.length; k++ ){
93 | chartData.datasets[j].data[k] = Number(chartData.datasets[j].data[k]);
94 | }
95 | }
96 |
97 | // add chart options
98 | var config = chartConfig[canvas.getAttribute("data-chart")];
99 | if ( config ) {
100 | for (var j = 0; j < chartData.datasets.length; j++ ){
101 | for (var attrname in config) {
102 | if ( !chartData.datasets[j][attrname] ) {
103 | chartData.datasets[j][attrname] = config[attrname][j%config[attrname].length];
104 | }
105 | }
106 | }
107 | }
108 |
109 | canvas.chart = new Chart(ctx, { type: canvas.getAttribute("data-chart"), data: chartData, options: chartOptions });
110 |
111 | }
112 |
113 | function updateChart(canvas, idx, data) {
114 | canvas.chart.data.datasets[idx].data = data;
115 | recreateChart( canvas );
116 | }
117 |
118 | var initializeCharts = function(){
119 | // Get all canvases
120 | var canvases = document.querySelectorAll("canvas");
121 | for (var i = 0; i < canvases.length; i++ ){
122 | // check if canvas has data-chart attribute
123 | if ( canvases[i].hasAttribute("data-chart") ){
124 | var CSV = canvases[i].innerHTML.trim();
125 | var comments = CSV.match(//g);
126 | CSV = CSV.replace(//g,'').replace(/^\s*\n/gm, "")
127 | if ( ! canvases[i].hasAttribute("data-chart-src") ) {
128 | createChart(canvases[i], CSV, comments);
129 | }
130 | else {
131 | var canvas = canvases[i];
132 | var xhr = new XMLHttpRequest();
133 | xhr.onload = function() {
134 | if (xhr.readyState === 4) {
135 | createChart(canvas, xhr.responseText, comments);
136 | }
137 | else {
138 | console.warn( 'Failed to get file ' + canvas.getAttribute("data-chart-src") +". ReadyState: " + xhr.readyState + ", Status: " + xhr.status);
139 | }
140 | };
141 |
142 | xhr.open( 'GET', canvas.getAttribute("data-chart-src"), false );
143 | try {
144 | xhr.send();
145 | }
146 | catch ( error ) {
147 | console.warn( 'Failed to get file ' + canvas.getAttribute("data-chart-src") + '. Make sure that the presentation and the file are served by a HTTP server and the file can be found there. ' + error );
148 | }
149 | }
150 |
151 | }
152 | }
153 | }
154 |
155 | function recreateChart(canvas) {
156 | // clear data to redraw animation
157 | var data = canvas.chart.data.datasets;
158 | canvas.chart.data.datasets = [];
159 | canvas.chart.update();
160 | canvas.style.visibility = "hidden";
161 | setTimeout( function(canvas, data) {
162 | canvas.chart.data.datasets = data;
163 | canvas.style.visibility = "visible";
164 | canvas.chart.update();
165 | }, 500, canvas, data); // wait for slide transition to re-add data and animation
166 | /*
167 | var config = canvas.chart.config;
168 | canvas.chart.destroy();
169 | setTimeout( function() { canvas.chart = new Chart(canvas, config);}, 500); // wait for slide transition
170 | */
171 | }
172 |
173 | // check if chart option is given or not
174 | var chartConfig = Reveal.getConfig().chart || {};
175 |
176 | // set global chart options
177 | var config = chartConfig.defaults;
178 | if ( config ) {
179 | mergeRecursive(Chart.defaults, config);
180 | }
181 |
182 | Reveal.addEventListener('ready', function(){
183 | initializeCharts();
184 | Reveal.addEventListener('slidechanged', function(){
185 | var canvases = Reveal.getCurrentSlide().querySelectorAll("canvas[data-chart]");
186 | for (var i = 0; i < canvases.length; i++ ){
187 | if ( canvases[i].chart && canvases[i].chart.config.options.animation !== false ) {
188 | recreateChart( canvases[i] );
189 | }
190 | }
191 |
192 | });
193 | });
194 |
195 | this.update = updateChart;
196 |
197 | return this;
198 | };
199 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/theme/night.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Black theme for reveal.js.
3 | *
4 | * Copyright (C) 2011-2012 Hakim El Hattab, http://hakim.se
5 | */
6 | @import url(https://fonts.googleapis.com/css?family=Montserrat:700);
7 | @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,400italic,700italic);
8 | section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
9 | color: #222;
10 | }
11 |
12 | /*********************************************
13 | * GLOBAL STYLES
14 | *********************************************/
15 | :root {
16 | --r-background-color: #111;
17 | --r-main-font: Open Sans, sans-serif;
18 | --r-main-font-size: 40px;
19 | --r-main-color: #eee;
20 | --r-block-margin: 20px;
21 | --r-heading-margin: 0 0 20px 0;
22 | --r-heading-font: Montserrat, Impact, sans-serif;
23 | --r-heading-color: #eee;
24 | --r-heading-line-height: 1.2;
25 | --r-heading-letter-spacing: -0.03em;
26 | --r-heading-text-transform: none;
27 | --r-heading-text-shadow: none;
28 | --r-heading-font-weight: normal;
29 | --r-heading1-text-shadow: none;
30 | --r-heading1-size: 3.77em;
31 | --r-heading2-size: 2.11em;
32 | --r-heading3-size: 1.55em;
33 | --r-heading4-size: 1em;
34 | --r-code-font: monospace;
35 | --r-link-color: #e7ad52;
36 | --r-link-color-dark: #d08a1d;
37 | --r-link-color-hover: #f3d7ac;
38 | --r-selection-background-color: #e7ad52;
39 | --r-selection-color: #fff;
40 | }
41 |
42 | .reveal-viewport {
43 | background: #111;
44 | background-color: var(--r-background-color);
45 | }
46 |
47 | .reveal {
48 | font-family: var(--r-main-font);
49 | font-size: var(--r-main-font-size);
50 | font-weight: normal;
51 | color: var(--r-main-color);
52 | }
53 |
54 | .reveal ::selection {
55 | color: var(--r-selection-color);
56 | background: var(--r-selection-background-color);
57 | text-shadow: none;
58 | }
59 |
60 | .reveal ::-moz-selection {
61 | color: var(--r-selection-color);
62 | background: var(--r-selection-background-color);
63 | text-shadow: none;
64 | }
65 |
66 | .reveal .slides section,
67 | .reveal .slides section > section {
68 | line-height: 1.3;
69 | font-weight: inherit;
70 | }
71 |
72 | /*********************************************
73 | * HEADERS
74 | *********************************************/
75 | .reveal h1,
76 | .reveal h2,
77 | .reveal h3,
78 | .reveal h4,
79 | .reveal h5,
80 | .reveal h6 {
81 | margin: var(--r-heading-margin);
82 | color: var(--r-heading-color);
83 | font-family: var(--r-heading-font);
84 | font-weight: var(--r-heading-font-weight);
85 | line-height: var(--r-heading-line-height);
86 | letter-spacing: var(--r-heading-letter-spacing);
87 | text-transform: var(--r-heading-text-transform);
88 | text-shadow: var(--r-heading-text-shadow);
89 | word-wrap: break-word;
90 | }
91 |
92 | .reveal h1 {
93 | font-size: var(--r-heading1-size);
94 | }
95 |
96 | .reveal h2 {
97 | font-size: var(--r-heading2-size);
98 | }
99 |
100 | .reveal h3 {
101 | font-size: var(--r-heading3-size);
102 | }
103 |
104 | .reveal h4 {
105 | font-size: var(--r-heading4-size);
106 | }
107 |
108 | .reveal h1 {
109 | text-shadow: var(--r-heading1-text-shadow);
110 | }
111 |
112 | /*********************************************
113 | * OTHER
114 | *********************************************/
115 | .reveal p {
116 | margin: var(--r-block-margin) 0;
117 | line-height: 1.3;
118 | }
119 |
120 | /* Remove trailing margins after titles */
121 | .reveal h1:last-child,
122 | .reveal h2:last-child,
123 | .reveal h3:last-child,
124 | .reveal h4:last-child,
125 | .reveal h5:last-child,
126 | .reveal h6:last-child {
127 | margin-bottom: 0;
128 | }
129 |
130 | /* Ensure certain elements are never larger than the slide itself */
131 | .reveal img,
132 | .reveal video,
133 | .reveal iframe {
134 | max-width: 95%;
135 | max-height: 95%;
136 | }
137 |
138 | .reveal strong,
139 | .reveal b {
140 | font-weight: bold;
141 | }
142 |
143 | .reveal em {
144 | font-style: italic;
145 | }
146 |
147 | .reveal ol,
148 | .reveal dl,
149 | .reveal ul {
150 | display: inline-block;
151 | text-align: left;
152 | margin: 0 0 0 1em;
153 | }
154 |
155 | .reveal ol {
156 | list-style-type: decimal;
157 | }
158 |
159 | .reveal ul {
160 | list-style-type: disc;
161 | }
162 |
163 | .reveal ul ul {
164 | list-style-type: square;
165 | }
166 |
167 | .reveal ul ul ul {
168 | list-style-type: circle;
169 | }
170 |
171 | .reveal ul ul,
172 | .reveal ul ol,
173 | .reveal ol ol,
174 | .reveal ol ul {
175 | display: block;
176 | margin-left: 40px;
177 | }
178 |
179 | .reveal dt {
180 | font-weight: bold;
181 | }
182 |
183 | .reveal dd {
184 | margin-left: 40px;
185 | }
186 |
187 | .reveal blockquote {
188 | display: block;
189 | position: relative;
190 | width: 70%;
191 | margin: var(--r-block-margin) auto;
192 | padding: 5px;
193 | font-style: italic;
194 | background: rgba(255, 255, 255, 0.05);
195 | box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.2);
196 | }
197 |
198 | .reveal blockquote p:first-child,
199 | .reveal blockquote p:last-child {
200 | display: inline-block;
201 | }
202 |
203 | .reveal q {
204 | font-style: italic;
205 | }
206 |
207 | .reveal pre {
208 | display: block;
209 | position: relative;
210 | width: 90%;
211 | margin: var(--r-block-margin) auto;
212 | text-align: left;
213 | font-size: 0.55em;
214 | font-family: var(--r-code-font);
215 | line-height: 1.2em;
216 | word-wrap: break-word;
217 | box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.15);
218 | }
219 |
220 | .reveal code {
221 | font-family: var(--r-code-font);
222 | text-transform: none;
223 | tab-size: 2;
224 | }
225 |
226 | .reveal pre code {
227 | display: block;
228 | padding: 5px;
229 | overflow: auto;
230 | max-height: 400px;
231 | word-wrap: normal;
232 | }
233 |
234 | .reveal .code-wrapper {
235 | white-space: normal;
236 | }
237 |
238 | .reveal .code-wrapper code {
239 | white-space: pre;
240 | }
241 |
242 | .reveal table {
243 | margin: auto;
244 | border-collapse: collapse;
245 | border-spacing: 0;
246 | }
247 |
248 | .reveal table th {
249 | font-weight: bold;
250 | }
251 |
252 | .reveal table th,
253 | .reveal table td {
254 | text-align: left;
255 | padding: 0.2em 0.5em 0.2em 0.5em;
256 | border-bottom: 1px solid;
257 | }
258 |
259 | .reveal table th[align=center],
260 | .reveal table td[align=center] {
261 | text-align: center;
262 | }
263 |
264 | .reveal table th[align=right],
265 | .reveal table td[align=right] {
266 | text-align: right;
267 | }
268 |
269 | .reveal table tbody tr:last-child th,
270 | .reveal table tbody tr:last-child td {
271 | border-bottom: none;
272 | }
273 |
274 | .reveal sup {
275 | vertical-align: super;
276 | font-size: smaller;
277 | }
278 |
279 | .reveal sub {
280 | vertical-align: sub;
281 | font-size: smaller;
282 | }
283 |
284 | .reveal small {
285 | display: inline-block;
286 | font-size: 0.6em;
287 | line-height: 1.2em;
288 | vertical-align: top;
289 | }
290 |
291 | .reveal small * {
292 | vertical-align: top;
293 | }
294 |
295 | .reveal img {
296 | margin: var(--r-block-margin) 0;
297 | }
298 |
299 | /*********************************************
300 | * LINKS
301 | *********************************************/
302 | .reveal a {
303 | color: var(--r-link-color);
304 | text-decoration: none;
305 | transition: color 0.15s ease;
306 | }
307 |
308 | .reveal a:hover {
309 | color: var(--r-link-color-hover);
310 | text-shadow: none;
311 | border: none;
312 | }
313 |
314 | .reveal .roll span:after {
315 | color: #fff;
316 | background: var(--r-link-color-dark);
317 | }
318 |
319 | /*********************************************
320 | * Frame helper
321 | *********************************************/
322 | .reveal .r-frame {
323 | border: 4px solid var(--r-main-color);
324 | box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
325 | }
326 |
327 | .reveal a .r-frame {
328 | transition: all 0.15s linear;
329 | }
330 |
331 | .reveal a:hover .r-frame {
332 | border-color: var(--r-link-color);
333 | box-shadow: 0 0 20px rgba(0, 0, 0, 0.55);
334 | }
335 |
336 | /*********************************************
337 | * NAVIGATION CONTROLS
338 | *********************************************/
339 | .reveal .controls {
340 | color: var(--r-link-color);
341 | }
342 |
343 | /*********************************************
344 | * PROGRESS BAR
345 | *********************************************/
346 | .reveal .progress {
347 | background: rgba(0, 0, 0, 0.2);
348 | color: var(--r-link-color);
349 | }
350 |
351 | /*********************************************
352 | * PRINT BACKGROUND
353 | *********************************************/
354 | @media print {
355 | .backgrounds {
356 | background-color: var(--r-background-color);
357 | }
358 | }
--------------------------------------------------------------------------------
/apresentacao/slides.md:
--------------------------------------------------------------------------------
1 | ---
2 | theme: "night"
3 | transition: "slide"
4 | title: "Configuração de projetos"
5 | enableMenu: false
6 | enableSearch: false
7 | enableChalkboard: false
8 | highlightTheme: "monokai"
9 | progressBar: true
10 | ---
11 |
12 | ## Boas vindas
13 |
14 | --
15 |
16 | ## Muito obrigado pela presença!
17 |
18 | 
19 |
20 | --
21 |
22 | ### O que vamos abordar?
23 |
24 | {width=70%}
25 |
26 | --
27 |
28 | ### O que vamos abordar?
29 |
30 | - VsCode config
31 | - Commits
32 | - ESLint
33 | - Github Actions
34 | - Docker
35 |
36 | ---
37 |
38 | ### Antes de tudo, quem sou eu?
39 |
40 | --
41 |
42 | ### Eu sou ...
43 |
44 | - Thiago Mariotto
45 | - 25 Anos
46 | - Ciência da computação
47 | - Instrutor Backend Trybe
48 |
49 | ---
50 |
51 | ### Porque esse tema é importante?
52 |
53 | > É importante termos uma base sólida e estruturada para desenvolvermos nossa aplicação, definindo as configurações iniciais, é mais fácil compartilhar o código e evitar problemas futuros.
54 |
55 | ---
56 |
57 | ### Configurações do Visual Studio Code
58 |
59 | > Pergunta: O que vem na sua cabeça com esse título?
60 |
61 | --
62 |
63 | ### Configurações do Visual Studio Code
64 |
65 | > Você sabia que é possível compartilhar suas configurações de projeto do VsCode com outras pessoas?
66 |
67 | --
68 |
69 | ### Configurações do Visual Studio Code
70 |
71 | > É importante pois, caso uma pessoa venha, por exemplo, realizar um Code Review, ela trabalhe em cima das mesmas regras que você definiu.
72 |
73 | --
74 |
75 | ### Configurações do Visual Studio Code
76 |
77 | > Como fazemos isso?
78 |
79 | --
80 |
81 | ### Configurações do Visual Studio Code
82 | ```json
83 | {
84 | "editor.formatOnPaste": true,
85 | "editor.formatOnSave": true,
86 | "editor.formatOnSaveMode": true,
87 | "editor.formatOnType": true,
88 | "editor.tabSize": 2,
89 | "editor.codeActionsOnSave": {
90 | "source.fixAll": true,
91 | "source.organizeImports": true
92 | // ...
93 | }
94 |
95 | }
96 | ```
97 |
98 | --
99 |
100 | ### Configurações do Visual Studio Code
101 |
102 | - dessa forma podemos compartilhar nossas configurações de ambiente de projeto com outras pessoas.
103 | - o arquivo sobrepõe suas configurações locais.
104 |
105 | ---
106 |
107 | ### Commits
108 |
109 | {width=40%}
110 |
111 | --
112 |
113 | ## Padronização de commits
114 |
115 | - Commitlint
116 | - Husky
117 | - Commitizen
118 |
119 | --
120 |
121 | ### Commits Atômicos
122 |
123 | --
124 |
125 | ### Commits Atômicos
126 |
127 | - Submeta pequenas alterações que foram realizadas em seu código.
128 |
129 | --
130 |
131 | ### Commits Atômicos
132 |
133 | - Seus commits devem contar uma história, a história de desenvolvimento do seu projeto;
134 |
135 | --
136 |
137 | ### Commits Atômicos
138 |
139 | - Nada de commit bomba.
140 |
141 | --
142 |
143 | ### Conventional Commits
144 |
145 | [Documentação](https://www.conventionalcommits.org/en/v1.0.0/)
146 |
147 | > Ele fornece um conjunto fácil de regras para criar um histórico de commit explícito descrevendo os recursos, correções e alterações feitas nas mensagens de commit.
148 |
149 | --
150 |
151 | ### Conventional Commits
152 |
153 | ```sh
154 | $ git commit -m "feat: insert validation user register"
155 |
156 | $ git commit -m "fix: remove typo user validation register"
157 | ```
158 |
159 | --
160 |
161 | ### Commitlint
162 |
163 | [Documentação](https://commitlint.js.org/#/guides-local-setup)
164 |
165 | > Podemos Definir que utilizaremos o Conventional Commits, mas nada garante que vamos respeitar ou lembrar as regras em todos os commits.
166 |
167 | --
168 |
169 | ### Commitlint
170 |
171 | > Com ele conseguimos verificar se a mensagem de commit está dentro dos padrões definidos (Linter dos commits).
172 |
173 | --
174 |
175 | ## Commitizen
176 |
177 | [Documentação](http://commitizen.github.io/cz-cli/)
178 |
179 | > O Commitizen é uma biblioteca que vai nos ajudar a criar os commits seguindo o padrão do Conventional Commit. Ela gera uma interface no terminal e assim vamos conseguir acessar todos os tipos de commits e suas descrições.
180 |
181 | --
182 |
183 | ### Husky
184 |
185 | [Documentação](https://typicode.github.io/husky/#/)
186 |
187 | > É possível criar gatilhos em determinadas ações, utilizaremos o Husky para disparar uma ação antes de um commit para executar o commitizen e verificar se a mensagem do commit está seguindo o padrão definido.
188 |
189 | --
190 |
191 | ### Colocando tudo isso em prática
192 |
193 | 
194 |
195 | --
196 |
197 | ### Iniciando Commitlint
198 |
199 | ```sh
200 | $ npm init -y
201 | $ git init
202 |
203 | # install commit lint
204 | $ npm install --save-dev @commitlint/cli
205 | $ npm install --save-dev @commitlint/config-conventional
206 |
207 | # atomic commit
208 | $ git add package.json
209 | $ git commit -m "feat: add commit lint lib"
210 |
211 | # Configure commitlint to use conventional config
212 | $ echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
213 |
214 | ```
215 |
216 | --
217 |
218 | ### Testando commitlint
219 |
220 | ```sh
221 | # Para testar a biblioteca
222 | echo "teste" | npx commitlint # deve apontar um erro
223 |
224 | echo "feat: teste" | npx commitlint # deve funcionar corretamente
225 | ```
226 |
227 | --
228 |
229 | ### Iniciando Husky
230 |
231 | ```sh
232 | # instalando a lib
233 | $ npm install husky -D
234 |
235 | # atomic commit
236 | $ git add package.json
237 | $ git commit -m "feat: add husky lib"
238 |
239 | # ativando os hooks (gatilhos)
240 | $ npx husky install
241 |
242 | # Add hook que vai disparar o commitlint
243 | $ npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
244 |
245 | ```
246 |
247 | --
248 |
249 | ### Iniciando Husky
250 |
251 | ```json
252 | // para ativar os hooks automaticamente após instalação
253 | "scripts": {
254 | "prepare": "husky install"
255 | }
256 |
257 | // caso o script não seja adicionado ao package.json, toda vez
258 | // que um clone for realizado é necessário realizar
259 | // `$ npx husky install`
260 | ```
261 |
262 | --
263 |
264 | ### Realizando um commit
265 |
266 | ```sh
267 | $ echo "node_modules/" > .gitignore
268 |
269 | $ git status
270 | $ git add .gitignore
271 | $ git commit -m "qualquer coisa"
272 | $ git commit -m "chore: add gitignore"
273 | ```
274 |
275 | --
276 |
277 | ### Adicionando o Commitizen
278 |
279 | ```sh
280 | $ npm i commitizen -D
281 | $ npx commitizen init cz-conventional-changelog --save-dev --save-exact
282 |
283 | $ echo "console.log(1);" > index.js
284 | $ git add index.js
285 |
286 | "scripts": {
287 | "commit": "cz"
288 | }
289 |
290 | $ npm run commit
291 | ```
292 |
293 | --
294 |
295 | ### Utilizando o Commitizen
296 |
297 | 1. Selecione o tipo de mudança que você está realizando
298 | 2. Qual é o escopo desta mudança (por exemplo, componente ou nome do arquivo)
299 | 3. Escreva uma descrição breve e imperativa da mudança (máx. 82 caracteres):
300 |
301 | --
302 |
303 | ### Utilizando o Commitizen
304 |
305 | 4. Forneça uma descrição mais longa da mudança:
306 | 5. Existem alterações importantes (importante saber sobre `Semantic Versioning`)
307 | 6. Essa mudança afeta algum problema em aberto? (Issues)
308 |
309 | ---
310 |
311 | ## ESLint
312 |
313 | 
314 |
315 | --
316 |
317 | ## O que é o ESLint?
318 |
319 | > Analisa seu código estaticamente para encontrar problemas. Você pode executar o ESLint como parte de seu pipeline de integração contínua (CI). Os problemas encontrados pelo ESLint podem ser corrigidos automaticamente.
320 |
321 | --
322 |
323 | ### Iniciando ESLint Backend
324 |
325 | ```sh
326 | $ mkdir backend && cd backend
327 | $ mv ../index.js backend
328 |
329 | $ npm init -y
330 | $ npm install eslint -D
331 | $ npx eslint --init
332 |
333 | $ git add [...]
334 | $ npm run commit
335 | ```
336 |
337 | --
338 |
339 | ### Executando eslint
340 |
341 | ```json
342 | "lint": "eslint --no-inline-config --no-error-on-unmatched-pattern -c .eslintrc.json ."
343 |
344 | $ npm run lint
345 | ```
346 |
347 | --
348 |
349 | ### Github Actions
350 |
351 | [Documentação](https://github.com/features/actions)
352 |
353 | 
354 |
355 | --
356 |
357 | ### Github Actions
358 |
359 | > O GitHub Actions facilita a automatização de todos os seus fluxos de trabalho de software. Crie, teste e implante seu código diretamente do GitHub.
360 |
361 | --
362 |
363 | ### Github Actions - Continuous Integration
364 |
365 | - Uma CI é realizada com sucesso quando novas mudanças no código são desenvolvidas, testadas e consolidadas em um repositório, por exemplo, a correção de um bug ou o deploy de uma feature nova.
366 |
367 | --
368 |
369 | ### Github Action + ESLint
370 |
371 | > Vamos criar uma Action para que, todas as vezes que um PR for aberto ou um push for realizado, o ESLint execute todos os testes em nosso código.
372 |
373 | --
374 |
375 | ### Por onde começamos?
376 |
377 | 
378 |
379 | --
380 |
381 | ### Configurando minhas Actions
382 |
383 | --
384 |
385 | ### Configurando minhas Actions
386 |
387 | ```sh
388 | # vamos voltar para a raiz do projeto ./
389 | $ mkdir .github/workflows/main.yml
390 | ```
391 |
392 | --
393 |
394 | ### Configurando minhas Actions
395 |
396 | ```yml
397 | on:
398 | pull_request:
399 | types: [opened, synchronize]
400 |
401 | jobs:
402 | eslint:
403 | runs-on: ubuntu-latest
404 | steps:
405 | - uses: actions/checkout@v2
406 |
407 | - uses: actions/setup-node@v2
408 | with:
409 | node-version: 14
410 |
411 | - name: Install back-end modules
412 | run: npm i --prefix backend
413 |
414 | - name: Run linter on back-end
415 | run: npm run lint --prefix backend
416 | ```
417 |
418 | --
419 |
420 | ### Testando uma action
421 |
422 | > Para isso é necessário realizar um Pull Request em um repositório.
423 |
424 | ---
425 |
426 | ### Docker
427 |
428 | {width=70%}
429 |
430 | --
431 |
432 | ### Docker
433 |
434 | > Não basta só compartilharmos nossas configurações de trabalho.
435 |
436 | --
437 |
438 | ### Docker
439 |
440 | > Podemos compartilhar nosso código pronto para ser executado, testado ou modificado, mas como?
441 |
442 | --
443 |
444 | ### "Dockerizando" sua aplicação
445 |
446 | 
447 |
448 | --
449 |
450 | ## Dockerizando sua aplicação
451 |
452 | > Fornecendo toda a estrutura base do projeto para que qualquer pessoa consiga executa-lo em sua máquina, continuando o desenvolvimento ou realizando testes.
453 |
454 | --
455 |
456 | ### Case
457 |
458 | > Pense o seguinte caso: você está participando de um processo seletivo em que precisa construir uma aplicação simulando uma loja de vendas de sapatos.
459 |
460 | --
461 |
462 | ### Case
463 |
464 | > É bem provável que você irá desenvolver um CRUD de vendas e ou estoque.
465 |
466 | --
467 |
468 | ### Case
469 |
470 | > Para desenvolver, você seleciona 3 ferramentas: Node, React e MySQL.
471 |
472 | --
473 |
474 | ### Case
475 |
476 | > Após finalizado, como ficaria sua aplicação para ser enviada a pessoa avaliadora? Conte-me ...
477 |
478 | --
479 |
480 | ### Case
481 |
482 | > Agora, imagine que: a pessoa que irá testar sua aplicação trabalha com Python, não possuí node e nem MySQL instalado na máquina :/
483 |
484 | --
485 |
486 | > Ela vai ter um trabalhão não é mesmo?
487 |
488 | --
489 |
490 | ## Mão ~~na massa~~ no teclado
491 |
492 | 
493 |
494 | --
495 |
496 | ### Utilizando Docker
497 |
498 | > Vamos trabalhar com um exemplo parecido
499 |
500 | --
501 |
502 | ### Utilizando Docker
503 |
504 | > Vamos imaginar que estamos desenvolvendo uma aplicação completa (front e back), utilizando as seguintes ferramentas:
505 |
506 | --
507 |
508 | ### Nossas ferramentas
509 |
510 | - API com Node rodando na versão 12.22;
511 | - Aplicação WEB com REACT e node na versão 12.22;
512 | - Banco de dados MySQL na versão 5.7;
513 |
514 | --
515 |
516 | ### Colocando em prática
517 |
518 | 1. Criar o Dockerfile do Backend
519 | 2. Criar o Dockerfile do Frontend
520 | 3. Criar o Docker Compose
521 | 1. Serviço do Back utilizando o Dockerfile
522 | 2. Serviço do Front utilizando o Dockerfile
523 | 3. Serviço MySQL sendo populado com um banco de dados
524 |
525 | --
526 |
527 | ### Colocando em prática
528 |
529 | > Ponto de atenção: o container do Frontend é dependente do container do Backend e o Backend por sua vez é dependente do MySQL.
530 |
531 | --
532 |
533 | ## Let's Code
534 |
535 | --
536 |
537 | ### Dockerfile Frontend
538 |
539 | ```yml
540 | FROM node:12.22-alpine
541 |
542 |
543 | WORKDIR /app
544 |
545 | COPY package*.json ./
546 |
547 | RUN npm install
548 |
549 | RUN chmod 777 node_modules
550 |
551 | COPY . .
552 |
553 | EXPOSE 3000
554 |
555 | CMD ["npm", "start"]
556 | ```
557 |
558 | --
559 |
560 | ### Dockerfile Backend
561 |
562 | ```yml
563 | FROM node:12.22-alpine
564 |
565 | WORKDIR /app
566 |
567 | COPY package*.json ./
568 |
569 | RUN npm install
570 |
571 | RUN chmod 777 node_modules
572 |
573 | COPY . .
574 |
575 | EXPOSE 3333
576 |
577 | CMD ["npm", "start"]
578 | ```
579 |
580 | --
581 |
582 | ### Docker compose
583 |
584 | ```yml
585 | version: '3.1'
586 |
587 | services:
588 | database:
589 | image: mysql:5.7
590 | restart: always
591 | container_name: mysql_compose
592 | ports:
593 | - 3306:3306
594 | environment:
595 | - MYSQL_ROOT_PASSWORD=docker
596 | volumes:
597 | - ./backend/database/mysql-seeder:/docker-entrypoint-initdb.d
598 |
599 | api:
600 | build: ./backend
601 | container_name: backend_compose
602 | ports:
603 | - 3333:3333
604 | depends_on:
605 | - database
606 | volumes:
607 | - /app/node_modules
608 | - ./backend:/app
609 |
610 | web:
611 | build: ./frontend
612 | container_name: frontend_compose
613 | ports:
614 | - 3000:3000
615 | volumes:
616 | - /app/node_modules
617 | - ./frontend:/app
618 | depends_on:
619 | - api
620 | ```
621 |
622 |
623 | --
624 |
625 | > Agora nossa pessoa avaliadora poderá testar nosso código executando somente um comando.
626 |
627 | ---
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/plugin/animate/plugin.js:
--------------------------------------------------------------------------------
1 | /*****************************************************************
2 | ** Author: Asvin Goel, goel@telematique.eu
3 | **
4 | ** A plugin for animating slide content.
5 | **
6 | ** Version: 0.1.0
7 | **
8 | ** License: MIT license (see LICENSE.md)
9 | **
10 | ******************************************************************/
11 |
12 | window.RevealAnimate = window.RevealAnimate || {
13 | id: 'RevealAnimate',
14 | init: function(deck) {
15 | initAnimate(deck);
16 | },
17 | play: function() { play(); },
18 | pause: function() { pause(); },
19 | seek: function(timestamp) { seek(timestamp); },
20 | };
21 |
22 | const initAnimate = function(Reveal){
23 | var config = Reveal.getConfig().animate || {};
24 | var autoplay = config.autoplay;
25 |
26 | var playback = false;
27 | var isRecording = false;
28 | var timer = null;
29 | var initialized = 0;
30 |
31 | function parseJSON(str) {
32 | str = str.replace(/(\r\n|\n|\r|\t)/gm,""); // remove line breaks and tabs
33 | var json;
34 | try {
35 | json = JSON.parse(str, function (key, value) {
36 | if (value && (typeof value === 'string') && value.indexOf("function") === 0) {
37 | // we can only pass a function as string in JSON ==> doing a real function
38 | // eval("var jsFunc = " + value);
39 | var jsFunc = new Function('return ' + value)();
40 | return jsFunc;
41 | }
42 | return value;
43 | });
44 | } catch (e) {
45 | return null;
46 | }
47 | return json;
48 | }
49 |
50 | function load( element, config, filename, callback ) {
51 | var xhr = new XMLHttpRequest();
52 | xhr.onload = function() {
53 | if (xhr.readyState === 4) {
54 | callback( element, config, xhr.responseText );
55 | }
56 | else {
57 | callback( "Failed to get file. ReadyState: " + xhr.readyState + ", Status: " + xhr.status );
58 | }
59 | };
60 | xhr.open( 'GET', filename, true );
61 | xhr.send();
62 | }
63 |
64 | function parseComments( element ) {
65 | var config = {};
66 | var comments = element.innerHTML.trim().match(//g);
67 | //console.log(comments)
68 | if ( comments !== null ) for (var k = 0; k < comments.length; k++ ){
69 | comments[k] = comments[k].replace(//,'');
71 | var config = parseJSON(comments[k]);
72 | //console.warn(comments[k], config);
73 |
74 | if ( config ) {
75 | if ( config.animation && Array.isArray(config.animation) && config.animation.length && !Array.isArray(config.animation[0]) ) {
76 | // without fragments the animation can be specified as a single array (animation steps)
77 | config.animation = [ config.animation ];
78 | }
79 | break;
80 | }
81 | }
82 |
83 | //console.warn(element, config);
84 | return config;
85 | }
86 |
87 | function getAnimatedSVG( container ) {
88 | var elements = SVG.find('svg');
89 | var svg = elements.toArray().find(element => element.node.parentElement == container);
90 | //console.warn("FOUND",svg.node);
91 | return svg;
92 | }
93 |
94 | /*****************************************************************
95 | ** Set up animations
96 | ******************************************************************/
97 | function setupAnimations( container, config ) {
98 | //console.warn("setupAnimations");
99 | if ( !config ) return;
100 |
101 | container.svg = getAnimatedSVG( container );
102 |
103 | // pre-animation setup
104 | var setup = config.setup;
105 | if ( setup ) {
106 | for (var i = 0; i < setup.length; i++ ){
107 | try {
108 | if ( setup[i].element ) {
109 | //console.log(setup[i].element,setup[i].modifier,setup[i].parameters);
110 | var elements = container.svg.find(setup[i].element);
111 | if ( !elements.length ) {
112 | console.warn("Cannot find element to set up with selector: " + setup[i].element + "!");
113 | }
114 |
115 | //console.warn(elements);
116 | //console.log("element(" + setup[i].element + ")." + setup[i].modifier + "(" + setup[i].parameters + ")");
117 | //console.log("element(" + setup[i].element + ")." + setup[i].modifier + "(" + setup[i].parameters + ")");
118 | for (var j = 0; j < elements.length; j++ ){
119 | if ( typeof setup[i].modifier === "function" ) {
120 | // if modifier is function execute it
121 | setup[i].modifier.apply(elements[j],setup[i].parameters);
122 | }
123 | else {
124 | // apply modifier to element
125 | elements[j][setup[i].modifier].apply(elements[j],setup[i].parameters);
126 | }
127 | }
128 |
129 | }
130 | else {
131 | // no element is provided
132 | if ( typeof setup[i].modifier === "function" ) {
133 | // if modifier is function execute it
134 | setup[i].modifier.apply(container.svg,setup[i].parameters);
135 | }
136 | else {
137 | // apply modifier to root
138 | container.svg[setup[i].modifier].apply(container.svg,setup[i].parameters);
139 | }
140 | }
141 | }
142 | catch( error ) {
143 | console.error("Error '" + error + "' setting up element " + JSON.stringify(setup[i]));
144 | }
145 | }
146 | //console.warn(container.svg.node.getAttribute("style"));
147 | }
148 |
149 | container.animation = new SVG.Timeline().persist(true);
150 | container.animationSchedule = []; // completion time of each fragment animation
151 |
152 | // setup animation
153 | var animations = config.animation;
154 | if ( animations ) {
155 |
156 | container.animationSchedule.length = animations.length;
157 | var timestamp = 0;
158 | for (var fragment = 0; fragment < animations.length; fragment++ ){
159 | container.animationSchedule[fragment] = {};
160 | container.animationSchedule[fragment].begin = timestamp;
161 | for (var i = 0; i < animations[fragment].length; i++ ){
162 | try {
163 | // add each animation step
164 | var elements = container.svg.find(animations[fragment][i].element);
165 | //console.log("element(" + animations[fragment][i].element + ")." + animations[fragment][i].modifier + "(" + animations[fragment][i].parameters + ")");
166 | if ( !elements.length ) {
167 | console.warn("Cannot find element to animate with selector: " + animations[fragment][i].element + "!");
168 | }
169 | for (var j = 0; j < elements.length; j++ ){
170 | elements[j].timeline( container.animation );
171 | var anim = elements[j].animate(animations[fragment][i].duration,animations[fragment][i].delay,animations[fragment][i].when)
172 | anim[animations[fragment][i].modifier].apply(anim,animations[fragment][i].parameters);
173 | }
174 |
175 | //console.log("Duration:", anim.duration());
176 | timestamp = anim.duration();
177 | }
178 | catch( error ) {
179 | console.error("Error '" + error + "' setting up animation " + JSON.stringify(animations[fragment][i]));
180 | }
181 | }
182 | // set animationSchedule for each fragment animation
183 | var schedule = container.animation.schedule();
184 | if ( schedule.length ) {
185 | timestamp = schedule[schedule.length-1].end;
186 | }
187 | container.animationSchedule[fragment].end = timestamp;
188 | }
189 | container.animation.stop();
190 | //console.warn(container.animation.schedule());
191 | // console.warn("Schedule", container.animationSchedule);
192 | }
193 |
194 | // setup current slide
195 | if ( Reveal.getCurrentSlide().contains( container ) ) {
196 | Reveal.layout(); // Update layout to account for svg size
197 | animateSlide(0);
198 | }
199 |
200 | initialized += 1;
201 | }
202 |
203 | function initialize() {
204 | //console.log("Initialize animations");
205 | // Get all animations
206 | var elements = document.querySelectorAll("[data-animate]");
207 | for (var i = 0; i < elements.length; i++ ){
208 | var config = parseComments( elements[i] );
209 | var src = elements[i].getAttribute("data-src");
210 | if ( src ) {
211 | var element = elements[i];
212 | load( elements[i], config, src, function( element, config, response ) {
213 | if ( printMode ) {
214 | // do not load svg multiple times
215 | element.removeAttribute("data-src")
216 | }
217 | element.innerHTML = response + element.innerHTML;
218 | setupAnimations( element, config );
219 | });
220 | }
221 | else {
222 | setupAnimations( elements[i], config );
223 | }
224 | }
225 | }
226 |
227 |
228 | function play() {
229 | //console.log("Play",Reveal.getCurrentSlide());
230 | var elements = Reveal.getCurrentSlide().querySelectorAll("[data-animate]");
231 | for (var i = 0; i < elements.length; i++ ){
232 | //console.warn("Play",elements[i]);
233 | if ( elements[i].animation ) {
234 | elements[i].animation.play();
235 | }
236 | }
237 | autoPause();
238 | }
239 |
240 | function pause() {
241 | //console.log("Pause");
242 | if ( timer ) { clearTimeout( timer ); timer = null; }
243 |
244 | var elements = Reveal.getCurrentSlide().querySelectorAll("[data-animate]");
245 | for (var i = 0; i < elements.length; i++ ){
246 | if ( elements[i].animation ) {
247 | elements[i].animation.pause();
248 | }
249 | }
250 | }
251 |
252 | function autoPause() {
253 |
254 | if ( timer ) { clearTimeout( timer ); timer = null; }
255 | var fragment = Reveal.getIndices().f + 1 || 0; // in reveal.js fragments start with index 0, here with index 1
256 |
257 |
258 |
259 | var elements = Reveal.getCurrentSlide().querySelectorAll("[data-animate]");
260 |
261 | for (var i = 0; i < elements.length; i++ ){
262 | if ( elements[i].animation && elements[i].animationSchedule[fragment] ) {
263 | //console.log( elements[i].animationSchedule[fragment].end, elements[i].animation.time());
264 | var timeout = elements[i].animationSchedule[fragment].end - elements[i].animation.time();
265 | timer = setTimeout(pause,timeout);
266 | }
267 | //console.log("Auto pause",elements[i], timeout);
268 | }
269 |
270 | }
271 |
272 | function seek( timestamp ) {
273 | //console.log("Seek", timestamp);
274 | var elements = Reveal.getCurrentSlide().querySelectorAll("[data-animate]");
275 | var fragment = Reveal.getIndices().f + 1 || 0; // in reveal.js fragments start with index 0, here with index 1
276 | for (var i = 0; i < elements.length; i++ ){
277 | //console.log("Seek",timestamp,elements[i].animationSchedule[fragment].begin + (timestamp || 0) );
278 | if ( elements[i].animation && elements[i].animationSchedule[fragment] ) {
279 | elements[i].animation.time( elements[i].animationSchedule[fragment].begin + (timestamp || 0) );
280 | }
281 | }
282 | if ( timer ) {
283 | // update time if animation is running
284 | autoPause();
285 | }
286 | }
287 |
288 |
289 | // Control animation
290 | function animateSlide( timestamp ) {
291 | // pause();
292 | //console.log("Animate slide", timestamp);
293 | if ( timestamp !== undefined ) {
294 | seek( timestamp);
295 | }
296 | if ( Reveal.isAutoSliding() || autoplay || playback || isRecording ) {
297 | //console.log("Start animation");
298 | play();
299 | }
300 | else {
301 | pause();
302 | }
303 | //console.log("Done");
304 | }
305 |
306 | /*****************************************************************
307 | ** Print
308 | ******************************************************************/
309 | var printMode = ( /print-pdf/gi ).test( window.location.search );
310 | //console.log("createPrintout" + printMode)
311 |
312 | function initializePrint( ) {
313 | //return;
314 | //console.log("initializePrint", document.querySelectorAll(".pdf-page").length);
315 | if ( !document.querySelectorAll(".pdf-page").length ) {
316 | // wait for pdf pages to be created
317 | setTimeout( initializePrint, 500 );
318 | return;
319 | }
320 | initialize();
321 | createPrintout();
322 | }
323 |
324 | function createPrintout( ) {
325 | //console.log("createPrintout", document.querySelectorAll(".pdf-page").length, document.querySelectorAll("[data-animate]").length );
326 | if ( initialized < document.querySelectorAll("[data-animate]").length ) {
327 | //console.log("wait");
328 | // wait for animations to be loaded
329 | setTimeout( createPrintout, 500 );
330 | return;
331 | }
332 | var pages = document.querySelectorAll(".pdf-page");
333 | for ( var i = 0; i < pages.length; i++ ) {
334 | var fragment = -1;
335 | var current = pages[i].querySelectorAll(".current-fragment");
336 | for ( var j = 0; j < current.length; j++ ) {
337 | if ( Number(current[j].getAttribute("data-fragment-index")) > fragment ) {
338 | fragment = Number(current[j].getAttribute("data-fragment-index") );
339 | }
340 | }
341 | fragment += 1;
342 | var elements = pages[i].querySelectorAll("[data-animate]");
343 | for ( var j = 0; j < elements.length; j++ ) {
344 | //console.log(i,fragment, elements[j]);
345 |
346 | if ( elements[j].animation && elements[j].animationSchedule && elements[j].animationSchedule[fragment] ) {
347 | //console.log(i,fragment, elements[j].animationSchedule[fragment].begin);
348 | elements[j].animation.time( elements[j].animationSchedule[fragment].end );
349 | }
350 | var fragments = elements[j].querySelectorAll("svg > [data-fragment-index]");
351 | //console.log(i,fragment, elements[j], fragments);
352 | for ( var k = 0; k < fragments.length; k++ ) {
353 | if ( fragments[k].getAttribute("data-fragment-index") < fragment ) {
354 | fragments[k].classList.add("visible");
355 | }
356 | }
357 | }
358 | }
359 | }
360 | /*****************************************************************
361 | ** Event listeners
362 | ******************************************************************/
363 |
364 | Reveal.addEventListener( 'ready', function( event ) {
365 | //console.log('ready ');
366 | /*
367 | if ( printMode ) {
368 | initializePrint();
369 | return;
370 | }
371 | */
372 | initialize();
373 |
374 | if ( printMode ) {
375 | initializePrint();
376 | return;
377 | }
378 |
379 | Reveal.addEventListener('slidechanged', function(){
380 | //console.log('slidechanged',Reveal.getIndices());
381 | animateSlide(0);
382 | });
383 |
384 | Reveal.addEventListener( 'overviewshown', function( event ) {
385 | // pause animation
386 | pause();
387 | } );
388 |
389 | /*
390 | Reveal.addEventListener( 'overviewhidden', function( event ) {
391 | } );
392 | */
393 | Reveal.addEventListener( 'paused', function( event ) {
394 | //console.log('paused ');
395 | // pause animation
396 | pause();
397 | } );
398 | /*
399 | Reveal.addEventListener( 'resumed', function( event ) {
400 | console.log('resumed ');
401 | // resume animation
402 | } );
403 | */
404 | Reveal.addEventListener( 'fragmentshown', function( event ) {
405 | //console.log("fragmentshown",event);
406 | animateSlide(0);
407 | } );
408 |
409 | Reveal.addEventListener( 'fragmenthidden', function( event ) {
410 | //console.log("fragmentshown",event);
411 | animateSlide(0);
412 | } );
413 | } );
414 |
415 |
416 | /*****************************************************************
417 | ** Playback
418 | ******************************************************************/
419 |
420 | document.addEventListener('seekplayback', function( event ) {
421 | //console.log('event seekplayback ' + event.timestamp);
422 | // set animation to event.timestamp
423 | animateSlide(event.timestamp);
424 | });
425 |
426 |
427 | document.addEventListener('startplayback', function( event ) {
428 | //console.log('event startplayback ' + event.timestamp);
429 | playback = true;
430 | animateSlide(event.timestamp);
431 | });
432 |
433 | document.addEventListener('stopplayback', function( event ) {
434 | //console.log('event stopplayback ', event);
435 | playback = false;
436 | animateSlide();
437 | });
438 |
439 | document.addEventListener('startrecording', function( event ) {
440 | //console.log('event startrecording ' + event.timestamp);
441 | isRecording = true;
442 | animateSlide(0);
443 | });
444 |
445 | document.addEventListener('stoprecording', function( event ) {
446 | //console.log('event stoprecording ' + event.timestamp);
447 | isRecording = false;
448 | animateSlide();
449 | });
450 |
451 | this.play = play;
452 | this.pause = pause;
453 | this.seek = seek;
454 | return this;
455 | };
456 |
457 |
458 |
--------------------------------------------------------------------------------
/apresentacao/export/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Configuração de projetos
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Boas vindas
67 |
68 |
69 |
70 |
71 | Muito obrigado pela presença!
72 |
73 |
74 |
75 |
76 |
77 | O que vamos abordar?
78 |
79 |
80 |
81 |
82 |
83 | O que vamos abordar?
84 |
85 | VsCode config
86 | Commits
87 | ESLint
88 | Github Actions
89 | Docker
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 | Antes de tudo, quem sou eu?
104 |
105 |
106 |
107 |
108 | Eu sou …
109 |
110 | Thiago Mariotto
111 | 25 Anos
112 | Ciência da computação
113 | Instrutor Backend Trybe
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 | Porque esse tema é importante?
128 |
129 | É importante termos uma base sólida e estruturada para desenvolvermos nossa aplicação, definindo as configurações iniciais, é mais fácil compartilhar o código e evitar problemas futuros.
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | Configurações do Visual Studio Code
141 |
142 | Pergunta: O que vem na sua cabeça com esse título?
143 |
144 |
145 |
146 |
147 |
148 | Configurações do Visual Studio Code
149 |
150 | Você sabia que é possível compartilhar suas configurações de projeto do VsCode com outras pessoas?
151 |
152 |
153 |
154 |
155 |
156 | Configurações do Visual Studio Code
157 |
158 | É importante pois, caso uma pessoa venha, por exemplo, realizar um Code Review, ela trabalhe em cima das mesmas regras que você definiu.
159 |
160 |
161 |
162 |
163 |
164 | Configurações do Visual Studio Code
165 |
166 | Como fazemos isso?
167 |
168 |
169 |
170 |
171 |
172 | Configurações do Visual Studio Code
173 | {
174 | "editor.formatOnPaste": true,
175 | "editor.formatOnSave": true,
176 | "editor.formatOnSaveMode": true,
177 | "editor.formatOnType": true,
178 | "editor.tabSize": 2,
179 | "editor.codeActionsOnSave": {
180 | "source.fixAll": true,
181 | "source.organizeImports": true
182 | // ...
183 | }
184 |
185 | }
186 |
187 |
188 |
189 |
190 |
191 | Configurações do Visual Studio Code
192 |
193 | dessa forma podemos compartilhar nossas configurações de ambiente de projeto com outras pessoas.
194 | o arquivo sobrepõe suas configurações locais.
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 | Commits
209 |
210 |
211 |
212 |
213 |
214 | Padronização de commits
215 |
216 | Commitlint
217 | Husky
218 | Commitizen
219 |
220 |
221 |
222 |
223 |
224 | Commits Atômicos
225 |
226 |
227 |
228 |
229 | Commits Atômicos
230 |
231 | Submeta pequenas alterações que foram realizadas em seu código.
232 |
233 |
234 |
235 |
236 |
237 | Commits Atômicos
238 |
239 | Seus commits devem contar uma história, a história de desenvolvimento do seu projeto;
240 |
241 |
242 |
243 |
244 |
245 | Commits Atômicos
246 |
247 | Nada de commit bomba.
248 |
249 |
250 |
251 |
252 |
253 | Conventional Commits
254 | Documentação
255 |
256 | Ele fornece um conjunto fácil de regras para criar um histórico de commit explícito descrevendo os recursos, correções e alterações feitas nas mensagens de commit.
257 |
258 |
259 |
260 |
261 |
262 | Conventional Commits
263 | $ git commit -m "feat: insert validation user register"
264 |
265 | $ git commit -m "fix: remove typo user validation register"
266 |
267 |
268 |
269 |
270 |
271 | Commitlint
272 | Documentação
273 |
274 | Podemos Definir que utilizaremos o Conventional Commits, mas nada garante que vamos respeitar ou lembrar as regras em todos os commits.
275 |
276 |
277 |
278 |
279 |
280 | Commitlint
281 |
282 | Com ele conseguimos verificar se a mensagem de commit está dentro dos padrões definidos (Linter dos commits).
283 |
284 |
285 |
286 |
287 |
288 | Commitizen
289 | Documentação
290 |
291 | O Commitizen é uma biblioteca que vai nos ajudar a criar os commits seguindo o padrão do Conventional Commit. Ela gera uma interface no terminal e assim vamos conseguir acessar todos os tipos de commits e suas descrições.
292 |
293 |
294 |
295 |
296 |
297 | Husky
298 | Documentação
299 |
300 | É possível criar gatilhos em determinadas ações, utilizaremos o Husky para disparar uma ação antes de um commit para executar o commitizen e verificar se a mensagem do commit está seguindo o padrão definido.
301 |
302 |
303 |
304 |
305 |
306 | Colocando tudo isso em prática
307 |
308 |
309 |
310 |
311 |
312 | Iniciando Commitlint
313 | $ npm init -y
314 | $ git init
315 |
316 | # install commit lint
317 | $ npm install --save-dev @commitlint/cli
318 | $ npm install --save-dev @commitlint/config-conventional
319 |
320 | # atomic commit
321 | $ git add package.json
322 | $ git commit -m "feat: add commit lint lib"
323 |
324 | # Configure commitlint to use conventional config
325 | $ echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
326 |
327 |
328 |
329 |
330 |
331 |
332 | Testando commitlint
333 | # Para testar a biblioteca
334 | echo "teste" | npx commitlint # deve apontar um erro
335 |
336 | echo "feat: teste" | npx commitlint # deve funcionar corretamente
337 |
338 |
339 |
340 |
341 |
342 | Iniciando Husky
343 | # instalando a lib
344 | $ npm install husky -D
345 |
346 | # atomic commit
347 | $ git add package.json
348 | $ git commit -m "feat: add husky lib"
349 |
350 | # ativando os hooks (gatilhos)
351 | $ npx husky install
352 |
353 | # Add hook que vai disparar o commitlint
354 | $ npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
355 |
356 |
357 |
358 |
359 |
360 |
361 | Iniciando Husky
362 | // para ativar os hooks automaticamente após instalação
363 | "scripts": {
364 | "prepare": "husky install"
365 | }
366 |
367 | // caso o script não seja adicionado ao package.json, toda vez
368 | // que um clone for realizado é necessário realizar
369 | // `$ npx husky install`
370 |
371 |
372 |
373 |
374 |
375 | Realizando um commit
376 | $ echo "node_modules/" > .gitignore
377 |
378 | $ git status
379 | $ git add .gitignore
380 | $ git commit -m "qualquer coisa"
381 | $ git commit -m "chore: add gitignore"
382 |
383 |
384 |
385 |
386 |
387 | Adicionando o Commitizen
388 | $ npm i commitizen -D
389 | $ npx commitizen init cz-conventional-changelog --save-dev --save-exact
390 |
391 | $ echo "console.log(1);" > index.js
392 | $ git add index.js
393 |
394 | "scripts": {
395 | "commit": "cz"
396 | }
397 |
398 | $ npm run commit
399 |
400 |
401 |
402 |
403 |
404 | Utilizando o Commitizen
405 |
406 | Selecione o tipo de mudança que você está realizando
407 | Qual é o escopo desta mudança (por exemplo, componente ou nome do arquivo)
408 | Escreva uma descrição breve e imperativa da mudança (máx. 82 caracteres):
409 |
410 |
411 |
412 |
413 |
414 | Utilizando o Commitizen
415 |
416 | Forneça uma descrição mais longa da mudança:
417 | Existem alterações importantes (importante saber sobre Semantic Versioning)
418 | Essa mudança afeta algum problema em aberto? (Issues)
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 | ESLint
433 |
434 |
435 |
436 |
437 |
438 | O que é o ESLint?
439 |
440 | Analisa seu código estaticamente para encontrar problemas. Você pode executar o ESLint como parte de seu pipeline de integração contínua (CI). Os problemas encontrados pelo ESLint podem ser corrigidos automaticamente.
441 |
442 |
443 |
444 |
445 |
446 | Iniciando ESLint Backend
447 | $ mkdir backend && cd backend
448 | $ mv ../index.js backend
449 |
450 | $ npm init -y
451 | $ npm install eslint -D
452 | $ npx eslint --init
453 |
454 | $ git add [...]
455 | $ npm run commit
456 |
457 |
458 |
459 |
460 |
461 | Executando eslint
462 | "lint": "eslint --no-inline-config --no-error-on-unmatched-pattern -c .eslintrc.json ."
463 |
464 | $ npm run lint
465 |
466 |
467 |
468 |
469 |
475 |
476 |
477 | Github Actions
478 |
479 | O GitHub Actions facilita a automatização de todos os seus fluxos de trabalho de software. Crie, teste e implante seu código diretamente do GitHub.
480 |
481 |
482 |
483 |
484 |
485 | Github Actions - Continuous Integration
486 |
487 | Uma CI é realizada com sucesso quando novas mudanças no código são desenvolvidas, testadas e consolidadas em um repositório, por exemplo, a correção de um bug ou o deploy de uma feature nova.
488 |
489 |
490 |
491 |
492 |
493 | Github Action + ESLint
494 |
495 | Vamos criar uma Action para que, todas as vezes que um PR for aberto ou um push for realizado, o ESLint execute todos os testes em nosso código.
496 |
497 |
498 |
499 |
500 |
501 | Por onde começamos?
502 |
503 |
504 |
505 |
506 |
507 | Configurando minhas Actions
508 |
509 |
510 |
511 |
512 | Configurando minhas Actions
513 | # vamos voltar para a raiz do projeto ./
514 | $ mkdir .github/workflows/main.yml
515 |
516 |
517 |
518 |
519 |
520 | Configurando minhas Actions
521 | on:
522 | pull_request:
523 | types: [opened, synchronize]
524 |
525 | jobs:
526 | eslint:
527 | runs-on: ubuntu-latest
528 | steps:
529 | - uses: actions/checkout@v2
530 |
531 | - uses: actions/setup-node@v2
532 | with:
533 | node-version: 14
534 |
535 | - name: Install back-end modules
536 | run: npm i --prefix backend
537 |
538 | - name: Run linter on back-end
539 | run: npm run lint --prefix backend
540 |
541 |
542 |
543 |
544 |
545 | Testando uma action
546 |
547 | Para isso é necessário realizar um Pull Request em um repositório.
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 | Docker
562 |
563 |
564 |
565 |
566 |
567 | Docker
568 |
569 | Não basta só compartilharmos nossas configurações de trabalho.
570 |
571 |
572 |
573 |
574 |
575 | Docker
576 |
577 | Podemos compartilhar nosso código pronto para ser executado, testado ou modificado, mas como?
578 |
579 |
580 |
581 |
582 |
583 | “Dockerizando” sua aplicação
584 |
585 |
586 |
587 |
588 |
589 | Dockerizando sua aplicação
590 |
591 | Fornecendo toda a estrutura base do projeto para que qualquer pessoa consiga executa-lo em sua máquina, continuando o desenvolvimento ou realizando testes.
592 |
593 |
594 |
595 |
596 |
597 | Case
598 |
599 | Pense o seguinte caso: você está participando de um processo seletivo em que precisa construir uma aplicação simulando uma loja de vendas de sapatos.
600 |
601 |
602 |
603 |
604 |
605 | Case
606 |
607 | É bem provável que você irá desenvolver um CRUD de vendas e ou estoque.
608 |
609 |
610 |
611 |
612 |
613 | Case
614 |
615 | Para desenvolver, você seleciona 3 ferramentas: Node, React e MySQL.
616 |
617 |
618 |
619 |
620 |
621 | Case
622 |
623 | Após finalizado, como ficaria sua aplicação para ser enviada a pessoa avaliadora? Conte-me …
624 |
625 |
626 |
627 |
628 |
629 | Case
630 |
631 | Agora, imagine que: a pessoa que irá testar sua aplicação trabalha com Python, não possuí node e nem MySQL instalado na máquina :/
632 |
633 |
634 |
635 |
636 |
637 |
638 | Ela vai ter um trabalhão não é mesmo?
639 |
640 |
641 |
642 |
643 |
644 | Mão na massa no teclado
645 |
646 |
647 |
648 |
649 |
650 | Utilizando Docker
651 |
652 | Vamos trabalhar com um exemplo parecido
653 |
654 |
655 |
656 |
657 |
658 | Utilizando Docker
659 |
660 | Vamos imaginar que estamos desenvolvendo uma aplicação completa (front e back), utilizando as seguintes ferramentas:
661 |
662 |
663 |
664 |
665 |
666 | Nossas ferramentas
667 |
668 | API com Node rodando na versão 12.22;
669 | Aplicação WEB com REACT e node na versão 12.22;
670 | Banco de dados MySQL na versão 5.7;
671 |
672 |
673 |
674 |
675 |
676 | Colocando em prática
677 |
678 | Criar o Dockerfile do Backend
679 | Criar o Dockerfile do Frontend
680 | Criar o Docker Compose
681 |
682 | Serviço do Back utilizando o Dockerfile
683 | Serviço do Front utilizando o Dockerfile
684 | Serviço MySQL sendo populado com um banco de dados
685 |
686 |
687 |
688 |
689 |
690 |
691 |
692 | Colocando em prática
693 |
694 | Ponto de atenção: o container do Frontend é dependente do container do Backend e o Backend por sua vez é dependente do MySQL.
695 |
696 |
697 |
698 |
699 |
700 | Let’s Code
701 |
702 |
703 |
704 |
705 | Dockerfile Frontend
706 | FROM node:12.22-alpine
707 |
708 |
709 | WORKDIR /app
710 |
711 | COPY package*.json ./
712 |
713 | RUN npm install
714 |
715 | RUN chmod 777 node_modules
716 |
717 | COPY . .
718 |
719 | EXPOSE 3000
720 |
721 | CMD ["npm", "start"]
722 |
723 |
724 |
725 |
726 |
727 | Dockerfile Backend
728 | FROM node:12.22-alpine
729 |
730 | WORKDIR /app
731 |
732 | COPY package*.json ./
733 |
734 | RUN npm install
735 |
736 | RUN chmod 777 node_modules
737 |
738 | COPY . .
739 |
740 | EXPOSE 3333
741 |
742 | CMD ["npm", "start"]
743 |
744 |
745 |
746 |
747 |
748 | Docker compose
749 | version: '3.1'
750 |
751 | services:
752 | database:
753 | image: mysql:5.7
754 | restart: always
755 | container_name: mysql_compose
756 | ports:
757 | - 3306:3306
758 | environment:
759 | - MYSQL_ROOT_PASSWORD=docker
760 | volumes:
761 | - ./backend/database/mysql-seeder:/docker-entrypoint-initdb.d
762 |
763 | api:
764 | build: ./backend
765 | container_name: backend_compose
766 | ports:
767 | - 3333:3333
768 | depends_on:
769 | - database
770 | volumes:
771 | - /app/node_modules
772 | - ./backend:/app
773 |
774 | web:
775 | build: ./frontend
776 | container_name: frontend_compose
777 | ports:
778 | - 3000:3000
779 | volumes:
780 | - /app/node_modules
781 | - ./frontend:/app
782 | depends_on:
783 | - api
784 |
785 |
786 |
787 |
788 |
789 |
790 | Agora nossa pessoa avaliadora poderá testar nosso código executando somente um comando.
791 |
792 |
793 |
794 |
795 |
796 |
797 |
798 |
799 |
800 |
801 |
802 |
803 |
804 |
805 |
806 |
807 |
808 |
809 |
810 |
811 |
812 |
813 |
814 |
815 |
816 |
817 |
818 |
819 |
820 |
821 |
822 |
823 |
824 |
825 |
826 |
827 |
828 |
829 |
830 |
831 |
832 |
833 |
834 |
835 |
836 |
837 |
838 |
839 |
840 |
1034 |
1035 |
1036 |
1037 |
--------------------------------------------------------------------------------
/apresentacao/export/libs/reveal.js/4.1.3/reveal.css:
--------------------------------------------------------------------------------
1 | /*!
2 | * reveal.js 4.1.1
3 | * https://revealjs.com
4 | * MIT licensed
5 | *
6 | * Copyright (C) 2020 Hakim El Hattab, https://hakim.se
7 | */
8 | .reveal .r-stretch,.reveal .stretch{max-width:none;max-height:none}.reveal pre.r-stretch code,.reveal pre.stretch code{height:100%;max-height:100%;box-sizing:border-box}.reveal .r-fit-text{display:inline-block;white-space:nowrap}.reveal .r-stack{display:grid}.reveal .r-stack>*{grid-area:1/1;margin:auto}.reveal .r-hstack,.reveal .r-vstack{display:flex}.reveal .r-hstack img,.reveal .r-hstack video,.reveal .r-vstack img,.reveal .r-vstack video{min-width:0;min-height:0;-o-object-fit:contain;object-fit:contain}.reveal .r-vstack{flex-direction:column;align-items:center;justify-content:center}.reveal .r-hstack{flex-direction:row;align-items:center;justify-content:center}.reveal .items-stretch{align-items:stretch}.reveal .items-start{align-items:flex-start}.reveal .items-center{align-items:center}.reveal .items-end{align-items:flex-end}.reveal .justify-between{justify-content:space-between}.reveal .justify-around{justify-content:space-around}.reveal .justify-start{justify-content:flex-start}.reveal .justify-center{justify-content:center}.reveal .justify-end{justify-content:flex-end}html.reveal-full-page{width:100%;height:100%;height:100vh;height:calc(var(--vh,1vh) * 100);overflow:hidden}.reveal-viewport{height:100%;overflow:hidden;position:relative;line-height:1;margin:0;background-color:#fff;color:#000}.reveal .slides section .fragment{opacity:0;visibility:hidden;transition:all .2s ease;will-change:opacity}.reveal .slides section .fragment.visible{opacity:1;visibility:inherit}.reveal .slides section .fragment.disabled{transition:none}.reveal .slides section .fragment.grow{opacity:1;visibility:inherit}.reveal .slides section .fragment.grow.visible{transform:scale(1.3)}.reveal .slides section .fragment.shrink{opacity:1;visibility:inherit}.reveal .slides section .fragment.shrink.visible{transform:scale(.7)}.reveal .slides section .fragment.zoom-in{transform:scale(.1)}.reveal .slides section .fragment.zoom-in.visible{transform:none}.reveal .slides section .fragment.fade-out{opacity:1;visibility:inherit}.reveal .slides section .fragment.fade-out.visible{opacity:0;visibility:hidden}.reveal .slides section .fragment.semi-fade-out{opacity:1;visibility:inherit}.reveal .slides section .fragment.semi-fade-out.visible{opacity:.5;visibility:inherit}.reveal .slides section .fragment.strike{opacity:1;visibility:inherit}.reveal .slides section .fragment.strike.visible{text-decoration:line-through}.reveal .slides section .fragment.fade-up{transform:translate(0,40px)}.reveal .slides section .fragment.fade-up.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-down{transform:translate(0,-40px)}.reveal .slides section .fragment.fade-down.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-right{transform:translate(-40px,0)}.reveal .slides section .fragment.fade-right.visible{transform:translate(0,0)}.reveal .slides section .fragment.fade-left{transform:translate(40px,0)}.reveal .slides section .fragment.fade-left.visible{transform:translate(0,0)}.reveal .slides section .fragment.current-visible,.reveal .slides section .fragment.fade-in-then-out{opacity:0;visibility:hidden}.reveal .slides section .fragment.current-visible.current-fragment,.reveal .slides section .fragment.fade-in-then-out.current-fragment{opacity:1;visibility:inherit}.reveal .slides section .fragment.fade-in-then-semi-out{opacity:0;visibility:hidden}.reveal .slides section .fragment.fade-in-then-semi-out.visible{opacity:.5;visibility:inherit}.reveal .slides section .fragment.fade-in-then-semi-out.current-fragment{opacity:1;visibility:inherit}.reveal .slides section .fragment.highlight-blue,.reveal .slides section .fragment.highlight-current-blue,.reveal .slides section .fragment.highlight-current-green,.reveal .slides section .fragment.highlight-current-red,.reveal .slides section .fragment.highlight-green,.reveal .slides section .fragment.highlight-red{opacity:1;visibility:inherit}.reveal .slides section .fragment.highlight-red.visible{color:#ff2c2d}.reveal .slides section .fragment.highlight-green.visible{color:#17ff2e}.reveal .slides section .fragment.highlight-blue.visible{color:#1b91ff}.reveal .slides section .fragment.highlight-current-red.current-fragment{color:#ff2c2d}.reveal .slides section .fragment.highlight-current-green.current-fragment{color:#17ff2e}.reveal .slides section .fragment.highlight-current-blue.current-fragment{color:#1b91ff}.reveal:after{content:"";font-style:italic}.reveal iframe{z-index:1}.reveal a{position:relative}@keyframes bounce-right{0%,10%,25%,40%,50%{transform:translateX(0)}20%{transform:translateX(10px)}30%{transform:translateX(-5px)}}@keyframes bounce-left{0%,10%,25%,40%,50%{transform:translateX(0)}20%{transform:translateX(-10px)}30%{transform:translateX(5px)}}@keyframes bounce-down{0%,10%,25%,40%,50%{transform:translateY(0)}20%{transform:translateY(10px)}30%{transform:translateY(-5px)}}.reveal .controls{display:none;position:absolute;top:auto;bottom:12px;right:12px;left:auto;z-index:11;color:#000;pointer-events:none;font-size:10px}.reveal .controls button{position:absolute;padding:0;background-color:transparent;border:0;outline:0;cursor:pointer;color:currentColor;transform:scale(.9999);transition:color .2s ease,opacity .2s ease,transform .2s ease;z-index:2;pointer-events:auto;font-size:inherit;visibility:hidden;opacity:0;-webkit-appearance:none;-webkit-tap-highlight-color:transparent}.reveal .controls .controls-arrow:after,.reveal .controls .controls-arrow:before{content:"";position:absolute;top:0;left:0;width:2.6em;height:.5em;border-radius:.25em;background-color:currentColor;transition:all .15s ease,background-color .8s ease;transform-origin:.2em 50%;will-change:transform}.reveal .controls .controls-arrow{position:relative;width:3.6em;height:3.6em}.reveal .controls .controls-arrow:before{transform:translateX(.5em) translateY(1.55em) rotate(45deg)}.reveal .controls .controls-arrow:after{transform:translateX(.5em) translateY(1.55em) rotate(-45deg)}.reveal .controls .controls-arrow:hover:before{transform:translateX(.5em) translateY(1.55em) rotate(40deg)}.reveal .controls .controls-arrow:hover:after{transform:translateX(.5em) translateY(1.55em) rotate(-40deg)}.reveal .controls .controls-arrow:active:before{transform:translateX(.5em) translateY(1.55em) rotate(36deg)}.reveal .controls .controls-arrow:active:after{transform:translateX(.5em) translateY(1.55em) rotate(-36deg)}.reveal .controls .navigate-left{right:6.4em;bottom:3.2em;transform:translateX(-10px)}.reveal .controls .navigate-left.highlight{animation:bounce-left 2s 50 both ease-out}.reveal .controls .navigate-right{right:0;bottom:3.2em;transform:translateX(10px)}.reveal .controls .navigate-right .controls-arrow{transform:rotate(180deg)}.reveal .controls .navigate-right.highlight{animation:bounce-right 2s 50 both ease-out}.reveal .controls .navigate-up{right:3.2em;bottom:6.4em;transform:translateY(-10px)}.reveal .controls .navigate-up .controls-arrow{transform:rotate(90deg)}.reveal .controls .navigate-down{right:3.2em;bottom:-1.4em;padding-bottom:1.4em;transform:translateY(10px)}.reveal .controls .navigate-down .controls-arrow{transform:rotate(-90deg)}.reveal .controls .navigate-down.highlight{animation:bounce-down 2s 50 both ease-out}.reveal .controls[data-controls-back-arrows=faded] .navigate-up.enabled{opacity:.3}.reveal .controls[data-controls-back-arrows=faded] .navigate-up.enabled:hover{opacity:1}.reveal .controls[data-controls-back-arrows=hidden] .navigate-up.enabled{opacity:0;visibility:hidden}.reveal .controls .enabled{visibility:visible;opacity:.9;cursor:pointer;transform:none}.reveal .controls .enabled.fragmented{opacity:.5}.reveal .controls .enabled.fragmented:hover,.reveal .controls .enabled:hover{opacity:1}.reveal:not(.rtl) .controls[data-controls-back-arrows=faded] .navigate-left.enabled{opacity:.3}.reveal:not(.rtl) .controls[data-controls-back-arrows=faded] .navigate-left.enabled:hover{opacity:1}.reveal:not(.rtl) .controls[data-controls-back-arrows=hidden] .navigate-left.enabled{opacity:0;visibility:hidden}.reveal.rtl .controls[data-controls-back-arrows=faded] .navigate-right.enabled{opacity:.3}.reveal.rtl .controls[data-controls-back-arrows=faded] .navigate-right.enabled:hover{opacity:1}.reveal.rtl .controls[data-controls-back-arrows=hidden] .navigate-right.enabled{opacity:0;visibility:hidden}.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-down,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-up{display:none}.reveal:not(.has-vertical-slides) .controls .navigate-left,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-left{bottom:1.4em;right:5.5em}.reveal:not(.has-vertical-slides) .controls .navigate-right,.reveal[data-navigation-mode=linear].has-horizontal-slides .navigate-right{bottom:1.4em;right:.5em}.reveal:not(.has-horizontal-slides) .controls .navigate-up{right:1.4em;bottom:5em}.reveal:not(.has-horizontal-slides) .controls .navigate-down{right:1.4em;bottom:.5em}.reveal.has-dark-background .controls{color:#fff}.reveal.has-light-background .controls{color:#000}.reveal.no-hover .controls .controls-arrow:active:before,.reveal.no-hover .controls .controls-arrow:hover:before{transform:translateX(.5em) translateY(1.55em) rotate(45deg)}.reveal.no-hover .controls .controls-arrow:active:after,.reveal.no-hover .controls .controls-arrow:hover:after{transform:translateX(.5em) translateY(1.55em) rotate(-45deg)}@media screen and (min-width:500px){.reveal .controls[data-controls-layout=edges]{top:0;right:0;bottom:0;left:0}.reveal .controls[data-controls-layout=edges] .navigate-down,.reveal .controls[data-controls-layout=edges] .navigate-left,.reveal .controls[data-controls-layout=edges] .navigate-right,.reveal .controls[data-controls-layout=edges] .navigate-up{bottom:auto;right:auto}.reveal .controls[data-controls-layout=edges] .navigate-left{top:50%;left:.8em;margin-top:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-right{top:50%;right:.8em;margin-top:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-up{top:.8em;left:50%;margin-left:-1.8em}.reveal .controls[data-controls-layout=edges] .navigate-down{bottom:-.3em;left:50%;margin-left:-1.8em}}.reveal .progress{position:absolute;display:none;height:3px;width:100%;bottom:0;left:0;z-index:10;background-color:rgba(0,0,0,.2);color:#fff}.reveal .progress:after{content:"";display:block;position:absolute;height:10px;width:100%;top:-10px}.reveal .progress span{display:block;height:100%;width:100%;background-color:currentColor;transition:transform .8s cubic-bezier(.26,.86,.44,.985);transform-origin:0 0;transform:scaleX(0)}.reveal .slide-number{position:absolute;display:block;right:8px;bottom:8px;z-index:31;font-family:Helvetica,sans-serif;font-size:12px;line-height:1;color:#fff;background-color:rgba(0,0,0,.4);padding:5px}.reveal .slide-number a{color:currentColor}.reveal .slide-number-delimiter{margin:0 3px}.reveal{position:relative;width:100%;height:100%;overflow:hidden;touch-action:pinch-zoom}.reveal.embedded{touch-action:pan-y}.reveal .slides{position:absolute;width:100%;height:100%;top:0;right:0;bottom:0;left:0;margin:auto;pointer-events:none;overflow:visible;z-index:1;text-align:center;perspective:600px;perspective-origin:50% 40%}.reveal .slides>section{perspective:600px}.reveal .slides>section,.reveal .slides>section>section{display:none;position:absolute;width:100%;pointer-events:auto;z-index:10;transform-style:flat;transition:transform-origin .8s cubic-bezier(.26,.86,.44,.985),transform .8s cubic-bezier(.26,.86,.44,.985),visibility .8s cubic-bezier(.26,.86,.44,.985),opacity .8s cubic-bezier(.26,.86,.44,.985)}.reveal[data-transition-speed=fast] .slides section{transition-duration:.4s}.reveal[data-transition-speed=slow] .slides section{transition-duration:1.2s}.reveal .slides section[data-transition-speed=fast]{transition-duration:.4s}.reveal .slides section[data-transition-speed=slow]{transition-duration:1.2s}.reveal .slides>section.stack{padding-top:0;padding-bottom:0;pointer-events:none;height:100%}.reveal .slides>section.present,.reveal .slides>section>section.present{display:block;z-index:11;opacity:1}.reveal .slides>section:empty,.reveal .slides>section>section:empty,.reveal .slides>section>section[data-background-interactive],.reveal .slides>section[data-background-interactive]{pointer-events:none}.reveal.center,.reveal.center .slides,.reveal.center .slides section{min-height:0!important}.reveal .slides>section:not(.present),.reveal .slides>section>section:not(.present){pointer-events:none}.reveal.overview .slides>section,.reveal.overview .slides>section>section{pointer-events:auto}.reveal .slides>section.future,.reveal .slides>section.past,.reveal .slides>section>section.future,.reveal .slides>section>section.past{opacity:0}.reveal.slide section{-webkit-backface-visibility:hidden;backface-visibility:hidden}.reveal .slides>section[data-transition=slide].past,.reveal .slides>section[data-transition~=slide-out].past,.reveal.slide .slides>section:not([data-transition]).past{transform:translate(-150%,0)}.reveal .slides>section[data-transition=slide].future,.reveal .slides>section[data-transition~=slide-in].future,.reveal.slide .slides>section:not([data-transition]).future{transform:translate(150%,0)}.reveal .slides>section>section[data-transition=slide].past,.reveal .slides>section>section[data-transition~=slide-out].past,.reveal.slide .slides>section>section:not([data-transition]).past{transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=slide].future,.reveal .slides>section>section[data-transition~=slide-in].future,.reveal.slide .slides>section>section:not([data-transition]).future{transform:translate(0,150%)}.reveal.linear section{-webkit-backface-visibility:hidden;backface-visibility:hidden}.reveal .slides>section[data-transition=linear].past,.reveal .slides>section[data-transition~=linear-out].past,.reveal.linear .slides>section:not([data-transition]).past{transform:translate(-150%,0)}.reveal .slides>section[data-transition=linear].future,.reveal .slides>section[data-transition~=linear-in].future,.reveal.linear .slides>section:not([data-transition]).future{transform:translate(150%,0)}.reveal .slides>section>section[data-transition=linear].past,.reveal .slides>section>section[data-transition~=linear-out].past,.reveal.linear .slides>section>section:not([data-transition]).past{transform:translate(0,-150%)}.reveal .slides>section>section[data-transition=linear].future,.reveal .slides>section>section[data-transition~=linear-in].future,.reveal.linear .slides>section>section:not([data-transition]).future{transform:translate(0,150%)}.reveal .slides section[data-transition=default].stack,.reveal.default .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=default].past,.reveal .slides>section[data-transition~=default-out].past,.reveal.default .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=default].future,.reveal .slides>section[data-transition~=default-in].future,.reveal.default .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=default].past,.reveal .slides>section>section[data-transition~=default-out].past,.reveal.default .slides>section>section:not([data-transition]).past{transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=default].future,.reveal .slides>section>section[data-transition~=default-in].future,.reveal.default .slides>section>section:not([data-transition]).future{transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides section[data-transition=convex].stack,.reveal.convex .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=convex].past,.reveal .slides>section[data-transition~=convex-out].past,.reveal.convex .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=convex].future,.reveal .slides>section[data-transition~=convex-in].future,.reveal.convex .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=convex].past,.reveal .slides>section>section[data-transition~=convex-out].past,.reveal.convex .slides>section>section:not([data-transition]).past{transform:translate3d(0,-300px,0) rotateX(70deg) translate3d(0,-300px,0)}.reveal .slides>section>section[data-transition=convex].future,.reveal .slides>section>section[data-transition~=convex-in].future,.reveal.convex .slides>section>section:not([data-transition]).future{transform:translate3d(0,300px,0) rotateX(-70deg) translate3d(0,300px,0)}.reveal .slides section[data-transition=concave].stack,.reveal.concave .slides section.stack{transform-style:preserve-3d}.reveal .slides>section[data-transition=concave].past,.reveal .slides>section[data-transition~=concave-out].past,.reveal.concave .slides>section:not([data-transition]).past{transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal .slides>section[data-transition=concave].future,.reveal .slides>section[data-transition~=concave-in].future,.reveal.concave .slides>section:not([data-transition]).future{transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal .slides>section>section[data-transition=concave].past,.reveal .slides>section>section[data-transition~=concave-out].past,.reveal.concave .slides>section>section:not([data-transition]).past{transform:translate3d(0,-80%,0) rotateX(-70deg) translate3d(0,-80%,0)}.reveal .slides>section>section[data-transition=concave].future,.reveal .slides>section>section[data-transition~=concave-in].future,.reveal.concave .slides>section>section:not([data-transition]).future{transform:translate3d(0,80%,0) rotateX(70deg) translate3d(0,80%,0)}.reveal .slides section[data-transition=zoom],.reveal.zoom .slides section:not([data-transition]){transition-timing-function:ease}.reveal .slides>section[data-transition=zoom].past,.reveal .slides>section[data-transition~=zoom-out].past,.reveal.zoom .slides>section:not([data-transition]).past{visibility:hidden;transform:scale(16)}.reveal .slides>section[data-transition=zoom].future,.reveal .slides>section[data-transition~=zoom-in].future,.reveal.zoom .slides>section:not([data-transition]).future{visibility:hidden;transform:scale(.2)}.reveal .slides>section>section[data-transition=zoom].past,.reveal .slides>section>section[data-transition~=zoom-out].past,.reveal.zoom .slides>section>section:not([data-transition]).past{transform:scale(16)}.reveal .slides>section>section[data-transition=zoom].future,.reveal .slides>section>section[data-transition~=zoom-in].future,.reveal.zoom .slides>section>section:not([data-transition]).future{transform:scale(.2)}.reveal.cube .slides{perspective:1300px}.reveal.cube .slides section{padding:30px;min-height:700px;-webkit-backface-visibility:hidden;backface-visibility:hidden;box-sizing:border-box;transform-style:preserve-3d}.reveal.center.cube .slides section{min-height:0}.reveal.cube .slides section:not(.stack):before{content:"";position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);border-radius:4px;transform:translateZ(-20px)}.reveal.cube .slides section:not(.stack):after{content:"";position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0 0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);transform:translateZ(-90px) rotateX(65deg)}.reveal.cube .slides>section.stack{padding:0;background:0 0}.reveal.cube .slides>section.past{transform-origin:100% 0;transform:translate3d(-100%,0,0) rotateY(-90deg)}.reveal.cube .slides>section.future{transform-origin:0 0;transform:translate3d(100%,0,0) rotateY(90deg)}.reveal.cube .slides>section>section.past{transform-origin:0 100%;transform:translate3d(0,-100%,0) rotateX(90deg)}.reveal.cube .slides>section>section.future{transform-origin:0 0;transform:translate3d(0,100%,0) rotateX(-90deg)}.reveal.page .slides{perspective-origin:0 50%;perspective:3000px}.reveal.page .slides section{padding:30px;min-height:700px;box-sizing:border-box;transform-style:preserve-3d}.reveal.page .slides section.past{z-index:12}.reveal.page .slides section:not(.stack):before{content:"";position:absolute;display:block;width:100%;height:100%;left:0;top:0;background:rgba(0,0,0,.1);transform:translateZ(-20px)}.reveal.page .slides section:not(.stack):after{content:"";position:absolute;display:block;width:90%;height:30px;left:5%;bottom:0;background:0 0;z-index:1;border-radius:4px;box-shadow:0 95px 25px rgba(0,0,0,.2);-webkit-transform:translateZ(-90px) rotateX(65deg)}.reveal.page .slides>section.stack{padding:0;background:0 0}.reveal.page .slides>section.past{transform-origin:0 0;transform:translate3d(-40%,0,0) rotateY(-80deg)}.reveal.page .slides>section.future{transform-origin:100% 0;transform:translate3d(0,0,0)}.reveal.page .slides>section>section.past{transform-origin:0 0;transform:translate3d(0,-40%,0) rotateX(80deg)}.reveal.page .slides>section>section.future{transform-origin:0 100%;transform:translate3d(0,0,0)}.reveal .slides section[data-transition=fade],.reveal.fade .slides section:not([data-transition]),.reveal.fade .slides>section>section:not([data-transition]){transform:none;transition:opacity .5s}.reveal.fade.overview .slides section,.reveal.fade.overview .slides>section>section{transition:none}.reveal .slides section[data-transition=none],.reveal.none .slides section:not([data-transition]){transform:none;transition:none}.reveal .pause-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background:#000;visibility:hidden;opacity:0;z-index:100;transition:all 1s ease}.reveal .pause-overlay .resume-button{position:absolute;bottom:20px;right:20px;color:#ccc;border-radius:2px;padding:6px 14px;border:2px solid #ccc;font-size:16px;background:0 0;cursor:pointer}.reveal .pause-overlay .resume-button:hover{color:#fff;border-color:#fff}.reveal.paused .pause-overlay{visibility:visible;opacity:1}.reveal .no-transition,.reveal .no-transition *,.reveal .slides.disable-slide-transitions section{transition:none!important}.reveal .slides.disable-slide-transitions section{transform:none!important}.reveal .backgrounds{position:absolute;width:100%;height:100%;top:0;left:0;perspective:600px}.reveal .slide-background{display:none;position:absolute;width:100%;height:100%;opacity:0;visibility:hidden;overflow:hidden;background-color:rgba(0,0,0,0);transition:all .8s cubic-bezier(.26,.86,.44,.985)}.reveal .slide-background-content{position:absolute;width:100%;height:100%;background-position:50% 50%;background-repeat:no-repeat;background-size:cover}.reveal .slide-background.stack{display:block}.reveal .slide-background.present{opacity:1;visibility:visible;z-index:2}.print-pdf .reveal .slide-background{opacity:1!important;visibility:visible!important}.reveal .slide-background video{position:absolute;width:100%;height:100%;max-width:none;max-height:none;top:0;left:0;-o-object-fit:cover;object-fit:cover}.reveal .slide-background[data-background-size=contain] video{-o-object-fit:contain;object-fit:contain}.reveal>.backgrounds .slide-background[data-background-transition=none],.reveal[data-background-transition=none]>.backgrounds .slide-background:not([data-background-transition]){transition:none}.reveal>.backgrounds .slide-background[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background:not([data-background-transition]){opacity:1;-webkit-backface-visibility:hidden;backface-visibility:hidden}.reveal>.backgrounds .slide-background.past[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background.past:not([data-background-transition]){transform:translate(-100%,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background.future:not([data-background-transition]){transform:translate(100%,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){transform:translate(0,-100%)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=slide],.reveal[data-background-transition=slide]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){transform:translate(0,100%)}.reveal>.backgrounds .slide-background.past[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(-100%,0,0) rotateY(-90deg) translate3d(-100%,0,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(100%,0,0) rotateY(90deg) translate3d(100%,0,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(0,-100%,0) rotateX(90deg) translate3d(0,-100%,0)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=convex],.reveal[data-background-transition=convex]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(0,100%,0) rotateX(-90deg) translate3d(0,100%,0)}.reveal>.backgrounds .slide-background.past[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(-100%,0,0) rotateY(90deg) translate3d(-100%,0,0)}.reveal>.backgrounds .slide-background.future[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(100%,0,0) rotateY(-90deg) translate3d(100%,0,0)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;transform:translate3d(0,-100%,0) rotateX(-90deg) translate3d(0,-100%,0)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=concave],.reveal[data-background-transition=concave]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;transform:translate3d(0,100%,0) rotateX(90deg) translate3d(0,100%,0)}.reveal>.backgrounds .slide-background[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background:not([data-background-transition]){transition-timing-function:ease}.reveal>.backgrounds .slide-background.past[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background.past:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(16)}.reveal>.backgrounds .slide-background.future[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background.future:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(.2)}.reveal>.backgrounds .slide-background>.slide-background.past[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.past:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(16)}.reveal>.backgrounds .slide-background>.slide-background.future[data-background-transition=zoom],.reveal[data-background-transition=zoom]>.backgrounds .slide-background>.slide-background.future:not([data-background-transition]){opacity:0;visibility:hidden;transform:scale(.2)}.reveal[data-transition-speed=fast]>.backgrounds .slide-background{transition-duration:.4s}.reveal[data-transition-speed=slow]>.backgrounds .slide-background{transition-duration:1.2s}.reveal [data-auto-animate-target^=unmatched]{will-change:opacity}.reveal section[data-auto-animate]:not(.stack):not([data-auto-animate=running]) [data-auto-animate-target^=unmatched]{opacity:0}.reveal.overview{perspective-origin:50% 50%;perspective:700px}.reveal.overview .slides{-moz-transform-style:preserve-3d}.reveal.overview .slides section{height:100%;top:0!important;opacity:1!important;overflow:hidden;visibility:visible!important;cursor:pointer;box-sizing:border-box}.reveal.overview .slides section.present,.reveal.overview .slides section:hover{outline:10px solid rgba(150,150,150,.4);outline-offset:10px}.reveal.overview .slides section .fragment{opacity:1;transition:none}.reveal.overview .slides section:after,.reveal.overview .slides section:before{display:none!important}.reveal.overview .slides>section.stack{padding:0;top:0!important;background:0 0;outline:0;overflow:visible}.reveal.overview .backgrounds{perspective:inherit;-moz-transform-style:preserve-3d}.reveal.overview .backgrounds .slide-background{opacity:1;visibility:visible;outline:10px solid rgba(150,150,150,.1);outline-offset:10px}.reveal.overview .backgrounds .slide-background.stack{overflow:visible}.reveal.overview .slides section,.reveal.overview-deactivating .slides section{transition:none}.reveal.overview .backgrounds .slide-background,.reveal.overview-deactivating .backgrounds .slide-background{transition:none}.reveal.rtl .slides,.reveal.rtl .slides h1,.reveal.rtl .slides h2,.reveal.rtl .slides h3,.reveal.rtl .slides h4,.reveal.rtl .slides h5,.reveal.rtl .slides h6{direction:rtl;font-family:sans-serif}.reveal.rtl code,.reveal.rtl pre{direction:ltr}.reveal.rtl ol,.reveal.rtl ul{text-align:right}.reveal.rtl .progress span{transform-origin:100% 0}.reveal.has-parallax-background .backgrounds{transition:all .8s ease}.reveal.has-parallax-background[data-transition-speed=fast] .backgrounds{transition-duration:.4s}.reveal.has-parallax-background[data-transition-speed=slow] .backgrounds{transition-duration:1.2s}.reveal>.overlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:1000;background:rgba(0,0,0,.9);transition:all .3s ease}.reveal>.overlay .spinner{position:absolute;display:block;top:50%;left:50%;width:32px;height:32px;margin:-16px 0 0 -16px;z-index:10;background-image:url(data:image/gif;base64,R0lGODlhIAAgAPMAAJmZmf%2F%2F%2F6%2Bvr8nJybW1tcDAwOjo6Nvb26ioqKOjo7Ozs%2FLy8vz8%2FAAAAAAAAAAAACH%2FC05FVFNDQVBFMi4wAwEAAAAh%2FhpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh%2BQQJCgAAACwAAAAAIAAgAAAE5xDISWlhperN52JLhSSdRgwVo1ICQZRUsiwHpTJT4iowNS8vyW2icCF6k8HMMBkCEDskxTBDAZwuAkkqIfxIQyhBQBFvAQSDITM5VDW6XNE4KagNh6Bgwe60smQUB3d4Rz1ZBApnFASDd0hihh12BkE9kjAJVlycXIg7CQIFA6SlnJ87paqbSKiKoqusnbMdmDC2tXQlkUhziYtyWTxIfy6BE8WJt5YJvpJivxNaGmLHT0VnOgSYf0dZXS7APdpB309RnHOG5gDqXGLDaC457D1zZ%2FV%2FnmOM82XiHRLYKhKP1oZmADdEAAAh%2BQQJCgAAACwAAAAAIAAgAAAE6hDISWlZpOrNp1lGNRSdRpDUolIGw5RUYhhHukqFu8DsrEyqnWThGvAmhVlteBvojpTDDBUEIFwMFBRAmBkSgOrBFZogCASwBDEY%2FCZSg7GSE0gSCjQBMVG023xWBhklAnoEdhQEfyNqMIcKjhRsjEdnezB%2BA4k8gTwJhFuiW4dokXiloUepBAp5qaKpp6%2BHo7aWW54wl7obvEe0kRuoplCGepwSx2jJvqHEmGt6whJpGpfJCHmOoNHKaHx61WiSR92E4lbFoq%2BB6QDtuetcaBPnW6%2BO7wDHpIiK9SaVK5GgV543tzjgGcghAgAh%2BQQJCgAAACwAAAAAIAAgAAAE7hDISSkxpOrN5zFHNWRdhSiVoVLHspRUMoyUakyEe8PTPCATW9A14E0UvuAKMNAZKYUZCiBMuBakSQKG8G2FzUWox2AUtAQFcBKlVQoLgQReZhQlCIJesQXI5B0CBnUMOxMCenoCfTCEWBsJColTMANldx15BGs8B5wlCZ9Po6OJkwmRpnqkqnuSrayqfKmqpLajoiW5HJq7FL1Gr2mMMcKUMIiJgIemy7xZtJsTmsM4xHiKv5KMCXqfyUCJEonXPN2rAOIAmsfB3uPoAK%2B%2BG%2Bw48edZPK%2BM6hLJpQg484enXIdQFSS1u6UhksENEQAAIfkECQoAAAAsAAAAACAAIAAABOcQyEmpGKLqzWcZRVUQnZYg1aBSh2GUVEIQ2aQOE%2BG%2BcD4ntpWkZQj1JIiZIogDFFyHI0UxQwFugMSOFIPJftfVAEoZLBbcLEFhlQiqGp1Vd140AUklUN3eCA51C1EWMzMCezCBBmkxVIVHBWd3HHl9JQOIJSdSnJ0TDKChCwUJjoWMPaGqDKannasMo6WnM562R5YluZRwur0wpgqZE7NKUm%2BFNRPIhjBJxKZteWuIBMN4zRMIVIhffcgojwCF117i4nlLnY5ztRLsnOk%2BaV%2BoJY7V7m76PdkS4trKcdg0Zc0tTcKkRAAAIfkECQoAAAAsAAAAACAAIAAABO4QyEkpKqjqzScpRaVkXZWQEximw1BSCUEIlDohrft6cpKCk5xid5MNJTaAIkekKGQkWyKHkvhKsR7ARmitkAYDYRIbUQRQjWBwJRzChi9CRlBcY1UN4g0%2FVNB0AlcvcAYHRyZPdEQFYV8ccwR5HWxEJ02YmRMLnJ1xCYp0Y5idpQuhopmmC2KgojKasUQDk5BNAwwMOh2RtRq5uQuPZKGIJQIGwAwGf6I0JXMpC8C7kXWDBINFMxS4DKMAWVWAGYsAdNqW5uaRxkSKJOZKaU3tPOBZ4DuK2LATgJhkPJMgTwKCdFjyPHEnKxFCDhEAACH5BAkKAAAALAAAAAAgACAAAATzEMhJaVKp6s2nIkolIJ2WkBShpkVRWqqQrhLSEu9MZJKK9y1ZrqYK9WiClmvoUaF8gIQSNeF1Er4MNFn4SRSDARWroAIETg1iVwuHjYB1kYc1mwruwXKC9gmsJXliGxc%2BXiUCby9ydh1sOSdMkpMTBpaXBzsfhoc5l58Gm5yToAaZhaOUqjkDgCWNHAULCwOLaTmzswadEqggQwgHuQsHIoZCHQMMQgQGubVEcxOPFAcMDAYUA85eWARmfSRQCdcMe0zeP1AAygwLlJtPNAAL19DARdPzBOWSm1brJBi45soRAWQAAkrQIykShQ9wVhHCwCQCACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiRMDjI0Fd30%2FiI2UA5GSS5UDj2l6NoqgOgN4gksEBgYFf0FDqKgHnyZ9OX8HrgYHdHpcHQULXAS2qKpENRg7eAMLC7kTBaixUYFkKAzWAAnLC7FLVxLWDBLKCwaKTULgEwbLA4hJtOkSBNqITT3xEgfLpBtzE%2FjiuL04RGEBgwWhShRgQExHBAAh%2BQQJCgAAACwAAAAAIAAgAAAE7xDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfZiCqGk5dTESJeaOAlClzsJsqwiJwiqnFrb2nS9kmIcgEsjQydLiIlHehhpejaIjzh9eomSjZR%2BipslWIRLAgMDOR2DOqKogTB9pCUJBagDBXR6XB0EBkIIsaRsGGMMAxoDBgYHTKJiUYEGDAzHC9EACcUGkIgFzgwZ0QsSBcXHiQvOwgDdEwfFs0sDzt4S6BK4xYjkDOzn0unFeBzOBijIm1Dgmg5YFQwsCMjp1oJ8LyIAACH5BAkKAAAALAAAAAAgACAAAATwEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GGl6NoiPOH16iZKNlH6KmyWFOggHhEEvAwwMA0N9GBsEC6amhnVcEwavDAazGwIDaH1ipaYLBUTCGgQDA8NdHz0FpqgTBwsLqAbWAAnIA4FWKdMLGdYGEgraigbT0OITBcg5QwPT4xLrROZL6AuQAPUS7bxLpoWidY0JtxLHKhwwMJBTHgPKdEQAACH5BAkKAAAALAAAAAAgACAAAATrEMhJaVKp6s2nIkqFZF2VIBWhUsJaTokqUCoBq%2BE71SRQeyqUToLA7VxF0JDyIQh%2FMVVPMt1ECZlfcjZJ9mIKoaTl1MRIl5o4CUKXOwmyrCInCKqcWtvadL2SYhyASyNDJ0uIiUd6GAULDJCRiXo1CpGXDJOUjY%2BYip9DhToJA4RBLwMLCwVDfRgbBAaqqoZ1XBMHswsHtxtFaH1iqaoGNgAIxRpbFAgfPQSqpbgGBqUD1wBXeCYp1AYZ19JJOYgH1KwA4UBvQwXUBxPqVD9L3sbp2BNk2xvvFPJd%2BMFCN6HAAIKgNggY0KtEBAAh%2BQQJCgAAACwAAAAAIAAgAAAE6BDISWlSqerNpyJKhWRdlSAVoVLCWk6JKlAqAavhO9UkUHsqlE6CwO1cRdCQ8iEIfzFVTzLdRAmZX3I2SfYIDMaAFdTESJeaEDAIMxYFqrOUaNW4E4ObYcCXaiBVEgULe0NJaxxtYksjh2NLkZISgDgJhHthkpU4mW6blRiYmZOlh4JWkDqILwUGBnE6TYEbCgevr0N1gH4At7gHiRpFaLNrrq8HNgAJA70AWxQIH1%2BvsYMDAzZQPC9VCNkDWUhGkuE5PxJNwiUK4UfLzOlD4WvzAHaoG9nxPi5d%2BjYUqfAhhykOFwJWiAAAIfkECQoAAAAsAAAAACAAIAAABPAQyElpUqnqzaciSoVkXVUMFaFSwlpOCcMYlErAavhOMnNLNo8KsZsMZItJEIDIFSkLGQoQTNhIsFehRww2CQLKF0tYGKYSg%2BygsZIuNqJksKgbfgIGepNo2cIUB3V1B3IvNiBYNQaDSTtfhhx0CwVPI0UJe0%2Bbm4g5VgcGoqOcnjmjqDSdnhgEoamcsZuXO1aWQy8KAwOAuTYYGwi7w5h%2BKr0SJ8MFihpNbx%2B4Erq7BYBuzsdiH1jCAzoSfl0rVirNbRXlBBlLX%2BBP0XJLAPGzTkAuAOqb0WT5AH7OcdCm5B8TgRwSRKIHQtaLCwg1RAAAOwAAAAAAAAAAAA%3D%3D);visibility:visible;opacity:.6;transition:all .3s ease}.reveal>.overlay header{position:absolute;left:0;top:0;width:100%;padding:5px;z-index:2;box-sizing:border-box}.reveal>.overlay header a{display:inline-block;width:40px;height:40px;line-height:36px;padding:0 10px;float:right;opacity:.6;box-sizing:border-box}.reveal>.overlay header a:hover{opacity:1}.reveal>.overlay header a .icon{display:inline-block;width:20px;height:20px;background-position:50% 50%;background-size:100%;background-repeat:no-repeat}.reveal>.overlay header a.close .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAABkklEQVRYR8WX4VHDMAxG6wnoJrABZQPYBCaBTWAD2g1gE5gg6OOsXuxIlr40d81dfrSJ9V4c2VLK7spHuTJ/5wpM07QXuXc5X0opX2tEJcadjHuV80li/FgxTIEK/5QBCICBD6xEhSMGHgQPgBgLiYVAB1dpSqKDawxTohFw4JSEA3clzgIBPCURwE2JucBR7rhPJJv5OpJwDX+SfDjgx1wACQeJG1aChP9K/IMmdZ8DtESV1WyP3Bt4MwM6sj4NMxMYiqUWHQu4KYA/SYkIjOsm3BXYWMKFDwU2khjCQ4ELJUJ4SmClRArOCmSXGuKma0fYD5CbzHxFpCSGAhfAVSSUGDUk2BWZaff2g6GE15BsBQ9nwmpIGDiyHQddwNTMKkbZaf9fajXQca1EX44puJZUsnY0ObGmITE3GVLCbEhQUjGVt146j6oasWN+49Vph2w1pZ5EansNZqKBm1txbU57iRRcZ86RWMDdWtBJUHBHwoQPi1GV+JCbntmvok7iTX4/Up9mgyTc/FJYDTcndgH/AA5A/CHsyEkVAAAAAElFTkSuQmCC)}.reveal>.overlay header a.external .icon{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAcElEQVRYR+2WSQoAIQwEzf8f7XiOMkUQxUPlGkM3hVmiQfQR9GYnH1SsAQlI4DiBqkCMoNb9y2e90IAEJPAcgdznU9+engMaeJ7Azh5Y1U67gAho4DqBqmB1buAf0MB1AlVBek83ZPkmJMGc1wAR+AAqod/B97TRpQAAAABJRU5ErkJggg==)}.reveal>.overlay .viewport{position:absolute;display:flex;top:50px;right:0;bottom:0;left:0}.reveal>.overlay.overlay-preview .viewport iframe{width:100%;height:100%;max-width:100%;max-height:100%;border:0;opacity:0;visibility:hidden;transition:all .3s ease}.reveal>.overlay.overlay-preview.loaded .viewport iframe{opacity:1;visibility:visible}.reveal>.overlay.overlay-preview.loaded .viewport-inner{position:absolute;z-index:-1;left:0;top:45%;width:100%;text-align:center;letter-spacing:normal}.reveal>.overlay.overlay-preview .x-frame-error{opacity:0;transition:opacity .3s ease .3s}.reveal>.overlay.overlay-preview.loaded .x-frame-error{opacity:1}.reveal>.overlay.overlay-preview.loaded .spinner{opacity:0;visibility:hidden;transform:scale(.2)}.reveal>.overlay.overlay-help .viewport{overflow:auto;color:#fff}.reveal>.overlay.overlay-help .viewport .viewport-inner{width:600px;margin:auto;padding:20px 20px 80px 20px;text-align:center;letter-spacing:normal}.reveal>.overlay.overlay-help .viewport .viewport-inner .title{font-size:20px}.reveal>.overlay.overlay-help .viewport .viewport-inner table{border:1px solid #fff;border-collapse:collapse;font-size:16px}.reveal>.overlay.overlay-help .viewport .viewport-inner table td,.reveal>.overlay.overlay-help .viewport .viewport-inner table th{width:200px;padding:14px;border:1px solid #fff;vertical-align:middle}.reveal>.overlay.overlay-help .viewport .viewport-inner table th{padding-top:20px;padding-bottom:20px}.reveal .playback{position:absolute;left:15px;bottom:20px;z-index:30;cursor:pointer;transition:all .4s ease;-webkit-tap-highlight-color:transparent}.reveal.overview .playback{opacity:0;visibility:hidden}.reveal .hljs{min-height:100%}.reveal .hljs table{margin:initial}.reveal .hljs-ln-code,.reveal .hljs-ln-numbers{padding:0;border:0}.reveal .hljs-ln-numbers{opacity:.6;padding-right:.75em;text-align:right;vertical-align:top}.reveal .hljs.has-highlights tr:not(.highlight-line){opacity:.4}.reveal .hljs:not(:first-child).fragment{position:absolute;top:0;left:0;width:100%;box-sizing:border-box}.reveal pre[data-auto-animate-target]{overflow:hidden}.reveal pre[data-auto-animate-target] code{height:100%}.reveal .roll{display:inline-block;line-height:1.2;overflow:hidden;vertical-align:top;perspective:400px;perspective-origin:50% 50%}.reveal .roll:hover{background:0 0;text-shadow:none}.reveal .roll span{display:block;position:relative;padding:0 2px;pointer-events:none;transition:all .4s ease;transform-origin:50% 0;transform-style:preserve-3d;-webkit-backface-visibility:hidden;backface-visibility:hidden}.reveal .roll:hover span{background:rgba(0,0,0,.5);transform:translate3d(0,0,-45px) rotateX(90deg)}.reveal .roll span:after{content:attr(data-title);display:block;position:absolute;left:0;top:0;padding:0 2px;-webkit-backface-visibility:hidden;backface-visibility:hidden;transform-origin:50% 0;transform:translate3d(0,110%,0) rotateX(-90deg)}.reveal aside.notes{display:none}.reveal .speaker-notes{display:none;position:absolute;width:33.3333333333%;height:100%;top:0;left:100%;padding:14px 18px 14px 18px;z-index:1;font-size:18px;line-height:1.4;border:1px solid rgba(0,0,0,.05);color:#222;background-color:#f5f5f5;overflow:auto;box-sizing:border-box;text-align:left;font-family:Helvetica,sans-serif;-webkit-overflow-scrolling:touch}.reveal .speaker-notes .notes-placeholder{color:#ccc;font-style:italic}.reveal .speaker-notes:focus{outline:0}.reveal .speaker-notes:before{content:"Speaker notes";display:block;margin-bottom:10px;opacity:.5}.reveal.show-notes{max-width:75%;overflow:visible}.reveal.show-notes .speaker-notes{display:block}@media screen and (min-width:1600px){.reveal .speaker-notes{font-size:20px}}@media screen and (max-width:1024px){.reveal.show-notes{border-left:0;max-width:none;max-height:70%;max-height:70vh;overflow:visible}.reveal.show-notes .speaker-notes{top:100%;left:0;width:100%;height:42.8571428571%;height:30vh;border:0}}@media screen and (max-width:600px){.reveal.show-notes{max-height:60%;max-height:60vh}.reveal.show-notes .speaker-notes{top:100%;height:66.6666666667%;height:40vh}.reveal .speaker-notes{font-size:14px}}.zoomed .reveal *,.zoomed .reveal :after,.zoomed .reveal :before{-webkit-backface-visibility:visible!important;backface-visibility:visible!important}.zoomed .reveal .controls,.zoomed .reveal .progress{opacity:0}.zoomed .reveal .roll span{background:0 0}.zoomed .reveal .roll span:after{visibility:hidden}html.print-pdf *{-webkit-print-color-adjust:exact}html.print-pdf{width:100%;height:100%;overflow:visible}html.print-pdf body{margin:0 auto!important;border:0;padding:0;float:none!important;overflow:visible}html.print-pdf .nestedarrow,html.print-pdf .reveal .controls,html.print-pdf .reveal .playback,html.print-pdf .reveal .progress,html.print-pdf .reveal.overview,html.print-pdf .state-background{display:none!important}html.print-pdf .reveal pre code{overflow:hidden!important;font-family:Courier,"Courier New",monospace!important}html.print-pdf .reveal{width:auto!important;height:auto!important;overflow:hidden!important}html.print-pdf .reveal .slides{position:static;width:100%!important;height:auto!important;zoom:1!important;pointer-events:initial;left:auto;top:auto;margin:0!important;padding:0!important;overflow:visible;display:block;perspective:none;perspective-origin:50% 50%}html.print-pdf .reveal .slides .pdf-page{position:relative;overflow:hidden;z-index:1;page-break-after:always}html.print-pdf .reveal .slides section{visibility:visible!important;display:block!important;position:absolute!important;margin:0!important;padding:0!important;box-sizing:border-box!important;min-height:1px;opacity:1!important;transform-style:flat!important;transform:none!important}html.print-pdf .reveal section.stack{position:relative!important;margin:0!important;padding:0!important;page-break-after:avoid!important;height:auto!important;min-height:auto!important}html.print-pdf .reveal img{box-shadow:none}html.print-pdf .reveal .backgrounds{display:none}html.print-pdf .reveal .slide-background{display:block!important;position:absolute;top:0;left:0;width:100%;height:100%;z-index:auto!important}html.print-pdf .reveal.show-notes{max-width:none;max-height:none}html.print-pdf .reveal .speaker-notes-pdf{display:block;width:100%;height:auto;max-height:none;top:auto;right:auto;bottom:auto;left:auto;z-index:100}html.print-pdf .reveal .speaker-notes-pdf[data-layout=separate-page]{position:relative;color:inherit;background-color:transparent;padding:20px;page-break-after:always;border:0}html.print-pdf .reveal .slide-number-pdf{display:block;position:absolute;font-size:14px}html.print-pdf .aria-status{display:none}@media print{html:not(.print-pdf){background:#fff;width:auto;height:auto;overflow:visible}html:not(.print-pdf) body{background:#fff;font-size:20pt;width:auto;height:auto;border:0;margin:0 5%;padding:0;overflow:visible;float:none!important}html:not(.print-pdf) .controls,html:not(.print-pdf) .fork-reveal,html:not(.print-pdf) .nestedarrow,html:not(.print-pdf) .reveal .backgrounds,html:not(.print-pdf) .reveal .progress,html:not(.print-pdf) .reveal .slide-number,html:not(.print-pdf) .share-reveal,html:not(.print-pdf) .state-background{display:none!important}html:not(.print-pdf) body,html:not(.print-pdf) li,html:not(.print-pdf) p,html:not(.print-pdf) td{font-size:20pt!important;color:#000}html:not(.print-pdf) h1,html:not(.print-pdf) h2,html:not(.print-pdf) h3,html:not(.print-pdf) h4,html:not(.print-pdf) h5,html:not(.print-pdf) h6{color:#000!important;height:auto;line-height:normal;text-align:left;letter-spacing:normal}html:not(.print-pdf) h1{font-size:28pt!important}html:not(.print-pdf) h2{font-size:24pt!important}html:not(.print-pdf) h3{font-size:22pt!important}html:not(.print-pdf) h4{font-size:22pt!important;font-variant:small-caps}html:not(.print-pdf) h5{font-size:21pt!important}html:not(.print-pdf) h6{font-size:20pt!important;font-style:italic}html:not(.print-pdf) a:link,html:not(.print-pdf) a:visited{color:#000!important;font-weight:700;text-decoration:underline}html:not(.print-pdf) div,html:not(.print-pdf) ol,html:not(.print-pdf) p,html:not(.print-pdf) ul{visibility:visible;position:static;width:auto;height:auto;display:block;overflow:visible;margin:0;text-align:left!important}html:not(.print-pdf) .reveal pre,html:not(.print-pdf) .reveal table{margin-left:0;margin-right:0}html:not(.print-pdf) .reveal pre code{padding:20px}html:not(.print-pdf) .reveal blockquote{margin:20px 0}html:not(.print-pdf) .reveal .slides{position:static!important;width:auto!important;height:auto!important;left:0!important;top:0!important;margin-left:0!important;margin-top:0!important;padding:0!important;zoom:1!important;transform:none!important;overflow:visible!important;display:block!important;text-align:left!important;perspective:none;perspective-origin:50% 50%}html:not(.print-pdf) .reveal .slides section{visibility:visible!important;position:static!important;width:auto!important;height:auto!important;display:block!important;overflow:visible!important;left:0!important;top:0!important;margin-left:0!important;margin-top:0!important;padding:60px 20px!important;z-index:auto!important;opacity:1!important;page-break-after:always!important;transform-style:flat!important;transform:none!important;transition:none!important}html:not(.print-pdf) .reveal .slides section.stack{padding:0!important}html:not(.print-pdf) .reveal section:last-of-type{page-break-after:avoid!important}html:not(.print-pdf) .reveal section .fragment{opacity:1!important;visibility:visible!important;transform:none!important}html:not(.print-pdf) .reveal section img{display:block;margin:15px 0;background:#fff;border:1px solid #666;box-shadow:none}html:not(.print-pdf) .reveal section small{font-size:.8em}html:not(.print-pdf) .reveal .hljs{max-height:100%;white-space:pre-wrap;word-wrap:break-word;word-break:break-word;font-size:15pt}html:not(.print-pdf) .reveal .hljs .hljs-ln-numbers{white-space:nowrap}html:not(.print-pdf) .reveal .hljs td{font-size:inherit!important;color:inherit!important}}
--------------------------------------------------------------------------------