事前学習・準備¶
-ほげほげ
-diff --git a/_build/doctrees/arduino.doctree b/_build/doctrees/arduino.doctree deleted file mode 100644 index 33ad2c9..0000000 --- a/_build/doctrees/arduino.doctree +++ /dev/null Binary files differ diff --git a/_build/doctrees/conclusion.doctree b/_build/doctrees/conclusion.doctree deleted file mode 100644 index af88511..0000000 --- a/_build/doctrees/conclusion.doctree +++ /dev/null Binary files differ diff --git a/_build/doctrees/environment.pickle b/_build/doctrees/environment.pickle deleted file mode 100644 index 72788fb..0000000 --- a/_build/doctrees/environment.pickle +++ /dev/null Binary files differ diff --git a/_build/doctrees/index.doctree b/_build/doctrees/index.doctree deleted file mode 100644 index 4292cac..0000000 --- a/_build/doctrees/index.doctree +++ /dev/null Binary files differ diff --git a/_build/doctrees/intro.doctree b/_build/doctrees/intro.doctree deleted file mode 100644 index 8068d9f..0000000 --- a/_build/doctrees/intro.doctree +++ /dev/null Binary files differ diff --git a/_build/doctrees/tutorial.doctree b/_build/doctrees/tutorial.doctree deleted file mode 100644 index e000de5..0000000 --- a/_build/doctrees/tutorial.doctree +++ /dev/null Binary files differ diff --git a/_build/html/._index.html b/_build/html/._index.html deleted file mode 100644 index 6024177..0000000 --- a/_build/html/._index.html +++ /dev/null Binary files differ diff --git a/_build/html/.buildinfo b/_build/html/.buildinfo deleted file mode 100644 index 55d3c07..0000000 --- a/_build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: c18e6f25cd4b4a34b46014271d5895eb -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/_build/html/.doctrees/00_pre.doctree b/_build/html/.doctrees/00_pre.doctree deleted file mode 100644 index 39aaed2..0000000 --- a/_build/html/.doctrees/00_pre.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/01_week.doctree b/_build/html/.doctrees/01_week.doctree deleted file mode 100644 index 23bea06..0000000 --- a/_build/html/.doctrees/01_week.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/02_week.doctree b/_build/html/.doctrees/02_week.doctree deleted file mode 100644 index ee00ab5..0000000 --- a/_build/html/.doctrees/02_week.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/appendix.doctree b/_build/html/.doctrees/appendix.doctree deleted file mode 100644 index f60d416..0000000 --- a/_build/html/.doctrees/appendix.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/arduino.doctree b/_build/html/.doctrees/arduino.doctree deleted file mode 100644 index 33ad2c9..0000000 --- a/_build/html/.doctrees/arduino.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/conclusion.doctree b/_build/html/.doctrees/conclusion.doctree deleted file mode 100644 index af88511..0000000 --- a/_build/html/.doctrees/conclusion.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/environment.pickle b/_build/html/.doctrees/environment.pickle deleted file mode 100644 index a368c3a..0000000 --- a/_build/html/.doctrees/environment.pickle +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/faq.doctree b/_build/html/.doctrees/faq.doctree deleted file mode 100644 index 63d3e7d..0000000 --- a/_build/html/.doctrees/faq.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/index.doctree b/_build/html/.doctrees/index.doctree deleted file mode 100644 index 4292cac..0000000 --- a/_build/html/.doctrees/index.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/intro.doctree b/_build/html/.doctrees/intro.doctree deleted file mode 100644 index 8068d9f..0000000 --- a/_build/html/.doctrees/intro.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/pre.doctree b/_build/html/.doctrees/pre.doctree deleted file mode 100644 index 629f569..0000000 --- a/_build/html/.doctrees/pre.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/tutorial.doctree b/_build/html/.doctrees/tutorial.doctree deleted file mode 100644 index e000de5..0000000 --- a/_build/html/.doctrees/tutorial.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/week1.doctree b/_build/html/.doctrees/week1.doctree deleted file mode 100644 index 8ef50d7..0000000 --- a/_build/html/.doctrees/week1.doctree +++ /dev/null Binary files differ diff --git a/_build/html/.doctrees/week2.doctree b/_build/html/.doctrees/week2.doctree deleted file mode 100644 index 06aea98..0000000 --- a/_build/html/.doctrees/week2.doctree +++ /dev/null Binary files differ diff --git a/_build/html/00_pre.html b/_build/html/00_pre.html deleted file mode 100644 index 39e8151..0000000 --- a/_build/html/00_pre.html +++ /dev/null @@ -1,227 +0,0 @@ - - - - -
- - - - -ほげほげ
-Short
- */ - .o-tooltip--left { - position: relative; - } - - .o-tooltip--left:after { - opacity: 0; - visibility: hidden; - position: absolute; - content: attr(data-tooltip); - padding: .2em; - font-size: .8em; - left: -.2em; - background: grey; - color: white; - white-space: nowrap; - z-index: 2; - border-radius: 2px; - transform: translateX(-102%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); -} - -.o-tooltip--left:hover:after { - display: block; - opacity: 1; - visibility: visible; - transform: translateX(-100%) translateY(0); - transition: opacity 0.2s cubic-bezier(0.64, 0.09, 0.08, 1), transform 0.2s cubic-bezier(0.64, 0.09, 0.08, 1); - transition-delay: .5s; -} - -/* By default the copy button shouldn't show up when printing a page */ -@media print { - button.copybtn { - display: none; - } -} diff --git a/_build/html/_static/copybutton.js b/_build/html/_static/copybutton.js deleted file mode 100644 index 40ac331..0000000 --- a/_build/html/_static/copybutton.js +++ /dev/null @@ -1,220 +0,0 @@ -// Localization support -const messages = { - 'en': { - 'copy': 'Copy', - 'copy_to_clipboard': 'Copy to clipboard', - 'copy_success': 'Copied!', - 'copy_failure': 'Failed to copy', - }, - 'es' : { - 'copy': 'Copiar', - 'copy_to_clipboard': 'Copiar al portapapeles', - 'copy_success': '¡Copiado!', - 'copy_failure': 'Error al copiar', - }, - 'de' : { - 'copy': 'Kopieren', - 'copy_to_clipboard': 'In die Zwischenablage kopieren', - 'copy_success': 'Kopiert!', - 'copy_failure': 'Fehler beim Kopieren', - }, - 'fr' : { - 'copy': 'Copier', - 'copy_to_clipboard': 'Copié dans le presse-papier', - 'copy_success': 'Copié !', - 'copy_failure': 'Échec de la copie', - }, - 'ru': { - 'copy': 'Скопировать', - 'copy_to_clipboard': 'Скопировать в буфер', - 'copy_success': 'Скопировано!', - 'copy_failure': 'Не удалось скопировать', - }, - 'zh-CN': { - 'copy': '复制', - 'copy_to_clipboard': '复制到剪贴板', - 'copy_success': '复制成功!', - 'copy_failure': '复制失败', - }, - 'it' : { - 'copy': 'Copiare', - 'copy_to_clipboard': 'Copiato negli appunti', - 'copy_success': 'Copiato!', - 'copy_failure': 'Errore durante la copia', - } -} - -let locale = 'en' -if( document.documentElement.lang !== undefined - && messages[document.documentElement.lang] !== undefined ) { - locale = document.documentElement.lang -} - -let doc_url_root = DOCUMENTATION_OPTIONS.URL_ROOT; -if (doc_url_root == '#') { - doc_url_root = ''; -} - -/** - * SVG files for our copy buttons - */ -let iconCheck = `` - -// If the user specified their own SVG use that, otherwise use the default -let iconCopy = ``; -if (!iconCopy) { - iconCopy = `` -} - -/** - * Set up copy/paste for code blocks - */ - -const runWhenDOMLoaded = cb => { - if (document.readyState != 'loading') { - cb() - } else if (document.addEventListener) { - document.addEventListener('DOMContentLoaded', cb) - } else { - document.attachEvent('onreadystatechange', function() { - if (document.readyState == 'complete') cb() - }) - } -} - -const codeCellId = index => `codecell${index}` - -// Clears selected text since ClipboardJS will select the text when copying -const clearSelection = () => { - if (window.getSelection) { - window.getSelection().removeAllRanges() - } else if (document.selection) { - document.selection.empty() - } -} - -// Changes tooltip text for two seconds, then changes it back -const temporarilyChangeTooltip = (el, oldText, newText) => { - el.setAttribute('data-tooltip', newText) - el.classList.add('success') - setTimeout(() => el.setAttribute('data-tooltip', oldText), 2000) - setTimeout(() => el.classList.remove('success'), 2000) -} - -// Changes the copy button icon for two seconds, then changes it back -const temporarilyChangeIcon = (el) => { - el.innerHTML = iconCheck; - setTimeout(() => {el.innerHTML = iconCopy}, 2000) -} - -const addCopyButtonToCodeCells = () => { - // If ClipboardJS hasn't loaded, wait a bit and try again. This - // happens because we load ClipboardJS asynchronously. - if (window.ClipboardJS === undefined) { - setTimeout(addCopyButtonToCodeCells, 250) - return - } - - // Add copybuttons to all of our code cells - const codeCells = document.querySelectorAll('div.highlight pre') - codeCells.forEach((codeCell, index) => { - const id = codeCellId(index) - codeCell.setAttribute('id', id) - - const clipboardButton = id => - `` - codeCell.insertAdjacentHTML('afterend', clipboardButton(id)) - }) - -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} - - -var copyTargetText = (trigger) => { - var target = document.querySelector(trigger.attributes['data-clipboard-target'].value); - return formatCopyText(target.innerText, '', false, true, true, true, '', '') -} - - // Initialize with a callback so we can modify the text before copy - const clipboard = new ClipboardJS('.copybtn', {text: copyTargetText}) - - // Update UI with error/success messages - clipboard.on('success', event => { - clearSelection() - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_success']) - temporarilyChangeIcon(event.trigger) - }) - - clipboard.on('error', event => { - temporarilyChangeTooltip(event.trigger, messages[locale]['copy'], messages[locale]['copy_failure']) - }) -} - -runWhenDOMLoaded(addCopyButtonToCodeCells) \ No newline at end of file diff --git a/_build/html/_static/copybutton_funcs.js b/_build/html/_static/copybutton_funcs.js deleted file mode 100644 index b9168c5..0000000 --- a/_build/html/_static/copybutton_funcs.js +++ /dev/null @@ -1,58 +0,0 @@ -function escapeRegExp(string) { - return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string -} - -// Callback when a copy button is clicked. Will be passed the node that was clicked -// should then grab the text and replace pieces of text that shouldn't be used in output -export function formatCopyText(textContent, copybuttonPromptText, isRegexp = false, onlyCopyPromptLines = true, removePrompts = true, copyEmptyLines = true, lineContinuationChar = "", hereDocDelim = "") { - - var regexp; - var match; - - // Do we check for line continuation characters and "HERE-documents"? - var useLineCont = !!lineContinuationChar - var useHereDoc = !!hereDocDelim - - // create regexp to capture prompt and remaining line - if (isRegexp) { - regexp = new RegExp('^(' + copybuttonPromptText + ')(.*)') - } else { - regexp = new RegExp('^(' + escapeRegExp(copybuttonPromptText) + ')(.*)') - } - - const outputLines = []; - var promptFound = false; - var gotLineCont = false; - var gotHereDoc = false; - const lineGotPrompt = []; - for (const line of textContent.split('\n')) { - match = line.match(regexp) - if (match || gotLineCont || gotHereDoc) { - promptFound = regexp.test(line) - lineGotPrompt.push(promptFound) - if (removePrompts && promptFound) { - outputLines.push(match[2]) - } else { - outputLines.push(line) - } - gotLineCont = line.endsWith(lineContinuationChar) & useLineCont - if (line.includes(hereDocDelim) & useHereDoc) - gotHereDoc = !gotHereDoc - } else if (!onlyCopyPromptLines) { - outputLines.push(line) - } else if (copyEmptyLines && line.trim() === '') { - outputLines.push(line) - } - } - - // If no lines with the prompt were found then just use original lines - if (lineGotPrompt.some(v => v === true)) { - textContent = outputLines.join('\n'); - } - - // Remove a trailing newline to avoid auto-running when pasting - if (textContent.endsWith("\n")) { - textContent = textContent.slice(0, -1) - } - return textContent -} diff --git a/_build/html/_static/css/badge_only.css b/_build/html/_static/css/badge_only.css deleted file mode 100644 index e380325..0000000 --- a/_build/html/_static/css/badge_only.css +++ /dev/null @@ -1 +0,0 @@ -.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-style:normal;font-weight:400;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#FontAwesome) format("svg")}.fa:before{font-family:FontAwesome;font-style:normal;font-weight:400;line-height:1}.fa:before,a .fa{text-decoration:inherit}.fa:before,a .fa,li .fa{display:inline-block}li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-.8em}ul.fas li .fa{width:.8em}ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before,.icon-book:before{content:"\f02d"}.fa-caret-down:before,.icon-caret-down:before{content:"\f0d7"}.fa-caret-up:before,.icon-caret-up:before{content:"\f0d8"}.fa-caret-left:before,.icon-caret-left:before{content:"\f0d9"}.fa-caret-right:before,.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60}.rst-versions .rst-current-version:after{clear:both;content:"";display:block}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}} \ No newline at end of file diff --git a/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff b/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff deleted file mode 100644 index 6cb6000..0000000 --- a/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 b/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 deleted file mode 100644 index 7059e23..0000000 --- a/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff b/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff deleted file mode 100644 index f815f63..0000000 --- a/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 b/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 deleted file mode 100644 index f2c76e5..0000000 --- a/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/fontawesome-webfont.eot b/_build/html/_static/css/fonts/fontawesome-webfont.eot deleted file mode 100644 index e9f60ca..0000000 --- a/_build/html/_static/css/fonts/fontawesome-webfont.eot +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/fontawesome-webfont.svg b/_build/html/_static/css/fonts/fontawesome-webfont.svg deleted file mode 100644 index 855c845..0000000 --- a/_build/html/_static/css/fonts/fontawesome-webfont.svg +++ /dev/null @@ -1,2671 +0,0 @@ - - - diff --git a/_build/html/_static/css/fonts/fontawesome-webfont.ttf b/_build/html/_static/css/fonts/fontawesome-webfont.ttf deleted file mode 100644 index 35acda2..0000000 --- a/_build/html/_static/css/fonts/fontawesome-webfont.ttf +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/fontawesome-webfont.woff b/_build/html/_static/css/fonts/fontawesome-webfont.woff deleted file mode 100644 index 400014a..0000000 --- a/_build/html/_static/css/fonts/fontawesome-webfont.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/fontawesome-webfont.woff2 b/_build/html/_static/css/fonts/fontawesome-webfont.woff2 deleted file mode 100644 index 4d13fc6..0000000 --- a/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-bold-italic.woff b/_build/html/_static/css/fonts/lato-bold-italic.woff deleted file mode 100644 index 88ad05b..0000000 --- a/_build/html/_static/css/fonts/lato-bold-italic.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-bold-italic.woff2 b/_build/html/_static/css/fonts/lato-bold-italic.woff2 deleted file mode 100644 index c4e3d80..0000000 --- a/_build/html/_static/css/fonts/lato-bold-italic.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-bold.woff b/_build/html/_static/css/fonts/lato-bold.woff deleted file mode 100644 index c6dff51..0000000 --- a/_build/html/_static/css/fonts/lato-bold.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-bold.woff2 b/_build/html/_static/css/fonts/lato-bold.woff2 deleted file mode 100644 index bb19504..0000000 --- a/_build/html/_static/css/fonts/lato-bold.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-normal-italic.woff b/_build/html/_static/css/fonts/lato-normal-italic.woff deleted file mode 100644 index 76114bc..0000000 --- a/_build/html/_static/css/fonts/lato-normal-italic.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-normal-italic.woff2 b/_build/html/_static/css/fonts/lato-normal-italic.woff2 deleted file mode 100644 index 3404f37..0000000 --- a/_build/html/_static/css/fonts/lato-normal-italic.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-normal.woff b/_build/html/_static/css/fonts/lato-normal.woff deleted file mode 100644 index ae1307f..0000000 --- a/_build/html/_static/css/fonts/lato-normal.woff +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/fonts/lato-normal.woff2 b/_build/html/_static/css/fonts/lato-normal.woff2 deleted file mode 100644 index 3bf9843..0000000 --- a/_build/html/_static/css/fonts/lato-normal.woff2 +++ /dev/null Binary files differ diff --git a/_build/html/_static/css/theme.css b/_build/html/_static/css/theme.css deleted file mode 100644 index 0d9ae7e..0000000 --- a/_build/html/_static/css/theme.css +++ /dev/null @@ -1,4 +0,0 @@ -html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio,canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden],audio:not([controls]){display:none}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}blockquote{margin:0}dfn{font-style:italic}ins{background:#ff9;text-decoration:none}ins,mark{color:#000}mark{background:#ff0;font-style:italic;font-weight:700}.rst-content code,.rst-content tt,code,kbd,pre,samp{font-family:monospace,serif;_font-family:courier new,monospace;font-size:1em}pre{white-space:pre}q{quotes:none}q:after,q:before{content:"";content:none}small{font-size:85%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}dl,ol,ul{margin:0;padding:0;list-style:none;list-style-image:none}li{list-style:none}dd{margin:0}img{border:0;-ms-interpolation-mode:bicubic;vertical-align:middle;max-width:100%}svg:not(:root){overflow:hidden}figure,form{margin:0}label{cursor:pointer}button,input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}button,input{line-height:normal}button,input[type=button],input[type=reset],input[type=submit]{cursor:pointer;-webkit-appearance:button;*overflow:visible}button[disabled],input[disabled]{cursor:default}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}textarea{resize:vertical}table{border-collapse:collapse;border-spacing:0}td{vertical-align:top}.chromeframe{margin:.2em 0;background:#ccc;color:#000;padding:.2em 0}.ir{display:block;border:0;text-indent:-999em;overflow:hidden;background-color:transparent;background-repeat:no-repeat;text-align:left;direction:ltr;*line-height:0}.ir br{display:none}.hidden{display:none!important;visibility:hidden}.visuallyhidden{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.visuallyhidden.focusable:active,.visuallyhidden.focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}.invisible{visibility:hidden}.relative{position:relative}big,small{font-size:100%}@media print{body,html,section{background:none!important}*{box-shadow:none!important;text-shadow:none!important;filter:none!important;-ms-filter:none!important}a,a:visited{text-decoration:underline}.ir a:after,a[href^="#"]:after,a[href^="javascript:"]:after{content:""}blockquote,pre{page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}@page{margin:.5cm}.rst-content .toctree-wrapper>p.caption,h2,h3,p{orphans:3;widows:3}.rst-content .toctree-wrapper>p.caption,h2,h3{page-break-after:avoid}}.btn,.fa:before,.icon:before,.rst-content .admonition,.rst-content .admonition-title:before,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .code-block-caption .headerlink:before,.rst-content .danger,.rst-content .eqno .headerlink:before,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-alert,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before,.wy-nav-top a,.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a,input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],select,textarea{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:after,.clearfix:before{display:table;content:""}.clearfix:after{clear:both}/*! - * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:FontAwesome;src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713);src:url(fonts/fontawesome-webfont.eot?674f50d287a8c48dc19ba404d20fe713?#iefix&v=4.7.0) format("embedded-opentype"),url(fonts/fontawesome-webfont.woff2?af7ae505a9eed503f8b8e6982036873e) format("woff2"),url(fonts/fontawesome-webfont.woff?fee66e712a8a08eef5805a46892932ad) format("woff"),url(fonts/fontawesome-webfont.ttf?b06871f281fee6b241d60582ae9369b9) format("truetype"),url(fonts/fontawesome-webfont.svg?912ec66d7572ff821749319396470bde#fontawesomeregular) format("svg");font-weight:400;font-style:normal}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14286em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14286em;width:2.14286em;top:.14286em;text-align:center}.fa-li.fa-lg{left:-1.85714em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa-pull-left.icon,.fa.fa-pull-left,.rst-content .code-block-caption .fa-pull-left.headerlink,.rst-content .eqno .fa-pull-left.headerlink,.rst-content .fa-pull-left.admonition-title,.rst-content code.download span.fa-pull-left:first-child,.rst-content dl dt .fa-pull-left.headerlink,.rst-content h1 .fa-pull-left.headerlink,.rst-content h2 .fa-pull-left.headerlink,.rst-content h3 .fa-pull-left.headerlink,.rst-content h4 .fa-pull-left.headerlink,.rst-content h5 .fa-pull-left.headerlink,.rst-content h6 .fa-pull-left.headerlink,.rst-content p .fa-pull-left.headerlink,.rst-content table>caption .fa-pull-left.headerlink,.rst-content tt.download span.fa-pull-left:first-child,.wy-menu-vertical li.current>a button.fa-pull-left.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-left.toctree-expand,.wy-menu-vertical li button.fa-pull-left.toctree-expand{margin-right:.3em}.fa-pull-right.icon,.fa.fa-pull-right,.rst-content .code-block-caption .fa-pull-right.headerlink,.rst-content .eqno .fa-pull-right.headerlink,.rst-content .fa-pull-right.admonition-title,.rst-content code.download span.fa-pull-right:first-child,.rst-content dl dt .fa-pull-right.headerlink,.rst-content h1 .fa-pull-right.headerlink,.rst-content h2 .fa-pull-right.headerlink,.rst-content h3 .fa-pull-right.headerlink,.rst-content h4 .fa-pull-right.headerlink,.rst-content h5 .fa-pull-right.headerlink,.rst-content h6 .fa-pull-right.headerlink,.rst-content p .fa-pull-right.headerlink,.rst-content table>caption .fa-pull-right.headerlink,.rst-content tt.download span.fa-pull-right:first-child,.wy-menu-vertical li.current>a button.fa-pull-right.toctree-expand,.wy-menu-vertical li.on a button.fa-pull-right.toctree-expand,.wy-menu-vertical li button.fa-pull-right.toctree-expand{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left,.pull-left.icon,.rst-content .code-block-caption .pull-left.headerlink,.rst-content .eqno .pull-left.headerlink,.rst-content .pull-left.admonition-title,.rst-content code.download span.pull-left:first-child,.rst-content dl dt .pull-left.headerlink,.rst-content h1 .pull-left.headerlink,.rst-content h2 .pull-left.headerlink,.rst-content h3 .pull-left.headerlink,.rst-content h4 .pull-left.headerlink,.rst-content h5 .pull-left.headerlink,.rst-content h6 .pull-left.headerlink,.rst-content p .pull-left.headerlink,.rst-content table>caption .pull-left.headerlink,.rst-content tt.download span.pull-left:first-child,.wy-menu-vertical li.current>a button.pull-left.toctree-expand,.wy-menu-vertical li.on a button.pull-left.toctree-expand,.wy-menu-vertical li button.pull-left.toctree-expand{margin-right:.3em}.fa.pull-right,.pull-right.icon,.rst-content .code-block-caption .pull-right.headerlink,.rst-content .eqno .pull-right.headerlink,.rst-content .pull-right.admonition-title,.rst-content code.download span.pull-right:first-child,.rst-content dl dt .pull-right.headerlink,.rst-content h1 .pull-right.headerlink,.rst-content h2 .pull-right.headerlink,.rst-content h3 .pull-right.headerlink,.rst-content h4 .pull-right.headerlink,.rst-content h5 .pull-right.headerlink,.rst-content h6 .pull-right.headerlink,.rst-content p .pull-right.headerlink,.rst-content table>caption .pull-right.headerlink,.rst-content tt.download span.pull-right:first-child,.wy-menu-vertical li.current>a button.pull-right.toctree-expand,.wy-menu-vertical li.on a button.pull-right.toctree-expand,.wy-menu-vertical li button.pull-right.toctree-expand{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scaleX(-1);-ms-transform:scaleX(-1);transform:scaleX(-1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scaleY(-1);-ms-transform:scaleY(-1);transform:scaleY(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:""}.fa-music:before{content:""}.fa-search:before,.icon-search:before{content:""}.fa-envelope-o:before{content:""}.fa-heart:before{content:""}.fa-star:before{content:""}.fa-star-o:before{content:""}.fa-user:before{content:""}.fa-film:before{content:""}.fa-th-large:before{content:""}.fa-th:before{content:""}.fa-th-list:before{content:""}.fa-check:before{content:""}.fa-close:before,.fa-remove:before,.fa-times:before{content:""}.fa-search-plus:before{content:""}.fa-search-minus:before{content:""}.fa-power-off:before{content:""}.fa-signal:before{content:""}.fa-cog:before,.fa-gear:before{content:""}.fa-trash-o:before{content:""}.fa-home:before,.icon-home:before{content:""}.fa-file-o:before{content:""}.fa-clock-o:before{content:""}.fa-road:before{content:""}.fa-download:before,.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{content:""}.fa-arrow-circle-o-down:before{content:""}.fa-arrow-circle-o-up:before{content:""}.fa-inbox:before{content:""}.fa-play-circle-o:before{content:""}.fa-repeat:before,.fa-rotate-right:before{content:""}.fa-refresh:before{content:""}.fa-list-alt:before{content:""}.fa-lock:before{content:""}.fa-flag:before{content:""}.fa-headphones:before{content:""}.fa-volume-off:before{content:""}.fa-volume-down:before{content:""}.fa-volume-up:before{content:""}.fa-qrcode:before{content:""}.fa-barcode:before{content:""}.fa-tag:before{content:""}.fa-tags:before{content:""}.fa-book:before,.icon-book:before{content:""}.fa-bookmark:before{content:""}.fa-print:before{content:""}.fa-camera:before{content:""}.fa-font:before{content:""}.fa-bold:before{content:""}.fa-italic:before{content:""}.fa-text-height:before{content:""}.fa-text-width:before{content:""}.fa-align-left:before{content:""}.fa-align-center:before{content:""}.fa-align-right:before{content:""}.fa-align-justify:before{content:""}.fa-list:before{content:""}.fa-dedent:before,.fa-outdent:before{content:""}.fa-indent:before{content:""}.fa-video-camera:before{content:""}.fa-image:before,.fa-photo:before,.fa-picture-o:before{content:""}.fa-pencil:before{content:""}.fa-map-marker:before{content:""}.fa-adjust:before{content:""}.fa-tint:before{content:""}.fa-edit:before,.fa-pencil-square-o:before{content:""}.fa-share-square-o:before{content:""}.fa-check-square-o:before{content:""}.fa-arrows:before{content:""}.fa-step-backward:before{content:""}.fa-fast-backward:before{content:""}.fa-backward:before{content:""}.fa-play:before{content:""}.fa-pause:before{content:""}.fa-stop:before{content:""}.fa-forward:before{content:""}.fa-fast-forward:before{content:""}.fa-step-forward:before{content:""}.fa-eject:before{content:""}.fa-chevron-left:before{content:""}.fa-chevron-right:before{content:""}.fa-plus-circle:before{content:""}.fa-minus-circle:before{content:""}.fa-times-circle:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before{content:""}.fa-check-circle:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before{content:""}.fa-question-circle:before{content:""}.fa-info-circle:before{content:""}.fa-crosshairs:before{content:""}.fa-times-circle-o:before{content:""}.fa-check-circle-o:before{content:""}.fa-ban:before{content:""}.fa-arrow-left:before{content:""}.fa-arrow-right:before{content:""}.fa-arrow-up:before{content:""}.fa-arrow-down:before{content:""}.fa-mail-forward:before,.fa-share:before{content:""}.fa-expand:before{content:""}.fa-compress:before{content:""}.fa-plus:before{content:""}.fa-minus:before{content:""}.fa-asterisk:before{content:""}.fa-exclamation-circle:before,.rst-content .admonition-title:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before{content:""}.fa-gift:before{content:""}.fa-leaf:before{content:""}.fa-fire:before,.icon-fire:before{content:""}.fa-eye:before{content:""}.fa-eye-slash:before{content:""}.fa-exclamation-triangle:before,.fa-warning:before{content:""}.fa-plane:before{content:""}.fa-calendar:before{content:""}.fa-random:before{content:""}.fa-comment:before{content:""}.fa-magnet:before{content:""}.fa-chevron-up:before{content:""}.fa-chevron-down:before{content:""}.fa-retweet:before{content:""}.fa-shopping-cart:before{content:""}.fa-folder:before{content:""}.fa-folder-open:before{content:""}.fa-arrows-v:before{content:""}.fa-arrows-h:before{content:""}.fa-bar-chart-o:before,.fa-bar-chart:before{content:""}.fa-twitter-square:before{content:""}.fa-facebook-square:before{content:""}.fa-camera-retro:before{content:""}.fa-key:before{content:""}.fa-cogs:before,.fa-gears:before{content:""}.fa-comments:before{content:""}.fa-thumbs-o-up:before{content:""}.fa-thumbs-o-down:before{content:""}.fa-star-half:before{content:""}.fa-heart-o:before{content:""}.fa-sign-out:before{content:""}.fa-linkedin-square:before{content:""}.fa-thumb-tack:before{content:""}.fa-external-link:before{content:""}.fa-sign-in:before{content:""}.fa-trophy:before{content:""}.fa-github-square:before{content:""}.fa-upload:before{content:""}.fa-lemon-o:before{content:""}.fa-phone:before{content:""}.fa-square-o:before{content:""}.fa-bookmark-o:before{content:""}.fa-phone-square:before{content:""}.fa-twitter:before{content:""}.fa-facebook-f:before,.fa-facebook:before{content:""}.fa-github:before,.icon-github:before{content:""}.fa-unlock:before{content:""}.fa-credit-card:before{content:""}.fa-feed:before,.fa-rss:before{content:""}.fa-hdd-o:before{content:""}.fa-bullhorn:before{content:""}.fa-bell:before{content:""}.fa-certificate:before{content:""}.fa-hand-o-right:before{content:""}.fa-hand-o-left:before{content:""}.fa-hand-o-up:before{content:""}.fa-hand-o-down:before{content:""}.fa-arrow-circle-left:before,.icon-circle-arrow-left:before{content:""}.fa-arrow-circle-right:before,.icon-circle-arrow-right:before{content:""}.fa-arrow-circle-up:before{content:""}.fa-arrow-circle-down:before{content:""}.fa-globe:before{content:""}.fa-wrench:before{content:""}.fa-tasks:before{content:""}.fa-filter:before{content:""}.fa-briefcase:before{content:""}.fa-arrows-alt:before{content:""}.fa-group:before,.fa-users:before{content:""}.fa-chain:before,.fa-link:before,.icon-link:before{content:""}.fa-cloud:before{content:""}.fa-flask:before{content:""}.fa-cut:before,.fa-scissors:before{content:""}.fa-copy:before,.fa-files-o:before{content:""}.fa-paperclip:before{content:""}.fa-floppy-o:before,.fa-save:before{content:""}.fa-square:before{content:""}.fa-bars:before,.fa-navicon:before,.fa-reorder:before{content:""}.fa-list-ul:before{content:""}.fa-list-ol:before{content:""}.fa-strikethrough:before{content:""}.fa-underline:before{content:""}.fa-table:before{content:""}.fa-magic:before{content:""}.fa-truck:before{content:""}.fa-pinterest:before{content:""}.fa-pinterest-square:before{content:""}.fa-google-plus-square:before{content:""}.fa-google-plus:before{content:""}.fa-money:before{content:""}.fa-caret-down:before,.icon-caret-down:before,.wy-dropdown .caret:before{content:""}.fa-caret-up:before{content:""}.fa-caret-left:before{content:""}.fa-caret-right:before{content:""}.fa-columns:before{content:""}.fa-sort:before,.fa-unsorted:before{content:""}.fa-sort-desc:before,.fa-sort-down:before{content:""}.fa-sort-asc:before,.fa-sort-up:before{content:""}.fa-envelope:before{content:""}.fa-linkedin:before{content:""}.fa-rotate-left:before,.fa-undo:before{content:""}.fa-gavel:before,.fa-legal:before{content:""}.fa-dashboard:before,.fa-tachometer:before{content:""}.fa-comment-o:before{content:""}.fa-comments-o:before{content:""}.fa-bolt:before,.fa-flash:before{content:""}.fa-sitemap:before{content:""}.fa-umbrella:before{content:""}.fa-clipboard:before,.fa-paste:before{content:""}.fa-lightbulb-o:before{content:""}.fa-exchange:before{content:""}.fa-cloud-download:before{content:""}.fa-cloud-upload:before{content:""}.fa-user-md:before{content:""}.fa-stethoscope:before{content:""}.fa-suitcase:before{content:""}.fa-bell-o:before{content:""}.fa-coffee:before{content:""}.fa-cutlery:before{content:""}.fa-file-text-o:before{content:""}.fa-building-o:before{content:""}.fa-hospital-o:before{content:""}.fa-ambulance:before{content:""}.fa-medkit:before{content:""}.fa-fighter-jet:before{content:""}.fa-beer:before{content:""}.fa-h-square:before{content:""}.fa-plus-square:before{content:""}.fa-angle-double-left:before{content:""}.fa-angle-double-right:before{content:""}.fa-angle-double-up:before{content:""}.fa-angle-double-down:before{content:""}.fa-angle-left:before{content:""}.fa-angle-right:before{content:""}.fa-angle-up:before{content:""}.fa-angle-down:before{content:""}.fa-desktop:before{content:""}.fa-laptop:before{content:""}.fa-tablet:before{content:""}.fa-mobile-phone:before,.fa-mobile:before{content:""}.fa-circle-o:before{content:""}.fa-quote-left:before{content:""}.fa-quote-right:before{content:""}.fa-spinner:before{content:""}.fa-circle:before{content:""}.fa-mail-reply:before,.fa-reply:before{content:""}.fa-github-alt:before{content:""}.fa-folder-o:before{content:""}.fa-folder-open-o:before{content:""}.fa-smile-o:before{content:""}.fa-frown-o:before{content:""}.fa-meh-o:before{content:""}.fa-gamepad:before{content:""}.fa-keyboard-o:before{content:""}.fa-flag-o:before{content:""}.fa-flag-checkered:before{content:""}.fa-terminal:before{content:""}.fa-code:before{content:""}.fa-mail-reply-all:before,.fa-reply-all:before{content:""}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:""}.fa-location-arrow:before{content:""}.fa-crop:before{content:""}.fa-code-fork:before{content:""}.fa-chain-broken:before,.fa-unlink:before{content:""}.fa-question:before{content:""}.fa-info:before{content:""}.fa-exclamation:before{content:""}.fa-superscript:before{content:""}.fa-subscript:before{content:""}.fa-eraser:before{content:""}.fa-puzzle-piece:before{content:""}.fa-microphone:before{content:""}.fa-microphone-slash:before{content:""}.fa-shield:before{content:""}.fa-calendar-o:before{content:""}.fa-fire-extinguisher:before{content:""}.fa-rocket:before{content:""}.fa-maxcdn:before{content:""}.fa-chevron-circle-left:before{content:""}.fa-chevron-circle-right:before{content:""}.fa-chevron-circle-up:before{content:""}.fa-chevron-circle-down:before{content:""}.fa-html5:before{content:""}.fa-css3:before{content:""}.fa-anchor:before{content:""}.fa-unlock-alt:before{content:""}.fa-bullseye:before{content:""}.fa-ellipsis-h:before{content:""}.fa-ellipsis-v:before{content:""}.fa-rss-square:before{content:""}.fa-play-circle:before{content:""}.fa-ticket:before{content:""}.fa-minus-square:before{content:""}.fa-minus-square-o:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before{content:""}.fa-level-up:before{content:""}.fa-level-down:before{content:""}.fa-check-square:before{content:""}.fa-pencil-square:before{content:""}.fa-external-link-square:before{content:""}.fa-share-square:before{content:""}.fa-compass:before{content:""}.fa-caret-square-o-down:before,.fa-toggle-down:before{content:""}.fa-caret-square-o-up:before,.fa-toggle-up:before{content:""}.fa-caret-square-o-right:before,.fa-toggle-right:before{content:""}.fa-eur:before,.fa-euro:before{content:""}.fa-gbp:before{content:""}.fa-dollar:before,.fa-usd:before{content:""}.fa-inr:before,.fa-rupee:before{content:""}.fa-cny:before,.fa-jpy:before,.fa-rmb:before,.fa-yen:before{content:""}.fa-rouble:before,.fa-rub:before,.fa-ruble:before{content:""}.fa-krw:before,.fa-won:before{content:""}.fa-bitcoin:before,.fa-btc:before{content:""}.fa-file:before{content:""}.fa-file-text:before{content:""}.fa-sort-alpha-asc:before{content:""}.fa-sort-alpha-desc:before{content:""}.fa-sort-amount-asc:before{content:""}.fa-sort-amount-desc:before{content:""}.fa-sort-numeric-asc:before{content:""}.fa-sort-numeric-desc:before{content:""}.fa-thumbs-up:before{content:""}.fa-thumbs-down:before{content:""}.fa-youtube-square:before{content:""}.fa-youtube:before{content:""}.fa-xing:before{content:""}.fa-xing-square:before{content:""}.fa-youtube-play:before{content:""}.fa-dropbox:before{content:""}.fa-stack-overflow:before{content:""}.fa-instagram:before{content:""}.fa-flickr:before{content:""}.fa-adn:before{content:""}.fa-bitbucket:before,.icon-bitbucket:before{content:""}.fa-bitbucket-square:before{content:""}.fa-tumblr:before{content:""}.fa-tumblr-square:before{content:""}.fa-long-arrow-down:before{content:""}.fa-long-arrow-up:before{content:""}.fa-long-arrow-left:before{content:""}.fa-long-arrow-right:before{content:""}.fa-apple:before{content:""}.fa-windows:before{content:""}.fa-android:before{content:""}.fa-linux:before{content:""}.fa-dribbble:before{content:""}.fa-skype:before{content:""}.fa-foursquare:before{content:""}.fa-trello:before{content:""}.fa-female:before{content:""}.fa-male:before{content:""}.fa-gittip:before,.fa-gratipay:before{content:""}.fa-sun-o:before{content:""}.fa-moon-o:before{content:""}.fa-archive:before{content:""}.fa-bug:before{content:""}.fa-vk:before{content:""}.fa-weibo:before{content:""}.fa-renren:before{content:""}.fa-pagelines:before{content:""}.fa-stack-exchange:before{content:""}.fa-arrow-circle-o-right:before{content:""}.fa-arrow-circle-o-left:before{content:""}.fa-caret-square-o-left:before,.fa-toggle-left:before{content:""}.fa-dot-circle-o:before{content:""}.fa-wheelchair:before{content:""}.fa-vimeo-square:before{content:""}.fa-try:before,.fa-turkish-lira:before{content:""}.fa-plus-square-o:before,.wy-menu-vertical li button.toctree-expand:before{content:""}.fa-space-shuttle:before{content:""}.fa-slack:before{content:""}.fa-envelope-square:before{content:""}.fa-wordpress:before{content:""}.fa-openid:before{content:""}.fa-bank:before,.fa-institution:before,.fa-university:before{content:""}.fa-graduation-cap:before,.fa-mortar-board:before{content:""}.fa-yahoo:before{content:""}.fa-google:before{content:""}.fa-reddit:before{content:""}.fa-reddit-square:before{content:""}.fa-stumbleupon-circle:before{content:""}.fa-stumbleupon:before{content:""}.fa-delicious:before{content:""}.fa-digg:before{content:""}.fa-pied-piper-pp:before{content:""}.fa-pied-piper-alt:before{content:""}.fa-drupal:before{content:""}.fa-joomla:before{content:""}.fa-language:before{content:""}.fa-fax:before{content:""}.fa-building:before{content:""}.fa-child:before{content:""}.fa-paw:before{content:""}.fa-spoon:before{content:""}.fa-cube:before{content:""}.fa-cubes:before{content:""}.fa-behance:before{content:""}.fa-behance-square:before{content:""}.fa-steam:before{content:""}.fa-steam-square:before{content:""}.fa-recycle:before{content:""}.fa-automobile:before,.fa-car:before{content:""}.fa-cab:before,.fa-taxi:before{content:""}.fa-tree:before{content:""}.fa-spotify:before{content:""}.fa-deviantart:before{content:""}.fa-soundcloud:before{content:""}.fa-database:before{content:""}.fa-file-pdf-o:before{content:""}.fa-file-word-o:before{content:""}.fa-file-excel-o:before{content:""}.fa-file-powerpoint-o:before{content:""}.fa-file-image-o:before,.fa-file-photo-o:before,.fa-file-picture-o:before{content:""}.fa-file-archive-o:before,.fa-file-zip-o:before{content:""}.fa-file-audio-o:before,.fa-file-sound-o:before{content:""}.fa-file-movie-o:before,.fa-file-video-o:before{content:""}.fa-file-code-o:before{content:""}.fa-vine:before{content:""}.fa-codepen:before{content:""}.fa-jsfiddle:before{content:""}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-ring:before,.fa-life-saver:before,.fa-support:before{content:""}.fa-circle-o-notch:before{content:""}.fa-ra:before,.fa-rebel:before,.fa-resistance:before{content:""}.fa-empire:before,.fa-ge:before{content:""}.fa-git-square:before{content:""}.fa-git:before{content:""}.fa-hacker-news:before,.fa-y-combinator-square:before,.fa-yc-square:before{content:""}.fa-tencent-weibo:before{content:""}.fa-qq:before{content:""}.fa-wechat:before,.fa-weixin:before{content:""}.fa-paper-plane:before,.fa-send:before{content:""}.fa-paper-plane-o:before,.fa-send-o:before{content:""}.fa-history:before{content:""}.fa-circle-thin:before{content:""}.fa-header:before{content:""}.fa-paragraph:before{content:""}.fa-sliders:before{content:""}.fa-share-alt:before{content:""}.fa-share-alt-square:before{content:""}.fa-bomb:before{content:""}.fa-futbol-o:before,.fa-soccer-ball-o:before{content:""}.fa-tty:before{content:""}.fa-binoculars:before{content:""}.fa-plug:before{content:""}.fa-slideshare:before{content:""}.fa-twitch:before{content:""}.fa-yelp:before{content:""}.fa-newspaper-o:before{content:""}.fa-wifi:before{content:""}.fa-calculator:before{content:""}.fa-paypal:before{content:""}.fa-google-wallet:before{content:""}.fa-cc-visa:before{content:""}.fa-cc-mastercard:before{content:""}.fa-cc-discover:before{content:""}.fa-cc-amex:before{content:""}.fa-cc-paypal:before{content:""}.fa-cc-stripe:before{content:""}.fa-bell-slash:before{content:""}.fa-bell-slash-o:before{content:""}.fa-trash:before{content:""}.fa-copyright:before{content:""}.fa-at:before{content:""}.fa-eyedropper:before{content:""}.fa-paint-brush:before{content:""}.fa-birthday-cake:before{content:""}.fa-area-chart:before{content:""}.fa-pie-chart:before{content:""}.fa-line-chart:before{content:""}.fa-lastfm:before{content:""}.fa-lastfm-square:before{content:""}.fa-toggle-off:before{content:""}.fa-toggle-on:before{content:""}.fa-bicycle:before{content:""}.fa-bus:before{content:""}.fa-ioxhost:before{content:""}.fa-angellist:before{content:""}.fa-cc:before{content:""}.fa-ils:before,.fa-shekel:before,.fa-sheqel:before{content:""}.fa-meanpath:before{content:""}.fa-buysellads:before{content:""}.fa-connectdevelop:before{content:""}.fa-dashcube:before{content:""}.fa-forumbee:before{content:""}.fa-leanpub:before{content:""}.fa-sellsy:before{content:""}.fa-shirtsinbulk:before{content:""}.fa-simplybuilt:before{content:""}.fa-skyatlas:before{content:""}.fa-cart-plus:before{content:""}.fa-cart-arrow-down:before{content:""}.fa-diamond:before{content:""}.fa-ship:before{content:""}.fa-user-secret:before{content:""}.fa-motorcycle:before{content:""}.fa-street-view:before{content:""}.fa-heartbeat:before{content:""}.fa-venus:before{content:""}.fa-mars:before{content:""}.fa-mercury:before{content:""}.fa-intersex:before,.fa-transgender:before{content:""}.fa-transgender-alt:before{content:""}.fa-venus-double:before{content:""}.fa-mars-double:before{content:""}.fa-venus-mars:before{content:""}.fa-mars-stroke:before{content:""}.fa-mars-stroke-v:before{content:""}.fa-mars-stroke-h:before{content:""}.fa-neuter:before{content:""}.fa-genderless:before{content:""}.fa-facebook-official:before{content:""}.fa-pinterest-p:before{content:""}.fa-whatsapp:before{content:""}.fa-server:before{content:""}.fa-user-plus:before{content:""}.fa-user-times:before{content:""}.fa-bed:before,.fa-hotel:before{content:""}.fa-viacoin:before{content:""}.fa-train:before{content:""}.fa-subway:before{content:""}.fa-medium:before{content:""}.fa-y-combinator:before,.fa-yc:before{content:""}.fa-optin-monster:before{content:""}.fa-opencart:before{content:""}.fa-expeditedssl:before{content:""}.fa-battery-4:before,.fa-battery-full:before,.fa-battery:before{content:""}.fa-battery-3:before,.fa-battery-three-quarters:before{content:""}.fa-battery-2:before,.fa-battery-half:before{content:""}.fa-battery-1:before,.fa-battery-quarter:before{content:""}.fa-battery-0:before,.fa-battery-empty:before{content:""}.fa-mouse-pointer:before{content:""}.fa-i-cursor:before{content:""}.fa-object-group:before{content:""}.fa-object-ungroup:before{content:""}.fa-sticky-note:before{content:""}.fa-sticky-note-o:before{content:""}.fa-cc-jcb:before{content:""}.fa-cc-diners-club:before{content:""}.fa-clone:before{content:""}.fa-balance-scale:before{content:""}.fa-hourglass-o:before{content:""}.fa-hourglass-1:before,.fa-hourglass-start:before{content:""}.fa-hourglass-2:before,.fa-hourglass-half:before{content:""}.fa-hourglass-3:before,.fa-hourglass-end:before{content:""}.fa-hourglass:before{content:""}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:""}.fa-hand-paper-o:before,.fa-hand-stop-o:before{content:""}.fa-hand-scissors-o:before{content:""}.fa-hand-lizard-o:before{content:""}.fa-hand-spock-o:before{content:""}.fa-hand-pointer-o:before{content:""}.fa-hand-peace-o:before{content:""}.fa-trademark:before{content:""}.fa-registered:before{content:""}.fa-creative-commons:before{content:""}.fa-gg:before{content:""}.fa-gg-circle:before{content:""}.fa-tripadvisor:before{content:""}.fa-odnoklassniki:before{content:""}.fa-odnoklassniki-square:before{content:""}.fa-get-pocket:before{content:""}.fa-wikipedia-w:before{content:""}.fa-safari:before{content:""}.fa-chrome:before{content:""}.fa-firefox:before{content:""}.fa-opera:before{content:""}.fa-internet-explorer:before{content:""}.fa-television:before,.fa-tv:before{content:""}.fa-contao:before{content:""}.fa-500px:before{content:""}.fa-amazon:before{content:""}.fa-calendar-plus-o:before{content:""}.fa-calendar-minus-o:before{content:""}.fa-calendar-times-o:before{content:""}.fa-calendar-check-o:before{content:""}.fa-industry:before{content:""}.fa-map-pin:before{content:""}.fa-map-signs:before{content:""}.fa-map-o:before{content:""}.fa-map:before{content:""}.fa-commenting:before{content:""}.fa-commenting-o:before{content:""}.fa-houzz:before{content:""}.fa-vimeo:before{content:""}.fa-black-tie:before{content:""}.fa-fonticons:before{content:""}.fa-reddit-alien:before{content:""}.fa-edge:before{content:""}.fa-credit-card-alt:before{content:""}.fa-codiepie:before{content:""}.fa-modx:before{content:""}.fa-fort-awesome:before{content:""}.fa-usb:before{content:""}.fa-product-hunt:before{content:""}.fa-mixcloud:before{content:""}.fa-scribd:before{content:""}.fa-pause-circle:before{content:""}.fa-pause-circle-o:before{content:""}.fa-stop-circle:before{content:""}.fa-stop-circle-o:before{content:""}.fa-shopping-bag:before{content:""}.fa-shopping-basket:before{content:""}.fa-hashtag:before{content:""}.fa-bluetooth:before{content:""}.fa-bluetooth-b:before{content:""}.fa-percent:before{content:""}.fa-gitlab:before,.icon-gitlab:before{content:""}.fa-wpbeginner:before{content:""}.fa-wpforms:before{content:""}.fa-envira:before{content:""}.fa-universal-access:before{content:""}.fa-wheelchair-alt:before{content:""}.fa-question-circle-o:before{content:""}.fa-blind:before{content:""}.fa-audio-description:before{content:""}.fa-volume-control-phone:before{content:""}.fa-braille:before{content:""}.fa-assistive-listening-systems:before{content:""}.fa-american-sign-language-interpreting:before,.fa-asl-interpreting:before{content:""}.fa-deaf:before,.fa-deafness:before,.fa-hard-of-hearing:before{content:""}.fa-glide:before{content:""}.fa-glide-g:before{content:""}.fa-sign-language:before,.fa-signing:before{content:""}.fa-low-vision:before{content:""}.fa-viadeo:before{content:""}.fa-viadeo-square:before{content:""}.fa-snapchat:before{content:""}.fa-snapchat-ghost:before{content:""}.fa-snapchat-square:before{content:""}.fa-pied-piper:before{content:""}.fa-first-order:before{content:""}.fa-yoast:before{content:""}.fa-themeisle:before{content:""}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:""}.fa-fa:before,.fa-font-awesome:before{content:""}.fa-handshake-o:before{content:""}.fa-envelope-open:before{content:""}.fa-envelope-open-o:before{content:""}.fa-linode:before{content:""}.fa-address-book:before{content:""}.fa-address-book-o:before{content:""}.fa-address-card:before,.fa-vcard:before{content:""}.fa-address-card-o:before,.fa-vcard-o:before{content:""}.fa-user-circle:before{content:""}.fa-user-circle-o:before{content:""}.fa-user-o:before{content:""}.fa-id-badge:before{content:""}.fa-drivers-license:before,.fa-id-card:before{content:""}.fa-drivers-license-o:before,.fa-id-card-o:before{content:""}.fa-quora:before{content:""}.fa-free-code-camp:before{content:""}.fa-telegram:before{content:""}.fa-thermometer-4:before,.fa-thermometer-full:before,.fa-thermometer:before{content:""}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:""}.fa-thermometer-2:before,.fa-thermometer-half:before{content:""}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:""}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:""}.fa-shower:before{content:""}.fa-bath:before,.fa-bathtub:before,.fa-s15:before{content:""}.fa-podcast:before{content:""}.fa-window-maximize:before{content:""}.fa-window-minimize:before{content:""}.fa-window-restore:before{content:""}.fa-times-rectangle:before,.fa-window-close:before{content:""}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:""}.fa-bandcamp:before{content:""}.fa-grav:before{content:""}.fa-etsy:before{content:""}.fa-imdb:before{content:""}.fa-ravelry:before{content:""}.fa-eercast:before{content:""}.fa-microchip:before{content:""}.fa-snowflake-o:before{content:""}.fa-superpowers:before{content:""}.fa-wpexplorer:before{content:""}.fa-meetup:before{content:""}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}.fa,.icon,.rst-content .admonition-title,.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content code.download span:first-child,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink,.rst-content tt.download span:first-child,.wy-dropdown .caret,.wy-inline-validate.wy-inline-validate-danger .wy-input-context,.wy-inline-validate.wy-inline-validate-info .wy-input-context,.wy-inline-validate.wy-inline-validate-success .wy-input-context,.wy-inline-validate.wy-inline-validate-warning .wy-input-context,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li button.toctree-expand{font-family:inherit}.fa:before,.icon:before,.rst-content .admonition-title:before,.rst-content .code-block-caption .headerlink:before,.rst-content .eqno .headerlink:before,.rst-content code.download span:first-child:before,.rst-content dl dt .headerlink:before,.rst-content h1 .headerlink:before,.rst-content h2 .headerlink:before,.rst-content h3 .headerlink:before,.rst-content h4 .headerlink:before,.rst-content h5 .headerlink:before,.rst-content h6 .headerlink:before,.rst-content p.caption .headerlink:before,.rst-content p .headerlink:before,.rst-content table>caption .headerlink:before,.rst-content tt.download span:first-child:before,.wy-dropdown .caret:before,.wy-inline-validate.wy-inline-validate-danger .wy-input-context:before,.wy-inline-validate.wy-inline-validate-info .wy-input-context:before,.wy-inline-validate.wy-inline-validate-success .wy-input-context:before,.wy-inline-validate.wy-inline-validate-warning .wy-input-context:before,.wy-menu-vertical li.current>a button.toctree-expand:before,.wy-menu-vertical li.on a button.toctree-expand:before,.wy-menu-vertical li button.toctree-expand:before{font-family:FontAwesome;display:inline-block;font-style:normal;font-weight:400;line-height:1;text-decoration:inherit}.rst-content .code-block-caption a .headerlink,.rst-content .eqno a .headerlink,.rst-content a .admonition-title,.rst-content code.download a span:first-child,.rst-content dl dt a .headerlink,.rst-content h1 a .headerlink,.rst-content h2 a .headerlink,.rst-content h3 a .headerlink,.rst-content h4 a .headerlink,.rst-content h5 a .headerlink,.rst-content h6 a .headerlink,.rst-content p.caption a .headerlink,.rst-content p a .headerlink,.rst-content table>caption a .headerlink,.rst-content tt.download a span:first-child,.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand,.wy-menu-vertical li a button.toctree-expand,a .fa,a .icon,a .rst-content .admonition-title,a .rst-content .code-block-caption .headerlink,a .rst-content .eqno .headerlink,a .rst-content code.download span:first-child,a .rst-content dl dt .headerlink,a .rst-content h1 .headerlink,a .rst-content h2 .headerlink,a .rst-content h3 .headerlink,a .rst-content h4 .headerlink,a .rst-content h5 .headerlink,a .rst-content h6 .headerlink,a .rst-content p.caption .headerlink,a .rst-content p .headerlink,a .rst-content table>caption .headerlink,a .rst-content tt.download span:first-child,a .wy-menu-vertical li button.toctree-expand{display:inline-block;text-decoration:inherit}.btn .fa,.btn .icon,.btn .rst-content .admonition-title,.btn .rst-content .code-block-caption .headerlink,.btn .rst-content .eqno .headerlink,.btn .rst-content code.download span:first-child,.btn .rst-content dl dt .headerlink,.btn .rst-content h1 .headerlink,.btn .rst-content h2 .headerlink,.btn .rst-content h3 .headerlink,.btn .rst-content h4 .headerlink,.btn .rst-content h5 .headerlink,.btn .rst-content h6 .headerlink,.btn .rst-content p .headerlink,.btn .rst-content table>caption .headerlink,.btn .rst-content tt.download span:first-child,.btn .wy-menu-vertical li.current>a button.toctree-expand,.btn .wy-menu-vertical li.on a button.toctree-expand,.btn .wy-menu-vertical li button.toctree-expand,.nav .fa,.nav .icon,.nav .rst-content .admonition-title,.nav .rst-content .code-block-caption .headerlink,.nav .rst-content .eqno .headerlink,.nav .rst-content code.download span:first-child,.nav .rst-content dl dt .headerlink,.nav .rst-content h1 .headerlink,.nav .rst-content h2 .headerlink,.nav .rst-content h3 .headerlink,.nav .rst-content h4 .headerlink,.nav .rst-content h5 .headerlink,.nav .rst-content h6 .headerlink,.nav .rst-content p .headerlink,.nav .rst-content table>caption .headerlink,.nav .rst-content tt.download span:first-child,.nav .wy-menu-vertical li.current>a button.toctree-expand,.nav .wy-menu-vertical li.on a button.toctree-expand,.nav .wy-menu-vertical li button.toctree-expand,.rst-content .btn .admonition-title,.rst-content .code-block-caption .btn .headerlink,.rst-content .code-block-caption .nav .headerlink,.rst-content .eqno .btn .headerlink,.rst-content .eqno .nav .headerlink,.rst-content .nav .admonition-title,.rst-content code.download .btn span:first-child,.rst-content code.download .nav span:first-child,.rst-content dl dt .btn .headerlink,.rst-content dl dt .nav .headerlink,.rst-content h1 .btn .headerlink,.rst-content h1 .nav .headerlink,.rst-content h2 .btn .headerlink,.rst-content h2 .nav .headerlink,.rst-content h3 .btn .headerlink,.rst-content h3 .nav .headerlink,.rst-content h4 .btn .headerlink,.rst-content h4 .nav .headerlink,.rst-content h5 .btn .headerlink,.rst-content h5 .nav .headerlink,.rst-content h6 .btn .headerlink,.rst-content h6 .nav .headerlink,.rst-content p .btn .headerlink,.rst-content p .nav .headerlink,.rst-content table>caption .btn .headerlink,.rst-content table>caption .nav .headerlink,.rst-content tt.download .btn span:first-child,.rst-content tt.download .nav span:first-child,.wy-menu-vertical li .btn button.toctree-expand,.wy-menu-vertical li.current>a .btn button.toctree-expand,.wy-menu-vertical li.current>a .nav button.toctree-expand,.wy-menu-vertical li .nav button.toctree-expand,.wy-menu-vertical li.on a .btn button.toctree-expand,.wy-menu-vertical li.on a .nav button.toctree-expand{display:inline}.btn .fa-large.icon,.btn .fa.fa-large,.btn .rst-content .code-block-caption .fa-large.headerlink,.btn .rst-content .eqno .fa-large.headerlink,.btn .rst-content .fa-large.admonition-title,.btn .rst-content code.download span.fa-large:first-child,.btn .rst-content dl dt .fa-large.headerlink,.btn .rst-content h1 .fa-large.headerlink,.btn .rst-content h2 .fa-large.headerlink,.btn .rst-content h3 .fa-large.headerlink,.btn .rst-content h4 .fa-large.headerlink,.btn .rst-content h5 .fa-large.headerlink,.btn .rst-content h6 .fa-large.headerlink,.btn .rst-content p .fa-large.headerlink,.btn .rst-content table>caption .fa-large.headerlink,.btn .rst-content tt.download span.fa-large:first-child,.btn .wy-menu-vertical li button.fa-large.toctree-expand,.nav .fa-large.icon,.nav .fa.fa-large,.nav .rst-content .code-block-caption .fa-large.headerlink,.nav .rst-content .eqno .fa-large.headerlink,.nav .rst-content .fa-large.admonition-title,.nav .rst-content code.download span.fa-large:first-child,.nav .rst-content dl dt .fa-large.headerlink,.nav .rst-content h1 .fa-large.headerlink,.nav .rst-content h2 .fa-large.headerlink,.nav .rst-content h3 .fa-large.headerlink,.nav .rst-content h4 .fa-large.headerlink,.nav .rst-content h5 .fa-large.headerlink,.nav .rst-content h6 .fa-large.headerlink,.nav .rst-content p .fa-large.headerlink,.nav .rst-content table>caption .fa-large.headerlink,.nav .rst-content tt.download span.fa-large:first-child,.nav .wy-menu-vertical li button.fa-large.toctree-expand,.rst-content .btn .fa-large.admonition-title,.rst-content .code-block-caption .btn .fa-large.headerlink,.rst-content .code-block-caption .nav .fa-large.headerlink,.rst-content .eqno .btn .fa-large.headerlink,.rst-content .eqno .nav .fa-large.headerlink,.rst-content .nav .fa-large.admonition-title,.rst-content code.download .btn span.fa-large:first-child,.rst-content code.download .nav span.fa-large:first-child,.rst-content dl dt .btn .fa-large.headerlink,.rst-content dl dt .nav .fa-large.headerlink,.rst-content h1 .btn .fa-large.headerlink,.rst-content h1 .nav .fa-large.headerlink,.rst-content h2 .btn .fa-large.headerlink,.rst-content h2 .nav .fa-large.headerlink,.rst-content h3 .btn .fa-large.headerlink,.rst-content h3 .nav .fa-large.headerlink,.rst-content h4 .btn .fa-large.headerlink,.rst-content h4 .nav .fa-large.headerlink,.rst-content h5 .btn .fa-large.headerlink,.rst-content h5 .nav .fa-large.headerlink,.rst-content h6 .btn .fa-large.headerlink,.rst-content h6 .nav .fa-large.headerlink,.rst-content p .btn .fa-large.headerlink,.rst-content p .nav .fa-large.headerlink,.rst-content table>caption .btn .fa-large.headerlink,.rst-content table>caption .nav .fa-large.headerlink,.rst-content tt.download .btn span.fa-large:first-child,.rst-content tt.download .nav span.fa-large:first-child,.wy-menu-vertical li .btn button.fa-large.toctree-expand,.wy-menu-vertical li .nav button.fa-large.toctree-expand{line-height:.9em}.btn .fa-spin.icon,.btn .fa.fa-spin,.btn .rst-content .code-block-caption .fa-spin.headerlink,.btn .rst-content .eqno .fa-spin.headerlink,.btn .rst-content .fa-spin.admonition-title,.btn .rst-content code.download span.fa-spin:first-child,.btn .rst-content dl dt .fa-spin.headerlink,.btn .rst-content h1 .fa-spin.headerlink,.btn .rst-content h2 .fa-spin.headerlink,.btn .rst-content h3 .fa-spin.headerlink,.btn .rst-content h4 .fa-spin.headerlink,.btn .rst-content h5 .fa-spin.headerlink,.btn .rst-content h6 .fa-spin.headerlink,.btn .rst-content p .fa-spin.headerlink,.btn .rst-content table>caption .fa-spin.headerlink,.btn .rst-content tt.download span.fa-spin:first-child,.btn .wy-menu-vertical li button.fa-spin.toctree-expand,.nav .fa-spin.icon,.nav .fa.fa-spin,.nav .rst-content .code-block-caption .fa-spin.headerlink,.nav .rst-content .eqno .fa-spin.headerlink,.nav .rst-content .fa-spin.admonition-title,.nav .rst-content code.download span.fa-spin:first-child,.nav .rst-content dl dt .fa-spin.headerlink,.nav .rst-content h1 .fa-spin.headerlink,.nav .rst-content h2 .fa-spin.headerlink,.nav .rst-content h3 .fa-spin.headerlink,.nav .rst-content h4 .fa-spin.headerlink,.nav .rst-content h5 .fa-spin.headerlink,.nav .rst-content h6 .fa-spin.headerlink,.nav .rst-content p .fa-spin.headerlink,.nav .rst-content table>caption .fa-spin.headerlink,.nav .rst-content tt.download span.fa-spin:first-child,.nav .wy-menu-vertical li button.fa-spin.toctree-expand,.rst-content .btn .fa-spin.admonition-title,.rst-content .code-block-caption .btn .fa-spin.headerlink,.rst-content .code-block-caption .nav .fa-spin.headerlink,.rst-content .eqno .btn .fa-spin.headerlink,.rst-content .eqno .nav .fa-spin.headerlink,.rst-content .nav .fa-spin.admonition-title,.rst-content code.download .btn span.fa-spin:first-child,.rst-content code.download .nav span.fa-spin:first-child,.rst-content dl dt .btn .fa-spin.headerlink,.rst-content dl dt .nav .fa-spin.headerlink,.rst-content h1 .btn .fa-spin.headerlink,.rst-content h1 .nav .fa-spin.headerlink,.rst-content h2 .btn .fa-spin.headerlink,.rst-content h2 .nav .fa-spin.headerlink,.rst-content h3 .btn .fa-spin.headerlink,.rst-content h3 .nav .fa-spin.headerlink,.rst-content h4 .btn .fa-spin.headerlink,.rst-content h4 .nav .fa-spin.headerlink,.rst-content h5 .btn .fa-spin.headerlink,.rst-content h5 .nav .fa-spin.headerlink,.rst-content h6 .btn .fa-spin.headerlink,.rst-content h6 .nav .fa-spin.headerlink,.rst-content p .btn .fa-spin.headerlink,.rst-content p .nav .fa-spin.headerlink,.rst-content table>caption .btn .fa-spin.headerlink,.rst-content table>caption .nav .fa-spin.headerlink,.rst-content tt.download .btn span.fa-spin:first-child,.rst-content tt.download .nav span.fa-spin:first-child,.wy-menu-vertical li .btn button.fa-spin.toctree-expand,.wy-menu-vertical li .nav button.fa-spin.toctree-expand{display:inline-block}.btn.fa:before,.btn.icon:before,.rst-content .btn.admonition-title:before,.rst-content .code-block-caption .btn.headerlink:before,.rst-content .eqno .btn.headerlink:before,.rst-content code.download span.btn:first-child:before,.rst-content dl dt .btn.headerlink:before,.rst-content h1 .btn.headerlink:before,.rst-content h2 .btn.headerlink:before,.rst-content h3 .btn.headerlink:before,.rst-content h4 .btn.headerlink:before,.rst-content h5 .btn.headerlink:before,.rst-content h6 .btn.headerlink:before,.rst-content p .btn.headerlink:before,.rst-content table>caption .btn.headerlink:before,.rst-content tt.download span.btn:first-child:before,.wy-menu-vertical li button.btn.toctree-expand:before{opacity:.5;-webkit-transition:opacity .05s ease-in;-moz-transition:opacity .05s ease-in;transition:opacity .05s ease-in}.btn.fa:hover:before,.btn.icon:hover:before,.rst-content .btn.admonition-title:hover:before,.rst-content .code-block-caption .btn.headerlink:hover:before,.rst-content .eqno .btn.headerlink:hover:before,.rst-content code.download span.btn:first-child:hover:before,.rst-content dl dt .btn.headerlink:hover:before,.rst-content h1 .btn.headerlink:hover:before,.rst-content h2 .btn.headerlink:hover:before,.rst-content h3 .btn.headerlink:hover:before,.rst-content h4 .btn.headerlink:hover:before,.rst-content h5 .btn.headerlink:hover:before,.rst-content h6 .btn.headerlink:hover:before,.rst-content p .btn.headerlink:hover:before,.rst-content table>caption .btn.headerlink:hover:before,.rst-content tt.download span.btn:first-child:hover:before,.wy-menu-vertical li button.btn.toctree-expand:hover:before{opacity:1}.btn-mini .fa:before,.btn-mini .icon:before,.btn-mini .rst-content .admonition-title:before,.btn-mini .rst-content .code-block-caption .headerlink:before,.btn-mini .rst-content .eqno .headerlink:before,.btn-mini .rst-content code.download span:first-child:before,.btn-mini .rst-content dl dt .headerlink:before,.btn-mini .rst-content h1 .headerlink:before,.btn-mini .rst-content h2 .headerlink:before,.btn-mini .rst-content h3 .headerlink:before,.btn-mini .rst-content h4 .headerlink:before,.btn-mini .rst-content h5 .headerlink:before,.btn-mini .rst-content h6 .headerlink:before,.btn-mini .rst-content p .headerlink:before,.btn-mini .rst-content table>caption .headerlink:before,.btn-mini .rst-content tt.download span:first-child:before,.btn-mini .wy-menu-vertical li button.toctree-expand:before,.rst-content .btn-mini .admonition-title:before,.rst-content .code-block-caption .btn-mini .headerlink:before,.rst-content .eqno .btn-mini .headerlink:before,.rst-content code.download .btn-mini span:first-child:before,.rst-content dl dt .btn-mini .headerlink:before,.rst-content h1 .btn-mini .headerlink:before,.rst-content h2 .btn-mini .headerlink:before,.rst-content h3 .btn-mini .headerlink:before,.rst-content h4 .btn-mini .headerlink:before,.rst-content h5 .btn-mini .headerlink:before,.rst-content h6 .btn-mini .headerlink:before,.rst-content p .btn-mini .headerlink:before,.rst-content table>caption .btn-mini .headerlink:before,.rst-content tt.download .btn-mini span:first-child:before,.wy-menu-vertical li .btn-mini button.toctree-expand:before{font-size:14px;vertical-align:-15%}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning,.wy-alert{padding:12px;line-height:24px;margin-bottom:24px;background:#e7f2fa}.rst-content .admonition-title,.wy-alert-title{font-weight:700;display:block;color:#fff;background:#6ab0de;padding:6px 12px;margin:-12px -12px 12px}.rst-content .danger,.rst-content .error,.rst-content .wy-alert-danger.admonition,.rst-content .wy-alert-danger.admonition-todo,.rst-content .wy-alert-danger.attention,.rst-content .wy-alert-danger.caution,.rst-content .wy-alert-danger.hint,.rst-content .wy-alert-danger.important,.rst-content .wy-alert-danger.note,.rst-content .wy-alert-danger.seealso,.rst-content .wy-alert-danger.tip,.rst-content .wy-alert-danger.warning,.wy-alert.wy-alert-danger{background:#fdf3f2}.rst-content .danger .admonition-title,.rst-content .danger .wy-alert-title,.rst-content .error .admonition-title,.rst-content .error .wy-alert-title,.rst-content .wy-alert-danger.admonition-todo .admonition-title,.rst-content .wy-alert-danger.admonition-todo .wy-alert-title,.rst-content .wy-alert-danger.admonition .admonition-title,.rst-content .wy-alert-danger.admonition .wy-alert-title,.rst-content .wy-alert-danger.attention .admonition-title,.rst-content .wy-alert-danger.attention .wy-alert-title,.rst-content .wy-alert-danger.caution .admonition-title,.rst-content .wy-alert-danger.caution .wy-alert-title,.rst-content .wy-alert-danger.hint .admonition-title,.rst-content .wy-alert-danger.hint .wy-alert-title,.rst-content .wy-alert-danger.important .admonition-title,.rst-content .wy-alert-danger.important .wy-alert-title,.rst-content .wy-alert-danger.note .admonition-title,.rst-content .wy-alert-danger.note .wy-alert-title,.rst-content .wy-alert-danger.seealso .admonition-title,.rst-content .wy-alert-danger.seealso .wy-alert-title,.rst-content .wy-alert-danger.tip .admonition-title,.rst-content .wy-alert-danger.tip .wy-alert-title,.rst-content .wy-alert-danger.warning .admonition-title,.rst-content .wy-alert-danger.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-danger .admonition-title,.wy-alert.wy-alert-danger .rst-content .admonition-title,.wy-alert.wy-alert-danger .wy-alert-title{background:#f29f97}.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .warning,.rst-content .wy-alert-warning.admonition,.rst-content .wy-alert-warning.danger,.rst-content .wy-alert-warning.error,.rst-content .wy-alert-warning.hint,.rst-content .wy-alert-warning.important,.rst-content .wy-alert-warning.note,.rst-content .wy-alert-warning.seealso,.rst-content .wy-alert-warning.tip,.wy-alert.wy-alert-warning{background:#ffedcc}.rst-content .admonition-todo .admonition-title,.rst-content .admonition-todo .wy-alert-title,.rst-content .attention .admonition-title,.rst-content .attention .wy-alert-title,.rst-content .caution .admonition-title,.rst-content .caution .wy-alert-title,.rst-content .warning .admonition-title,.rst-content .warning .wy-alert-title,.rst-content .wy-alert-warning.admonition .admonition-title,.rst-content .wy-alert-warning.admonition .wy-alert-title,.rst-content .wy-alert-warning.danger .admonition-title,.rst-content .wy-alert-warning.danger .wy-alert-title,.rst-content .wy-alert-warning.error .admonition-title,.rst-content .wy-alert-warning.error .wy-alert-title,.rst-content .wy-alert-warning.hint .admonition-title,.rst-content .wy-alert-warning.hint .wy-alert-title,.rst-content .wy-alert-warning.important .admonition-title,.rst-content .wy-alert-warning.important .wy-alert-title,.rst-content .wy-alert-warning.note .admonition-title,.rst-content .wy-alert-warning.note .wy-alert-title,.rst-content .wy-alert-warning.seealso .admonition-title,.rst-content .wy-alert-warning.seealso .wy-alert-title,.rst-content .wy-alert-warning.tip .admonition-title,.rst-content .wy-alert-warning.tip .wy-alert-title,.rst-content .wy-alert.wy-alert-warning .admonition-title,.wy-alert.wy-alert-warning .rst-content .admonition-title,.wy-alert.wy-alert-warning .wy-alert-title{background:#f0b37e}.rst-content .note,.rst-content .seealso,.rst-content .wy-alert-info.admonition,.rst-content .wy-alert-info.admonition-todo,.rst-content .wy-alert-info.attention,.rst-content .wy-alert-info.caution,.rst-content .wy-alert-info.danger,.rst-content .wy-alert-info.error,.rst-content .wy-alert-info.hint,.rst-content .wy-alert-info.important,.rst-content .wy-alert-info.tip,.rst-content .wy-alert-info.warning,.wy-alert.wy-alert-info{background:#e7f2fa}.rst-content .note .admonition-title,.rst-content .note .wy-alert-title,.rst-content .seealso .admonition-title,.rst-content .seealso .wy-alert-title,.rst-content .wy-alert-info.admonition-todo .admonition-title,.rst-content .wy-alert-info.admonition-todo .wy-alert-title,.rst-content .wy-alert-info.admonition .admonition-title,.rst-content .wy-alert-info.admonition .wy-alert-title,.rst-content .wy-alert-info.attention .admonition-title,.rst-content .wy-alert-info.attention .wy-alert-title,.rst-content .wy-alert-info.caution .admonition-title,.rst-content .wy-alert-info.caution .wy-alert-title,.rst-content .wy-alert-info.danger .admonition-title,.rst-content .wy-alert-info.danger .wy-alert-title,.rst-content .wy-alert-info.error .admonition-title,.rst-content .wy-alert-info.error .wy-alert-title,.rst-content .wy-alert-info.hint .admonition-title,.rst-content .wy-alert-info.hint .wy-alert-title,.rst-content .wy-alert-info.important .admonition-title,.rst-content .wy-alert-info.important .wy-alert-title,.rst-content .wy-alert-info.tip .admonition-title,.rst-content .wy-alert-info.tip .wy-alert-title,.rst-content .wy-alert-info.warning .admonition-title,.rst-content .wy-alert-info.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-info .admonition-title,.wy-alert.wy-alert-info .rst-content .admonition-title,.wy-alert.wy-alert-info .wy-alert-title{background:#6ab0de}.rst-content .hint,.rst-content .important,.rst-content .tip,.rst-content .wy-alert-success.admonition,.rst-content .wy-alert-success.admonition-todo,.rst-content .wy-alert-success.attention,.rst-content .wy-alert-success.caution,.rst-content .wy-alert-success.danger,.rst-content .wy-alert-success.error,.rst-content .wy-alert-success.note,.rst-content .wy-alert-success.seealso,.rst-content .wy-alert-success.warning,.wy-alert.wy-alert-success{background:#dbfaf4}.rst-content .hint .admonition-title,.rst-content .hint .wy-alert-title,.rst-content .important .admonition-title,.rst-content .important .wy-alert-title,.rst-content .tip .admonition-title,.rst-content .tip .wy-alert-title,.rst-content .wy-alert-success.admonition-todo .admonition-title,.rst-content .wy-alert-success.admonition-todo .wy-alert-title,.rst-content .wy-alert-success.admonition .admonition-title,.rst-content .wy-alert-success.admonition .wy-alert-title,.rst-content .wy-alert-success.attention .admonition-title,.rst-content .wy-alert-success.attention .wy-alert-title,.rst-content .wy-alert-success.caution .admonition-title,.rst-content .wy-alert-success.caution .wy-alert-title,.rst-content .wy-alert-success.danger .admonition-title,.rst-content .wy-alert-success.danger .wy-alert-title,.rst-content .wy-alert-success.error .admonition-title,.rst-content .wy-alert-success.error .wy-alert-title,.rst-content .wy-alert-success.note .admonition-title,.rst-content .wy-alert-success.note .wy-alert-title,.rst-content .wy-alert-success.seealso .admonition-title,.rst-content .wy-alert-success.seealso .wy-alert-title,.rst-content .wy-alert-success.warning .admonition-title,.rst-content .wy-alert-success.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-success .admonition-title,.wy-alert.wy-alert-success .rst-content .admonition-title,.wy-alert.wy-alert-success .wy-alert-title{background:#1abc9c}.rst-content .wy-alert-neutral.admonition,.rst-content .wy-alert-neutral.admonition-todo,.rst-content .wy-alert-neutral.attention,.rst-content .wy-alert-neutral.caution,.rst-content .wy-alert-neutral.danger,.rst-content .wy-alert-neutral.error,.rst-content .wy-alert-neutral.hint,.rst-content .wy-alert-neutral.important,.rst-content .wy-alert-neutral.note,.rst-content .wy-alert-neutral.seealso,.rst-content .wy-alert-neutral.tip,.rst-content .wy-alert-neutral.warning,.wy-alert.wy-alert-neutral{background:#f3f6f6}.rst-content .wy-alert-neutral.admonition-todo .admonition-title,.rst-content .wy-alert-neutral.admonition-todo .wy-alert-title,.rst-content .wy-alert-neutral.admonition .admonition-title,.rst-content .wy-alert-neutral.admonition .wy-alert-title,.rst-content .wy-alert-neutral.attention .admonition-title,.rst-content .wy-alert-neutral.attention .wy-alert-title,.rst-content .wy-alert-neutral.caution .admonition-title,.rst-content .wy-alert-neutral.caution .wy-alert-title,.rst-content .wy-alert-neutral.danger .admonition-title,.rst-content .wy-alert-neutral.danger .wy-alert-title,.rst-content .wy-alert-neutral.error .admonition-title,.rst-content .wy-alert-neutral.error .wy-alert-title,.rst-content .wy-alert-neutral.hint .admonition-title,.rst-content .wy-alert-neutral.hint .wy-alert-title,.rst-content .wy-alert-neutral.important .admonition-title,.rst-content .wy-alert-neutral.important .wy-alert-title,.rst-content .wy-alert-neutral.note .admonition-title,.rst-content .wy-alert-neutral.note .wy-alert-title,.rst-content .wy-alert-neutral.seealso .admonition-title,.rst-content .wy-alert-neutral.seealso .wy-alert-title,.rst-content .wy-alert-neutral.tip .admonition-title,.rst-content .wy-alert-neutral.tip .wy-alert-title,.rst-content .wy-alert-neutral.warning .admonition-title,.rst-content .wy-alert-neutral.warning .wy-alert-title,.rst-content .wy-alert.wy-alert-neutral .admonition-title,.wy-alert.wy-alert-neutral .rst-content .admonition-title,.wy-alert.wy-alert-neutral .wy-alert-title{color:#404040;background:#e1e4e5}.rst-content .wy-alert-neutral.admonition-todo a,.rst-content .wy-alert-neutral.admonition a,.rst-content .wy-alert-neutral.attention a,.rst-content .wy-alert-neutral.caution a,.rst-content .wy-alert-neutral.danger a,.rst-content .wy-alert-neutral.error a,.rst-content .wy-alert-neutral.hint a,.rst-content .wy-alert-neutral.important a,.rst-content .wy-alert-neutral.note a,.rst-content .wy-alert-neutral.seealso a,.rst-content .wy-alert-neutral.tip a,.rst-content .wy-alert-neutral.warning a,.wy-alert.wy-alert-neutral a{color:#2980b9}.rst-content .admonition-todo p:last-child,.rst-content .admonition p:last-child,.rst-content .attention p:last-child,.rst-content .caution p:last-child,.rst-content .danger p:last-child,.rst-content .error p:last-child,.rst-content .hint p:last-child,.rst-content .important p:last-child,.rst-content .note p:last-child,.rst-content .seealso p:last-child,.rst-content .tip p:last-child,.rst-content .warning p:last-child,.wy-alert p:last-child{margin-bottom:0}.wy-tray-container{position:fixed;bottom:0;left:0;z-index:600}.wy-tray-container li{display:block;width:300px;background:transparent;color:#fff;text-align:center;box-shadow:0 5px 5px 0 rgba(0,0,0,.1);padding:0 24px;min-width:20%;opacity:0;height:0;line-height:56px;overflow:hidden;-webkit-transition:all .3s ease-in;-moz-transition:all .3s ease-in;transition:all .3s ease-in}.wy-tray-container li.wy-tray-item-success{background:#27ae60}.wy-tray-container li.wy-tray-item-info{background:#2980b9}.wy-tray-container li.wy-tray-item-warning{background:#e67e22}.wy-tray-container li.wy-tray-item-danger{background:#e74c3c}.wy-tray-container li.on{opacity:1;height:56px}@media screen and (max-width:768px){.wy-tray-container{bottom:auto;top:0;width:100%}.wy-tray-container li{width:100%}}button{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle;cursor:pointer;line-height:normal;-webkit-appearance:button;*overflow:visible}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}button[disabled]{cursor:default}.btn{display:inline-block;border-radius:2px;line-height:normal;white-space:nowrap;text-align:center;cursor:pointer;font-size:100%;padding:6px 12px 8px;color:#fff;border:1px solid rgba(0,0,0,.1);background-color:#27ae60;text-decoration:none;font-weight:400;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 2px -1px hsla(0,0%,100%,.5),inset 0 -2px 0 0 rgba(0,0,0,.1);outline-none:false;vertical-align:middle;*display:inline;zoom:1;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-transition:all .1s linear;-moz-transition:all .1s linear;transition:all .1s linear}.btn-hover{background:#2e8ece;color:#fff}.btn:hover{background:#2cc36b;color:#fff}.btn:focus{background:#2cc36b;outline:0}.btn:active{box-shadow:inset 0 -1px 0 0 rgba(0,0,0,.05),inset 0 2px 0 0 rgba(0,0,0,.1);padding:8px 12px 6px}.btn:visited{color:#fff}.btn-disabled,.btn-disabled:active,.btn-disabled:focus,.btn-disabled:hover,.btn:disabled{background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);filter:alpha(opacity=40);opacity:.4;cursor:not-allowed;box-shadow:none}.btn::-moz-focus-inner{padding:0;border:0}.btn-small{font-size:80%}.btn-info{background-color:#2980b9!important}.btn-info:hover{background-color:#2e8ece!important}.btn-neutral{background-color:#f3f6f6!important;color:#404040!important}.btn-neutral:hover{background-color:#e5ebeb!important;color:#404040}.btn-neutral:visited{color:#404040!important}.btn-success{background-color:#27ae60!important}.btn-success:hover{background-color:#295!important}.btn-danger{background-color:#e74c3c!important}.btn-danger:hover{background-color:#ea6153!important}.btn-warning{background-color:#e67e22!important}.btn-warning:hover{background-color:#e98b39!important}.btn-invert{background-color:#222}.btn-invert:hover{background-color:#2f2f2f!important}.btn-link{background-color:transparent!important;color:#2980b9;box-shadow:none;border-color:transparent!important}.btn-link:active,.btn-link:hover{background-color:transparent!important;color:#409ad5!important;box-shadow:none}.btn-link:visited{color:#9b59b6}.wy-btn-group .btn,.wy-control .btn{vertical-align:middle}.wy-btn-group{margin-bottom:24px;*zoom:1}.wy-btn-group:after,.wy-btn-group:before{display:table;content:""}.wy-btn-group:after{clear:both}.wy-dropdown{position:relative;display:inline-block}.wy-dropdown-active .wy-dropdown-menu{display:block}.wy-dropdown-menu{position:absolute;left:0;display:none;float:left;top:100%;min-width:100%;background:#fcfcfc;z-index:100;border:1px solid #cfd7dd;box-shadow:0 2px 2px 0 rgba(0,0,0,.1);padding:12px}.wy-dropdown-menu>dd>a{display:block;clear:both;color:#404040;white-space:nowrap;font-size:90%;padding:0 12px;cursor:pointer}.wy-dropdown-menu>dd>a:hover{background:#2980b9;color:#fff}.wy-dropdown-menu>dd.divider{border-top:1px solid #cfd7dd;margin:6px 0}.wy-dropdown-menu>dd.search{padding-bottom:12px}.wy-dropdown-menu>dd.search input[type=search]{width:100%}.wy-dropdown-menu>dd.call-to-action{background:#e3e3e3;text-transform:uppercase;font-weight:500;font-size:80%}.wy-dropdown-menu>dd.call-to-action:hover{background:#e3e3e3}.wy-dropdown-menu>dd.call-to-action .btn{color:#fff}.wy-dropdown.wy-dropdown-up .wy-dropdown-menu{bottom:100%;top:auto;left:auto;right:0}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu{background:#fcfcfc;margin-top:2px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a{padding:6px 12px}.wy-dropdown.wy-dropdown-bubble .wy-dropdown-menu a:hover{background:#2980b9;color:#fff}.wy-dropdown.wy-dropdown-left .wy-dropdown-menu{right:0;left:auto;text-align:right}.wy-dropdown-arrow:before{content:" ";border-bottom:5px solid #f5f5f5;border-left:5px solid transparent;border-right:5px solid transparent;position:absolute;display:block;top:-4px;left:50%;margin-left:-3px}.wy-dropdown-arrow.wy-dropdown-arrow-left:before{left:11px}.wy-form-stacked select{display:block}.wy-form-aligned .wy-help-inline,.wy-form-aligned input,.wy-form-aligned label,.wy-form-aligned select,.wy-form-aligned textarea{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-form-aligned .wy-control-group>label{display:inline-block;vertical-align:middle;width:10em;margin:6px 12px 0 0;float:left}.wy-form-aligned .wy-control{float:left}.wy-form-aligned .wy-control label{display:block}.wy-form-aligned .wy-control select{margin-top:6px}fieldset{margin:0}fieldset,legend{border:0;padding:0}legend{width:100%;white-space:normal;margin-bottom:24px;font-size:150%;*margin-left:-7px}label,legend{display:block}label{margin:0 0 .3125em;color:#333;font-size:90%}input,select,textarea{font-size:100%;margin:0;vertical-align:baseline;*vertical-align:middle}.wy-control-group{margin-bottom:24px;max-width:1200px;margin-left:auto;margin-right:auto;*zoom:1}.wy-control-group:after,.wy-control-group:before{display:table;content:""}.wy-control-group:after{clear:both}.wy-control-group.wy-control-group-required>label:after{content:" *";color:#e74c3c}.wy-control-group .wy-form-full,.wy-control-group .wy-form-halves,.wy-control-group .wy-form-thirds{padding-bottom:12px}.wy-control-group .wy-form-full input[type=color],.wy-control-group .wy-form-full input[type=date],.wy-control-group .wy-form-full input[type=datetime-local],.wy-control-group .wy-form-full input[type=datetime],.wy-control-group .wy-form-full input[type=email],.wy-control-group .wy-form-full input[type=month],.wy-control-group .wy-form-full input[type=number],.wy-control-group .wy-form-full input[type=password],.wy-control-group .wy-form-full input[type=search],.wy-control-group .wy-form-full input[type=tel],.wy-control-group .wy-form-full input[type=text],.wy-control-group .wy-form-full input[type=time],.wy-control-group .wy-form-full input[type=url],.wy-control-group .wy-form-full input[type=week],.wy-control-group .wy-form-full select,.wy-control-group .wy-form-halves input[type=color],.wy-control-group .wy-form-halves input[type=date],.wy-control-group .wy-form-halves input[type=datetime-local],.wy-control-group .wy-form-halves input[type=datetime],.wy-control-group .wy-form-halves input[type=email],.wy-control-group .wy-form-halves input[type=month],.wy-control-group .wy-form-halves input[type=number],.wy-control-group .wy-form-halves input[type=password],.wy-control-group .wy-form-halves input[type=search],.wy-control-group .wy-form-halves input[type=tel],.wy-control-group .wy-form-halves input[type=text],.wy-control-group .wy-form-halves input[type=time],.wy-control-group .wy-form-halves input[type=url],.wy-control-group .wy-form-halves input[type=week],.wy-control-group .wy-form-halves select,.wy-control-group .wy-form-thirds input[type=color],.wy-control-group .wy-form-thirds input[type=date],.wy-control-group .wy-form-thirds input[type=datetime-local],.wy-control-group .wy-form-thirds input[type=datetime],.wy-control-group .wy-form-thirds input[type=email],.wy-control-group .wy-form-thirds input[type=month],.wy-control-group .wy-form-thirds input[type=number],.wy-control-group .wy-form-thirds input[type=password],.wy-control-group .wy-form-thirds input[type=search],.wy-control-group .wy-form-thirds input[type=tel],.wy-control-group .wy-form-thirds input[type=text],.wy-control-group .wy-form-thirds input[type=time],.wy-control-group .wy-form-thirds input[type=url],.wy-control-group .wy-form-thirds input[type=week],.wy-control-group .wy-form-thirds select{width:100%}.wy-control-group .wy-form-full{float:left;display:block;width:100%;margin-right:0}.wy-control-group .wy-form-full:last-child{margin-right:0}.wy-control-group .wy-form-halves{float:left;display:block;margin-right:2.35765%;width:48.82117%}.wy-control-group .wy-form-halves:last-child,.wy-control-group .wy-form-halves:nth-of-type(2n){margin-right:0}.wy-control-group .wy-form-halves:nth-of-type(odd){clear:left}.wy-control-group .wy-form-thirds{float:left;display:block;margin-right:2.35765%;width:31.76157%}.wy-control-group .wy-form-thirds:last-child,.wy-control-group .wy-form-thirds:nth-of-type(3n){margin-right:0}.wy-control-group .wy-form-thirds:nth-of-type(3n+1){clear:left}.wy-control-group.wy-control-group-no-input .wy-control,.wy-control-no-input{margin:6px 0 0;font-size:90%}.wy-control-no-input{display:inline-block}.wy-control-group.fluid-input input[type=color],.wy-control-group.fluid-input input[type=date],.wy-control-group.fluid-input input[type=datetime-local],.wy-control-group.fluid-input input[type=datetime],.wy-control-group.fluid-input input[type=email],.wy-control-group.fluid-input input[type=month],.wy-control-group.fluid-input input[type=number],.wy-control-group.fluid-input input[type=password],.wy-control-group.fluid-input input[type=search],.wy-control-group.fluid-input input[type=tel],.wy-control-group.fluid-input input[type=text],.wy-control-group.fluid-input input[type=time],.wy-control-group.fluid-input input[type=url],.wy-control-group.fluid-input input[type=week]{width:100%}.wy-form-message-inline{padding-left:.3em;color:#666;font-size:90%}.wy-form-message{display:block;color:#999;font-size:70%;margin-top:.3125em;font-style:italic}.wy-form-message p{font-size:inherit;font-style:italic;margin-bottom:6px}.wy-form-message p:last-child{margin-bottom:0}input{line-height:normal}input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;*overflow:visible}input[type=color],input[type=date],input[type=datetime-local],input[type=datetime],input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week]{-webkit-appearance:none;padding:6px;display:inline-block;border:1px solid #ccc;font-size:80%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;box-shadow:inset 0 1px 3px #ddd;border-radius:0;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}input[type=datetime-local]{padding:.34375em .625em}input[disabled]{cursor:default}input[type=checkbox],input[type=radio]{padding:0;margin-right:.3125em;*height:13px;*width:13px}input[type=checkbox],input[type=radio],input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}input[type=color]:focus,input[type=date]:focus,input[type=datetime-local]:focus,input[type=datetime]:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus{outline:0;outline:thin dotted\9;border-color:#333}input.no-focus:focus{border-color:#ccc!important}input[type=checkbox]:focus,input[type=file]:focus,input[type=radio]:focus{outline:thin dotted #333;outline:1px auto #129fea}input[type=color][disabled],input[type=date][disabled],input[type=datetime-local][disabled],input[type=datetime][disabled],input[type=email][disabled],input[type=month][disabled],input[type=number][disabled],input[type=password][disabled],input[type=search][disabled],input[type=tel][disabled],input[type=text][disabled],input[type=time][disabled],input[type=url][disabled],input[type=week][disabled]{cursor:not-allowed;background-color:#fafafa}input:focus:invalid,select:focus:invalid,textarea:focus:invalid{color:#e74c3c;border:1px solid #e74c3c}input:focus:invalid:focus,select:focus:invalid:focus,textarea:focus:invalid:focus{border-color:#e74c3c}input[type=checkbox]:focus:invalid:focus,input[type=file]:focus:invalid:focus,input[type=radio]:focus:invalid:focus{outline-color:#e74c3c}input.wy-input-large{padding:12px;font-size:100%}textarea{overflow:auto;vertical-align:top;width:100%;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif}select,textarea{padding:.5em .625em;display:inline-block;border:1px solid #ccc;font-size:80%;box-shadow:inset 0 1px 3px #ddd;-webkit-transition:border .3s linear;-moz-transition:border .3s linear;transition:border .3s linear}select{border:1px solid #ccc;background-color:#fff}select[multiple]{height:auto}select:focus,textarea:focus{outline:0}input[readonly],select[disabled],select[readonly],textarea[disabled],textarea[readonly]{cursor:not-allowed;background-color:#fafafa}input[type=checkbox][disabled],input[type=radio][disabled]{cursor:not-allowed}.wy-checkbox,.wy-radio{margin:6px 0;color:#404040;display:block}.wy-checkbox input,.wy-radio input{vertical-align:baseline}.wy-form-message-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle}.wy-input-prefix,.wy-input-suffix{white-space:nowrap;padding:6px}.wy-input-prefix .wy-input-context,.wy-input-suffix .wy-input-context{line-height:27px;padding:0 8px;display:inline-block;font-size:80%;background-color:#f3f6f6;border:1px solid #ccc;color:#999}.wy-input-suffix .wy-input-context{border-left:0}.wy-input-prefix .wy-input-context{border-right:0}.wy-switch{position:relative;display:block;height:24px;margin-top:12px;cursor:pointer}.wy-switch:before{left:0;top:0;width:36px;height:12px;background:#ccc}.wy-switch:after,.wy-switch:before{position:absolute;content:"";display:block;border-radius:4px;-webkit-transition:all .2s ease-in-out;-moz-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.wy-switch:after{width:18px;height:18px;background:#999;left:-3px;top:-3px}.wy-switch span{position:absolute;left:48px;display:block;font-size:12px;color:#ccc;line-height:1}.wy-switch.active:before{background:#1e8449}.wy-switch.active:after{left:24px;background:#27ae60}.wy-switch.disabled{cursor:not-allowed;opacity:.8}.wy-control-group.wy-control-group-error .wy-form-message,.wy-control-group.wy-control-group-error>label{color:#e74c3c}.wy-control-group.wy-control-group-error input[type=color],.wy-control-group.wy-control-group-error input[type=date],.wy-control-group.wy-control-group-error input[type=datetime-local],.wy-control-group.wy-control-group-error input[type=datetime],.wy-control-group.wy-control-group-error input[type=email],.wy-control-group.wy-control-group-error input[type=month],.wy-control-group.wy-control-group-error input[type=number],.wy-control-group.wy-control-group-error input[type=password],.wy-control-group.wy-control-group-error input[type=search],.wy-control-group.wy-control-group-error input[type=tel],.wy-control-group.wy-control-group-error input[type=text],.wy-control-group.wy-control-group-error input[type=time],.wy-control-group.wy-control-group-error input[type=url],.wy-control-group.wy-control-group-error input[type=week],.wy-control-group.wy-control-group-error textarea{border:1px solid #e74c3c}.wy-inline-validate{white-space:nowrap}.wy-inline-validate .wy-input-context{padding:.5em .625em;display:inline-block;font-size:80%}.wy-inline-validate.wy-inline-validate-success .wy-input-context{color:#27ae60}.wy-inline-validate.wy-inline-validate-danger .wy-input-context{color:#e74c3c}.wy-inline-validate.wy-inline-validate-warning .wy-input-context{color:#e67e22}.wy-inline-validate.wy-inline-validate-info .wy-input-context{color:#2980b9}.rotate-90{-webkit-transform:rotate(90deg);-moz-transform:rotate(90deg);-ms-transform:rotate(90deg);-o-transform:rotate(90deg);transform:rotate(90deg)}.rotate-180{-webkit-transform:rotate(180deg);-moz-transform:rotate(180deg);-ms-transform:rotate(180deg);-o-transform:rotate(180deg);transform:rotate(180deg)}.rotate-270{-webkit-transform:rotate(270deg);-moz-transform:rotate(270deg);-ms-transform:rotate(270deg);-o-transform:rotate(270deg);transform:rotate(270deg)}.mirror{-webkit-transform:scaleX(-1);-moz-transform:scaleX(-1);-ms-transform:scaleX(-1);-o-transform:scaleX(-1);transform:scaleX(-1)}.mirror.rotate-90{-webkit-transform:scaleX(-1) rotate(90deg);-moz-transform:scaleX(-1) rotate(90deg);-ms-transform:scaleX(-1) rotate(90deg);-o-transform:scaleX(-1) rotate(90deg);transform:scaleX(-1) rotate(90deg)}.mirror.rotate-180{-webkit-transform:scaleX(-1) rotate(180deg);-moz-transform:scaleX(-1) rotate(180deg);-ms-transform:scaleX(-1) rotate(180deg);-o-transform:scaleX(-1) rotate(180deg);transform:scaleX(-1) rotate(180deg)}.mirror.rotate-270{-webkit-transform:scaleX(-1) rotate(270deg);-moz-transform:scaleX(-1) rotate(270deg);-ms-transform:scaleX(-1) rotate(270deg);-o-transform:scaleX(-1) rotate(270deg);transform:scaleX(-1) rotate(270deg)}@media only screen and (max-width:480px){.wy-form button[type=submit]{margin:.7em 0 0}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=text],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week],.wy-form label{margin-bottom:.3em;display:block}.wy-form input[type=color],.wy-form input[type=date],.wy-form input[type=datetime-local],.wy-form input[type=datetime],.wy-form input[type=email],.wy-form input[type=month],.wy-form input[type=number],.wy-form input[type=password],.wy-form input[type=search],.wy-form input[type=tel],.wy-form input[type=time],.wy-form input[type=url],.wy-form input[type=week]{margin-bottom:0}.wy-form-aligned .wy-control-group label{margin-bottom:.3em;text-align:left;display:block;width:100%}.wy-form-aligned .wy-control{margin:1.5em 0 0}.wy-form-message,.wy-form-message-inline,.wy-form .wy-help-inline{display:block;font-size:80%;padding:6px 0}}@media screen and (max-width:768px){.tablet-hide{display:none}}@media screen and (max-width:480px){.mobile-hide{display:none}}.float-left{float:left}.float-right{float:right}.full-width{width:100%}.rst-content table.docutils,.rst-content table.field-list,.wy-table{border-collapse:collapse;border-spacing:0;empty-cells:show;margin-bottom:24px}.rst-content table.docutils caption,.rst-content table.field-list caption,.wy-table caption{color:#000;font:italic 85%/1 arial,sans-serif;padding:1em 0;text-align:center}.rst-content table.docutils td,.rst-content table.docutils th,.rst-content table.field-list td,.rst-content table.field-list th,.wy-table td,.wy-table th{font-size:90%;margin:0;overflow:visible;padding:8px 16px}.rst-content table.docutils td:first-child,.rst-content table.docutils th:first-child,.rst-content table.field-list td:first-child,.rst-content table.field-list th:first-child,.wy-table td:first-child,.wy-table th:first-child{border-left-width:0}.rst-content table.docutils thead,.rst-content table.field-list thead,.wy-table thead{color:#000;text-align:left;vertical-align:bottom;white-space:nowrap}.rst-content table.docutils thead th,.rst-content table.field-list thead th,.wy-table thead th{font-weight:700;border-bottom:2px solid #e1e4e5}.rst-content table.docutils td,.rst-content table.field-list td,.wy-table td{background-color:transparent;vertical-align:middle}.rst-content table.docutils td p,.rst-content table.field-list td p,.wy-table td p{line-height:18px}.rst-content table.docutils td p:last-child,.rst-content table.field-list td p:last-child,.wy-table td p:last-child{margin-bottom:0}.rst-content table.docutils .wy-table-cell-min,.rst-content table.field-list .wy-table-cell-min,.wy-table .wy-table-cell-min{width:1%;padding-right:0}.rst-content table.docutils .wy-table-cell-min input[type=checkbox],.rst-content table.field-list .wy-table-cell-min input[type=checkbox],.wy-table .wy-table-cell-min input[type=checkbox]{margin:0}.wy-table-secondary{color:grey;font-size:90%}.wy-table-tertiary{color:grey;font-size:80%}.rst-content table.docutils:not(.field-list) tr:nth-child(2n-1) td,.wy-table-backed,.wy-table-odd td,.wy-table-striped tr:nth-child(2n-1) td{background-color:#f3f6f6}.rst-content table.docutils,.wy-table-bordered-all{border:1px solid #e1e4e5}.rst-content table.docutils td,.wy-table-bordered-all td{border-bottom:1px solid #e1e4e5;border-left:1px solid #e1e4e5}.rst-content table.docutils tbody>tr:last-child td,.wy-table-bordered-all tbody>tr:last-child td{border-bottom-width:0}.wy-table-bordered{border:1px solid #e1e4e5}.wy-table-bordered-rows td{border-bottom:1px solid #e1e4e5}.wy-table-bordered-rows tbody>tr:last-child td{border-bottom-width:0}.wy-table-horizontal td,.wy-table-horizontal th{border-width:0 0 1px;border-bottom:1px solid #e1e4e5}.wy-table-horizontal tbody>tr:last-child td{border-bottom-width:0}.wy-table-responsive{margin-bottom:24px;max-width:100%;overflow:auto}.wy-table-responsive table{margin-bottom:0!important}.wy-table-responsive table td,.wy-table-responsive table th{white-space:nowrap}a{color:#2980b9;text-decoration:none;cursor:pointer}a:hover{color:#3091d1}a:visited{color:#9b59b6}html{height:100%}body,html{overflow-x:hidden}body{font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;font-weight:400;color:#404040;min-height:100%;background:#edf0f2}.wy-text-left{text-align:left}.wy-text-center{text-align:center}.wy-text-right{text-align:right}.wy-text-large{font-size:120%}.wy-text-normal{font-size:100%}.wy-text-small,small{font-size:80%}.wy-text-strike{text-decoration:line-through}.wy-text-warning{color:#e67e22!important}a.wy-text-warning:hover{color:#eb9950!important}.wy-text-info{color:#2980b9!important}a.wy-text-info:hover{color:#409ad5!important}.wy-text-success{color:#27ae60!important}a.wy-text-success:hover{color:#36d278!important}.wy-text-danger{color:#e74c3c!important}a.wy-text-danger:hover{color:#ed7669!important}.wy-text-neutral{color:#404040!important}a.wy-text-neutral:hover{color:#595959!important}.rst-content .toctree-wrapper>p.caption,h1,h2,h3,h4,h5,h6,legend{margin-top:0;font-weight:700;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif}p{line-height:24px;font-size:16px;margin:0 0 24px}h1{font-size:175%}.rst-content .toctree-wrapper>p.caption,h2{font-size:150%}h3{font-size:125%}h4{font-size:115%}h5{font-size:110%}h6{font-size:100%}hr{display:block;height:1px;border:0;border-top:1px solid #e1e4e5;margin:24px 0;padding:0}.rst-content code,.rst-content tt,code{white-space:nowrap;max-width:100%;background:#fff;border:1px solid #e1e4e5;font-size:75%;padding:0 5px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#e74c3c;overflow-x:auto}.rst-content tt.code-large,code.code-large{font-size:90%}.rst-content .section ul,.rst-content .toctree-wrapper ul,.rst-content section ul,.wy-plain-list-disc,article ul{list-style:disc;line-height:24px;margin-bottom:24px}.rst-content .section ul li,.rst-content .toctree-wrapper ul li,.rst-content section ul li,.wy-plain-list-disc li,article ul li{list-style:disc;margin-left:24px}.rst-content .section ul li p:last-child,.rst-content .section ul li ul,.rst-content .toctree-wrapper ul li p:last-child,.rst-content .toctree-wrapper ul li ul,.rst-content section ul li p:last-child,.rst-content section ul li ul,.wy-plain-list-disc li p:last-child,.wy-plain-list-disc li ul,article ul li p:last-child,article ul li ul{margin-bottom:0}.rst-content .section ul li li,.rst-content .toctree-wrapper ul li li,.rst-content section ul li li,.wy-plain-list-disc li li,article ul li li{list-style:circle}.rst-content .section ul li li li,.rst-content .toctree-wrapper ul li li li,.rst-content section ul li li li,.wy-plain-list-disc li li li,article ul li li li{list-style:square}.rst-content .section ul li ol li,.rst-content .toctree-wrapper ul li ol li,.rst-content section ul li ol li,.wy-plain-list-disc li ol li,article ul li ol li{list-style:decimal}.rst-content .section ol,.rst-content .section ol.arabic,.rst-content .toctree-wrapper ol,.rst-content .toctree-wrapper ol.arabic,.rst-content section ol,.rst-content section ol.arabic,.wy-plain-list-decimal,article ol{list-style:decimal;line-height:24px;margin-bottom:24px}.rst-content .section ol.arabic li,.rst-content .section ol li,.rst-content .toctree-wrapper ol.arabic li,.rst-content .toctree-wrapper ol li,.rst-content section ol.arabic li,.rst-content section ol li,.wy-plain-list-decimal li,article ol li{list-style:decimal;margin-left:24px}.rst-content .section ol.arabic li ul,.rst-content .section ol li p:last-child,.rst-content .section ol li ul,.rst-content .toctree-wrapper ol.arabic li ul,.rst-content .toctree-wrapper ol li p:last-child,.rst-content .toctree-wrapper ol li ul,.rst-content section ol.arabic li ul,.rst-content section ol li p:last-child,.rst-content section ol li ul,.wy-plain-list-decimal li p:last-child,.wy-plain-list-decimal li ul,article ol li p:last-child,article ol li ul{margin-bottom:0}.rst-content .section ol.arabic li ul li,.rst-content .section ol li ul li,.rst-content .toctree-wrapper ol.arabic li ul li,.rst-content .toctree-wrapper ol li ul li,.rst-content section ol.arabic li ul li,.rst-content section ol li ul li,.wy-plain-list-decimal li ul li,article ol li ul li{list-style:disc}.wy-breadcrumbs{*zoom:1}.wy-breadcrumbs:after,.wy-breadcrumbs:before{display:table;content:""}.wy-breadcrumbs:after{clear:both}.wy-breadcrumbs li{display:inline-block}.wy-breadcrumbs li.wy-breadcrumbs-aside{float:right}.wy-breadcrumbs li a{display:inline-block;padding:5px}.wy-breadcrumbs li a:first-child{padding-left:0}.rst-content .wy-breadcrumbs li tt,.wy-breadcrumbs li .rst-content tt,.wy-breadcrumbs li code{padding:5px;border:none;background:none}.rst-content .wy-breadcrumbs li tt.literal,.wy-breadcrumbs li .rst-content tt.literal,.wy-breadcrumbs li code.literal{color:#404040}.wy-breadcrumbs-extra{margin-bottom:0;color:#b3b3b3;font-size:80%;display:inline-block}@media screen and (max-width:480px){.wy-breadcrumbs-extra,.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}@media print{.wy-breadcrumbs li.wy-breadcrumbs-aside{display:none}}html{font-size:16px}.wy-affix{position:fixed;top:1.618em}.wy-menu a:hover{text-decoration:none}.wy-menu-horiz{*zoom:1}.wy-menu-horiz:after,.wy-menu-horiz:before{display:table;content:""}.wy-menu-horiz:after{clear:both}.wy-menu-horiz li,.wy-menu-horiz ul{display:inline-block}.wy-menu-horiz li:hover{background:hsla(0,0%,100%,.1)}.wy-menu-horiz li.divide-left{border-left:1px solid #404040}.wy-menu-horiz li.divide-right{border-right:1px solid #404040}.wy-menu-horiz a{height:32px;display:inline-block;line-height:32px;padding:0 16px}.wy-menu-vertical{width:300px}.wy-menu-vertical header,.wy-menu-vertical p.caption{color:#55a5d9;height:32px;line-height:32px;padding:0 1.618em;margin:12px 0 0;display:block;font-weight:700;text-transform:uppercase;font-size:85%;white-space:nowrap}.wy-menu-vertical ul{margin-bottom:0}.wy-menu-vertical li.divide-top{border-top:1px solid #404040}.wy-menu-vertical li.divide-bottom{border-bottom:1px solid #404040}.wy-menu-vertical li.current{background:#e3e3e3}.wy-menu-vertical li.current a{color:grey;border-right:1px solid #c9c9c9;padding:.4045em 2.427em}.wy-menu-vertical li.current a:hover{background:#d6d6d6}.rst-content .wy-menu-vertical li tt,.wy-menu-vertical li .rst-content tt,.wy-menu-vertical li code{border:none;background:inherit;color:inherit;padding-left:0;padding-right:0}.wy-menu-vertical li button.toctree-expand{display:block;float:left;margin-left:-1.2em;line-height:18px;color:#4d4d4d;border:none;background:none;padding:0}.wy-menu-vertical li.current>a,.wy-menu-vertical li.on a{color:#404040;font-weight:700;position:relative;background:#fcfcfc;border:none;padding:.4045em 1.618em}.wy-menu-vertical li.current>a:hover,.wy-menu-vertical li.on a:hover{background:#fcfcfc}.wy-menu-vertical li.current>a:hover button.toctree-expand,.wy-menu-vertical li.on a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.current>a button.toctree-expand,.wy-menu-vertical li.on a button.toctree-expand{display:block;line-height:18px;color:#333}.wy-menu-vertical li.toctree-l1.current>a{border-bottom:1px solid #c9c9c9;border-top:1px solid #c9c9c9}.wy-menu-vertical .toctree-l1.current .toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .toctree-l11>ul{display:none}.wy-menu-vertical .toctree-l1.current .current.toctree-l2>ul,.wy-menu-vertical .toctree-l2.current .current.toctree-l3>ul,.wy-menu-vertical .toctree-l3.current .current.toctree-l4>ul,.wy-menu-vertical .toctree-l4.current .current.toctree-l5>ul,.wy-menu-vertical .toctree-l5.current .current.toctree-l6>ul,.wy-menu-vertical .toctree-l6.current .current.toctree-l7>ul,.wy-menu-vertical .toctree-l7.current .current.toctree-l8>ul,.wy-menu-vertical .toctree-l8.current .current.toctree-l9>ul,.wy-menu-vertical .toctree-l9.current .current.toctree-l10>ul,.wy-menu-vertical .toctree-l10.current .current.toctree-l11>ul{display:block}.wy-menu-vertical li.toctree-l3,.wy-menu-vertical li.toctree-l4{font-size:.9em}.wy-menu-vertical li.toctree-l2 a,.wy-menu-vertical li.toctree-l3 a,.wy-menu-vertical li.toctree-l4 a,.wy-menu-vertical li.toctree-l5 a,.wy-menu-vertical li.toctree-l6 a,.wy-menu-vertical li.toctree-l7 a,.wy-menu-vertical li.toctree-l8 a,.wy-menu-vertical li.toctree-l9 a,.wy-menu-vertical li.toctree-l10 a{color:#404040}.wy-menu-vertical li.toctree-l2 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l3 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l4 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l5 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l6 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l7 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l8 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l9 a:hover button.toctree-expand,.wy-menu-vertical li.toctree-l10 a:hover button.toctree-expand{color:grey}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a,.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a,.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a,.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a,.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a,.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a,.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a,.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{display:block}.wy-menu-vertical li.toctree-l2.current>a{padding:.4045em 2.427em}.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{padding:.4045em 1.618em .4045em 4.045em}.wy-menu-vertical li.toctree-l3.current>a{padding:.4045em 4.045em}.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{padding:.4045em 1.618em .4045em 5.663em}.wy-menu-vertical li.toctree-l4.current>a{padding:.4045em 5.663em}.wy-menu-vertical li.toctree-l4.current li.toctree-l5>a{padding:.4045em 1.618em .4045em 7.281em}.wy-menu-vertical li.toctree-l5.current>a{padding:.4045em 7.281em}.wy-menu-vertical li.toctree-l5.current li.toctree-l6>a{padding:.4045em 1.618em .4045em 8.899em}.wy-menu-vertical li.toctree-l6.current>a{padding:.4045em 8.899em}.wy-menu-vertical li.toctree-l6.current li.toctree-l7>a{padding:.4045em 1.618em .4045em 10.517em}.wy-menu-vertical li.toctree-l7.current>a{padding:.4045em 10.517em}.wy-menu-vertical li.toctree-l7.current li.toctree-l8>a{padding:.4045em 1.618em .4045em 12.135em}.wy-menu-vertical li.toctree-l8.current>a{padding:.4045em 12.135em}.wy-menu-vertical li.toctree-l8.current li.toctree-l9>a{padding:.4045em 1.618em .4045em 13.753em}.wy-menu-vertical li.toctree-l9.current>a{padding:.4045em 13.753em}.wy-menu-vertical li.toctree-l9.current li.toctree-l10>a{padding:.4045em 1.618em .4045em 15.371em}.wy-menu-vertical li.toctree-l10.current>a{padding:.4045em 15.371em}.wy-menu-vertical li.toctree-l10.current li.toctree-l11>a{padding:.4045em 1.618em .4045em 16.989em}.wy-menu-vertical li.toctree-l2.current>a,.wy-menu-vertical li.toctree-l2.current li.toctree-l3>a{background:#c9c9c9}.wy-menu-vertical li.toctree-l2 button.toctree-expand{color:#a3a3a3}.wy-menu-vertical li.toctree-l3.current>a,.wy-menu-vertical li.toctree-l3.current li.toctree-l4>a{background:#bdbdbd}.wy-menu-vertical li.toctree-l3 button.toctree-expand{color:#969696}.wy-menu-vertical li.current ul{display:block}.wy-menu-vertical li ul{margin-bottom:0;display:none}.wy-menu-vertical li ul li a{margin-bottom:0;color:#d9d9d9;font-weight:400}.wy-menu-vertical a{line-height:18px;padding:.4045em 1.618em;display:block;position:relative;font-size:90%;color:#d9d9d9}.wy-menu-vertical a:hover{background-color:#4e4a4a;cursor:pointer}.wy-menu-vertical a:hover button.toctree-expand{color:#d9d9d9}.wy-menu-vertical a:active{background-color:#2980b9;cursor:pointer;color:#fff}.wy-menu-vertical a:active button.toctree-expand{color:#fff}.wy-side-nav-search{display:block;width:300px;padding:.809em;margin-bottom:.809em;z-index:200;background-color:#2980b9;text-align:center;color:#fcfcfc}.wy-side-nav-search input[type=text]{width:100%;border-radius:50px;padding:6px 12px;border-color:#2472a4}.wy-side-nav-search img{display:block;margin:auto auto .809em;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-side-nav-search .wy-dropdown>a,.wy-side-nav-search>a{color:#fcfcfc;font-size:100%;font-weight:700;display:inline-block;padding:4px 6px;margin-bottom:.809em;max-width:100%}.wy-side-nav-search .wy-dropdown>a:hover,.wy-side-nav-search>a:hover{background:hsla(0,0%,100%,.1)}.wy-side-nav-search .wy-dropdown>a img.logo,.wy-side-nav-search>a img.logo{display:block;margin:0 auto;height:auto;width:auto;border-radius:0;max-width:100%;background:transparent}.wy-side-nav-search .wy-dropdown>a.icon img.logo,.wy-side-nav-search>a.icon img.logo{margin-top:.85em}.wy-side-nav-search>div.version{margin-top:-.4045em;margin-bottom:.809em;font-weight:400;color:hsla(0,0%,100%,.3)}.wy-nav .wy-menu-vertical header{color:#2980b9}.wy-nav .wy-menu-vertical a{color:#b3b3b3}.wy-nav .wy-menu-vertical a:hover{background-color:#2980b9;color:#fff}[data-menu-wrap]{-webkit-transition:all .2s ease-in;-moz-transition:all .2s ease-in;transition:all .2s ease-in;position:absolute;opacity:1;width:100%;opacity:0}[data-menu-wrap].move-center{left:0;right:auto;opacity:1}[data-menu-wrap].move-left{right:auto;left:-100%;opacity:0}[data-menu-wrap].move-right{right:-100%;left:auto;opacity:0}.wy-body-for-nav{background:#fcfcfc}.wy-grid-for-nav{position:absolute;width:100%;height:100%}.wy-nav-side{position:fixed;top:0;bottom:0;left:0;padding-bottom:2em;width:300px;overflow-x:hidden;overflow-y:hidden;min-height:100%;color:#9b9b9b;background:#343131;z-index:200}.wy-side-scroll{width:320px;position:relative;overflow-x:hidden;overflow-y:scroll;height:100%}.wy-nav-top{display:none;background:#2980b9;color:#fff;padding:.4045em .809em;position:relative;line-height:50px;text-align:center;font-size:100%;*zoom:1}.wy-nav-top:after,.wy-nav-top:before{display:table;content:""}.wy-nav-top:after{clear:both}.wy-nav-top a{color:#fff;font-weight:700}.wy-nav-top img{margin-right:12px;height:45px;width:45px;background-color:#2980b9;padding:5px;border-radius:100%}.wy-nav-top i{font-size:30px;float:left;cursor:pointer;padding-top:inherit}.wy-nav-content-wrap{margin-left:300px;background:#fcfcfc;min-height:100%}.wy-nav-content{padding:1.618em 3.236em;height:100%;max-width:800px;margin:auto}.wy-body-mask{position:fixed;width:100%;height:100%;background:rgba(0,0,0,.2);display:none;z-index:499}.wy-body-mask.on{display:block}footer{color:grey}footer p{margin-bottom:12px}.rst-content footer span.commit tt,footer span.commit .rst-content tt,footer span.commit code{padding:0;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:1em;background:none;border:none;color:grey}.rst-footer-buttons{*zoom:1}.rst-footer-buttons:after,.rst-footer-buttons:before{width:100%;display:table;content:""}.rst-footer-buttons:after{clear:both}.rst-breadcrumbs-buttons{margin-top:12px;*zoom:1}.rst-breadcrumbs-buttons:after,.rst-breadcrumbs-buttons:before{display:table;content:""}.rst-breadcrumbs-buttons:after{clear:both}#search-results .search li{margin-bottom:24px;border-bottom:1px solid #e1e4e5;padding-bottom:24px}#search-results .search li:first-child{border-top:1px solid #e1e4e5;padding-top:24px}#search-results .search li a{font-size:120%;margin-bottom:12px;display:inline-block}#search-results .context{color:grey;font-size:90%}.genindextable li>ul{margin-left:24px}@media screen and (max-width:768px){.wy-body-for-nav{background:#fcfcfc}.wy-nav-top{display:block}.wy-nav-side{left:-300px}.wy-nav-side.shift{width:85%;left:0}.wy-menu.wy-menu-vertical,.wy-side-nav-search,.wy-side-scroll{width:auto}.wy-nav-content-wrap{margin-left:0}.wy-nav-content-wrap .wy-nav-content{padding:1.618em}.wy-nav-content-wrap.shift{position:fixed;min-width:100%;left:85%;top:0;height:100%;overflow:hidden}}@media screen and (min-width:1100px){.wy-nav-content-wrap{background:rgba(0,0,0,.05)}.wy-nav-content{margin:0;background:#fcfcfc}}@media print{.rst-versions,.wy-nav-side,footer{display:none}.wy-nav-content-wrap{margin-left:0}}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;font-family:Lato,proxima-nova,Helvetica Neue,Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:after,.rst-versions .rst-current-version:before{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-content .code-block-caption .rst-versions .rst-current-version .headerlink,.rst-content .eqno .rst-versions .rst-current-version .headerlink,.rst-content .rst-versions .rst-current-version .admonition-title,.rst-content code.download .rst-versions .rst-current-version span:first-child,.rst-content dl dt .rst-versions .rst-current-version .headerlink,.rst-content h1 .rst-versions .rst-current-version .headerlink,.rst-content h2 .rst-versions .rst-current-version .headerlink,.rst-content h3 .rst-versions .rst-current-version .headerlink,.rst-content h4 .rst-versions .rst-current-version .headerlink,.rst-content h5 .rst-versions .rst-current-version .headerlink,.rst-content h6 .rst-versions .rst-current-version .headerlink,.rst-content p .rst-versions .rst-current-version .headerlink,.rst-content table>caption .rst-versions .rst-current-version .headerlink,.rst-content tt.download .rst-versions .rst-current-version span:first-child,.rst-versions .rst-current-version .fa,.rst-versions .rst-current-version .icon,.rst-versions .rst-current-version .rst-content .admonition-title,.rst-versions .rst-current-version .rst-content .code-block-caption .headerlink,.rst-versions .rst-current-version .rst-content .eqno .headerlink,.rst-versions .rst-current-version .rst-content code.download span:first-child,.rst-versions .rst-current-version .rst-content dl dt .headerlink,.rst-versions .rst-current-version .rst-content h1 .headerlink,.rst-versions .rst-current-version .rst-content h2 .headerlink,.rst-versions .rst-current-version .rst-content h3 .headerlink,.rst-versions .rst-current-version .rst-content h4 .headerlink,.rst-versions .rst-current-version .rst-content h5 .headerlink,.rst-versions .rst-current-version .rst-content h6 .headerlink,.rst-versions .rst-current-version .rst-content p .headerlink,.rst-versions .rst-current-version .rst-content table>caption .headerlink,.rst-versions .rst-current-version .rst-content tt.download span:first-child,.rst-versions .rst-current-version .wy-menu-vertical li button.toctree-expand,.wy-menu-vertical li .rst-versions .rst-current-version button.toctree-expand{color:#fcfcfc}.rst-versions .rst-current-version .fa-book,.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#f1c40f;color:#000}.rst-versions.shift-up{height:auto;max-height:100%;overflow-y:scroll}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:grey;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:1px solid #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px;max-height:90%}.rst-versions.rst-badge .fa-book,.rst-versions.rst-badge .icon-book{float:none;line-height:30px}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book,.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge>.rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width:768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}}.rst-content .toctree-wrapper>p.caption,.rst-content h1,.rst-content h2,.rst-content h3,.rst-content h4,.rst-content h5,.rst-content h6{margin-bottom:24px}.rst-content img{max-width:100%;height:auto}.rst-content div.figure,.rst-content figure{margin-bottom:24px}.rst-content div.figure .caption-text,.rst-content figure .caption-text{font-style:italic}.rst-content div.figure p:last-child.caption,.rst-content figure p:last-child.caption{margin-bottom:0}.rst-content div.figure.align-center,.rst-content figure.align-center{text-align:center}.rst-content .section>a>img,.rst-content .section>img,.rst-content section>a>img,.rst-content section>img{margin-bottom:24px}.rst-content abbr[title]{text-decoration:none}.rst-content.style-external-links a.reference.external:after{font-family:FontAwesome;content:"\f08e";color:#b3b3b3;vertical-align:super;font-size:60%;margin:0 .2em}.rst-content blockquote{margin-left:24px;line-height:24px;margin-bottom:24px}.rst-content pre.literal-block{white-space:pre;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;display:block;overflow:auto}.rst-content div[class^=highlight],.rst-content pre.literal-block{border:1px solid #e1e4e5;overflow-x:auto;margin:1px 0 24px}.rst-content div[class^=highlight] div[class^=highlight],.rst-content pre.literal-block div[class^=highlight]{padding:0;border:none;margin:0}.rst-content div[class^=highlight] td.code{width:100%}.rst-content .linenodiv pre{border-right:1px solid #e6e9ea;margin:0;padding:12px;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;user-select:none;pointer-events:none}.rst-content div[class^=highlight] pre{white-space:pre;margin:0;padding:12px;display:block;overflow:auto}.rst-content div[class^=highlight] pre .hll{display:block;margin:0 -12px;padding:0 12px}.rst-content .linenodiv pre,.rst-content div[class^=highlight] pre,.rst-content pre.literal-block{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;font-size:12px;line-height:1.4}.rst-content div.highlight .gp,.rst-content div.highlight span.linenos{user-select:none;pointer-events:none}.rst-content div.highlight span.linenos{display:inline-block;padding-left:0;padding-right:12px;margin-right:12px;border-right:1px solid #e6e9ea}.rst-content .code-block-caption{font-style:italic;font-size:85%;line-height:1;padding:1em 0;text-align:center}@media print{.rst-content .codeblock,.rst-content div[class^=highlight],.rst-content div[class^=highlight] pre{white-space:pre-wrap}}.rst-content .admonition,.rst-content .admonition-todo,.rst-content .attention,.rst-content .caution,.rst-content .danger,.rst-content .error,.rst-content .hint,.rst-content .important,.rst-content .note,.rst-content .seealso,.rst-content .tip,.rst-content .warning{clear:both}.rst-content .admonition-todo .last,.rst-content .admonition-todo>:last-child,.rst-content .admonition .last,.rst-content .admonition>:last-child,.rst-content .attention .last,.rst-content .attention>:last-child,.rst-content .caution .last,.rst-content .caution>:last-child,.rst-content .danger .last,.rst-content .danger>:last-child,.rst-content .error .last,.rst-content .error>:last-child,.rst-content .hint .last,.rst-content .hint>:last-child,.rst-content .important .last,.rst-content .important>:last-child,.rst-content .note .last,.rst-content .note>:last-child,.rst-content .seealso .last,.rst-content .seealso>:last-child,.rst-content .tip .last,.rst-content .tip>:last-child,.rst-content .warning .last,.rst-content .warning>:last-child{margin-bottom:0}.rst-content .admonition-title:before{margin-right:4px}.rst-content .admonition table{border-color:rgba(0,0,0,.1)}.rst-content .admonition table td,.rst-content .admonition table th{background:transparent!important;border-color:rgba(0,0,0,.1)!important}.rst-content .section ol.loweralpha,.rst-content .section ol.loweralpha>li,.rst-content .toctree-wrapper ol.loweralpha,.rst-content .toctree-wrapper ol.loweralpha>li,.rst-content section ol.loweralpha,.rst-content section ol.loweralpha>li{list-style:lower-alpha}.rst-content .section ol.upperalpha,.rst-content .section ol.upperalpha>li,.rst-content .toctree-wrapper ol.upperalpha,.rst-content .toctree-wrapper ol.upperalpha>li,.rst-content section ol.upperalpha,.rst-content section ol.upperalpha>li{list-style:upper-alpha}.rst-content .section ol li>*,.rst-content .section ul li>*,.rst-content .toctree-wrapper ol li>*,.rst-content .toctree-wrapper ul li>*,.rst-content section ol li>*,.rst-content section ul li>*{margin-top:12px;margin-bottom:12px}.rst-content .section ol li>:first-child,.rst-content .section ul li>:first-child,.rst-content .toctree-wrapper ol li>:first-child,.rst-content .toctree-wrapper ul li>:first-child,.rst-content section ol li>:first-child,.rst-content section ul li>:first-child{margin-top:0}.rst-content .section ol li>p,.rst-content .section ol li>p:last-child,.rst-content .section ul li>p,.rst-content .section ul li>p:last-child,.rst-content .toctree-wrapper ol li>p,.rst-content .toctree-wrapper ol li>p:last-child,.rst-content .toctree-wrapper ul li>p,.rst-content .toctree-wrapper ul li>p:last-child,.rst-content section ol li>p,.rst-content section ol li>p:last-child,.rst-content section ul li>p,.rst-content section ul li>p:last-child{margin-bottom:12px}.rst-content .section ol li>p:only-child,.rst-content .section ol li>p:only-child:last-child,.rst-content .section ul li>p:only-child,.rst-content .section ul li>p:only-child:last-child,.rst-content .toctree-wrapper ol li>p:only-child,.rst-content .toctree-wrapper ol li>p:only-child:last-child,.rst-content .toctree-wrapper ul li>p:only-child,.rst-content .toctree-wrapper ul li>p:only-child:last-child,.rst-content section ol li>p:only-child,.rst-content section ol li>p:only-child:last-child,.rst-content section ul li>p:only-child,.rst-content section ul li>p:only-child:last-child{margin-bottom:0}.rst-content .section ol li>ol,.rst-content .section ol li>ul,.rst-content .section ul li>ol,.rst-content .section ul li>ul,.rst-content .toctree-wrapper ol li>ol,.rst-content .toctree-wrapper ol li>ul,.rst-content .toctree-wrapper ul li>ol,.rst-content .toctree-wrapper ul li>ul,.rst-content section ol li>ol,.rst-content section ol li>ul,.rst-content section ul li>ol,.rst-content section ul li>ul{margin-bottom:12px}.rst-content .section ol.simple li>*,.rst-content .section ol.simple li ol,.rst-content .section ol.simple li ul,.rst-content .section ul.simple li>*,.rst-content .section ul.simple li ol,.rst-content .section ul.simple li ul,.rst-content .toctree-wrapper ol.simple li>*,.rst-content .toctree-wrapper ol.simple li ol,.rst-content .toctree-wrapper ol.simple li ul,.rst-content .toctree-wrapper ul.simple li>*,.rst-content .toctree-wrapper ul.simple li ol,.rst-content .toctree-wrapper ul.simple li ul,.rst-content section ol.simple li>*,.rst-content section ol.simple li ol,.rst-content section ol.simple li ul,.rst-content section ul.simple li>*,.rst-content section ul.simple li ol,.rst-content section ul.simple li ul{margin-top:0;margin-bottom:0}.rst-content .line-block{margin-left:0;margin-bottom:24px;line-height:24px}.rst-content .line-block .line-block{margin-left:24px;margin-bottom:0}.rst-content .topic-title{font-weight:700;margin-bottom:12px}.rst-content .toc-backref{color:#404040}.rst-content .align-right{float:right;margin:0 0 24px 24px}.rst-content .align-left{float:left;margin:0 24px 24px 0}.rst-content .align-center{margin:auto}.rst-content .align-center:not(table){display:block}.rst-content .code-block-caption .headerlink,.rst-content .eqno .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink,.rst-content dl dt .headerlink,.rst-content h1 .headerlink,.rst-content h2 .headerlink,.rst-content h3 .headerlink,.rst-content h4 .headerlink,.rst-content h5 .headerlink,.rst-content h6 .headerlink,.rst-content p.caption .headerlink,.rst-content p .headerlink,.rst-content table>caption .headerlink{opacity:0;font-size:14px;font-family:FontAwesome;margin-left:.5em}.rst-content .code-block-caption .headerlink:focus,.rst-content .code-block-caption:hover .headerlink,.rst-content .eqno .headerlink:focus,.rst-content .eqno:hover .headerlink,.rst-content .toctree-wrapper>p.caption .headerlink:focus,.rst-content .toctree-wrapper>p.caption:hover .headerlink,.rst-content dl dt .headerlink:focus,.rst-content dl dt:hover .headerlink,.rst-content h1 .headerlink:focus,.rst-content h1:hover .headerlink,.rst-content h2 .headerlink:focus,.rst-content h2:hover .headerlink,.rst-content h3 .headerlink:focus,.rst-content h3:hover .headerlink,.rst-content h4 .headerlink:focus,.rst-content h4:hover .headerlink,.rst-content h5 .headerlink:focus,.rst-content h5:hover .headerlink,.rst-content h6 .headerlink:focus,.rst-content h6:hover .headerlink,.rst-content p.caption .headerlink:focus,.rst-content p.caption:hover .headerlink,.rst-content p .headerlink:focus,.rst-content p:hover .headerlink,.rst-content table>caption .headerlink:focus,.rst-content table>caption:hover .headerlink{opacity:1}.rst-content .btn:focus{outline:2px solid}.rst-content table>caption .headerlink:after{font-size:12px}.rst-content .centered{text-align:center}.rst-content .sidebar{float:right;width:40%;display:block;margin:0 0 24px 24px;padding:24px;background:#f3f6f6;border:1px solid #e1e4e5}.rst-content .sidebar dl,.rst-content .sidebar p,.rst-content .sidebar ul{font-size:90%}.rst-content .sidebar .last,.rst-content .sidebar>:last-child{margin-bottom:0}.rst-content .sidebar .sidebar-title{display:block;font-family:Roboto Slab,ff-tisa-web-pro,Georgia,Arial,sans-serif;font-weight:700;background:#e1e4e5;padding:6px 12px;margin:-24px -24px 24px;font-size:100%}.rst-content .highlighted{background:#f1c40f;box-shadow:0 0 0 2px #f1c40f;display:inline;font-weight:700}.rst-content .citation-reference,.rst-content .footnote-reference{vertical-align:baseline;position:relative;top:-.4em;line-height:0;font-size:90%}.rst-content .hlist{width:100%}.rst-content dl dt span.classifier:before{content:" : "}.rst-content dl dt span.classifier-delimiter{display:none!important}html.writer-html4 .rst-content table.docutils.citation,html.writer-html4 .rst-content table.docutils.footnote{background:none;border:none}html.writer-html4 .rst-content table.docutils.citation td,html.writer-html4 .rst-content table.docutils.citation tr,html.writer-html4 .rst-content table.docutils.footnote td,html.writer-html4 .rst-content table.docutils.footnote tr{border:none;background-color:transparent!important;white-space:normal}html.writer-html4 .rst-content table.docutils.citation td.label,html.writer-html4 .rst-content table.docutils.footnote td.label{padding-left:0;padding-right:0;vertical-align:top}html.writer-html5 .rst-content dl.field-list,html.writer-html5 .rst-content dl.footnote{display:grid;grid-template-columns:max-content auto}html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dt{padding-left:1rem}html.writer-html5 .rst-content dl.field-list>dt:after,html.writer-html5 .rst-content dl.footnote>dt:after{content:":"}html.writer-html5 .rst-content dl.field-list>dd,html.writer-html5 .rst-content dl.field-list>dt,html.writer-html5 .rst-content dl.footnote>dd,html.writer-html5 .rst-content dl.footnote>dt{margin-bottom:0}html.writer-html5 .rst-content dl.footnote{font-size:.9rem}html.writer-html5 .rst-content dl.footnote>dt{margin:0 .5rem .5rem 0;line-height:1.2rem;word-break:break-all;font-weight:400}html.writer-html5 .rst-content dl.footnote>dt>span.brackets{margin-right:.5rem}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:before{content:"["}html.writer-html5 .rst-content dl.footnote>dt>span.brackets:after{content:"]"}html.writer-html5 .rst-content dl.footnote>dt>span.fn-backref{font-style:italic}html.writer-html5 .rst-content dl.footnote>dd{margin:0 0 .5rem;line-height:1.2rem}html.writer-html5 .rst-content dl.footnote>dd p,html.writer-html5 .rst-content dl.option-list kbd{font-size:.9rem}.rst-content table.docutils.footnote,html.writer-html4 .rst-content table.docutils.citation,html.writer-html5 .rst-content dl.footnote{color:grey}.rst-content table.docutils.footnote code,.rst-content table.docutils.footnote tt,html.writer-html4 .rst-content table.docutils.citation code,html.writer-html4 .rst-content table.docutils.citation tt,html.writer-html5 .rst-content dl.footnote code,html.writer-html5 .rst-content dl.footnote tt{color:#555}.rst-content .wy-table-responsive.citation,.rst-content .wy-table-responsive.footnote{margin-bottom:0}.rst-content .wy-table-responsive.citation+:not(.citation),.rst-content .wy-table-responsive.footnote+:not(.footnote){margin-top:24px}.rst-content .wy-table-responsive.citation:last-child,.rst-content .wy-table-responsive.footnote:last-child{margin-bottom:24px}.rst-content table.docutils th{border-color:#e1e4e5}html.writer-html5 .rst-content table.docutils th{border:1px solid #e1e4e5}html.writer-html5 .rst-content table.docutils td>p,html.writer-html5 .rst-content table.docutils th>p{line-height:1rem;margin-bottom:0;font-size:.9rem}.rst-content table.docutils td .last,.rst-content table.docutils td .last>:last-child{margin-bottom:0}.rst-content table.field-list,.rst-content table.field-list td{border:none}.rst-content table.field-list td p{font-size:inherit;line-height:inherit}.rst-content table.field-list td>strong{display:inline-block}.rst-content table.field-list .field-name{padding-right:10px;text-align:left;white-space:nowrap}.rst-content table.field-list .field-body{text-align:left}.rst-content code,.rst-content tt{color:#000;font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;padding:2px 5px}.rst-content code big,.rst-content code em,.rst-content tt big,.rst-content tt em{font-size:100%!important;line-height:normal}.rst-content code.literal,.rst-content tt.literal{color:#e74c3c;white-space:normal}.rst-content code.xref,.rst-content tt.xref,a .rst-content code,a .rst-content tt{font-weight:700;color:#404040}.rst-content kbd,.rst-content pre,.rst-content samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace}.rst-content a code,.rst-content a tt{color:#2980b9}.rst-content dl{margin-bottom:24px}.rst-content dl dt{font-weight:700;margin-bottom:12px}.rst-content dl ol,.rst-content dl p,.rst-content dl table,.rst-content dl ul{margin-bottom:12px}.rst-content dl dd{margin:0 0 12px 24px;line-height:24px}html.writer-html4 .rst-content dl:not(.docutils),html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple){margin-bottom:24px}html.writer-html4 .rst-content dl:not(.docutils)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{display:table;margin:6px 0;font-size:90%;line-height:normal;background:#e7f2fa;color:#2980b9;border-top:3px solid #6ab0de;padding:6px;position:relative}html.writer-html4 .rst-content dl:not(.docutils)>dt:before,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:before{color:#6ab0de}html.writer-html4 .rst-content dl:not(.docutils)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt{margin-bottom:6px;border:none;border-left:3px solid #ccc;background:#f0f0f0;color:#555}html.writer-html4 .rst-content dl:not(.docutils) dl:not(.field-list)>dt .headerlink,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dl:not(.field-list)>dt .headerlink{color:#404040;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils)>dt:first-child,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt:first-child{margin-top:0}html.writer-html4 .rst-content dl:not(.docutils) code.descclassname,html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descclassname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{background-color:transparent;border:none;padding:0;font-size:100%!important}html.writer-html4 .rst-content dl:not(.docutils) code.descname,html.writer-html4 .rst-content dl:not(.docutils) tt.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) code.descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) tt.descname{font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .optional,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .optional{display:inline-block;padding:0 4px;color:#000;font-weight:700}html.writer-html4 .rst-content dl:not(.docutils) .property,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .property{display:inline-block;padding-right:8px;max-width:100%}html.writer-html4 .rst-content dl:not(.docutils) .k,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .k{font-style:italic}html.writer-html4 .rst-content dl:not(.docutils) .descclassname,html.writer-html4 .rst-content dl:not(.docutils) .descname,html.writer-html4 .rst-content dl:not(.docutils) .sig-name,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descclassname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .descname,html.writer-html5 .rst-content dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .sig-name{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,Courier,monospace;color:#000}.rst-content .viewcode-back,.rst-content .viewcode-link{display:inline-block;color:#27ae60;font-size:80%;padding-left:24px}.rst-content .viewcode-back{display:block;float:right}.rst-content p.rubric{margin-bottom:12px;font-weight:700}.rst-content code.download,.rst-content tt.download{background:inherit;padding:inherit;font-weight:400;font-family:inherit;font-size:inherit;color:inherit;border:inherit;white-space:inherit}.rst-content code.download span:first-child,.rst-content tt.download span:first-child{-webkit-font-smoothing:subpixel-antialiased}.rst-content code.download span:first-child:before,.rst-content tt.download span:first-child:before{margin-right:4px}.rst-content .guilabel{border:1px solid #7fbbe3;background:#e7f2fa;font-size:80%;font-weight:700;border-radius:4px;padding:2.4px 6px;margin:auto 2px}.rst-content .versionmodified{font-style:italic}@media screen and (max-width:480px){.rst-content .sidebar{width:100%}}span[id*=MathJax-Span]{color:#404040}.math{text-align:center}@font-face{font-family:Lato;src:url(fonts/lato-normal.woff2?bd03a2cc277bbbc338d464e679fe9942) format("woff2"),url(fonts/lato-normal.woff?27bd77b9162d388cb8d4c4217c7c5e2a) format("woff");font-weight:400;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold.woff2?cccb897485813c7c256901dbca54ecf2) format("woff2"),url(fonts/lato-bold.woff?d878b6c29b10beca227e9eef4246111b) format("woff");font-weight:700;font-style:normal;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-bold-italic.woff2?0b6bb6725576b072c5d0b02ecdd1900d) format("woff2"),url(fonts/lato-bold-italic.woff?9c7e4e9eb485b4a121c760e61bc3707c) format("woff");font-weight:700;font-style:italic;font-display:block}@font-face{font-family:Lato;src:url(fonts/lato-normal-italic.woff2?4eb103b4d12be57cb1d040ed5e162e9d) format("woff2"),url(fonts/lato-normal-italic.woff?f28f2d6482446544ef1ea1ccc6dd5892) format("woff");font-weight:400;font-style:italic;font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:400;src:url(fonts/Roboto-Slab-Regular.woff2?7abf5b8d04d26a2cafea937019bca958) format("woff2"),url(fonts/Roboto-Slab-Regular.woff?c1be9284088d487c5e3ff0a10a92e58c) format("woff");font-display:block}@font-face{font-family:Roboto Slab;font-style:normal;font-weight:700;src:url(fonts/Roboto-Slab-Bold.woff2?9984f4a9bda09be08e83f2506954adbe) format("woff2"),url(fonts/Roboto-Slab-Bold.woff?bed5564a116b05148e3b3bea6fb1162a) format("woff");font-display:block} \ No newline at end of file diff --git a/_build/html/_static/css3-mediaqueries.js b/_build/html/_static/css3-mediaqueries.js deleted file mode 100644 index 59735f5..0000000 --- a/_build/html/_static/css3-mediaqueries.js +++ /dev/null @@ -1 +0,0 @@ -if(typeof Object.create!=="function"){Object.create=function(e){function t(){}t.prototype=e;return new t}}var ua={toString:function(){return navigator.userAgent},test:function(e){return this.toString().toLowerCase().indexOf(e.toLowerCase())>-1}};ua.version=(ua.toString().toLowerCase().match(/[\s\S]+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)||[])[1];ua.webkit=ua.test("webkit");ua.gecko=ua.test("gecko")&&!ua.webkit;ua.opera=ua.test("opera");ua.ie=ua.test("msie")&&!ua.opera;ua.ie6=ua.ie&&document.compatMode&&typeof document.documentElement.style.maxHeight==="undefined";ua.ie7=ua.ie&&document.documentElement&&typeof document.documentElement.style.maxHeight!=="undefined"&&typeof XDomainRequest==="undefined";ua.ie8=ua.ie&&typeof XDomainRequest!=="undefined";var domReady=function(){var e=[];var t=function(){if(!arguments.callee.done){arguments.callee.done=true;for(var t=0;t').appendTo(this.out); - this.output = $('
\ - <%username%>\ - \ - <%time.delta%>\ -
\ -\ - reply ▿\ - proposal ▹\ - \ - \ - \ -
\ - \ -\ -<#proposal_diff#>\ -\ -
内蔵の赤外LEDを用いて、ビデオカメラ操作する例を リスト 29 に示します。
-ライブラリマネージャにて、IRremoteESP8266 をインストールしてください。ちなみに、テストしたバージョンは2.7.15でした。 2.7.15
より新しいバージョンだと、失敗する場合があります。もし最新版を入れてうまくいかない場合はダウングレードしてください。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 | /* IRremoteESP8266: IRsendDemo - demonstrates sending IR codes with IRsend.
-
- Version 1.1 January, 2019
- Based on Ken Shirriff's IrsendDemo Version 0.1 July, 2009,
- Copyright 2009 Ken Shirriff, http://arcfn.com
-
- An IR LED circuit *MUST* be connected to the ESP8266 on a pin
- as specified by kIrLed below.
-
- TL;DR: The IR LED needs to be driven by a transistor for a good result.
-
- Suggested circuit:
- https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending
-
- Common mistakes & tips:
- * * Don't just connect the IR LED directly to the pin, it won't
- have enough current to drive the IR LED effectively.
- * * Make sure you have the IR LED polarity correct.
- See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity
- * * Typical digital camera/phones can be used to see if the IR LED is flashed.
- Replace the IR LED with a normal LED if you don't have a digital camera
- when debugging.
- * * Avoid using the following pins unless you really know what you are doing:
- * * Pin 0/D3: Can interfere with the boot/program mode & support circuits.
- * * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere.
- * * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere.
- * * ESP-01 modules are tricky. We suggest you use a module with more GPIOs
- for your first time. e.g. ESP-12 etc.
-*/
-#include <M5StickCPlus.h>
-#include <IRremoteESP8266.h>
-#include <IRsend.h>
-
-const uint16_t kIrLed = 9; // 赤外LEDが接続されたピン番号
-
-IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message.
-
-// Example of data captured by IRrecvDumpV2.ino
-uint16_t photoshot[99] = {3488, 1740, 438, 424, 438, 1302, 440, 422, 438, 424, 440, 422, 440, 422,
- 440, 422, 438, 424, 438, 424, 438, 424, 438, 424, 438, 426, 438, 424,
- 438, 1302, 440, 422, 442, 422, 440, 424, 438, 424, 438, 424,
- 442, 420, 438, 1304, 438, 1304, 440, 1302, 438, 424, 438, 424, 438, 424,
- 438, 424, 438, 1302, 440, 424, 440, 1302, 440, 422, 438, 424, 440, 422,
- 440, 1302, 438, 1304, 438, 424, 438, 424, 438, 1304, 438, 1302, 438, 424,
- 438, 424, 462, 1278, 464, 1278, 464, 1278, 462, 1280, 460, 1280, 464, 398,
- 464, 398, 438
- }; // PANASONIC 40040E14667C
-
-uint16_t recording[99] = {3490, 1738, 440, 424, 438, 1304, 438, 424, 438, 424, 438, 424, 438, 424,
- 438, 424, 438, 424, 438, 424, 438, 424, 438, 424, 438, 424, 438, 424,
- 438, 1302, 440, 424, 442, 422, 438, 424, 438, 424, 438, 424, 438, 424,
- 438, 1302, 442, 1302, 438, 1302, 440, 424, 440, 424, 438, 424, 438, 424,
- 438, 1302, 442, 420, 442, 1302, 438, 424, 438, 422, 442, 422, 438, 424,
- 440, 1302, 438, 1302, 438, 424, 438, 424, 438, 1302, 442, 1300, 440, 424,
- 440, 422, 440, 1302, 440, 424, 462, 1278, 464, 400, 464, 398, 464, 1278, 464
- }; // PANASONIC 40040E143329
-
-void setup() {
- M5.begin();
- Serial.begin(115200);
- M5.Lcd.fillScreen(BLUE);
- irsend.begin();
-}
-
-void loop() {
- // Serial.println("NEC"); // irsend.sendNEC(0x00FFE01FUL);
- // Serial.println("Sony"); // irsend.sendSony(0xa90, 12, 2); // 12 bits & 2 repeats
- M5.update();
- if (M5.BtnA.wasReleased()) {
- irsend.sendRaw(photoshot, 99, 38); // Send a raw data capture at 38kHz.
- M5.Lcd.fillScreen(YELLOW);
- } else if (M5.BtnB.wasReleased()) {
- irsend.sendRaw(recording, 99, 38); // Send a raw data capture at 38kHz.
- M5.Lcd.fillScreen(RED);
- }
- delay(150);
- M5.Lcd.fillScreen(BLUE);
- // Serial.println("a Samsung A/C state from IRrecvDumpV2");
- // irsend.sendSamsungAC(samsungState);
- // delay(2000);
-}
- |
M5Stack社ENV II Unit(U001-B)
-https://lang-ship.com/blog/work/m5stack-env-ii-unit-u001-b/
-の、M5StickCでの使い方(GitHub)
-に従って、以下2つをライブラリマネージャから入れてください。(または、arduino-cli lib install "Adafruit BMP280 Library"
などで。)
Adafruit BMP280 Library
Adafruit SHT31 Library
上のリンクにあったプログラムとほぼ同じですが、リスト 30 が、気温・湿度・気圧をLCDとシリアルコンソールに出力するプログラムです。(すこしだけ改変しています)
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | /*
- Please install the < Adafruit BMP280 Library > (https://github.com/adafruit/Adafruit_BMP280_Library)
- < Adafruit SHT31 Library > (https://github.com/adafruit/Adafruit_SHT31)
- from the library manager before use.
- This code will display the temperature, humidity and air pressure information on the screen
- https://lang-ship.com/blog/work/m5stack-env-ii-unit-u001-b/
- */
-#include <M5StickCPlus.h>
-#include <Adafruit_BMP280.h>
-#include <Adafruit_SHT31.h>
-Adafruit_SHT31 sht3x = Adafruit_SHT31(&Wire);
-Adafruit_BMP280 bme = Adafruit_BMP280(&Wire);
-float tmp = 0.0;
-float hum = 0.0;
-float pressure = 0.0;
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.setTextSize(3);
- Wire.begin(32, 33);
- Serial.println(F("ENV Unit(SHT30 and BMP280) test..."));
- while (!bme.begin(0x76)) {
- Serial.println("Could not find a valid BMP280 sensor, check wiring!");
- M5.Lcd.println("Could not find a valid BMP280 sensor, check wiring!");
- }
- while (!sht3x.begin(0x44)) {
- Serial.println("Could not find a valid SHT3X sensor, check wiring!");
- M5.Lcd.println("Could not find a valid SHT3X sensor, check wiring!");
- }
- M5.Lcd.fillScreen(BLACK);
- M5.Lcd.println("ENV Unit test...");
-}
-void loop() {
- pressure = bme.readPressure();
- tmp = sht3x.readTemperature();
- hum = sht3x.readHumidity();
- Serial.printf("Temperature: %2.2f*C Humidity: %0.2f%% Pressure: %0.2fhPa\r\n", tmp, hum, pressure / 100);
- M5.Lcd.setCursor(0, 25);
- M5.Lcd.setTextColor(WHITE, BLACK);
- M5.Lcd.printf("Temp:%2.2f*C\n", tmp);
- M5.Lcd.printf("Humi:%2.2f%%\n", hum);
- M5.Lcd.printf("Prs :%2.0fhPa\n", pressure / 100);
- delay(1000);
-}
- |
警告
-ENV II HAT用のプログラムではありません。ENV II HAT用のサンプル
-参考:https://nn-hokuson.hatenablog.com/entry/2017/09/01/092945
-ボタンを押したときに、2種類の音を出す例を リスト 31 に示します。また、音データのサンプルを 16k.txt と -8k.txt におきました。 -(16kも8kも、Speaker Hatで聴く分には違いはわかりませんでしたので、8kでいいとおもいます。)
-リスト 31 のコメント(黄色ハイライト部分)をよく読んで、タブを追加し、16k.txt と 8k.txt の内容を貼り付けてください。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-
-const int servo_pin = 26;
-uint8_t ledChannel = 0;
-uint8_t resolution = 8;
-uint32_t sampling_rate = 16000; //16kの場合。8kの場合は、8000
-
-/*
- 別タブ(ファイル名はなんでもよい)に、音声データを以下の形式で貼っておく。
- 【音1】
- const uint8_t coin05_8k_raw[] PROGMEM = { 0x80, ... };
- const uint32_t coin05_8k_raw_len = 7218; // ←配列のサイズ
- 【音2】
- const uint8_t coin05_16k_raw[] PROGMEM = { 0x80, ... };
- const uint32_t coin05_16k_raw_len = 14437; // ←配列のサイズ
- PROGMEM と書くと、フラッシュメモリに配置する
-
- そのうえで、以下のextern文を、別タブの変数名と合わせて書く。
- 変数名を一致させることが重要です。
-*/
-// 【音1】
-extern const uint8_t coin05_8k_raw[];
-extern const uint32_t coin05_8k_raw_len;
-// 【音2】
-extern const uint8_t coin05_16k_raw[];
-extern const uint32_t coin05_16k_raw_len;
-
-void setup() {
- // put your setup code here, to run once:
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.setCursor(0, 30, 4);
- M5.Lcd.println(" speaker hat test");
- ledcSetup(ledChannel, sampling_rate * 32, resolution);
- ledcAttachPin(servo_pin, ledChannel);
- ledcWrite(ledChannel, 0);
-}
-void playMusic(const uint8_t* music_data, uint32_t len, uint16_t sample_rate) {
- uint32_t delay_interval = ((uint32_t)1000000 / sample_rate);
- for (int i = 0; i < len; i++) {
- ledcWrite(ledChannel, music_data[i]);
- delayMicroseconds(delay_interval);
- }
- ledcWriteTone(ledChannel, 0);
-}
-void loop() {
- M5.update();
- if (M5.BtnA.wasReleased()) {
- playMusic(coin05_16k_raw, coin05_16k_raw_len, sampling_rate + 800); //なぜか音が低いので +800した
- } else if (M5.BtnB.wasReleased()) {
- playMusic(coin05_8k_raw, coin05_8k_raw_len, sampling_rate / 2); // 8kなので、2で割った
- }
- ledcWriteTone(ledChannel, 0);
- delay(100);
-}
- |
https://notify-bot.line.me/ja/ で、トークンを取得しておく必要があります。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <WiFi.h>
-#include <WiFiMulti.h>
-#include <WiFiClient.h>
-#include <HTTPClient.h>
-
-WiFiMulti WiFiMulti;
-
-void setup() {
- Serial.begin(115200);
- WiFi.mode(WIFI_STA);
- WiFiMulti.addAP("miura_asp_2g", "********");
-
- // wait for WiFi connection
- Serial.print("Waiting for WiFi to connect...");
- while ((WiFiMulti.run() != WL_CONNECTED)) {
- Serial.print(".");
- delay(50);
- }
- Serial.println(" connected");
-}
-
-void loop() {
- HTTPClient http;
-
- if (http.begin("https://notify-api.line.me/api/notify")) { // HTTPS
- http.addHeader("Authorization", "Bearer TOKENTOKENTOKEN"); // ここのTOKENTOKEN... の部分に、取得したTokenを指定する
- http.addHeader("Content-Type", "application/x-www-form-urlencoded"); // format of postdata
- String postdata = "message=日本語でも大丈夫です";
- int httpCode = http.POST(postdata);
-
- // httpCode will be negative on error
- if (httpCode > 0) {
- // HTTP header has been send and Server response header has been handled
- Serial.printf("[HTTP] GET... code: %d\n", httpCode);
-
- // file found at server
- if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
- String payload = http.getString();
- Serial.println(payload);
- }
- } else {
- Serial.printf("[HTTP] GET... failed, error: %s\n", http.errorToString(httpCode).c_str());
- }
- http.end();
- } else {
- Serial.printf("[HTTP] Unable to connect\n");
- }
-
- Serial.println();
- Serial.println("Waiting 2 minutes...");
- delay(60*2*1000); // 120秒まつ
-}
- |
Arduino.ino sample です。src/sketch_feb25a.ino に、ソースコードの例を示します。
-強調したい場合、たとえば
-ソースコード make
は、このようになります。$ hoge
のようになります。
--Conclusion が、結論への内部参照リンクになります。
-
Conclusion が、結論への内部参照リンクになります。
-void setup() {
- // put your setup code here, to run once:
-
-}
-
-void loop() {
- // put your main code here, to run repeatedly:
-
-}
-
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 | #include "M5StickCPlus.h"
-#include "fft.h"
-#include "esp_pm.h"
-#include <rom/crc.h>
-#include <driver/i2s.h>
-#include <driver/rmt.h>
-
-#include <BLEDevice.h>
-#include <BLEServer.h>
-#include <BLEUtils.h>
-typedef struct
-{
- point_3d_t start_point;
- point_3d_t end_point;
-} line_3d_t;
-
-typedef struct
-{
- double x;
- double y;
-} point_2d_t;
- |
これらのソースコードは、ファイルから直接差し込むほうが、間違いは少ないと思われます。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 | #include <M5StickCPlus.h>
-
-int PIN = 26;
-
-// +--- 15kΩ抵抗 --+-- CdSセル --+
-// | | |
-// GND G26 3V3
-// https://www.storange.jp/2012/03/arduinocds.html
-
-// 注意点: https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/ADC/
-
-void setup() {
- M5.begin();
-
- pinMode(PIN, ANALOG); // PINのモード設定
-
- // https://lang-ship.com/blog/work/m5stickc-io/
-}
-
-void loop() {
- Serial.printf("%04d\n", analogRead(PIN) ); // 暗 0〜4095 明
-
- delay(1000);
-}
- |
脚注の例です 1 。
-ここはConclusion です。src/sketch_feb25a.ino に、ソースコードの例を示します。
-Arduino に、ソースコードがあります。
-ipconfigによるIPアドレスの表示 -(クリックすると拡大します) が、画像へのリンクです。
- -https://sphinx-users.jp/ が、いちばんよくまとまっている。
-Arduino IDEを管理者権限で起動してみてください。管理者権限で起動するには、右クリック>その他>管理者権限で起動 をえらびます。
ウイルス対策ソフトが、ファイルの書き込みを制限している場合があります。一時的に機能を停止してみましょう。
Bボタンを押しながらUSBケーブルを差し込むと、復活する場合があるようです。
充電が不十分である可能性があります。ケーブルを接続してしばらく充電してみましょう。
シリアルポートが認識されていれば、適当なプログラム(画面表示を伴うプログラムのほうがわかりやすい)を書き込んでみましょう。
USB-TypeCの向き(!!)をかえてみましょう。改善する場合があります。
安いUSBケーブルは元々充電しかできない場合があります(この場合、シリアルポートが認識されません)。別のUSBケーブルを使用してください。
タスク化した関数を抜ける(終了する)ときに、自タスクを終了していない可能性があります。
その他、タスクに割り当てるメモリが足りない場合など、メモリ使用の不具合も、再起動を引き起こすことがあります。
Contents:
-近年、ディスプレイと無線通信機能を備えた、安価で高性能な小型マイコンモジュールが登場している。 -とくにM5シリーズ(M5Stack / M5StickC )は、ESP32 マイクロプロセッサとカラー液晶パネルを搭載しており、 -ボタンやセンサからの入力をもとに画面表示を書き換えたり、サーボモータを動かしたり、データをインターネット上のサーバに送信したり -することが簡単に行える。
-この実験(IoTプログラミング)では、M5StickCPlus を用いて、 -実世界の情報を読み取り、インターネット上の機器と連携動作しながら、実世界の環境に働きかける仕組みについての基礎を学んだうえで、 -グループによる創造的な開発を進められるようになることを目的とする。
-一般的な「実験」講義では、教員が指示した実験内容を順次実施し、各自が考察し、報告書にまとめる作業を行う。
-この実験では、教員が指示する「必ず実施すべき、与えられた実験」を少なくするかわりに、班としてどのような「システム」や「作品」を完成させたいか? -を話し合って決め、そのために必要な機能の調査と実験、開発を分担してすすめるPBL(Project-based Learning)の形式をとる。
-1週目の予習:M5StickCPlusの予備調査、開発環境の構築
1週目: M5StickCPlus の基本的な使用法と、機能の確認、グループで完成させる「システム」や「作品」についての話し合い、調査・開発の分担
1週目〜2週目の期間:分担した調査・開発をすすめ、記録を残す。部分的な統合試験を行う。
2週目: 分担して構築した機能の統合と動作試験、報告書(レポート)の執筆、発表会に向けた準備と、情報共有
報告書の雛形 ←こちらをコピー&班で共有し、班単位でまとめて執筆・提出していただきます。
-報告書(レポート)の評価基準を、以下に示す。
-成果物(「システム」や「作品」)の完成度、有用性
成果物を再現するための情報と、各機能レベルの実験内容が十分に記述されているか?
チーム活動が円滑に行えたかどうか(班として調査項目の洗い出しと分担、機能の統合がうまくできたかどうか)や、レポートの執筆担当範囲が明確になっているか?
開発の目的や意図は明確か?
図や写真を効果的に用いて、わかりやすく記述されているか?
引用する場合、引用部分と班として記述した部分が明確に区別できるか?参考文献が明記されているか?
(図を含む)引用部分に対する、独自の記述・報告内容の割合、および、ページ数
説明の一貫性と、読みやすさ(書式、文体は統一されているか?)
適切な抽象度の単語・用語を用いているか?
うまくいかなかった場合は、その理由がどの程度明確になっているか、解決の道筋・方向性が示されているか?
発表会における評価基準も、上記の基準に準じる。
-arduino-cli https://arduino.github.io/arduino-cli/0.21/
---
-- -
arduino-cli コマンドリファレンス https://arduino.github.io/arduino-cli/0.21/commands/arduino-cli/
M5StickC非公式日本語リファレンス https://lang-ship.com/reference/unofficial/M5StickC
スイッチサイエンス M5StickC Plus https://www.switch-science.com/catalog/6470
M5StickCガイド https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/docs/M5StickC_Guide_Japanese.pdf
M5StickC Plus に、プログラムを書き込むには、 -おもに以下の方法があります。
-Arduino IDE
arduino-cli (Command-Line Interface)
PlatformIO
2021年度は1. の方法を用いましたが、初期設定が若干面倒なのと、エディタの編集機能が弱いので、今年は arduino-cli を用いる方法を推奨します。 -ただし、arduino-cli はビルドと書き込みのみで、ファイル編集ができませんので、別途エディタとして Visual Studio Code を導入します。 -余力がある人は、Visual Studio Code に Arduino拡張機能を追加して設定すると、ボタン一つで書き込みできる(Arduino IDEに近い)操作感を得ることができます。
-注釈
-M5StickC Plusは、2017年に発売されたM5StickC の後継版です。ディスプレイサイズと解像度、バッテリ容量が向上しています。また、ブザーも追加されているため、簡単な音を本体のみで鳴らすことができます。
-注釈
-UIFlowという、Webベースのブロックプログラミング環境もありますが、本実験では柔軟性と拡張性を重視し、Arduino/arduino-cli を使用します。Arduino/arduino-cli ではC言語でプログラムを記述します。
-以下、こまかいですが、
-arduino-cli のインストール
arduino-cli でボード情報とライブラリのインストール
サンプルファイルのコンパイルと転送
Visual Studio Code のインストール
Arduino拡張機能の追加と設定
の順に、説明します。
-arduino-cli をインストールします。
-Git for Windows をインストールしてください。Setup時にいろいろ訊かれますが、すべてそのまま「Next」を押して進めて大丈夫です。
Git Bash を起動して、ターミナルに以下のコマンドを入力してください(図 1 )。(この下の灰色のテキストエリアの右端の四角アイコンを押すと、コマンドをコピーできます。)
-curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
-
図 1 arduino-cli のインストールコマンド実行後の画面(例)
-Homebrew パッケージマネージャ をまだ入れていない場合は、インストールしてください。ターミナルを開き、以下のコマンドを実行します。
-/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
-
続けて、ターミナルで、以下のコマンドを実行してください。
-brew update
-brew install git arduino-cli
-
ここで (2) と (3) を行う準備として、サンプルファイルと設定ファイルを 三浦の Git リポジトリ からダウンロードします。ターミナル (or Git Bash) で以下のコマンドを実行してください。
-git clone https://git.istlab.info/git/miura250/M5StickCPlus_FactoryTest2022.git
-cd M5StickCPlus_FactoryTest2022
-ls -al
-
(cd のあとのフォルダ名が長いので、途中でTabキーを押して補完することをおすすめします。)
-ls -al
の結果は、図 2 のようになります。
図 2 サンプルファイルの中身を確認
-以下のコマンドを入力すると、(2) arduino-cli でM5StickCPlusの開発をするための準備として、「ボード情報とライブラリのインストール」 を行います。
-./setup.sh
-
注釈
-setup.sh は事前準備のときの 1回だけ実行すればOKです。その後、ライブラリが必要となり、追加でダウンロードするときは、arduino-cli lib install XXXX コマンドを実行してください。
-以下のコマンドを入力すると、(3) のサンプルファイル(FactoryTest2022)の「コンパイル」 を行います(図 3)。
-./compile.sh
-
警告
-M5StickCPlus本体がない事前準備の段階で、できるのは、ここまでです。 以下の「書き込み」は、本体をUSB接続したあとで、行う作業になります。次のステップとして、(4)のVisual Studio Code のインストール に進んでください。
-以下のコマンドを入力すると、(3) の「書き込み」 を行います(図 3)。 ただし「書き込み」は、M5StickCPlus本体をUSB接続していないと失敗します。
-./upload.sh
-
注釈
-今後、ソースコード(ここでは、FactoryTest2022.ino)を編集していくと、「コンパイル」と「書き込み」 を頻繁に実行することになります。その場合、以下のように && でつなげて1回のコマンド入力でも実行できます。
-./compile.sh && ./upload.sh
-
図 3 コンパイルと書き込み(upload)を行っている様子
-Windows の場合は、Microsoft Store で、Visual Studio Code のインストールができます。Mac の場合は、インストーラー でダウンロードしてください。
-必須ではないですが、できれば次のページを参考に、 Arduino拡張機能の追加と設定 をしておくとよいでしょう。
-この設定をしておくと、ソースコード編集→保存→右上のボタン で、書き込みができます。
-注釈
-この設定をしない場合でも、(3) のコマンドライン(またはシェルスクリプト)を修正・実行すれば、書き込みができます。
-ここはチュートリアルです。ほげほげほげ。自動コンパイルテスト。さらにテスト。
-ipconfigによるIPアドレスの表示 -(クリックすると拡大します)
-https://ss.istlab.info/ が、講義システムになります。
-ipconfigによるIPアドレスの表示 -(クリックすると拡大します) に、ipconfigによるIPアドレスの表示を示します。
-注釈
-図への参照は、同一ファイル内からしかできない??
-図表番号は、pip3 install sphinx-numfig
をすれば、つくようです。
図表番号を参照するときは、f_ipconfig
のように、numref をつかいます。参考サイト:https://sphinx-users.jp/reverse-dict/images/numbering.html
fig_ipconfig
だと、番号がつく? →結果として、ついた。
fig_ipconfig
ipconfigによるIPアドレスの表示
-(クリックすると拡大します) のようにすれば、番号とキャプションが両方はいります。
See <http://docutils.sf.net/rst.html> for introductory docs.
-David Goodger <goodger@python.org>
-$Date: 2013-02-20 02:10:53 +0100 (Mi, 20. Feb 2013) $
-$Revision: 7612 $
-This is a "docinfo block", or bibliographic field list
-注釈
-If you are reading this as HTML, please read -cheatsheet.txt instead to see the input syntax examples!
-Section titles are underlined or overlined & underlined.
-Grid table:
-Paragraphs are flush-left, -separated by blank lines. --- |
-Literal block, preceded by "::": -Indented
- or: -> Quoted
- |
-
>>> print 'Doctest block'
-Doctest block
- |
-|
-
-Line blocks preserve line breaks & indents. [new in 0.3.6]
-
-
-Useful for addresses, verse, and adornment-free lists; long
-lines can be wrapped with continuation lines.
- |
-
Simple tables:
-List Type |
-Examples (syntax in the text source) |
-
---|---|
Bullet list |
-
|
-
Enumerated list |
-
|
-
Definition list |
-
|
-
Field list |
-
|
-
Option list |
-
|
-
Explicit Markup |
-Examples (visible in the text source) |
-
---|---|
Footnote |
-
|
-
Citation |
-
|
-
Hyperlink Target |
-- |
Anonymous Target |
-- |
Directive ("::") |
-![]() |
-
Substitution Def |
-- |
Comment |
-- |
Empty Comment |
-(".." on a line by itself, with blank lines before & after, -used to separate indentation contexts) |
-
emphasis; strong emphasis; interpreted text; interpreted text
-with role; inline literal text
; standalone hyperlink,
-http://docutils.sourceforge.net; named reference, reStructuredText;
-anonymous reference; footnote reference, 1; citation reference,
-[CIT2002]; like an inline directive; inline internal target.
See <http://docutils.sf.net/docs/ref/rst/directives.html> for full info.
-Directive Name |
-Description (Docutils version added to, in [brackets]) |
-
---|---|
attention |
-Specific admonition; also "caution", "danger", -"error", "hint", "important", "note", "tip", "warning" |
-
admonition |
-Generic titled admonition: |
-
image |
-
|
-
figure |
-Like "image", but with optional caption and legend |
-
topic |
-
|
-
sidebar |
-
|
-
parsed-literal |
-A literal block with parsed inline markup |
-
rubric |
-
|
-
epigraph |
-Block quote with class="epigraph" |
-
highlights |
-Block quote with class="highlights" |
-
pull-quote |
-Block quote with class="pull-quote" |
-
compound |
-Compound paragraphs [0.3.6] |
-
container |
-Generic block-level container element [0.3.10] |
-
table |
-Create a titled table [0.3.1] |
-
list-table |
-Create a table from a uniform two-level bullet list [0.3.8] |
-
csv-table |
-Create a table from CSV data [0.3.4] |
-
contents |
-Generate a table of contents |
-
sectnum |
-Automatically number sections, subsections, etc. |
-
header, footer |
-Create document decorations [0.3.8] |
-
target-notes |
-Create an explicit footnote for each external target |
-
math |
-Mathematical notation (input in LaTeX format) |
-
meta |
-HTML-specific metadata |
-
include |
-Read an external reST file as if it were inline |
-
raw |
-Non-reST data passed untouched to the Writer |
-
replace |
-Replacement text for substitution definitions |
-
unicode |
-Unicode character code conversion for substitution defs |
-
date |
-Generates today's date; for substitution defs |
-
class |
-Set a "class" attribute on the next element |
-
role |
-Create a custom interpreted text role [0.3.2] |
-
default-role |
-Set the default interpreted text role [0.3.10] |
-
title |
-Set the metadata document title [0.3.10] |
-
See <http://docutils.sf.net/docs/ref/rst/roles.html> for full info.
-Role Name |
-Description |
-
---|---|
emphasis |
-Equivalent to emphasis |
-
literal |
-Equivalent to |
-
math |
-Mathematical notation (input in LaTeX format) |
-
PEP |
-Reference to a numbered Python Enhancement Proposal |
-
RFC |
-Reference to a numbered Internet Request For Comments |
-
raw |
-For non-reST data; cannot be used directly (see docs) [0.3.6] |
-
strong |
-Equivalent to strong |
-
sub |
-Subscript |
-
sup |
-Superscript |
-
title |
-Title reference (book, etc.); standard default role |
-
注釈
-以下の項目について、全員がすべてを試す必要はありません(あきらかに、時間が足りなくなります)。役割分担をして、手分けして動作の確認と、同じ班のメンバーへの動作説明・共有をして、すすめてください。必要に応じて、検証する機能を絞り込んでください。
-電源を入れるには、電源ボタンを、2秒間長押しします。
電源を切るには、電源ボタン(M5と書かれたAボタンの左側面)を、6秒間長押しします。その際、プログラムによっては再スタートしたように見える場合がありますが、気にせずに長押し継続してください。
動画をみる→ https://youtu.be/Lo1jZbAeT8Y
M5StickCガイド の、4ページ目、ハードウェアの概要も参考になります。
プログラムの書き込み を参照してください。
-以下のソースコード例は、リストの右上の□ボタンを押すと、クリップボードに簡単にコピーできます。右上のボタンが表示されていないときは、右にスクロールしてください。
ソースコードのインデントは、CTRL+T (Macの場合はCommand+T)キーで、自動整形できます。
#include <M5StickC.h>
は、M5StickC用のヘッダファイル指定です。 M5StickCPlus では、画面解像度が異なるので、 #include <M5StickCPlus.h>
に変更しないと、表示がおかしくなることがあります。
大文字と小文字は厳密に区別されます。
画面(LCD)をつかうプログラムを書き込んだあと、画面を使わないプログラムを書き込むと、前のプログラムの画面が残ることがあります。
スケッチブック(プログラムを構成する、複数のソースコードを含むファイル、他のIDEではプロジェクトと呼ぶ場合もある)をコピーしたいときは、内包するフォルダごとコピーしてください。その際、フォルダ名と、メインのソースコードファイル名(拡張子以外の部分)は、一致している必要があります。
その他、よくある質問は、Frequently-Asked Questions (FAQ: よくある質問) に随時追記していきます。
リスト 1 は、シリアルモニタへ文字列を出力するシンプルな例です。グローバル変数 num を 0 に設定したうえで、setup()関数が1回実行されます。その後、loop()関数が繰り返し実行されます。
-プログラムの出力をみるには、Arduino IDEで「シリアルモニタ」をひらいてください。コードエディタ右上の虫眼鏡アイコンボタンをおします。
-Serialクラスには、print()関数、println()関数、 printf()関数があります。Serial通信を用いると、デバイス側の変数の値や状況を、PC側で確認するプログラムを書くことができます。
-なお、文字化けしたり、???と表示されるときは、シリアルモニタの通信速度(ボーレート)を、右下で 115200 bps
に変更し、プログラムで設定した速度と一致させてください。
1 -2 -3 -4 -5 -6 -7 -8 -9 | int num = 0;
-void setup() {
- Serial.begin(115200); // 通信速度をbpsで設定
-}
-void loop() {
- Serial.printf("%d \n" , num);
- num++;
- delay(500); // 500ミリ秒待つ
-}
- |
シリアルモニタは、デバイスからの出力を確認するだけではなく、デバイスに文字を送信することもできます。リスト 2 は、シリアルモニタを介して、PCからデバイスに文字を送信する例です。シリアルモニタ上部のテキストエリアから 0 を送信すると、カウンタ num をリセットします。10〜14行目で、PCから送信された文字を、1文字ずつ Serial.read()
で読み取って、配列 buf
に格納しています。PCから複数の文字を1回で送信すると、 Serial.available()
は連続して 1 (=true) を返しますので、1回に送信された文字をすべて buf
に格納することができます。ちなみに、シリアルモニタで送信された文字列の最後は、改行コード(10)が付与されます。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 | int num = 0;
-char buf[100];
-
-void setup() {
- Serial.begin(115200); // 通信速度をbpsで設定
-}
-
-void loop() {
- int pos = 0;
- while (Serial.available()) { //PCから送信された文字があるあいだ、くりかえす
- char c = Serial.read(); // 1バイト読み取る
- buf[pos] = c; // 配列buf に格納
- pos++; // 格納位置をひとつ右へ
- }
- if (pos > 0) {
- buf[pos] = 0; // さいごに Null (文字列の終端)を追加(これを忘れるとどうなる?)
- Serial.print("> from pc: ");
- Serial.print( buf ); // 格納しておいた文字列を表示
- if (buf[0] == '0' && pos == 2) { // buf={ 48(='0'), 10(=改行) } のとき
- num = 0; // num を 0 にする
- Serial.println( "Reset num" );
- }
- delay(2000);
- }
-
- Serial.printf("%d \n" , num );
- num++;
- delay(500);
-}
- |
注釈
-16行目の処理を忘れると、どうなるでしょうか? また、buf が溢れると、なにが起きるでしょうか?プログラムを書くときは、常に例外的な事象がおきる可能性を考えておきましょう。ただし、全ての例外的な事象に対処するのは困難な場合が多いです。
-M5StickCのDisplay周り解析 <https://lang-ship.com/blog/work/m5stickc-display> が詳しいです。
リスト 3 のサンプルでは、外側から内側に向かって、10ピクセルずつ余白を残しながら、色を変えて塗りつぶしています。その後、8,16,26ピクセルフォント(それぞれ1,2,4番)をsetCursor()関数で指定して、print()関数で文字列を描画しています。
M5StickCPlusの機能である液晶ディスプレイ(LCD)を使用するため、 #include <M5StickCPlus.h>
を指定し、M5.begin()
を呼び出しています。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.fillRect(0, 0, 240, 135, RED);
- //M5StickCPlusの画面サイズは、240 x 135
-
- M5.Lcd.fillRect(10, 10, 220, 115, ORANGE);
- M5.Lcd.fillRect(20, 20, 200, 95, YELLOW);
- M5.Lcd.fillRect(30, 30, 180, 75, GREENYELLOW);
- M5.Lcd.fillRect(40, 40, 160, 55, CYAN);
- M5.Lcd.fillRect(50, 50, 140, 35, BLUE);
- M5.Lcd.fillRect(60, 60, 120, 15, MAGENTA);
-
- M5.Lcd.setTextFont(1); // 8pixel ASCII font
- M5.Lcd.setTextSize(1); // Magnify (x1-7)
- M5.Lcd.setTextColor(WHITE);
- M5.Lcd.setCursor(10,1); M5.Lcd.print("RED");
- M5.Lcd.setTextColor(BLACK);
- M5.Lcd.setCursor(20,11); M5.Lcd.print("ORANGE");
- M5.Lcd.setCursor(30,21); M5.Lcd.print("YELLOW");
- M5.Lcd.setCursor(40,31); M5.Lcd.print("GREENYELLOW");
- M5.Lcd.setCursor(50,41); M5.Lcd.print("CYAN");
- M5.Lcd.setTextColor(WHITE);
- M5.Lcd.setCursor(60,51); M5.Lcd.print("BLUE");
- M5.Lcd.setCursor(70,60,2); M5.Lcd.print("MAGENTA (2)");
- // setCursorの第3引数は、TextFont番号
-
- M5.Lcd.setTextColor(BLACK);
- M5.Lcd.setCursor(30,90,4); M5.Lcd.print("26pixel ASCII (4)");
-}
-
-void loop() {
-}
- |
画面の向きは、setRotation() 関数で、設定します。0〜3までの整数で、指定します。
- -注釈
-フォントの種類を設定するときは、setTextFont() や、setCursor()の第3引数をつかいます。setTextSize() は、指定したフォントを「縦横何倍に引き伸ばして表示するか?」を設定します。ここの「倍率」を2以上に増やすと、若干ギザギザが目立つようになります。
-本体には、3つのボタンがあります。 -(参考:M5StickCガイド の、4ページ目、ハードウェアの概要)
-リスト 4 に、ボタンをおしたらシリアルモニタに表示する例を示します。ボタンも、M5StickC/CPlusの機能なので、 #include <M5StickCPlus.h>
を指定し、M5.begin()
を呼び出しておく必要があります。また、ボタンの状態を読み出して、ボタンオブジェクト(BtnA,BtnB)に設定するために、 M5.update()
を、ループのなかに入れておく必要があります( update()の定義 )。長押しと普通押しを区別したい場合は、ifで確認する順番(長押しを先に判定する)が重要です。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 | #include <M5StickCPlus.h>
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
-}
-
-void loop() {
- M5.update(); // 各ボタンの状態を(読み取って)更新する:ボタンを判定するときは必須。
-
- if (M5.BtnA.wasReleasefor(1000) ) {
- Serial.println("[A] was Pressed longer than 1s");
- } else if (M5.BtnA.wasReleased()) {
- Serial.println("[A] was Pressed");
- } else if (M5.BtnB.wasReleasefor(1000) ) {
- Serial.println("[B] was Pressed longer than 1s");
- } else if (M5.BtnB.wasReleased()) {
- Serial.println("[B] was Pressed");
- } else if (M5.Axp.GetBtnPress() == 2) {
- Serial.println("[Power] was Pressed");
- }
- delay(10);
-}
- |
注釈
-非公式リファレンスの「ボタン管理(Button)」 も参考になります。
-リスト 5 に、文字列から整数に変換したり、16進数表現の文字列を10進数に変換する例を示します。
-Stringクラスを用いると、char配列 / byte配列 / 小文字変換や、空白改行の削除(ただし文字列の前後のみ)、部分文字列の取得などができます。
-元のデータが保持されるメソッドと、破壊されるメソッドがあることに注意しましょう。
-M5系デバイスのLCDでは、色を16ビット値(赤5bit/緑6bit/青5bit)で表現しています。 M5.Lcd.color565()
という関数もありますが、ここではビット演算の理解を深めるため、関数を定義しています。
-C言語のポインタや、シフト演算などを理解していると、このような処理を円滑に記述できるようになります。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 | #include <M5StickCPlus.h>
-
-void setup() {
- Serial.begin(115200);
- M5.begin();
- M5.Lcd.setRotation(3);
- Serial.println("整数 または 6文字の16進数(RRGGBB)を入力してください。");
-}
-
-String str = ""; // String: 可変長の文字列クラス
-void loop() {
- char buf[100] = {0};
- int pos = 0;
- while (Serial.available()) { //PCから送信された文字があるあいだ、くりかえす
- char c = Serial.read(); // 1バイト読み取る
- buf[pos] = c; // 配列buf に格納
- pos++; // 格納位置をひとつ右へ
- }
- if (pos > 0) {
- buf[pos] = 0;
- String sbuf = buf;
- sbuf.trim(); //文字列の前と後の空白と改行を取り除く(破壊的メソッド)
- str.concat(sbuf); // 文字列の連結 (意味としては、str = str + sbuf)
- Serial.println(str);
- if (isDigit(sbuf)) {
- int num = sbuf.toInt();
- Serial.println( num * num );
- }
- if (sbuf.length() == 6) { // RRGGBBとして、LCD画面の背景を塗りつぶす
- sbuf.toLowerCase();
- uint8_t r = hexToDec( sbuf.substring(0, 2) );
- uint8_t g = hexToDec( sbuf.substring(2, 4) );
- uint8_t b = hexToDec( sbuf.substring(4, 6) );
- M5.Lcd.fillScreen( getColorUInt16( r , g , b ) );
- M5.Lcd.setCursor(0, 70, 4);
- M5.Lcd.printf(" %02x %02x %02x \n", r, g, b);
- M5.Lcd.printf(" %d %d %d ", r, g, b);
- }
- }
- delay(50);
-}
-//全ての文字が0〜9なら、1(true)を返す
-bool isDigit(String s) {
- bool isAllDigit = true;
- const char *p = s.c_str(); // String.c_str() は、NULLで終端されたchar配列の先頭アドレスを返す
- while ( *p != 0 ) {
- if (*p < '0' || '9' < *p) isAllDigit = false;
- p++;
- }
- return isAllDigit;
-}
-// M5 用の、16ビットカラー値に変換 引用:https://qiita.com/nnn112358/items/ea6b5e81623ba690343c
-uint16_t getColorUInt16(uint8_t red, uint8_t green, uint8_t blue) {
- return ((red >> 3) << 11) | ((green >> 2) << 5) | (blue >> 3);
-}
-// 引数hex が16進表記の文字列だと仮定して、10進の値を返す
-uint8_t hexToDec(String hex) {
- int dec = 0;
- int tmp = 0;
- for (int p = 0; p < hex.length(); p++) {
- tmp = int(hex.charAt(p));
- if ( '0' <= tmp && tmp <= '9' ) tmp = tmp - '0';
- if ( 'a' <= tmp && tmp <= 'f' ) tmp = tmp - 'a' + 10;
- if ( 'A' <= tmp && tmp <= 'F' ) tmp = tmp - 'A' + 10;
- tmp = constrain(tmp, 0, 15); //例外処理
- dec = (dec * 16) + tmp;
- }
- return dec;
-}
- |
注釈
-変数の型一覧 uint16_t は unsigned int 16bit type の略です。 |br| 参考:M5StackのLCDディスプレイの色をRGBで指定する。
-リスト 6 は、内蔵Beepを鳴らすサンプルです。音の周波数は、最初の1オクターブ (f[0]〜f[6]) のみを配列宣言時に指定し、残りの3オクターブはsetup()内で、倍数を計算して配列に設定しています。
-setBeep()
と beep()
を使うと、同じビープ音を使い回すときは記述が短くて便利ですが、通常は tone()
のほうが簡潔です。
-どちらの記法でも、命令実行のあと、音の停止を待たずに、すぐに次の処理に移行します(ノンブロッキング)。
-継続ミリ秒数(ms)は、 M5.Beep.update()
が周期的に呼び出せるときに指定し、それ以外は省略するとよいでしょう。(結局、 delay()
と mute()
が必要になるため)
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-
-int f[28] = { 262, 294, 330, 349, 392, 440, 494 }; // 配列のサイズは4オクターブ分
-void setup() {
- Serial.begin(115200);
- M5.begin();
- M5.Lcd.setRotation(3);
- for (int i = 0; i < 7; i++) {
- f[i + 7] = f[i] * 2;
- f[i + 14] = f[i] * 4;
- f[i + 21] = f[i] * 8;
- }
- // setBeep( Hz, ms) でビープ音を設定して、beep()で鳴らす。
- M5.Beep.setBeep(523, 500); M5.Beep.beep(); delay(500);
- // tone( Hz, ms ) で鳴らす方法
- M5.Beep.tone(1046, 500); delay(500);
- // msを省略し、tone( Hz ) で鳴らす(結局、delayが必要になるので)
- M5.Beep.tone(2092); delay(500);
- // ここはmsを指定するとよい (loopのM5.Beep.updateが停めてくれるので、delayを省略できる)
- M5.Beep.tone(2092 * 2, 1000);
-}
-
-void loop() {
- M5.Beep.update(); //tone()やsetBeep()で指定した時間を過ぎていたら音を止める。
- // M5.Beep.mute() とすると、すぐに停止する。
-
- while (Serial.available()) {
- char c = Serial.read();
- if (c < 'c' || 'z' < c) continue; // c〜zの文字以外なら、以降のwhile内処理をスキップ
- M5.Beep.tone( f[c - 'c'] , 1000); // 1秒鳴らす
- Serial.println( f[c - 'c'] );
- }
- delay(50);
-}
- |
M5StickCPlusには、2つのLEDランプが内蔵されています。GPIO(General Purpose Input/Output)の10番 には、赤色LED、GPIO9 には、赤外LEDが接続されています。 -場所は、USBケーブルを挿す面の反対側の面にある、小さな穴2つの内側です。
-リスト 7 は、赤色LEDを点滅させるシンプルなプログラムです。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 | int PIN = 10; // 赤色LED G10
-//int PIN = 9; // Ir LED (カメラには映りますが、肉眼では見えません) G9
-// その他、G0 (0) , G25 (25), G26 (26) がつかえます。
-// https://lang-ship.com/blog/work/m5stickc-io/
-
-void setup() {
- pinMode(PIN, OUTPUT); // PINのモード設定
-}
-
-void loop() {
- digitalWrite(PIN, HIGH); // HIGH = 1
- delay(1000);
- digitalWrite(PIN, LOW); // LOW = 0
- delay(500);
-}
- |
外部のLED等は、 G0, G25, G26 に接続します。(GROVE端子のG32, G33も利用できます。) -サンプルプログラムは、リスト 7 と同様です。PIN 番号を、0 / 25 / 26 に変更してください。
-ブレッドボードに、抵抗とLEDを直列に接続します。 -LEDの長い足のほうに、G0 (or G25 or G26) をジャンパワイヤで接続し、反対側(短い足)のほうを、GND (グランド)に接続します。 -ポートを「HIGH」にすると、3.3Vの電圧がかかります。
- -警告
-LEDのみで回路を構成しないよう注意!一般に、LEDは抵抗をつないで使用しないと、故障したり、最悪の場合破裂したりして危険です。ただし、抵抗入りLEDであれば問題ありません。
-パルス幅変調とは、信号の周期Tに対する、パルスの幅を変化させる方法です。 -直流モータの速度制御や、サーボモータの制御、LEDの明度調整などに使われます。
- -Copyright (C) 2021 by Junichi Akita, CC BY-SA
-リスト 8 は、赤色LEDを点滅させるシンプルなプログラムです。 ledcSetup(チャンネル, 周波数, 分解能)
で、PWMチャンネル(0〜3)に対する周波数と分解能設定をし、 lecAttachPin(ピン番号, チャンネル)
で、PWMチャンネルを適用する出力ピンを選択します。そのあと、 ledcWrite(チャンネル, 値)
で、分解能で設定したビットで表現できる最大値+1以下の値を指定することで、デューティー比を設定します。リスト 8 の場合、分解能で8bitを指定したので、0〜256 の値が、デューティー比 0〜1 のパルス生成に対応します。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 | int PIN = 10; // 内蔵LED
-int PWM_CH = 1; // 0~3で指定する。0にすると高音が鳴って耳障り?
-
-void setup() {
- pinMode(PIN, OUTPUT); // PINのモード設定
- ledcSetup(PWM_CH, 90, 8); // CH, 周波数(Hz) 【 90Hz より、小さくするとどうなる?】 , 分解能(bit)
- ledcAttachPin(PIN, PWM_CH);
- // https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/LED_Control/
-}
-
-void loop() {
- int i;
-
- for (int i = 0 ; i < 256 ; i++) {
- ledcWrite(PWM_CH, i);
- delay( 5 );
- }
- for (int i = 256 ; i > 0 ; i--) {
- ledcWrite(PWM_CH, i);
- delay( 5 );
- }
-}
- |
注釈
-ソースコードのコメントにも書いていますが、周波数を小さくする(20〜30程度)と、どうなるでしょうか?ぜひやってみてください。
-リスト 9 は、サーボハット のサーボモータを動かすサンプルです。サーボモータの制御はPWMですので、基本的に、上のPWMとやっていることは同じです。おまけとして、LEDも点灯させました。map関数
は、Arduinoで使える関数で、範囲に対応する値を変換するときに使います。ここでは、サーボ制御で用いる5〜33の値を、LED制御の値0〜256に変換しています。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 | #define MLOW 5
-#define MHIGH 33
-
-void setup() {
- ledcSetup(1, 50, 8); //サーボハット CH1
- ledcAttachPin(26, 1);
-
- pinMode(10, OUTPUT);
- ledcSetup(2, 100, 8);//LED CH2
- ledcAttachPin(10, 2);
-}
-
-void loop() {
- for (int i = MLOW; i <= MHIGH; i = i + 1) {
- ledcWrite(1, i);
- int v = map(i, MLOW, MHIGH, 0, 256); // 範囲5〜33に対するiの値を、範囲0〜256に変換
- ledcWrite(2, v);
- delay(50);
- }
- delay(300);
- for (int i = MHIGH; i >= MLOW; i = i - 1) {
- ledcWrite(1, i);
- int v = map(i, MLOW, MHIGH, 0, 256);
- ledcWrite(2, v);
- delay(20);
- }
- delay(300);
-}
- |
ADCは、Analog to Digital Converter の意味です。
-analogRead(PIN)
は、PIN番ピンの電圧(0~3.3V)を、0〜4095 の値で返します。一般に、抵抗値が変化するタイプのセンサは、この方法をつかって、読み取ることができます。
警告
-ADC にかいてあるように、G26, G32, G33, G36のみ使えます。G26は、無線利用時には使えません。
-リスト 10 はCdSセル(照度センサ) の値を読み取るサンプルです。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 | int PIN = 26;
-
-// +--- 15kΩ抵抗 --+-- CdSセル --+
-// | | |
-// GND G26 3V3
-// https://www.storange.jp/2012/03/arduinocds.html
-
-// 注意点: https://lang-ship.com/reference/unofficial/M5StickC/Peripherals/ADC/
-
-void setup() {
- Serial.begin(115200);
- pinMode(PIN, ANALOG); // PINのモード設定
- // https://lang-ship.com/blog/work/m5stickc-io/
-}
-
-void loop() {
- Serial.printf("%04d\n", analogRead(PIN) ); // 暗 0 〜 4095 明
- delay(1000);
-}
- |
圧力センサや、曲げセンサも、同様の方法で利用することができます。
-リスト 11 は、内蔵されている加速度センサ(MPU6886) の値を表示するサンプルです。ちなみに、IMUとは、Inertial Measurement Unit: 慣性計測装置 の略です。 -「ツール」→「シリアルプロッタ」をひらくと、値をグラフでみることができます。(通信速度設定を、115200bps に設定してください) -ジャイロセンサの値も取得可能です。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 | // 参考にしたサイト: https://qiita.com/kitazaki/items/1ce671532270cd44fabf
-
-#include <M5StickCPlus.h>
-
-float gyroX, gyroY, gyroZ; // ジャイロデータ
-float ax, ay, az; // 加速度データ
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.IMU.Init();
- Serial.begin(115200);
- Serial.println("");
-}
-void loop() {
- M5.IMU.getGyroData(&gyroX, &gyroY, &gyroZ);
- M5.IMU.getAccelData(&ax, &ay, &az);
- M5.Lcd.setCursor(0, 10, 2);
-
- M5.Lcd.printf("aX :%7.2f \naY :%7.2f \naZ :%7.2f mg \n\n", ax , ay , az );
- Serial.printf("%7.2f , %7.2f , %7.2f \n", ax , ay , az); //シリアルプロッタ用の出力
-
- M5.Lcd.printf("gX :%7.2f \ngY :%7.2f \ngZ :%7.2f mg ", gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes);
- // Serial.printf("%7.2f,%7.2f,%7.2f,", gyroX * M5.IMU.gRes, gyroY * M5.IMU.gRes, gyroZ * M5.IMU.gRes);
-
- delay(50);
-}
- |
注釈
-実験時間中に、送信のみを手軽に試したい場合は、付録の リスト 29 を書き込んで、教員を呼んでください。
-赤外線リモコン受信モジュールが必要です。ここでは、GP1UXC41QS を前提に、話をすすめます。
-また、準備として、ライブラリマネージャにて、IRremoteESP8266 をインストールします。ちなみに、テストしたバージョンは2.7.15でした。 2.7.15
より新しいバージョンだと、失敗する場合があります。もし最新版を入れてうまくいかない場合はダウングレードしてください。
注釈
-ライブラリマネージャは、「スケッチ」→「ライブラリをインクルード」→「ライブラリを管理…」で、ひらきます。
-ファイルメニュー → スケッチ例 → IRremoteESP8266 → IRrecvDumpV2 を選択します。
-ブレッドボードに、以下の図のように配線します。Pとかいてある面が、受光器が出っ張っている面だとおもってください。47Ωの抵抗を、5Vとの間に入れます。
-赤外線リモコン受信モジュールに接続したピンを const uint16_t kRecvPin = 36;
として設定します。
-受光器にリモコンを向けて、ボタンを押すと、シリアルモニタに情報が表示されます。ここでは、Protocol : NEC , Code 0x2FD48B7 (32 Bits) と表示されたとします。この数値(uint32_t)を覚えておきます。
内蔵の赤外LEDを用いて、信号を送信する例を リスト 12 に示します。 -内蔵の赤外LED光はあまり強くないため、50cm程度まで近づかないと反応しない場合があります。また、太陽光の影響を強く受けます。 -単体の赤外LEDを接続して用いると、距離を伸ばすことができます。
-なお、NECフォーマットではない赤外線リモコンの通信フォーマットについては、 赤外線リモコンの通信フォーマット や、スケッチ例を参考にしてください。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 | #include <IRremoteESP8266.h>
-#include <IRsend.h>
-
-uint16_t kIrLed = 9; // 内蔵IrLED
-IRsend irsend(kIrLed);
-
-uint32_t code = 0x2FD48B7; // Toshiba TV Power
-void setup() {
- irsend.begin();
-}
-
-void loop() {
- irsend.sendNEC( code , 32);
- delay(5000);
-}
- |
M5.Lcd ではじまる画面描画命令は、表示されている画面に対して、直接描画するため、画面のちらつきが生じることがあります。 -TFT_eSprite クラスを用いると、画面に表示されていない仮想画面(オフスクリーン)を作成して、そこに対して描画を行っておき、さいごにまとめて仮想画面の内容をメインの画面(Lcd)に描画することができます。 -これにより、画面のちらつきが抑制できます(ダブルバッファリング)。 -ちらつき防止のほかに、なめらかに画面スクロールする目的で、実画面よりも大きい仮想画面を作成しておき、その一部の領域のみを実画面に描画するといった用途にも使われます。
-TFT_eSprite クラスは、Lcdクラスとほぼ同様の描画関数を備えています。リスト 13 は、スプライトの効果あり/なしを確認できるサンプルプログラムです。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-
-int USE_SPRITE = 0 ; //スプライトを使用するとき1
-
-TFT_eSprite spu = TFT_eSprite(&M5.Lcd); // Sprite object
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
-
- spu.setColorDepth(8);
- spu.createSprite(240, 135);
-
- randomSeed(analogRead(0));
-}
-
-void loop() {
- int r = random(100000);
- if ( USE_SPRITE ) {
- spu.fillSprite( CYAN );
- spu.setCursor(30, 34, 4); spu.setTextSize(2);
- spu.setTextColor( WHITE, BLUE );
- spu.printf(" %d \n Sprite ", r );
- spu.pushSprite(0, 0);
- } else {
- M5.Lcd.fillScreen( CYAN );
- M5.Lcd.setCursor(30, 34, 4); M5.Lcd.setTextSize(2);
- M5.Lcd.setTextColor( WHITE, BLUE );
- M5.Lcd.printf(" %d \n LCD ", r);
- }
-
- M5.update();
- if (M5.BtnA.wasReleased()) {
- USE_SPRITE = 1 - USE_SPRITE ; // スプライト使用の切り替え(1なら0、0なら1)
- M5.Beep.tone(1000 + 1000 * USE_SPRITE, 500);
- }
- M5.Beep.update();
- delay(100);
-}
- |
リスト 14 は、Wifi接続のサンプルです。ssid
と password
には、環境にあわせたものを入力してください。接続すると、m5デバイスのIPアドレスを画面に表示します。本当にWifi接続できたかどうかを、PCのターミナルからpingを打つなどして、確認してみましょう。(Windowsの場合、コマンドプロンプトをひらき、ping のあとに、半角スペースと、確認したいIPアドレスを入れます)
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-#include <WiFi.h>
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.fillScreen(ORANGE);
- M5.Lcd.setCursor(10, 50, 4);
-
- WiFi.begin(ssid, password); // 接続開始
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- M5.Beep.tone(2000); delay(200);
- M5.Beep.mute(); delay(300);
- M5.Lcd.print(".");
- }
- // 接続完了!!
- M5.Beep.tone(4000);
- M5.Lcd.fillScreen(GREEN);
- M5.Lcd.setCursor(0, 40, 4);
- M5.Lcd.setTextColor(BLACK, GREEN);
- M5.Lcd.print(" Wifi Connected!\n ");
- String gotip = WiFi.localIP().toString(); // m5デバイスのIPアドレス
- M5.Lcd.println(gotip);
- delay(1500);
- M5.Beep.mute();
-}
-
-void loop() {
-}
- |
Wifi接続するだけでは、あまり意味がないので、Telnetサーバを起動する例を リスト 15 に示します。
-シリアルモニタを開いて、IPアドレス(192.168.xxx.xxx)を確認したら、ターミナル(コマンドプロンプト)で、telnet 192.168.xxx.xxx
と入力して、接続します。(Windowsでは https://www.imamura.biz/blog/27493 を参照し、telnetを有効にしてください。)
-telnet から文字を入力すると、シリアルモニタに表示されます。
-逆に、シリアルモニタから文字を入力すると、Telnet接続しているターミナルに、文字が表示されます。
-WiFiServer server(23)
で、23番ポートで待ち受けるサーバを、作成しています。
-ちなみに、WiFiMulti
は、複数のアクセスポイントに対して、Wifi接続を試みることができる機能(クラス)です。ただし、最終的に繋がるのは1つのアクセスポイントになります。
注釈
-Telnet接続を切断するときは、まずControlキーをおしながら ]
をおしてください。プロンプトに telnet>
と表示されますので、quit
と打ち込むと終了します。 Escape character is '^]'.
の ^
は、Controlキーのことです。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 80 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 90 - 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - 99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 | // オリジナルのWifiTelnetToSerial を、改変しました。
-/*
- WiFiTelnetToSerial - Example Transparent UART to Telnet Server for ESP32
-
- Copyright (c) 2017 Hristo Gochkov. All rights reserved.
- This file is part of the ESP32 WiFi library for Arduino environment.
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-#include <WiFi.h>
-#include <WiFiMulti.h>
-
-WiFiMulti wifiMulti;
-
-//how many clients should be able to telnet to this ESP32
-#define MAX_SRV_CLIENTS 3
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-WiFiServer server(23);
-WiFiClient serverClients[MAX_SRV_CLIENTS];
-
-void setup() {
- Serial.begin(115200);
- Serial.println("\nConnecting");
-
- wifiMulti.addAP(ssid, password);
- // wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2");
- // wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3");
-
- Serial.println("Connecting Wifi ");
- for (int loops = 10; loops > 0; loops--) {
- if (wifiMulti.run() == WL_CONNECTED) {
- Serial.println("");
- Serial.print("WiFi connected ");
- Serial.print("IP address: ");
- Serial.println(WiFi.localIP());
- break;
- }
- else {
- Serial.println(loops);
- delay(1000);
- }
- }
- if (wifiMulti.run() != WL_CONNECTED) {
- Serial.println("WiFi connect failed");
- delay(1000);
- ESP.restart();
- }
-
- //start UART and the server
- // Serial2.begin(9600);
- server.begin();
- server.setNoDelay(true);
-
- Serial.print("Ready! Use 'telnet ");
- Serial.print(WiFi.localIP());
- Serial.println(" 23' to connect");
-}
-
-void loop() {
- uint8_t i;
- if (wifiMulti.run() == WL_CONNECTED) {
- //check if there are any new clients
- if (server.hasClient()) {
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- //find free/disconnected spot
- if (!serverClients[i] || !serverClients[i].connected()) {
- if (serverClients[i]) serverClients[i].stop();
- serverClients[i] = server.available();
- if (!serverClients[i]) Serial.println("available broken");
- Serial.print("New client: ");
- Serial.print(i); Serial.print(' ');
- Serial.println(serverClients[i].remoteIP());
- break;
- }
- }
- if (i >= MAX_SRV_CLIENTS) {
- //no free/disconnected spot so reject
- server.available().stop();
- }
- }
- //check clients for data
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i] && serverClients[i].connected()) {
- if (serverClients[i].available()) {
- //get data from the telnet client and push it to the UART
- while (serverClients[i].available()) Serial.write(serverClients[i].read());
- }
- }
- else {
- if (serverClients[i]) {
- serverClients[i].stop();
- }
- }
- }
- //check ==UART== => Serial for data
- if (Serial.available()) {
- size_t len = Serial.available();
- uint8_t sbuf[len];
- Serial.readBytes(sbuf, len);
- //push UART data to all connected telnet clients
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i] && serverClients[i].connected()) {
- serverClients[i].write(sbuf, len);
- delay(1);
- }
- }
- }
- }
- else {
- Serial.println("WiFi not connected!");
- for (i = 0; i < MAX_SRV_CLIENTS; i++) {
- if (serverClients[i]) serverClients[i].stop();
- }
- delay(1000);
- }
-}
- |
M5StickCPlusには、システム時間(localTime)と、RTC(リアルタイムクロック:時計の機能を備えたICのこと)の2種類の時計があります。システム時間は、システムリセット(再起動)のたびに、時刻もリセットされますが、後者のRTCはリセットされません。
-リスト 16 に、NTPサーバを使ってシステム時間の修正をしたのち、システム時間を1秒ごとに取得して、シリアルモニタに表示する例を示します。こちらは、M5のライブラリは不要です。configTime()でNTPサーバを設定しておくと、1時間に1回、NTPサーバに接続して、時刻修正します。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 | #include <WiFi.h>
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-void setup() {
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- Serial.print(".");
- }
-// char* ntpserver = "ntp.nict.jp"; // 学内のNetworkを利用するときは、10.64.7.184 にする
- char* ntpserver = "192.168.11.11"; // 学内のNetworkを利用するときは、10.64.7.184 にする
- configTime(9 * 3600, 0, ntpserver);//GMTとの時差(秒) が9*3600, サマータイムで進める時間(秒)が0
-}
-
-void loop() {
- struct tm localTime;
- char buf[30];
- getLocalTime(&localTime);
- sprintf(buf, ">> %04d/%02d/%02d %02d:%02d:%02d",
- localTime.tm_year + 1900,
- localTime.tm_mon + 1,
- localTime.tm_mday,
- localTime.tm_hour,
- localTime.tm_min,
- localTime.tm_sec
- );
- Serial.println(buf);
- delay(1000);
-}
- |
警告
-configTime() を行わない状況で、システム時間(localTime)を取得しようとすると、取得に数秒ほど時間がかかります。
-リスト 17 は、RTCの時刻を表示するサンプルです。なお、5行目で USE_NTP
に 1 が設定してあれば、RTCに時刻を設定します。常時Wifiネットワークに接続できない場合は、RTCを利用することが望ましいです。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-#include <WiFi.h>
-// #include "time.h"
-
-#define USE_NTP 1 // NTPからRTCに時刻設定するなら1
-
-void setRTCfromLT(struct tm lt) {
- RTC_DateTypeDef DateStruct;
- DateStruct.Year = lt.tm_year + 1900;
- DateStruct.Month = lt.tm_mon + 1;
- DateStruct.Date = lt.tm_mday;
- DateStruct.WeekDay = lt.tm_wday;
- M5.Rtc.SetData(&DateStruct);
-
- RTC_TimeTypeDef TimeStruct;
- TimeStruct.Hours = lt.tm_hour;
- TimeStruct.Minutes = lt.tm_min;
- TimeStruct.Seconds = lt.tm_sec+1;
- M5.Rtc.SetTime(&TimeStruct);
-}
-
-void getRTC(char* buf) {
- RTC_DateTypeDef DateStruct;
- RTC_TimeTypeDef TimeStruct;
- M5.Rtc.GetData(&DateStruct);
- M5.Rtc.GetTime(&TimeStruct);
- sprintf(buf, "%04d/%02d/%02d %02d:%02d:%02d",
- DateStruct.Year, DateStruct.Month, DateStruct.Date,
- TimeStruct.Hours, TimeStruct.Minutes, TimeStruct.Seconds
- );
-}
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- Serial.begin(115200);
-
- if (USE_NTP) {
- const char* ssid = "miura2g";
- const char* password = "jikken2022";
- const char* ntpserver = "192.168.11.11"; // or ntp.nict.jp"; // or 10.64.7.184 for CIT-ap1x
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- Serial.print(".");
- }
- configTime(9 * 3600, 0, ntpserver);
-
- struct tm localTime;
- while (localTime.tm_year < 80) {
- getLocalTime(&localTime); delay(50);
- }
- setRTCfromLT(localTime);
- }
-}
-
-void loop() {
- char buf[30];
- getRTC(buf); // bufに、日時文字列を書き込む
- Serial.println(buf);
- M5.Lcd.fillScreen(BLUE);
- M5.Lcd.setCursor(0, 50, 4);
- M5.Lcd.println(buf);
- delay(1000);
-}
- |
注釈
-RTCに一旦時刻を設定しておくと、初期状態で書き込まれているプログラムFactoryTest の「BMP8563 RTC Time」でも、その時刻が表示されるようになります。
-リスト 18 は、HTTP通信で天気予報Web APIに接続するサンプルです。HTTPClientクラスを用いると、ブラウザでURLを指定してWebページを開くように、WebサーバにGETメソッドやPOSTメソッドでリクエストを送信して、ステータスコードやレスポンスを取得することができます。このサンプルでは、シリアルコンソールに、天気予報をJSON形式で表示します。JSON(ジェイソン)とは、Javascriptのオブジェクトの形式でデータを表現する記法です。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <WiFi.h>
-#include <HTTPClient.h> // ステータスコードの定義もここにある
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-// 天気予報API https://weather.tsukumijima.net/ から、千葉の天気を取得
-const char* weatherapi_url = "http://weather.tsukumijima.net/api/forecast/city/120010";
-
-void setup() {
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- delay(50);
- Serial.print(".");
- }
- delay(1000);
-
- HTTPClient http; // クライアント作成
- http.begin(weatherapi_url); // HTTPでサーバに接続
- int httpCode = http.GET(); // ステータスコードを取得
- if (httpCode > 0) {
- Serial.println(httpCode);
- if (httpCode == HTTP_CODE_OK) { // ステータスコードが「成功」(200) なら
- String payload = http.getString();
- Serial.println(payload);
- }
- }
- http.end();
-}
-
-void loop() {
-}
- |
警告
-https (SSL) 通信でPOSTメソッドで送信する場合は、付録→LINE Notify (リスト 32)を参考にしてください。以前は「スケッチ例→HTTPClient→BasicHttpsClient を参照して、WiFiClientSecure クラスを使用してください。」と書いていましたが、WifiClientSecureは必要ありません。
-HTTP通信で、サーバにデータを送信して格納したいとおもっても、適当なサーバを準備するのは手間がかかることがあります。
-Google Apps Scriptを用いると、HTTP通信で Google Spreadsheet にデータを書き込んだり、読み取ったりするWebサービスを作成し、WebAPIとして公開することができます。
-(Google Spreadsheetのメニューで) 拡張機能→Apps Script または、ツール→スクリプトエディタ で、リスト 19 を「コード.gs」に書き込みます。14行目で「シート1」の一番下の行に、配列array の要素を追加します。18行目のgetRange(1,3).getValue()は、スプレッドシートのC1(3列1行)の値を取得しています。ここに「=average(C2:C200)」のようにしておくと、データの平均値を取得することもできます。
-作成した「コード.gs」について、「公開」→「ウェブアプリケーションとして導入...」で、Webアプリとして公開できます。(なお、「新しいエディタ」では表示が異なるため、できない可能性があります。)
-作成できたかどうかをパソコンから確認するには、コマンドラインから、以下のように入力します(ただし、curlが必要です。val1=10 と val2=20 のあいだは&記号ですので、シェルでバックグラウンド処理されないように、URLをシングルクォートで囲っています。-L (--location)は、リダイレクト先にリクエストを発行するcurlのオプションです。)
-curl -L 'https://script.google.com/macros/s/XxXxXxXxXx/exec?val1=10&val2=20'
-
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 | function doGet(e) {
- var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
- var sheet = spreadsheet.getSheetByName('シート1');
- var now = new Date();
- var array = [];
- array.push(now);
-
- for(var k in e['parameter']) {
- array.push(k);
- array.push(e['parameter'][k]);
- }
- var params = JSON.stringify(e);
- array.push(params);
- sheet.appendRow( array );
-
- var lastRow = sheet.getLastRow();
-
- var output = ContentService.createTextOutput(sheet.getRange(1,3).getValue()+" "+lastRow);
- output.setMimeType(ContentService.MimeType.TEXT);
- return output;
-}
- |
警告
-doGet関数の返却値は、本来はHTTPのレスポンスとして受け取れるのですが、現状の HTTPClient
ではリダイレクトをうまく処理できない?ため、Google App Scriptの出力を受け取れない可能性があります。
すこし長いですが、リスト 20 は、80番ポートでHTTPでの通信を待ち受け(listenし)て、クライアントからの接続情報(ヘッダ情報)を返すWebサーバのシンプルな例です。クライアント(ブラウザ)からのリクエスト行のうち、 GET
または POST
ではじまる行があれば、変数 meth
に格納します。つまり、変数 meth
には、ブラウザで発行したリクエストのURLが含まれることになります。(methはmethodの略。)POSTメソッドで送信されていれば、リクエストボディに記述されたデータを変数 post
に格納します。 クライアント(ブラウザ)に返す「レスポンス」は、 client.println()
で送信します。最後に、client.stop()
で、サーバ側から接続を切断します。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 | #include <WiFi.h>
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-WiFiServer server(80);
-
-void setup() {
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- delay(50);
- Serial.print(".");
- }
- String ip = WiFi.localIP().toString(); // m5デバイスのIPアドレス
- Serial.printf("\nopen http://%s\n\n", ip.c_str() );
-
- server.begin(); // Webサーバを開始
-}
-
-void loop() {
- WiFiClient client = server.available();
- if (client) {
- String req = "" ;
- String tmp = "" , meth = "" ;
- while (client.connected()) { // loop while the client's connected
- if (client.available()) { // if there's bytes to read from the client,
- char c = client.read(); // read a byte, then
- req += c;
- if (c == '\n') { // if the byte is a newline character
- if (tmp.length() == 0) { // end of request, break while loop
- break;
- } else { //まだ継続
- if (tmp.startsWith("GET ") || tmp.startsWith("POST ") ) {
- meth = tmp;
- }
- tmp = "";
- }
- } else if (c != '\r') { // if you got anything else but a carriage return character,
- tmp += c; // add it to the end of the currentLine
- }
- }
- } // end of while
-
- Serial.println(meth);
- if ( meth.startsWith("GET /") ) {
- client.println("HTTP/1.1 200 OK"); // header (with response code)
- client.println("Content-Type:text/plain");
- client.println(""); // HTTPでは、header と body の区切りは改行
- client.println(meth);
- client.println("-- request --");
- client.println(req);
- }
-
- if ( meth.startsWith("POST ") ) {
- String post = "";
- char buf[257];
- int n;
- while ((n = client.available()) > 0) {
- if (n < 256) {
- client.readBytes(buf, n) ;
- buf[n] = 0 ;
- } else {
- client.readBytes(buf, 256) ;
- buf[256] = 0 ;
- }
- }
- post += buf ;
-
- client.println("HTTP/1.1 200 OK");
- client.println("Content-Type:text/plain");
- client.println(""); // HTTPでは、header と body の区切りは改行
- client.println(meth);
- client.println("-- request --");
- client.println(req);
- client.println("-- post data --");
- client.println(post);
- }
- // close the connection:
- client.stop();
- Serial.println(" --- Client Disconnected.");
- }
- delay(100);
-}
- |
センサデータを返すだけなら問題ありませんが、クライアントからのデータを GET / POST で受信して処理する場合は、 key1=val1&key2=val2
のような文字列を要素に分解する必要がでてきます。あまり深入りしませんが、正規表現で文字列を照合・抽出する Regexp
や、抽出した結果をハッシュ/辞書として保存する Dictionary
ライブラリを導入すると、複雑なリクエストやデータを扱いやすくなるでしょう。
-リスト 21 に、RGBの色指定文字列などのリクエスト文字列をパースして辞書に追加するプログラムの断片を示します。注意:このプログラム( リスト 21 )は、単体では動作しません
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 | #include <Regexp.h>
-#include <Dictionary.h>
-
-Dictionary *dict = new Dictionary(); // 辞書/ハッシュ。キー文字列→値 を保持するデータ構造
-
-void match_callback (const char * match, // matching string (not null-terminated)
- const unsigned int length, // length of matching string
- const MatchState & ms) // MatchState in use (to get captures)
-{
- char k [10]; // size must be large enough to hold captures
- char v [10]; // size must be large enough to hold captures
- ms.GetCapture(k, 0);
- ms.GetCapture(v, 1);
- dict->insert(k, v); // 辞書に追加 (たとえば、 red→120 を追加)
-} // end of match_callback
-
-// たとえば、*cbuf = "red=120&green=255&blue=9" のような文字列を想定する
-void param2dict(char *cbuf){
- MatchState ms (cbuf); //正規表現マッチャーの作成
- ms.GlobalMatch ("([a-z]+)=([0-9]+)", match_callback); // (key)=(value) で複数回マッチングする。match_callback は別関数。
- int r = dict->search("red").toInt(); // 辞書 dict
- int g = dict->search("green").toInt();
- int b = dict->search("blue").toInt();
- int32_t bgcolor = (int(r * 31 / 255) << 11) | (int(g * 63 / 255) << 5) | (int(b * 31 / 255));
-}
- |
MQTT(Message Queue Telemetry Transport) は、センサデータをデバイス間で共有・流通させるときなどに使われる、軽量のメッセージ送受信プロトコルです。 -ここで、「軽量」とは、HTTPに比べて、ヘッダ部分のデータが少ない、という意味です。 -MQTTでは、サーバのことを「ブローカ」と呼びます。ここでは、データを送信するPublisherと、データを受信するSubscriberの2つのデバイスと、ブローカの3つの構成要素で説明します。
-Publisherは、ブローカに接続しデータを送信します。このとき、 「トピック」 と呼ばれる、データの登録先を文字列で指定します。また、retainデータとして送信するかどうかも指定します。retainとは「保持・維持」の意味で、最後に送ったデータをブローカに残しておきたい場合、rateinデータとします。 -Subscriberは、ブローカに接続し、トピックをサブスクライブ(購読)します。このとき、トピックに書き込まれているretainデータがあれば、最初にそのデータを受信します。retainデータがなければ、Publisherが新しいデータをトピックに送信したタイミングで、データを受信します。 -このような通信手段(プロトコル)を、パブリッシュ/サブスクライブモデル と呼びます。参考サイト: -IoT初心者向け!「MQTT」について簡単にまとめてみる
-リスト 22 は、MQTT Publisherのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 office/temp
というトピックにデータ(シリアルコンソールで送信した文字列)を書き込みます。 パスワードはここには書けませんので、講義システム(三浦担当講義用)を参照してください。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 -70 | // MQTT Publisher example
-//#include <M5StickCPlus.h>
-#include <WiFi.h>
-// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★
-#include <PubSubClient.h>
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-const char* server = "192.168.11.11"; // "mqtt.istlab.info";
-const int port = 1883; // 注:学内ネットワークはポート制限あり。
-const char* pubTopic = "office/temp"; //"ex1/groupXX/sensor";のようにして、他の班とかぶらないようにすること。
-const char* mquser = "ex1";
-//const char* mqpass = "***PASSWORD***"; // 講義システム(三浦担当講義用)を参照すること。
-const char* mqpass = ""; // 講義システム(三浦担当講義用)を参照すること。
-WiFiClient wifiClient;
-char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい
-PubSubClient mqttClient(wifiClient); // MQTT Client
-
-void setup() {
- // M5.begin();
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- Serial.print(".");
- delay(200);
- }
- Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス
- // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる
- // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい)
- // uint8_t mac[6];
- // esp_read_mac(mac, ESP_MAC_WIFI_STA);
- // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X",
- // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
- mqttClient.setServer(server, port);
-
- if (!mqttClient.connected()) {
- Serial.println("Try (re)connecting...");
- reconnect();
- }
-}
-
-void loop() {
- // シリアルコンソールから書き込みがあれば, publishする
- byte mbuf[100]; int pos = 0;
- while (Serial.available()) { // ノンブロッキング
- mbuf[pos] = Serial.read();
- pos++;
- }
- if (pos > 0) {
- mbuf[pos-1] = 0; //改行をNULLに置き換える
- Serial.println((char*)mbuf);
- // ブローカにデータを送信する。最後の false を true にすると、retained になる。
- bool ret = mqttClient.publish(pubTopic, mbuf, pos-1, false);
- if (!ret){
- Serial.println("publish failed.");
- }
- }
- delay(10);
-}
-
-void reconnect() {
- while (!mqttClient.connected()) {
- if (mqttClient.connect(clientid, mquser, mqpass)) {
- Serial.println("Connected to MQTT Broker.");
- } else {
- Serial.printf("Connect Failed. state=%d", mqttClient.state());
- }
- }
-}
- |
警告
-学内ネットワークからは、ポート制限のため、実験用ブローカ(mqtt.istlab.info) に接続できません。実験室に仮設するWifi基地局を利用してください。
-リスト 23 は、MQTT Subscriberのサンプルです。実験用ブローカ(mqtt.istlab.info)に接続して、 office/temp
というトピックを購読します。 パスワードはここには書けませんので、講義システム(三浦担当講義用)を参照してください。 JSON形式のデータを処理するときは、ArduinoJsonをつかってパージング/deserialize すると便利です(78行目以降にサンプルがあります)。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 | // MQTT Subscriber example
-// #include <M5StickCPlus.h>
-#include <WiFi.h>
-// ライブラリで PubSubClient をいれておく ★★★ 重要 ★★★
-#include <PubSubClient.h>
-// ライブラリで ArduinoJson v6.xをいれておく ★★★ 重要 ★★★
-// (注意:Arduino_Json v0.1.0 は別物)
-#include <ArduinoJson.h>
-
-const char* ssid = "miura2g";
-const char* password = "jikken2022";
-
-const char* server = "192.168.11.11"; // "mqtt.istlab.info";
-const int port = 1883; // 注:学内ネットワークはポート制限あり。
-const char* pubTopic = "office/temp"; // 例: ex1/groupXX/sensor
-const char* mquser = "ex1";
-const char* mqpass = "***PASSWORD***";
-WiFiClient wifiClient;
-char* clientid = "m5stickc01_00000001"; //デバイス個別に設定すればなんでもよい
-PubSubClient mqttClient(wifiClient); // MQTT Client
-
-void setup() {
-// M5.begin();
- Serial.begin(115200);
- WiFi.begin(ssid, password);
- while (WiFi.status() != WL_CONNECTED) { // 接続中...
- Serial.print(".");
- delay(200);
- }
- Serial.println( WiFi.localIP().toString() ); //取得したIPアドレス
- // 参考:WiFiデバイスのMACアドレスを取得し、clientid として用いる
- // (18行目のclientidの定義を変更し、char clientid[20]とするのがのぞましい)
- // uint8_t mac[6];
- // esp_read_mac(mac, ESP_MAC_WIFI_STA);
- // sprintf(clientid, "%02X:%02X:%02X:%02X:%02X:%02X",
- // mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
- mqttClient.setServer(server, port);
- mqttClient.setCallback(callback_on_subscribe);
-
- if (!mqttClient.connected()) {
- Serial.println("Try (re)connecting...");
- reconnect();
- }
- mqttClient.subscribe(pubTopic);
-
-}
-
-void loop() {
-
- mqttClient.loop(); // データがpublishされたら、callback_on_subscribe が呼ばれる
-
- delay(100);
-}
-
-void reconnect() {
- while (!mqttClient.connected()) {
- if (mqttClient.connect(clientid, mquser, mqpass)) {
- Serial.println("Connected to MQTT Broker.");
- } else {
- Serial.printf("Connect Failed. state=%d", mqttClient.state());
- }
- }
-}
-
-// データがPublishされたら、ここが実行される。(39行目でコールバック関数を設定しているため)
-void callback_on_subscribe(char* topic, byte* payload, unsigned int len) {
- char buf[100];
- Serial.print("Message arrived [");
- Serial.print(topic);
- Serial.print("] ");
- for (int i = 0; i < len ; i++) {
- buf[i] = (char)payload[i];
- }
- buf[len] = 0;
- Serial.println(buf);
- return;
- // 参考:JSON Parsing example
- // StaticJsonDocument<200> sjdoc;
- // deserializeJson(sjdoc, buf);
- // int intval = sjdoc["intval"];
- // const char* str = sjdoc["string"];
-}
- |
サブスクライブするときのトピック名には、ワイルドカードが指定できます。例えば、 office/+
-と指定すると、 office/temp
にも office/humid
にもマッチします。参考:MQTT の仕様
mosquitto は、オープンソースのMQTT Broker/Client 実装の1つです。参考までに、mosquitto クライアントを使用するコマンド例を示します。:
-#(パブリッシュ。retainなし: -m "メッセージ" )
- mosquitto_pub -h mqtt.istlab.info -u ex1 -P PASS -t office/temp -m "data or message"
-#(パブリッシュ。retainあり: -r )
- mosquitto_pub -h mqtt.istlab.info -u ex1 -P PASS -t office/temp -m "data or message" -r
-#(retainデータを削除。-n : send a null (zero length) message.)
- mosquitto_pub -h mqtt.istlab.info -u ex1 -P PASS -t office/temp -n -r
-#(サブスクライブ)
- mosquitto_sub -h mqtt.istlab.info -u ex1 -P PASS -t office/temp
-
3つ目の例に示すように、長さ0のretainデータを送信すると、retainデータを削除できます。
-注釈
-サンプルでは文字列(ASCII)データを送受信していますが、値をbyte配列・バイナリで送受信することもできます。
-「Serial通信」では、開発用PCのシリアルコンソールをつかって、USB接続を介して、文字列を送受信しました。 -「Wifi接続」のTelnetサーバでは、TCP/IP通信上でのTelnet接続を介して、文字列を送受信しました。
-ここでは、Bluetoothを用いて、上記と同様、2台のデバイス間で文字列を送受信する例を示します。Bluetoth では、機器同士は同一の「プロファイル」という通信方式に対応している必要があります。Serial Protocol Profile は、Bluetooth無線通信で仮想シリアル接続を可能にするプロファイルです。
-注釈
-基本的に ESP32同士をBluetoothシリアルでつないでみる と同じです。その他、一般的なBluetoothとBLEについての解説は、ESP32による近距離無線通信の実験② BLE通信 が参考になります。
-リスト 24 を、1台目のM5StickCPlusで実行し、BluetoothのMACアドレスを調べます。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-#include "BluetoothSerial.h"
-
-BluetoothSerial SerialBT;
-
-const char* dname = "BT_Serial_00"; // Slave device name
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.fillScreen(YELLOW);
- M5.Lcd.setTextColor(BLACK, YELLOW);
- M5.Lcd.setCursor(0, 0, 1);
- M5.Lcd.setTextSize(2);
-
- Serial.begin(115200);
- SerialBT.begin(dname); //Bluetooth device name
- Serial.println("The device started, now you can pair it with bluetooth!");
-
- uint8_t macBT[6];
- esp_read_mac(macBT, ESP_MAC_BT);
- char mac[20];
- sprintf(mac, "%02X:%02X:%02X:%02X:%02X:%02X", macBT[0], macBT[1], macBT[2], macBT[3], macBT[4], macBT[5]);
- Serial.println(mac);
- M5.Lcd.println(mac);
-
-}
-
-int line = 0;
-void loop() {
- char c;
- if (Serial.available()) {
- SerialBT.write(c = Serial.read());
- Serial.printf("read:%c\n", c);
- }
- if (SerialBT.available()) {
- Serial.write(c = SerialBT.read());
- SerialBT.write(c + 0);
- M5.Lcd.print(c);
- if (c == 0xa) line++;
- if (line > 7) {
- M5.Lcd.fillScreen(YELLOW); M5.Lcd.setCursor(0, 0, 1);
- line = 0;
- }
- }
-
- M5.update();
- if (M5.BtnA.wasReleasefor(1000) ) {
- SerialBT.println("[A] was Pressed longer than 1s");
- } else if (M5.BtnA.wasReleased()) {
- SerialBT.println("[A] was Pressed");
- } else if (M5.BtnB.wasReleasefor(1000) ) {
- SerialBT.println("[B] was Pressed longer than 1s");
- } else if (M5.BtnB.wasReleased()) {
- SerialBT.println("[B] was Pressed");
- } else if (M5.Axp.GetBtnPress() == 2) {
- SerialBT.println("[Power] was Pressed");
- }
-
- delay(20);
-}
- |
リスト 25 を、2台目のM5StickCPlusで実行します。このとき、ハイライトした行のところに、(1)で調べたMACアドレスを指定します。少し時間がかかりますが、デバイス名で接続先を指定することもできます。起動するときは、スレーブ側を先に起動しておき、あとでマスタ側を起動してください。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 - 67 - 68 - 69 - 70 - 71 - 72 - 73 - 74 - 75 - 76 - 77 - 78 - 79 - 80 - 81 - 82 - 83 - 84 - 85 - 86 - 87 - 88 - 89 - 90 - 91 - 92 - 93 - 94 - 95 - 96 - 97 - 98 - 99 -100 -101 -102 -103 -104 | #include <M5StickCPlus.h>
-#include <BluetoothSerial.h>
-
-BluetoothSerial SerialBT;
-
-bool willConnect = true;
-bool connected;
-
-const char* dname = "BT_Serial_00"; // Slave device name
-
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(3);
- M5.Lcd.fillScreen(BLUE);
-
- M5.Lcd.setTextColor(BLACK, CYAN);
- M5.Lcd.setCursor(0, 0, 1);
- M5.Lcd.setTextSize(2);
-
- Serial.begin(115200);
- SerialBT.begin("BT_Serial_01", true);
- Serial.println("The device started in master mode, make sure remote BT device is on!");
-
- // connect(address) is fast (upto 10 secs max), connect(name) is slow (upto 30 secs max) as it needs
- // to resolve name to address first, but it allows to connect to different devices with the same name.
- // Set CoreDebugLevel to Info to view devices bluetooth address and device names
- if (false) {
- connected = SerialBT.connect(dname);
- } else {
- uint8_t address[6] = {0x24, 0xA1, 0x60, 0x47, 0x84, 0x4E}; // MACアドレスが 24:A1:60:47:84:4E のとき
- connected = SerialBT.connect(address);
- }
- if (connected) {
- Serial.println("Connected Succesfully!");
- M5.Beep.tone(2000, 1000);
- M5.Lcd.fillScreen(CYAN);
- }
- // disconnect() may take upto 10 secs max
- // if (SerialBT.disconnect()) {
- // connected = false;
- // Serial.println("Disconnected Succesfully!");
- // }
- // this would reconnect to the name(will use address, if resolved) or address used with connect(name/address).
- //SerialBT.connect();
-}
-
-void connectOrDisconnect(bool willCon) {
- if (willCon && connected) return;
- if (willCon) {
- if (connected) {
- Serial.println("Connected Succesfully!");
- M5.Beep.tone(2000, 1000);
- M5.Lcd.fillScreen(CYAN);
- } else {
- while (!SerialBT.connected(10000)) {
- Serial.println("Failed to connect. Make sure remote device is available and in range, then restart app.");
- M5.Lcd.fillScreen(PURPLE);
- }
- }
- } else {
- if ( SerialBT.disconnect() ) {
- connected = false;
- Serial.println("Disconnected Succesfully!");
- M5.Lcd.fillScreen(BLUE);
- }
- }
-}
-int line = 0;
-void loop() {
- connectOrDisconnect( willConnect );
-
- char c;
- if (Serial.available()) {
- SerialBT.write(c = Serial.read());
- Serial.printf("read:%c\n", c);
- }
- if (SerialBT.available()) {
- Serial.write(c = SerialBT.read());
- M5.Lcd.print(c);
- if (c == 0xa) line++;
- if (line > 7) {
- M5.Lcd.fillScreen(CYAN); M5.Lcd.setCursor(0, 0, 1);
- line = 0;
- }
- }
-
- M5.update(); M5.Beep.update();
- if (M5.BtnA.wasReleasefor(1000) ) {
- SerialBT.println("[A] was Pressed longer than 1s");
- } else if (M5.BtnA.wasReleased()) {
- SerialBT.println("[A] was Pressed");
- } else if (M5.BtnB.wasReleasefor(1000) ) {
- SerialBT.println("[B] was Pressed longer than 1s");
- if (SerialBT.disconnect()) {
- connected = false;
- M5.Lcd.fillScreen(PURPLE);
- }
- } else if (M5.BtnB.wasReleased()) {
- SerialBT.println("[B] was Pressed");
- } else if (M5.Axp.GetBtnPress() == 2) {
- SerialBT.println("[Power] was Pressed");
- }
- delay(20);
-}
- |
BLEHIDDeviceを用いると、Human Interface Device(HID) Profileを導入して、マウスやキーボードの代用品が作成できます。(詳細は省略します。)
-再起動をすると、プログラムがリセットされて、通常の変数や配列データは消えてしまいます。Preferenceを用いると、不揮発性のフラッシュ領域を使ってデータを保存・復元することができます。
- -ESP.restart()
で、再起動します。
M5.Axp.Write1Byte(0x32, M5.Axp.Read8bit(0x32) | 0x80);
で、電源OFFします。
setCpuFrequencyMhz(240)
で、CPUのクロック数を変更できます。設定できる値は、240、160、80、40、20、10ですが、無線通信するなら80以上を設定する必要があります。
M5.Axp.ScreenBreath(8)
で、画面の明るさを調整できます。8〜15が標準的ですが、7でも微かに読めます。
リスト 26 に、Preferenceと電源制御のサンプルを示します。Aボタンでcountを増やし、Aボタン長押しでcountをリセットします。Bボタンで再起動、電源ボタンで電源OFFします。
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | #include <M5StickCPlus.h>
-#include <Preferences.h>
-
-Preferences pref;
-
-int count = 0;
-void setup() {
- M5.begin();
- M5.Lcd.setRotation(0); //縦型
- M5.Lcd.fillScreen(CYAN);
- M5.Lcd.setTextSize(2);
- loadCount(&count);
- M5.Beep.tone(2000, 500);
- M5.Lcd.printf("count = %d\n", count);
-}
-
-void loop() {
- M5.Beep.update();
- M5.update();
- if (M5.BtnA.wasReleasefor(1000) ) { // Aボタン長押し
- count = 0;
- saveCount(&count);
- M5.Beep.tone(1200, 300);
- M5.Lcd.printf("count = %d\n", count);
- } else if (M5.BtnA.wasReleased()) { // Aボタン押し
- count++ ;
- saveCount(&count);
- M5.Beep.tone(2000, 300);
- M5.Lcd.printf("count = %d\n", count);
- } else if (M5.BtnB.wasReleased()) { // Bボタン押し
- reboot();
- } else if (M5.Axp.GetBtnPress() == 2) { // 電源ボタン押し
- poweroff();
- }
- delay(50);
-}
-
-void loadCount(int *c) {
- pref.begin("mydata", false);
- *c = pref.getInt("count");
- pref.end();
-}
-void saveCount(int *c) {
- pref.begin("mydata", false);
- pref.putInt("count", *c);
- pref.end();
-}
-
-void poweroff() {
- M5.Axp.Write1Byte(0x32, M5.Axp.Read8bit(0x32) | 0x80);//PowerOff
-}
-
-void reboot() {
- ESP.restart();
-}
- |
1週目で学んだことを活かして、組み合わせてみましょう。
-Arduino IDEでは、プログラムを複数のファイル(たとえば、main.ino / sub.ino / hoge.cpp / hoge.h ) に分割して記述することができます。複数ファイルに分割することで、関数定義を機能別にまとめることができ、管理しやすくなります。
Arduino IDEでは、プログラムを構成する、複数のファイル(スケッチブック)を、1つのフォルダに入れて管理します。(スケッチブックのことを、他のIDEでは「プロジェクト」と呼ぶ場合もある)
スケッチブックに別のファイル(hogehoge.ino) を追加するには、右上にあるシリアルモニタをひらくアイコンの、下の「▼」ボタンからメニューをひらき、「新規タブ」を選択し、ファイル名(拡張子.ino をのぞいた、hogehogeの部分のみ)を入力します。
スケッチブックをコピーしたいときは、内包するフォルダごとコピーしてください。その際、フォルダ名と、メインのソースコードファイル名(拡張子以外の部分)は、一致している必要があります。
複数のファイルを置いたときの挙動について: ***.ino
ファイルの内容は、単純にメインのタブ(フォルダ名と同じinoファイル)にマージされます。***.cpp
や ***.c
という拡張子でファイルを作成した場合は、***.h
を作成する必要があります。参考:Properly using separate tabs with Arduino IDE
Git を利用すると、複数人で作業したファイルを統合しやすいです。
複数の機能を1つの loop()
にまとめようとすると、プログラムが複雑になります。タスクを用いると、 loop()
に相当する関数を複数定義し、並列に動作させることができます。
リスト 27 に、タスクを利用する例を示します。3つの異なるタスクを作成し、それぞれの関数内部で setup()
と loop()
に相当する処理を記述しています。
-引数の詳細については、非公式日本語リファレンス を参照してください。
-ここの例では、1つのファイルに記述していますが、タスクごとに別のファイルにすることもできます。 以下の例ではタスク生成時に、タスクハンドル TaskHandle_t
を設定しています。タスクハンドルは、タスクの一時停止(サスペンド)や、再開(レジューム)、削除のときにタスクを特定するために必要となります。
1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 -67 -68 -69 -70 | #include <M5StickCPlus.h>
-
-int interval_msec[] = { 333, 1000, 2000 }; // Led, Lcd, Beep
-TaskHandle_t tH[3];
-
-void ledTask(void *pvParam) {
- /** setup をここに書く **/
- portTickType lastTime;
- int PIN = 10;
- pinMode(PIN, OUTPUT); // PINのモード設定
- int highOrLow = 0;
- for (;;) {
- /** loop をここに書く **/
- lastTime = xTaskGetTickCount();
- vTaskDelayUntil(&lastTime, interval_msec[0] ); // 第2引数に、実行間隔ミリ秒を指定
- digitalWrite(PIN, highOrLow); // HIGH = 1, LOW = 0
- highOrLow = 1 - highOrLow; // HIGH <=> LOW を切り替える
- }
-}
-
-void lcdTask(void *pvParam) {
- /** setup をここに書く **/
- portTickType lastTime;
- M5.Lcd.setRotation(0);
- M5.Lcd.fillScreen(GREEN);
- M5.Lcd.setTextColor(WHITE, OLIVE);
- M5.Lcd.setTextSize(2);
- M5.Lcd.setCursor(0, 0);
- int count = 0;
- for (;;) {
- /** loop をここに書く **/
- M5.Lcd.printf("count=%d\n", count);
- count++;
- lastTime = xTaskGetTickCount();
- vTaskDelayUntil(&lastTime, interval_msec[1] ); // 第2引数に、実行間隔ミリ秒を指定
- if (count % 10 == 0) {
- M5.Lcd.fillScreen(GREEN);
- M5.Lcd.setCursor(0, 0);
- }
- }
-}
-
-void beepTask(void *pvParam) {
- /** setup をここに書く **/
- portTickType lastTime;
- int f[8] = { 262, 294, 330, 349, 392, 440, 494, 524 };
- int note = 0;
- for (;;) {
- /** loop をここに書く **/
- lastTime = xTaskGetTickCount(); // ここでの時刻を変数に保存
- M5.Beep.tone( f[note] );
- delay(500); //0.5秒鳴らす
- M5.Beep.mute();
- note = (note+1)%8;
- vTaskDelayUntil(&lastTime, interval_msec[2] );
- // 途中の処理やdelayは含まず、「保存」時刻の2秒後まで待つ。
- }
-}
-
-void setup() {
- M5.begin();
-
- xTaskCreatePinnedToCore(ledTask , "LedT", 4096, NULL, 1, &tH[0], 1/*<= CoreNo.*/ );
- xTaskCreatePinnedToCore(lcdTask , "LcdT", 4096, NULL, 1, &tH[1], 1/*<= CoreNo.*/ );
- xTaskCreatePinnedToCore(beepTask,"BeepT", 4096, NULL, 1, &tH[2], 0/*<= CoreNo.*/ );
-}
-
-void loop() {
- delay(10);
-}
- |
注釈
- -タスク生成時に、引数を渡すこともできます。リスト 28 に、引数を渡す例を示します。(次で述べるミューテックスを使って、排他制御もしています。)
-1 - 2 - 3 - 4 - 5 - 6 - 7 - 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 | xSemaphoreHandle mutex; //ミューテックス(排他制御用)
-
-void withArgTask(void *pvParam) {
- int num = *(int*) pvParam; // 引数は、グローバル変数のアドレスをポインタで渡す
- BaseType_t mStatus;
- char* tsknm = pcTaskGetTaskName(NULL); //自タスク名を取得するならNULL、他タスク名を取得するならタスクハンドルを引数に指定する。
- while (1) {
- mStatus = xSemaphoreTake(mutex, 500); // ミューテックスを取得
- if (mStatus == pdPASS) {
- Serial.println("----");
- Serial.printf("[%s] ", tsknm );
- delay(500);
- for (int i = 1; i < 6; i++) {
- Serial.printf("%d ", i * num);
- delay(300);
- }
- delay(300);
- Serial.printf("done \n");
- delay(300);
- xSemaphoreGive(mutex); // ミューテックスを解放
- vTaskDelete(NULL); // 自タスクを削除する
- } else {
- delay(random(10,100)); //ミューテックスがとれなかったらランダムに待つ
- }
- }
-}
-
-int arg[] = {2, 3, 5, 7, 11} ;
-char tskname[5];
-
-void setup() {
- Serial.begin(115200);
- mutex = xSemaphoreCreateMutex(); // ミューテックス作成
-}
-
-void loop() {
- Serial.println("-------");
- if (mutex != NULL) { // ミューテックスの作成に成功していたら
- for (int i = 0; i < 5; i++) {
- sprintf(tskname, "x%d", arg[i]);
- xTaskCreatePinnedToCore(withArgTask, tskname, 4096, &arg[i], 1, NULL , 1);
- }
- }
- delay(20 * 1000); // 次のタスクの仕込みまで、20秒待つ
-}
- |
警告
-引数をアドレスで渡すとき、関数内で宣言したローカル変数は使えません。グローバルな変数を使用する必要があります。
-複数のタスクを並列動作させると、リソース(入出力や、メモリ)に複数のタスクが同時アクセスすることで意図しない動作を引き起こすことがあります。 -ミューテックス(mutex: mutual exclusion)を用いると、リソースに同時にアクセスするタスクを1つに限定することができます。これを「排他制御」と呼びます。
-リスト 28 の例では、ミューテックスをつかって、1つのタスクの動作(シリアルコンソールへの書き込み)が終わるまで、他のタスクが待つ例です。 -このように、常時動いているタスクに対して、一時停止したり、処理を制限したりするのがミューテックスの使い方です。 -(参考:ESP32のFreeRTOS入門 その6 セマフォとミューテックス )
-これに対して、セマフォは、基本的には待機・一時停止状態にあるタスクに対して、動作許可を与える用途で使用されます。 -動作許可を与える主体・タイミングとしては、他のタスクや、「割り込み(ISR: interrupt service routine)」からになります。 -ただし、バイナリセマフォを用いるより、RTOS Task Notifications -を用いたほうが、高速かつメモリ使用量を削減できるようです。
-バイナリセマフォは、タスク間またはタスクと割り込み間の同期に適しています。
バイナリセマフォとミューテックスは似ていますが、いくつか本質的な違いがあります。ミューテックスは優先度を継承する機構が備わっていますが、バイナリセマフォには備わっていません。
注釈
- -今回の実験では、Arduino IDEでのM5StickCPlusプログラミングを行ってきました。これまでArduino IDEでM5StickCPlusに書き込んできたプログラムは、FreeRTOS (RealTime OS) というRTOSの仕組みをつかって動作しています。 -いいかえると、ESP32プロセッサ上で、FreeRTOS プログラミングをしていたことになります。ちなみに、M5StickCPlusのような画面やブザー、センサがついていない ESP32プロセッサ開発ボード も販売されています。
-MCU RTOS習得(2020年版) http://happytech.jp/bRTOS.html
その他のRTOSには、T-Kernel や ThreadX があります。こちらも、限られた資源(メモリやプロセッサ)で、厳密な処理時間管理が行える仕組みが備わっています。
- -
\ - Sort by:\ - best rated\ - newest\ - oldest\ -
\ -\ -
Add a comment\ - (markup):
\ -``code``
, \ - code blocks:::
and an indented block after blank line