famibee/SKYNovel

View on GitHub
docs/dev.html

Summary

Maintainability
Test Coverage
<!doctype html><html ⚡ lang="ja">
<head>
    <meta charset="utf-8">
    <script async src="https://cdn.ampproject.org/v0.js"></script>
    <link rel="preload" href="https://fonts.gstatic.com/s/inconsolata/v17/QldKNThLqRwH-OJ1UHjlKGlZ5qhExfHw.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://fonts.gstatic.com/s/montserrat/v13/JTUSjIg1_i6t8kCHKm459WlhyyTh89Y.woff2" as="font" type="font/woff2" crossorigin>
    <link rel="preload" href="https://cdn.ampproject.org/rtv/011905140117570/v0/amp-auto-lightbox-0.1.js" as="script">
    <link rel="preload" href="https://fonts.googleapis.com/css?family=Inconsolata|Montserrat" as="style">
    <title>SKYNovel 開発者向け情報 Information for developers</title>
    <link rel="canonical" href="https://famibee.github.io/SKYNovel/dev.html"/>
    <meta name="description" content="SKYNovel 開発者向け情報 Information for developers"/>
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"/>
    <style amp-boilerplate>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style>
    <noscript><style amp-boilerplate>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
    <link href="https://fonts.googleapis.com/css?family=Inconsolata|Montserrat" rel="stylesheet">
    <style amp-custom>
        .ampstart-footer{background-color:#fff;color:#000;font-size:.75rem;padding-top:7rem;padding-bottom:7rem}
        .ampstart-footer .ampstart-icon{fill:#000}
        .ampstart-footer .ampstart-social-follow li:last-child{margin-right:0}

        .ampstart-headerbar{background-color:#ffffffc0;color:#000;z-index:999;box-shadow:0 0 5px 2px rgba(0,0,0,.1)}
        .ampstart-headerbar+:not(amp-sidebar),.ampstart-headerbar+amp-sidebar+*{margin-top:3.5rem}
        .ampstart-headerbar-nav .ampstart-nav-item{padding:0 1.5rem;background:0 0;opacity:.8}
        .ampstart-headerbar-nav{line-height:3.5rem}

/*! Bassplate | MIT License | http://github.com/basscss/bassplate *//*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:inherit;font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button;appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{display:inline-block;vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details,menu{display:block}summary{display:list-item}canvas{display:inline-block}[hidden],template{display:none}.h1{font-size:3rem}.h2{font-size:2rem}.h3{font-size:1.5rem}.h4{font-size:1.125rem}.h5{font-size:.875rem}.h6{font-size:.75rem}.font-family-inherit{font-family:inherit}.font-size-inherit{font-size:inherit}.text-decoration-none{text-decoration:none}.bold{font-weight:700}.regular{font-weight:400}.italic{font-style:italic}.caps{letter-spacing:.2em}.left-align{text-align:left}.center{text-align:center}.right-align{text-align:right}.justify{text-align:justify}.nowrap{white-space:nowrap}.break-word{word-wrap:break-word}.line-height-1{line-height:1rem}.line-height-2{line-height:1.125rem}.line-height-3{line-height:1.5rem}.line-height-4{line-height:2rem}.list-style-none{list-style:none}.underline{text-decoration:underline}.truncate{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-reset{list-style:none;padding-left:0}.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.table{display:table}.table-cell{display:table-cell}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.left{float:left}.right{float:right}.fit{max-width:100%}.max-width-1{max-width:24rem}.max-width-2{max-width:32rem}.max-width-3{max-width:48rem}.max-width-4{max-width:64rem}.border-box{box-sizing:border-box}.align-baseline{vertical-align:baseline}.align-top{vertical-align:top}.align-middle{vertical-align:middle}.align-bottom{vertical-align:bottom}.m0{margin:0}.mt0{margin-top:0}.mr0{margin-right:0}.mb0{margin-bottom:0}.ml0,.mx0{margin-left:0}.mx0{margin-right:0}.my0{margin-top:0;margin-bottom:0}.m1{margin:1rem}.mt1{margin-top:1rem}.mr1{margin-right:1rem}.mb1{margin-bottom:1rem}.ml1,.mx1{margin-left:1rem}.mx1{margin-right:1rem}.my1{margin-top:1rem;margin-bottom:1rem}.m2{margin:1.5rem}.mt2{margin-top:1.5rem}.mr2{margin-right:1.5rem}.mb2{margin-bottom:1.5rem}.ml2,.mx2{margin-left:1.5rem}.mx2{margin-right:1.5rem}.my2{margin-top:1.5rem;margin-bottom:1.5rem}.m3{margin:2rem}.mt3{margin-top:2rem}.mr3{margin-right:2rem}.mb3{margin-bottom:2rem}.ml3,.mx3{margin-left:2rem}.mx3{margin-right:2rem}.my3{margin-top:2rem;margin-bottom:2rem}.m4{margin:2.5rem}.mt4{margin-top:2.5rem}.mr4{margin-right:2.5rem}.mb4{margin-bottom:2.5rem}.ml4,.mx4{margin-left:2.5rem}.mx4{margin-right:2.5rem}.my4{margin-top:2.5rem;margin-bottom:2.5rem}.mxn1{margin-left:-1rem;margin-right:-1rem}.mxn2{margin-left:-1.5rem;margin-right:-1.5rem}.mxn3{margin-left:-2rem;margin-right:-2rem}.mxn4{margin-left:-2.5rem;margin-right:-2.5rem}.ml-auto{margin-left:auto}.mr-auto,.mx-auto{margin-right:auto}.mx-auto{margin-left:auto}.p0{padding:0}.pt0{padding-top:0}.pr0{padding-right:0}.pb0{padding-bottom:0}.pl0,.px0{padding-left:0}.px0{padding-right:0}.py0{padding-top:0;padding-bottom:0}.p1{padding:1rem}.pt1{padding-top:1rem}.pr1{padding-right:1rem}.pb1{padding-bottom:1rem}.pl1{padding-left:1rem}.py1{padding-top:1rem;padding-bottom:1rem}.px1{padding-left:1rem;padding-right:1rem}.p2{padding:1.5rem}.pt2{padding-top:1.5rem}.pr2{padding-right:1.5rem}.pb2{padding-bottom:1.5rem}.pl2{padding-left:1.5rem}.py2{padding-top:1.5rem;padding-bottom:1.5rem}.px2{padding-left:1.5rem;padding-right:1.5rem}.p3{padding:2rem}.pt3{padding-top:2rem}.pr3{padding-right:2rem}.pb3{padding-bottom:2rem}.pl3{padding-left:2rem}.py3{padding-top:2rem;padding-bottom:2rem}.px3{padding-left:2rem;padding-right:2rem}.p4{padding:2.5rem}.pt4{padding-top:2.5rem}.pr4{padding-right:2.5rem}.pb4{padding-bottom:2.5rem}.pl4{padding-left:2.5rem}.py4{padding-top:2.5rem;padding-bottom:2.5rem}.px4{padding-left:2.5rem;padding-right:2.5rem}.col{float:left}.col,.col-right{box-sizing:border-box}.col-right{float:right}.col-1{width:8.33333%}.col-2{width:16.66667%}.col-3{width:25%}.col-4{width:33.33333%}.col-5{width:41.66667%}.col-6{width:50%}.col-7{width:58.33333%}.col-8{width:66.66667%}.col-9{width:75%}.col-10{width:83.33333%}.col-11{width:91.66667%}.col-12{width:100%}@media (min-width:40.06rem){.sm-col{float:left;box-sizing:border-box}.sm-col-right{float:right;box-sizing:border-box}.sm-col-1{width:8.33333%}.sm-col-2{width:16.66667%}.sm-col-3{width:25%}.sm-col-4{width:33.33333%}.sm-col-5{width:41.66667%}.sm-col-6{width:50%}.sm-col-7{width:58.33333%}.sm-col-8{width:66.66667%}.sm-col-9{width:75%}.sm-col-10{width:83.33333%}.sm-col-11{width:91.66667%}.sm-col-12{width:100%}}@media (min-width:52.06rem){.md-col{float:left;box-sizing:border-box}.md-col-right{float:right;box-sizing:border-box}.md-col-1{width:8.33333%}.md-col-2{width:16.66667%}.md-col-3{width:25%}.md-col-4{width:33.33333%}.md-col-5{width:41.66667%}.md-col-6{width:50%}.md-col-7{width:58.33333%}.md-col-8{width:66.66667%}.md-col-9{width:75%}.md-col-10{width:83.33333%}.md-col-11{width:91.66667%}.md-col-12{width:100%}}@media (min-width:64.06rem){.lg-col{float:left;box-sizing:border-box}.lg-col-right{float:right;box-sizing:border-box}.lg-col-1{width:8.33333%}.lg-col-2{width:16.66667%}.lg-col-3{width:25%}.lg-col-4{width:33.33333%}.lg-col-5{width:41.66667%}.lg-col-6{width:50%}.lg-col-7{width:58.33333%}.lg-col-8{width:66.66667%}.lg-col-9{width:75%}.lg-col-10{width:83.33333%}.lg-col-11{width:91.66667%}.lg-col-12{width:100%}}.flex{display:-webkit-box;display:-ms-flexbox;display:flex}@media (min-width:40.06rem){.sm-flex{display:-webkit-box;display:-ms-flexbox;display:flex}}@media (min-width:52.06rem){.md-flex{display:-webkit-box;display:-ms-flexbox;display:flex}}@media (min-width:64.06rem){.lg-flex{display:-webkit-box;display:-ms-flexbox;display:flex}}.flex-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.flex-wrap{-ms-flex-wrap:wrap;flex-wrap:wrap}.items-start{-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.items-end{-webkit-box-align:end;-ms-flex-align:end;align-items:flex-end}.items-center{-webkit-box-align:center;-ms-flex-align:center;align-items:center}.items-baseline{-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}.items-stretch{-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch}.self-start{-ms-flex-item-align:start;align-self:flex-start}.self-end{-ms-flex-item-align:end;align-self:flex-end}.self-center{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center}.self-baseline{-ms-flex-item-align:baseline;align-self:baseline}.self-stretch{-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch}.justify-start{-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.justify-end{-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}.justify-center{-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.justify-between{-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.justify-around{-ms-flex-pack:distribute;justify-content:space-around}.content-start{-ms-flex-line-pack:start;align-content:flex-start}.content-end{-ms-flex-line-pack:end;align-content:flex-end}.content-center{-ms-flex-line-pack:center;align-content:center}.content-between{-ms-flex-line-pack:justify;align-content:space-between}.content-around{-ms-flex-line-pack:distribute;align-content:space-around}.content-stretch{-ms-flex-line-pack:stretch;align-content:stretch}.flex-auto{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;min-width:0;min-height:0}.flex-none{-webkit-box-flex:0;-ms-flex:none;flex:none}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-last{-webkit-box-ordinal-group:100000;-ms-flex-order:99999;order:99999}.relative{position:relative}.absolute{position:absolute}.fixed{position:fixed}.top-0{top:0}.right-0{right:0}.bottom-0{bottom:0}.left-0{left:0}.z1{z-index:1}.z2{z-index:2}.z3{z-index:3}.z4{z-index:4}.border{border-style:solid;border-width:1px}.border-top{border-top-style:solid;border-top-width:1px}.border-right{border-right-style:solid;border-right-width:1px}.border-bottom{border-bottom-style:solid;border-bottom-width:1px}.border-left{border-left-style:solid;border-left-width:1px}.border-none{border:0}.rounded{border-radius:3px}.circle{border-radius:50%}.rounded-top{border-radius:3px 3px 0 0}.rounded-right{border-radius:0 3px 3px 0}.rounded-bottom{border-radius:0 0 3px 3px}.rounded-left{border-radius:3px 0 0 3px}.not-rounded{border-radius:0}.hide{position:absolute;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px)}@media (max-width:40rem){.xs-hide{display:none}}@media (min-width:40.06rem) and (max-width:52rem){.sm-hide{display:none}}@media (min-width:52.06rem) and (max-width:64rem){.md-hide{display:none}}@media (min-width:64.06rem){.lg-hide{display:none}}

    .h1,h1{font-size:3rem;line-height:3.5rem}
    .h2,h2{font-size:2rem;line-height:2.5rem}
    .h3,h3{font-size:1.5rem;line-height:2rem}
    .h4,h4{font-size:1.125rem;line-height:1.5rem}
    .h5,h5{font-size:.875rem;line-height:1.125rem}
    .h6,h6{font-size:.75rem;line-height:1rem}
    h1,h2,h3,h4,h5,h6{margin:0;padding:0;font-weight:400;letter-spacing:.06em}
    a,a:active,a:visited{color:inherit}
    .ampstart-btn{font-family:inherit;font-weight:inherit;font-size:1rem;line-height:1.125rem;padding:.7em .8em;text-decoration:none;white-space:nowrap;word-wrap:normal;vertical-align:middle;cursor:pointer;background-color:#fff;color:#4508b6;border:1px solid #4508b6}

    .w-header,h1,h2,h3,h4,h5,h6{font-family:Inconsolata,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;margin-top: 1.2em}
    .ampstart-headerbar-nav .ampstart-nav-item{padding-right:1rem}
    .ampstart-headerbar-nav .ampstart-nav-item.w-current-page{color:#066573}
    .ampstart-headerbar-nav .ampstart-nav-item.w-current-page:after,.anchor[selected]:after{content:'';display:block;height:4px;background:linear-gradient(90deg,#491e10 0,#ff004d)}

    aside li>a{text-decoration:none}

    .w-header{
        background-image:linear-gradient(90deg,#491e10 0,#ff004d);
        padding:7rem 0;
        color:#fff;
        -webkit-clip-path: polygon(0 1%, 100% 25%, 100% 100%, 0 75%);
        clip-path: polygon(0 1%, 100% 25%, 100% 100%, 0 75%);
    }

    .w-components-sec-nav{min-width:200px;margin-top:-4.5rem;padding-top:4.5rem}
    .w-components-sec-nav >p {
        background:linear-gradient(90deg,#491e10 0,#ff004d);
        color: white;
    }

    .w-heading{letter-spacing:inherit;position:relative;font-size:1.5rem;}

    .ampstart-footer{position:relative}
    .ampstart-footer:before{content:"";position:absolute;width:100%;height:35px;background-image:linear-gradient(90deg,#491e10 0,#ff004d);top:0;left:0;right:0}
    .ampstart-device-preview-mask,.ampstart-device-preview-select{background:#f9f7f7}
    .ampstart-device-preview-select{box-shadow:0 0 5px 2px rgba(0,0,0,.1)}

    .w-component-desc{margin-bottom:5rem; padding-left:1rem;padding-right:1rem;line-height: 1.6}
    .w-component-desc h1{letter-spacing:inherit;background:linear-gradient(90deg,#491e10 0,#ff004d);color: white}
    .w-component-desc:target:before{content:"";display:block;height:3.5rem}
    .w-component-desc [placeholder]{background:#fff}
    .w-component-rendered{margin-top:3.5rem}
    .w-component-desc pre{white-space:pre-line;background:#f9f7f7;overflow-y:auto;margin:0}
    .w-example-code amp-accordion [expanded] h3:after{-webkit-transform:scaleY(-1);transform:scaleY(-1)}@media (max-width:40rem){.w-component-desc>*{padding-left:0;padding-right:0}

    .w-header>*{padding-left:0;padding-right:0}}@media (max-width:363px){.w-component-iframe-container>amp-iframe{-webkit-transform:scale(.792);transform:scale(.792);-webkit-transform-origin:0 0;transform-origin:0 0;width:343px}}
    :root{--font-family-serif:Montserrat,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,Arial,sans-serif;--font-family-monospace:Consolas,Menlo,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New,monospace,sans-serif;--color-primary:#005AF0}

    body{font-family:var(--font-family-serif)}

    .abe-sublist,.ampstart-nav-item .abe-list-container{opacity:0;pointer-events:none;position:absolute}

    .ampstart-btn-secondary,.ampstart-btn-secondary[disabled],.ampstart-btn-secondary[disabled]:focus,.ampstart-btn-secondary[disabled]:hover,a.ampstart-btn-secondary,a.ampstart-btn-secondary.disabled,a.ampstart-btn-secondary.disabled:focus,a.ampstart-btn-secondary.disabled:hover{color:#fff;background:#4508b6;border:1px solid #fff}@keyframes slideUp{0%{transform:translateY(100%);opacity:.5}100%{transform:translateY(0);opacity:1}}amp-consent{background:#fff;box-shadow:rgba(0,0,0,.26) 0 0 19px 0;animation:.5s ease-out 0s 1 slideUp}

    table {margin: 1em 0;}
    th {background-color: #6033d1; color: white;}
    tr.y {background-color: #18bc9c; font-weight: bold;}
    table td {border-right: dashed 1px black; border-bottom: solid 1px black;}
    table.row td {border-bottom: solid 1px black;}
    span.red {color: #B60000;}
</style>
</head>
<body>
    <header class="ampstart-headerbar fixed flex justify-start items-center top-0 left-0 right-0 pl2 pr4">
        <div role="button" on="tap:header-sidebar.toggle" tabindex="0" class="ampstart-navbar-trigger md-hide lg-hide pr2">☰</div>
        <nav class="ampstart-headerbar-nav ampstart-nav xs-hide">
        <ul class="list-reset m0 p0 flex justify-center nowrap">
        <li class="ampstart-nav-item abe-nav-list">
            <a href="tag.html" class="text-decoration-none block">タグ</a>
        </li>
        <li class="ampstart-nav-item abe-nav-list">
            <a href="macro_plg.html" class="text-decoration-none block">マクロ・プラグイン</a>
        </li>
        <li class="ampstart-nav-item abe-nav-list w-current-page">
            <a href="dev.html" class="text-decoration-none block">開発者向け情報</a>
        </li>
        <li class="ampstart-nav-item abe-nav-list">
            <a href="https://github.com/famibee/SKYNovel" class="text-decoration-none block">github</a>
        </li>
        <li class="ampstart-nav-item abe-nav-list">
            <a href="https://famibee.blog.fc2.com/" class="text-decoration-none block">blog</a>
        </li>
    </ul>
    </nav>
    </header>

    <header class="w-header center" id="top-header">
        <h1 class="mb1">SKYNovel 開発者向け情報</h1>
        <p class="block mb4 caps text-decoration-none">SKYNovel Information for developers</p>
<!--
        <div class="w-index-header-action mx-auto">
<a class="ampstart-btn ampstart-btn-secondary caps mb1 mx2 text-decoration-none inline-block" href="/playground/#url=https://ampbyexample.com/components/amp-sidebar/source/">Open in Playground</a> <a class="ampstart-btn ampstart-btn-secondary caps mb1 mx2 text-decoration-none inline-block" href="/components/amp-sidebar/preview/">View Demo</a>
        </div>
-->
    </header>

<main class="flex pl2 mt1">
<aside class="w-components-sec-nav col-3 xs-hide sm-hide relative">
    <h3>項目一覧</h3>
    <p>入門編</p>
    <ul class="anchors list-reset m0 p0 px1">
        <li class="mb1"><a href="#isit">SKYNovelとは</a></li>
        <li class="mb1"><a href="#howto_start">SKYNovelのはじめかた</a></li>
        <li class="mb1"><a href="#inst_vscode">VSCodeをインストール</a></li>
        <li class="mb1"><a href="#inst_vscex">拡張機能をインストール</a></li>
        <li class="mb1"><a href="#inst_other">あとは 拡張機能 SKYNovel の指示に従って……</a></li>
        <li class="mb1"><a href="#start_tmp">テンプレートで始めよう</a></li>
        <li class="mb1"><a href="#remodel_title">改造してみよう</a></li>
        <li class="mb1"><a href="#autosave">(豆知識)VSCodeで自動保存</a></li>
        <li class="mb1"><a href="#script">スクリプトとは</a></li>
        <li class="mb1"><a href="#bracket">(豆知識)引用符っているの? いらないの?</a></li>
        <li class="mb1"><a href="#replace_bgm">BGM素材を差し替えよう</a></li>
    </ul>
    <p>初級テクニック</p>
    <ul class="anchors list-reset m0 p0 px1">
        <li class="mb1"><a href="#upd_sn">SKYNovelを更新しよう</a></li>
        <li class="mb1"><a href="#lay">(未作成)レイヤなどについて</a></li>
        <li class="mb1"><a href="#materials">サポートする画像・音声ファイルなど</a></li>
    </ul>
    <p>中級テクニック</p>
    <ul class="anchors list-reset m0 p0 px1">
        <li class="mb1"><a href="#val_debug">変数・定数の可視化機能</a></li>
        <li class="mb1"><a href="#reserve_value_save">セーブ変数(save:)</a></li>
        <li class="mb1"><a href="#reserve_value_sys">システム変数(sys:)</a></li>
        <li class="mb1"><a href="#reserve_value_tmp">雑用変数(tmp:)</a></li>
        <li class="mb1"><a href="#cond">式の評価と条件分岐</a></li>
        <li class="mb1"><a href="#calc">式で使える演算子と関数</a></li>
        <li class="mb1"><a href="#an2sn">AIRNovelからの変更点</a></li>
        <li class="mb1"><a href="#ruby">ルビ記法</a></li>
        <li class="mb1"><a href="#font">フォントの導入</a></li>
        <li class="mb1"><a href="#crypt">素材や・変数データを暗号化</a></li>
        <li class="mb1"><a href="#save_path">セーブデータの保存場所</a></li>
        <li class="mb1"><a href="#on_browser">ブラウザ版の公開方法</a></li>
    </ul>
</aside>

<article class="w-components flex-auto col-9">
<section class="w-component-desc">

<h1>入門編</h1>

<h2 id="isit" class="w-heading">SKYNovelとは</h2>
<h4>WebGL・JavaScriptを中心としたWeb技術によるノベルゲームシステムです。</h4>
<p class="mb2 px1">

    <ul type="disc">
    <li>参考記事:<a href="https://famibee.blog.fc2.com/blog-entry-604.html">一般公開開始時の概要記事</a></li>
    <li><a href="https://famibee.github.io/SKYNovel_gallery/" target="_blank" rel="noopener">どんな事が出来るの? What can SKYNovel do? sample</a><br/>
        ブラウザから直接動かせるサンプルギャラリーです(ソースファイル)</li>
    </ul>

</p>


<h2 id="howto_start" class="w-heading">SKYNovelのはじめかた</h2>
<h4>すべてGUIによるインストールです。</h4>
<p class="mb2 px1">

    <ul type="disc">
        <li><a href="https://code.visualstudio.com/" target="_blank" rel="noopener">Visual Studio Code</a>(以後VSCode)をインストール</li>
        <li><a href="https://marketplace.visualstudio.com/items?itemName=famibee2.skynovel2" target="_blank" rel="noopener">VSCode用拡張機能 SKYNovel</a> をインストール</li>
        <li>あとは 拡張機能 SKYNovel の指示に従って……</li>
    </ul>

</p>


<h2 id="inst_vscode" class="w-heading">VSCodeをインストール</h2>
<p class="mb2 px1">
    VSCodeは多機能なテキストエディタで、SKYNovel開発環境のベースとなります。フリーウェアです。<br/>
    <a href="https://code.visualstudio.com/" target="_blank" rel="noopener">ダウンロード</a>してインストールしていきます。<br/>
    <amp-img src="pic/inst_vscode0.webp" width="500" height="600" alt="">
        <amp-img fallback src="pic/inst_vscode0.jpg" width="500" height="600" alt=""></amp-img>
    </amp-img><br/>
    <amp-img src="pic/inst_vscode1.png" width="484" height="120" alt=""></amp-img><br/>

    <br/>
    Macの場合も同様です。<br/>
    <amp-img src="pic/inst_vscode0m.png" width="292" height="79" alt=""></amp-img><br/>
    <amp-img src="pic/inst_vscode1m.png" width="480" height="120" alt=""></amp-img><br/>
    Macの場合はzipを解凍するとappファイルが入っていますので、それを「アプリケーション」フォルダに移動するだけです。<br/>
    <amp-img src="pic/inst_vscode2m.jpg" width="451" height="100" alt=""></amp-img><br/>
    あとはアプリケーションとして起動できます。<br/>

    <br/>
    <br/>
    以後は Windowsの場合について解説していきます。<br/>
    exeを開くとインストーラーが起動します。<br/>
    <amp-img src="pic/inst_vscode1.png" width="484" height="120" alt=""></amp-img><br/>
    あとはよくあるソフトのインストールですが、注意点だけ赤丸しておきます。<br/>
    <amp-img src="pic/inst_vscode10.webp" width="510" height="401" alt="">
        <amp-img fallback src="pic/inst_vscode10.jpg" width="510" height="401" alt=""></amp-img>
    </amp-img><br/>
    <amp-img src="pic/inst_vscode11.webp" width="508" height="397" alt="">
        <amp-img fallback src="pic/inst_vscode11.jpg" width="508" height="397" alt=""></amp-img>
    </amp-img><br/>
    <amp-img src="pic/inst_vscode12.webp" width="508" height="394" alt="">
        <amp-img fallback src="pic/inst_vscode12.jpg" width="508" height="394" alt=""></amp-img>
    </amp-img><br/>
    <amp-img src="pic/inst_vscode13.webp" width="506" height="395" alt="">
        <amp-img fallback src="pic/inst_vscode13.jpg" width="506" height="395" alt=""></amp-img>
    </amp-img><br/>
    <amp-img src="pic/inst_vscode14.jpg" width="508" height="397" alt=""></amp-img><br/>
    <amp-img src="pic/inst_vscode15.jpg" width="506" height="393" alt=""></amp-img><br/>
    <amp-img src="pic/inst_vscode16.png" width="507" height="393" alt=""></amp-img><br/>
    インストールを完了し、起動できました。<br/>
    右下に【日本語言語パック】のインストールをうながす通知があるので、クリックして下さい。メニューなどGUIが日本語化されます。<br/>
    VSCodeの最低限の設定は以上です。<br/>
    <amp-img src="pic/inst_vscode17.png" width="2074" height="1558" alt="" layout="responsive"></amp-img><br/>

</p>


<h2 id="inst_vscex" class="w-heading">VSCode用拡張機能 SKYNovel をインストール</h2>
<h4>起動したVSCodeからインストールできます。</h4>
<p class="mb2 px1">

     左端の「Activity Bar」上から5つ目をクリックし、<br/>
    検索窓に「skynovel」(大文字小文字関係なく)入力すると、<br/>
    SKYNovel と書いてあるのが(恐らく)一つだけ検索に引っかかるので「インストール」を押して下さい。それだけです。<br/>
    <amp-img src="pic/inst_vscex0.jpg" width="850" height="539"></amp-img><br/>

    <br/>
     以降の説明では <a href="https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme" target="_blank" rel="noopener">Material Icon Theme - Visual Studio Marketplace</a> という拡張機能もインストールし、アイコンもカラフルにしています。<br/>


</p>


<h2 id="inst_other" class="w-heading">あとは 拡張機能 SKYNovel の指示に従って……</h2>
<h4>Node.jsなどをインストールしていきます。</h4>
<p class="mb2 px1">

     左端の「Activity Bar」に拡張機能 SKYNovelの「丸に紙飛行機」ロゴマークが表示されているので、クリックして下さい。<br/>
    <amp-img src="pic/inst_other1.jpg" width="125" height="590"></amp-img><br/>

     一番上に開発環境の状況が表示されています。エラーっぽい表示がされていますね。<br/>
     環境設定がまだすこし残っているわけです。<br/>
    <br/>
     同時に「SKYNovel開発環境 準備の手引き」というページが開かれていますか?<br/>
     開かれていない場合は、【Node.js】の行にマウスカーソルを乗せたときに表示される【矢印ボタン】を押してください。<br/>
    <amp-img src="pic/inst_other2.jpg" width="585" height="400"></amp-img><br/>
    
     図は「SKYNovel開発環境 準備の手引き」というページです。<br/>
     あとはその指示に従ってインストールを続けて下さい。<br/>
    <amp-img src="pic/inst_other3.jpg" width="672" height="358"></amp-img><br/>

     すると……<br/>
     エラーが消えました!<br/>
    <amp-img src="pic/inst_other4.jpg" width="585" height="400"></amp-img><br/>


     環境設定はここまでです。<br/>


</p>


<h2 id="start_tmp" class="w-heading">テンプレートで始めよう</h2>
<h4>すでに動くゲームをオープンソースで提供しており、これを改造していきます。</h4>
<p class="mb2 px1">

     例えば自作の小説本を出版するとします。<br/>
     その際、パルプの生成方法、紙の刷り方、印刷技術、装丁デザインの勉強等までする必要があるでしょうか?<br/>
     本来小説を書くというのは、紙とペンを用意し、書き始めることだけのはずです。<br/>
     良い小説を書くために「小説の書き方本」を読みあさり、知らない事を勉強する方向へ労力を注ぎ、胃を壊すぐらいコーヒーを飲みたいのではないでしょうか?<br/>
     同じように、まずはあなたの作品を造り上げることに専念して下さい。<br/>
    <br/>
    <br/>
     ●ではどうやって本にするのか?<br/>
     今ここに本があります。<br/>
     梶井基次郎 原作の短編ノベルゲーム「桜の樹の下には」または拙作「初音館にて」です。<br/>
     実はこれは鉛筆で書かれています。<br/>
     まずはこの本を消しゴム掛けして、元の文章をあなたの原作に書き換えてしまいましょう。<br/>
     本を作るところから、始める必要はありません。<br/>
     これはもちろんたとえ話ですが──同じようにして、あなたの本が完成するのです。<br/>
    <br/>
     作品を書いているうちに装丁を考えたり、紙質や手触りに凝ったりしたくなるかも知れません。<br/>
     その時は初級・中級・上級へと読み進めていって下さい。<br/>
     今度は小説を書く楽しみではなく、本を作る楽しみが待っています。<br/>


    <br/>
    <br/>
     どんなものか、お試しでやってみましょう。<br/>
    <br/>
    【ワークスペース】ビューにある「テンプレートから始める」ボタンを押します。<br/>
    <amp-img src="pic/TempWizard1.jpg" width="939" height="660" layout="responsive"></amp-img><br/>

    【テンプレートから始める】画面が表示されます。<br/>
    <amp-img src="pic/TempWizard2.jpg" width="1500" height="1639" layout="responsive"></amp-img><br/>

     上部に【プロジェクトフォルダ名】を入力します。半角英数記号を推奨しており、それ以外はエラーになります。<br/>
     この例では、【yokogaki】としておきます。<br/>
    <ul>
        <li>横書きノベルゲーム</li>
        <li>縦書きノベルゲーム</li>
        <li>小さなサンプル</li>
    </ul>
    ……などのタブを選択し、新規作成プロジェクトの基にしたいテンプレを選択します。<br/>
    <amp-img src="pic/TempWizard3.jpg" width="798" height="390" layout="responsive" style="border: 5px solid white;"></amp-img><br/>

     決めたら、【このテンプレを基にする】をクリック。<br/>
     フォルダ選択ダイアログが表示されるので、プロジェクトフォルダを置く場所を指定して下さい。<br/>
    <amp-img src="pic/TempWizard10.jpg" width="1500" height="1639" layout="responsive"></amp-img><br/>

     右下に進捗が表示されます。ネット回線が速いなら一分以内に完了し、フォルダを開きます。<br/>
    <amp-img src="pic/TempWizard11.jpg" width="750" height="216" layout="responsive"></amp-img><br/>

     新プロジェクトが開かれました。<br/>
    ※一部の特殊なフォルダでは図のようなセキュリティダイアログが表示されるので、【はい】をクリックします。<br/>
    <amp-img src="pic/TempWizard12.jpg" width="857" height="587" layout="responsive"></amp-img><br/>

     また、フォルダを開いた際、初回のみ初期化処理が走ります。しばしお待ち下さい。<br/>
    <amp-img src="pic/TempWizard13.jpg" width="447" height="374" layout="responsive"></amp-img><br/>

     このようなセキュリティダイアログも同様に【続行】をクリック。<br/>
    <amp-img src="pic/TempWizard14.jpg" width="757" height="460" layout="responsive"></amp-img><br/>

     下方の【ターミナル】も停止し、準備完了です。<br/>
     readme.txtが開かれ、サイドバーにはエクスプローラーやFinderのようなファイル一覧が表示されています。大文字表示ですが【yokogaki】フォルダ内です。<br/>
    <amp-img src="pic/TempWizard15.jpg" width="1499" height="1639" layout="responsive"></amp-img><br/>

     SKYNovelロゴをクリックすると、ワークスペースに現在開かれているプロジェクト(フォルダ)一覧が表示されます。ここでは【yokogaki】です。<br/>
     またプロジェクトごとにライブラリを更新したり、ブラウザ版を起動したり、ワンタッチで様々な操作ができるようになっています。詳細はまた別項にて解説します。<br/>
    <amp-img src="pic/TempWizard16.jpg" width="1500" height="1639" layout="responsive"></amp-img><br/>

     試しに【設定】をクリックしてみると、プロジェクトの様々な設定が入力できる画面が表示されます。<br/>
     プロジェクト名が【yokogaki】です。<br/>
    ※変更すると、フォルダ名はそのままにプロジェクト名のみが変更されます。パッケージのファイル名などがプロジェクト名を基にしています。<br/>
    <amp-img src="pic/TempWizard17.jpg" width="1500" height="1639" layout="responsive"></amp-img><br/>

     今度は【起動:ブラウザ版】右にマウスカーソルを乗せると現われる、【再生ボタン】をクリックしてみましょう。<br/>
    <amp-img src="pic/inst_other5.jpg" width="620" height="373" layout="responsive"></amp-img><br/>

     ブラウザが起動し、テンプレを基にしたブラウザ版ゲームが起動します。<br/>
    <br/>
     画像や音楽の素材を差し替えたり、スクリプトを書き換えたり。<br/>
     これを改造して、自分のゲームへと作り込んでいくわけです。<br/>
    <amp-img src="pic/inst_other6.jpg" width="1207" height="906" layout="responsive"></amp-img><br/>


</p>


<h2 id="remodel_title" class="w-heading">改造してみよう</h2>
<h4>テンプレートを改造してみましょう。まずはタイトル画面から。</h4>
<p class="mb2 px1">

     自由な文字列からボタンを作れる「文字ボタン」という機能があります。<br/>
     テンプレートのタイトル画面でも使用されていますので、これを変更してみましょう。<br/>
    <amp-img src="pic/remodel_title0.jpg" width="1024" height="768" layout="responsive"></amp-img><br/>

    「Activity Bar」一番上の「エクスプローラー」を選択します。<br/>
     【prj/script フォルダ】下の【main.sn】をクリックすると、そのファイルが開かれます。<br/>
     この拡張子【.sn】のファイルはスクリプトというテキストファイルで、シナリオや様々な演出はこのファイルを変更・記述していきます。<br/>
    <amp-img src="pic/remodel_title1.jpg" width="1024" height="768" layout="responsive"></amp-img>
    <br/>
    「わけの分からないことが書いてある! 意味不明!」<br/>
     ですが、いまは置いといてください。おいおい解説しますので。<br/>
    <br/>
    (余談)(慣れればお好きなテキストエディタで変更して構いません)<br/>
    ※文字コードはUTF-8、改行コードは LF 固定です。文字コード・改行コードを間違うミスに注意。<br/>

    <br/>
     ここで55行目付近にある「ロード」という文字を「つづきから」に変えてみます。<br/>
     メニューの【ファイル】-【保存】、あるいは Ctrl+Sショートカットで保存します。<br/>
    <amp-img src="pic/remodel_title2.jpg" width="1024" height="768" layout="responsive"></amp-img><br/>

     自動で再読み込みされます。<br/>
    (自動でされなければ、ブラウザの再読み込みボタンを押します)<br/>
    <amp-img src="pic/remodel_title3.jpg" width="474" height="278" layout="responsive"></amp-img><br/>

     文字が変更されました! ボタンもちゃんと押せます。<br/>
    <amp-img src="pic/remodel_title4.jpg" width="1024" height="768" layout="responsive"></amp-img><br/>

     さて、いまわざと触れませんでしたが、いま変更したのは「[button]タグのtext属性」というものです。<br/>
    「タグ??? 属性???」<br/>
     新しい言葉が出てきましたね。タグについて解説していきます。<br/>


</p>


<h2 id="autosave" class="w-heading">(豆知識)VSCodeで自動保存</h2>
<h4>スクリプトを変更するたびに保存を選んだり、毎回ショートカットを押すのは面倒!</h4>
<p class="mb2 px1">

     そこで、VSCode に保存を任せてしまいましょう。<br/>
     こちらの記事を参考に、VSCode を便利に設定してみて下さい。<br/>
      →<a href="https://notti-blog.com/entry/vscode-auto-save/" target="_blank" rel="noopener">[VS Code] 自動保存するように設定する | あいすのブログ</a>
     <a href="http://web.archive.org/web/20190521162502/https://notti-blog.com/entry/vscode-auto-save/" target="_blank" rel="noopener">(web.archive.org)</a><br/>
    <amp-img src="pic/vscode_autosave.jpg" width="725" height="373" layout="responsive"></amp-img>
    (注意)設定画面の「ダーティーファイル」というのは、「変更したけど保存してないファイル」という意味合いです。<br/>

    <br/>
     自分も「onFocusChange」にしてます。別のアプリをクリックしただけで保存してくれます。この辺はお好みで。<br/>
     スクリプトの変更を戻したい場合は、メニューの【編集】-【元に戻す】にて。「アンドゥ(UNDO)」というやつです。<br/>

    <br/>
     VSCode には他にも様々な便利設定があります。どんどん使いやすくしていきましょう!<br/>


</p>


<h2 id="script" class="w-heading">スクリプトとは</h2>
<h4>スクリプトってなんでしょう?</h4>
<p class="mb2 px1">

     SKYNovelにおけるスクリプトとは、<br/>
     テキストファイルに書いた「小説」に、タグなどによる「演出」を書き加えたものです。<br/>
    <br/>
     実際に見てみましょう。【main.sn】と同じフォルダにある、【ss_000.sn】を開いて下さい。<br/>
    <amp-img src="pic/script0.png" width="379" height="285"></amp-img><br/>

    <br/>
    「小説」は【君の部屋に行こう】という文字の部分です。<br/>
    「タグなどの命令」は「[」と「]」の半角文字の大括弧に挟まれた、英語や数字や記号の部分です。<br/>
    <amp-img src="pic/script1.jpg" width="480" height="451"></amp-img><br/>
    (余談)「;」で始まる部分はコメントや注釈と呼ばれるもので、制作者がメモを書ける機能です。SKYNovel 自体は読み飛ばしますので、スルーして下さい。<br/>

    <br/>
     7行目は「[r]」ですね。これを今後は「タグ名が r だ」と言い、「rタグ」と呼び、今後この文章(SKYNovel 開発者向け情報)では[r]と書きます。<br/>
    <br/>
    【bg=white】とか【visible=false】とか、たくさん「おまけ」が付いてる[grp]や18行目の[plc]に注目です。<br/>
    「おまけ」は、「属性」と呼びます。<br/>
     一つの働きをするタグに、細かい指示をする記述の事です。<br/>
     半角空白や改行で途切れて、複数指定できます。(タグがサポートしてない属性は無視されます)<br/>
    <br/>
     属性って色んなものにありますよね。<br/>
     呪文にも「タイプは炎系。力の源は闇。攻撃力は25。水棲生物に強い」<br/>
     女性キャラクターなら「年齢は十四歳。メガネは必須! 髪色は黒髪、背はちょっと高めなのを気にしている。スリーサイズはそれぞれ……」<br/>
     某ラーメン屋なら「アブラナシヤサイカラメマシニンニクスクナメ」<br/>
    <br/>
     同様に[sys_scenario_start]、最後に[grp]などなど。<br/>
     それぞれが小さな機能を持っています。それらを積み木のように組み合わせて、演出をしていきます。<br/>

    <br/>
     試しに [r] について知りましょう。<br/>
     タグの機能については「タグリファレンス」というWeb上の資料で確認できます。<br/>
     このページの左上の【タグ】からでもいいですが、リンクを張っておきます。<br/>
      →<a href="tag.htm#r" target="_blank" rel="noopener">SKYNovel タグリファレンス Tag Reference [r]</a><br/>
    「文字レイヤ」とか「ページ」とか色々不明の言葉がありますが──<br/>
     とにかく、【改行を出力する】機能を持っています。<br/>

    <br/>
    <br/>
     タグは言うなれば魔法の呪文。<br/>
     RPGなら暗い洞窟を明るく照らしたり、仲間の体力を回復したり、扉の鍵を開けたり。<br/>
     呪文は一つ一つに意味があり、役割があります。便利で頼りになる道具です。<br/>
     でも瀕死の仲間を明るく照らしたり、扉の体力(?)を回復したりしても意味はありません。<br/>
     タグの使い道を正しく理解し、よりよいノベルゲーム制作という冒険を進めましょう。<br/>
    <br/>
    「タグなどの命令」は一見ややこしく難しそうに見えます。<br/>
     ですが、「今すぐ」「全てを」理解する必要はありません。<br/>

     <a href="tag.html" target="_blank" rel="noopener">タグリファレンス</a>というカンニングペーパー、辞書があります。<br/>
     タグを使いこなすのに、「あんなタグがあったな」となんとなく憶えておけば、あとはタグリファレンスという辞書を引きながら記述していけばよいのです。<br/>

    <br/>
    <br/>
     例えばさっき「ロード」という文字を「つづきから」に変えたのは、<a href="tag.htm#button" target="_blank" rel="noopener">[button]</a> タグの text属性 を変更したのだった、というわけです。<br/>
    <amp-img src="pic/remodel_title1.jpg" width="1024" height="768" layout="responsive"></amp-img>


</p>


<h2 id="bracket" class="w-heading">(豆知識)引用符っているの? いらないの?</h2>
<h4>属性の値の引用符について。</h4>
<p class="mb2 px1">

     引用符、すなわち。<br/>
     属性の値でアポストロフィー【'】やクオーテーションマーク【"】で囲っていたりいなかったり、表記が揺れているのが分かるでしょうか?<br/>
     先ほど変更した[button]ですら、三種類が混在しています。<br/>
    <br/>
    [button text='つづきから' left=350 top=360 width=90 call=true label=*load hint="セーブ箇所から続ける" enterse=&sysse_choice clickse=&sysse_ok1]<br/>
    <br/>
     これはどの書き方でも同じ動作をします。ので、制作上はどれでも構いません。<br/>
    (見た目があまり美しくないので、揃えたほうが良さげですが……)<br/>
     ただ、「引用符に囲まないと半角空白が表現できない」などの理由で、この文法が用意されています。<br/>
     変更前に text=' ロード ' という記述だったのもそれです。<br/>
    (引用符を使わないと、属性の区切りと見なされエラーになってしまいます)<br/>
    <br/>
    引用符を文字として値にしたい場合もあります。<br/>
    その場合は text='太郎"うひょー"' という感じで指定できます。<br/>
    両方の引用符を使いたいときは……?<br/>
    実は【#】(半角いげたマーク)も引用符に使えるようになっています。<br/>
    text=#太郎"うひょー" 花子'むきょー'#<br/>
    <br/>
     では三種類の引用符を同時に文字としたいときは……?<br/>
    SKYNovel v1.18.8 より、エスケープシーケンスというものが導入されました。<br/>
    "\"'#"<br/>
    '"\'#'<br/>
    #"'\##<br/>
     というように、「\」を前に付けて下さい。<br/>


</p>


<h2 id="replace_bgm" class="w-heading">BGM素材を差し替えよう</h2>
<h4>素材を差し替えて、よりあなたの作品らしく</h4>
<p class="mb2 px1">

     audio フォルダに様々な mp3 ファイルが入っています。<br/>
     これらは効果音やBGM(バックグラウンドミュージック)のファイルです。<br/>
     タイトル画面でもBGMが流れていますが、これを変更してみましょう。<br/>
    <amp-img src="pic/replace_bgm0.jpg" width="379" height="285"></amp-img><br/>
     再び【main.sn】を開いて、64行目辺りにある<a href="macro_plg.htm#bgm" target="_blank" rel="noopener">[bgm]</a>に注目して下さい。<br/>

    <br/>
     fn="free10" となっているので、値をfree04に変更してみましょう。<br/>
     拡張子は省略できる、というのもポイントです。<br/>
    <br/>
     ページを再読み込みすると、なんだか明るい雰囲気のタイトル画面になりました。<br/>
     画像素材なども同じように変更・差し替えていくことができます。<br/>


</p>


<h1>初級テクニック</h1>

<h2 id="upd_sn" class="w-heading">SKYNovelを更新しよう</h2>
<h4>SKYNovelは随時更新されています。更新の通知と手段を知りましょう</h4>
<p class="mb2 px1">

     VSCode起動時、時々右下にポップアップが現われることがあります。<br/>
    <amp-img src="pic/upd_sn0.png" width="463" height="139"></amp-img><br/>

     上部【開発環境】にネット上の最新バージョン、<br/>
     下部【開発ツール】にあなたのPC/Mac上のバージョンが表示されます。<br/>
     値が異なりますね。最新版に更新しましょう。<br/>
    <amp-img src="pic/upd_sn1.jpg" width="324" height="404"></amp-img><br/>

     とはいっても、右にあるボタンを押すだけです。<br/>
     しばらく待つと、最新バージョンに更新されます。簡単ですね。<br/>
    <amp-img src="pic/upd_sn2.png" width="488" height="194"></amp-img><br/>


</p>


<h2 id="lay" class="w-heading">(レイヤなどについて)</h2>
<h4>(未作成)</h4>
<p class="mb2 px1">

     SKYNovel でも AIRNovel と概念は変わらないので、AIRNovel の解説文へのリンクでお茶を濁します。いずれ書きなおしたいです……。<br/>
      →<a href="https://famibee.web.fc2.com/tag_dev/dev.htm#layer">AIRNovel 開発者向け情報</a><br/>

    <br/>
    (予定稿・順不同)<br/>
    レイヤとは<br/>
    レイヤには裏表がある<br/>
    使用できる素材ファイル<br/>
    フォルダの追加削除<br/>
    ジャンプしてみる<br/>
    選択肢を作る<br/>
    スクリプト文法・詳細編<br/>
    <br/>
    マクロ<br/>

</p>


<h2 id="materials" class="w-heading">サポートする画像・音声ファイルなど</h2>
<h4>(未作成)</h4>
<p class="mb2 px1">

     サポートする素材ファイルの種類(拡張子)<br/>

    <br/>
    ・・スクリプト<br/>
      拡張子 sn のUTF-8・LF改行のテキストファイル(AIRNovel では an でした)<br/>
    <br/>
    ・・画像・動画・アニメ系<br/>
      png、jpg、jpeg、svg、mp4<br/>
      ※(2020/12/13時点:H265は未サポート。ブラウザ・Electron的に現在H264までしか再生できないらしい)<br/>
      スプライトシート json と png(または jpeg)<br/>
    <br/>
    ・・BGM・音声系<br/>
      mp3、m4a、ogg、aac、webm、flac、wav<br/>
      ※ただしブラウザ版はブラウザがサポートするモノのみ。<br/>
       アプリ版は Electron の Chromiumがサポートするモノのみ(aac以外)です。<br/>
    <br/>
    ・・フォント<br/>
      woff2、otf、ttf<br/>

</p>


<h1>中級テクニック</h1>

<h2 id="val_debug" class="w-heading">変数・定数の可視化機能</h2>
<h4>デベロッパーツールから変数や定数を確認できる機能です。</h4>
<p class="mb2 px1">

     ブラウザ版では、デベロッパーツール(ChromeやSafariの機能)を開いて【Application】-【Local Storage】から、システム変数(sys:)などの内容が見えます。<br/>
    ※直接値の変更・クリアができます。jsonで記入して下さい。<br/>
    ※暗号化もします。<br/>
    <amp-img src="pic/val_debug0.png" width="934" height="602" layout="responsive"></amp-img>

     またプロジェクトファイル(prj.json)を右クリック-【SKYNovel GUIで編集する】から【variable】にチェックすると、
    <amp-img src="pic/val_debug1a.png" width="568" height="514" layout="responsive"></amp-img>
    <amp-img src="pic/val_debug1b.png" width="515" height="275" layout="responsive"></amp-img>
    全ての変数が可視化されます。(Session Storageのほうに表示される)<br/>
    ※こちらは値の変更をサポートしていません。[s][l]などの停止時に出力するだけです。<br/>
    ※暗号化ON/OFFも予定しています。<br/>
    <amp-img src="pic/val_debug2.png" width="674" height="368" layout="responsive"></amp-img>

</p>
<h2 id="reserve_value_save" class="w-heading">セーブ変数(save:)</h2>
<h4>セーブデータにセーブされる変数</h4>
<p class="mb2 px1">
    [record_place]と[save]でセーブデータに保存され、[load]で回復できる変数。<br/>
    同じ変数でもセーブデータ個別に違う値になる想定で使う。<br/>
    別のセーブデータを[load]すると、現在のセーブ変数は上書きされる。<br/>
    <br/>
    <br/>
    ※スクリプターが自由に新たに値セット・取得できますが、SKYNovelが値を設定している変数や定数もあります。<br/>
    const.sn.〜、sn.〜という名前はSKYNovelが使いますので、皆さんは新規に作成しないで下さい。<br/>
    以下の表にあるモノを使うの(読み・書き)は全然OKです!<br/>
    (const.sn.〜は必ずしも定数ではなく、一部は実行中にSKYNovelが値を変更する場合があります)<br/>
    <br/>
    冒頭がconstな変数は、書く(設定)することができません。<br/>
    constでない変数は、設定するとその値がシステムに反映されます。<br/>
    例えば「&sn.auto.enabled=true」は自動読みすすみモードを有効にします。

<table><tr><th>変数名</th><th>初期値</th><th>値域・型</th><th>コメント</th></tr>
<tr><td>save:const.sn.autowc.enabled</td><td>false</td><td>true、false</td><td>[<a href="tag.htm#current" target="_blank" rel="noopener">autowc</a>](文字ごとのウェイト)enabled属性で指定した値。</td></tr>
<tr><td>save:const.sn.autowc.text</td><td rowspan="2">''</td><td rowspan="2">文字列</td><td rowspan="2">[<a href="tag.htm#current" target="_blank" rel="noopener">autowc</a>](文字ごとのウェイト)同名属性で指定した値。<br/>
カンマ区切りで複数文字設定可能。ただしtextとtimeは常に同数にすること。設定は常にリセット&上書き<br/>
[autowc enabled=true text="二六八" time="500,1000,1500"]
</td></tr>
<tr><td>save:const.sn.autowc.time</td></tr>
</td></tr>
<tr><td>save:const.sn.mesLayer</td><td>''</td><td>文字列</td><td>デフォルト文字レイヤ。レイヤ指定を省略した時はこの値が使われる。[<a href="tag.htm#current" target="_blank" rel="noopener">current</a>]で変更できる</td></tr>
<tr><td>save:const.sn.sound.【buf】.fn</td><td>''</td><td>ファイル名</td><td>
    サウンドバッファの再生ファイル名<br/>
    任意のbuf属性を指定した[<a href="tag.htm#playse" target="_blank" rel="noopener">playse</a> buf=【buf】] 実行で自動で生まれる変数
</td></tr>
<tr><td>save:const.sn.sound.【buf】.volume</td><td>1</td><td>0.0〜1.0</td><td>
    サウンドバッファの目標音量<br/>
    任意のbuf属性を指定した[<a href="tag.htm#playse" target="_blank" rel="noopener">playse</a> buf=【buf】] 実行で自動で生まれる変数<br/>
    <br/>
    [volume]での volume属性や、「sys:const.sn.sound.【buf】.volume」は基準音量であり、別物である点に注意
</td></tr>
<tr><td>save:sn.doRecLog</td><td>false</td><td>true、false</td><td>テキストを履歴に記録するか</td></tr>
<tr><td>save:const.sn.sLog</td><td>'[]'</td><td>文字列</td><td>
    履歴テキスト<br/>
    【2019/12/18】内容が const.sn.log.json と同様に。<br/>
    →以前は、'\f'区切りの妙なフォーマットだった。
</td></tr>
<tr><td>save:const.sn.loopPlaying</td><td>'{}'</td><td>json</td><td>ループ中のサウンドバッファ</td></tr>
<tr><td>save:const.sn.scriptFn</td><td>''</td><td>スクリプト名</td><td>最後に[<a href="tag.htm#record_place" target="_blank" rel="noopener">record_place</a>]したスクリプト名</td></tr>
<tr><td>save:const.sn.scriptIdx</td><td>0</td><td>整数</td><td>最後に[<a href="tag.htm#record_place" target="_blank" rel="noopener">record_place</a>]したスクリプトインデックス(行番号ではなく内部トークン単位)</td></tr>
<tr><td>save:const.sn.layer.(文字レイヤ名).enabled</td><td>true</td><td>true、false</td><td>文字レイヤのenabled値</td></tr>
</table>

<br/>
 音量関連変数が save: と sys: で似たような名前の変数があるので解説します。<br/>
<br/>

 ・音量関連変数(値域は全て0.0〜1.0)<br/>
  ・アプリ全体の基準音量:sys:sn.sound.global_volume<br/>
  ・基準音量:sys:const.an.sound.(バッファ名).volume【設定画面で設定する値】<br/>
  ・目標音量:save:const.an.sound.(バッファ名).volume【[playse]系で指定する値】<br/>
<br/>
 ・実際の再生音量=基準音量 x 目標音量 x アプリ全体の基準音量<br/>
  ([volume volume=0.2]、[playbgm volume=0.5]だと 0.2 x 0.5 x アプリ全体の基準音量)<br/>
<br/>
 ・再生中に[volume]volume属性指定時:音量を計算しなおす。<br/>
   アプリ全体の基準音量 = 1の時、<br/>
  ([volume volume=1.0][playse volume=0.5](再生音量 1.0 x 0.5 = 0.5)で再生中、[volume volume=0.7]で再生音量が 0.7 x 0.5 = 0.35 になる)<br/>


</p>
<h2 id="reserve_value_sys" class="w-heading">システム変数(sys:)</h2>
<h4>(セーブデータに関わらず)共通でセーブされる変数</h4>
<p class="mb2 px1">
    変数の変更が即時に保存される変数。<br/>
    セーブデータに関わらず、共通して使用する情報を保存する用途。(例:アルバム解放情報・ゲームの達成率など)<br/>
    <br/>
    <br/>
    ※スクリプターが自由に新たに値セット・取得できますが、SKYNovelが値を設定している変数や定数もあります。<br/>
    const.sn.〜、sn.〜という名前はSKYNovelが使いますので、皆さんは新規に作成しないで下さい。<br/>
    以下の表にあるモノを使うの(読み・書き)は全然OKです!<br/>
    (const.sn.〜は必ずしも定数ではなく、一部は実行中にSKYNovelが値を変更する場合があります)<br/>
    <br/>
    冒頭がconstな変数は、書く(設定)することができません。<br/>
    constでない変数は、設定するとその値がシステムに反映されます。<br/>
    例えば「&sys:TextLayer.Back.Alpha」はテキストウインドウの背景の濃度を変更できます。

<table><tr><th>変数名</th><th>初期値</th><th>値域・型</th><th>コメント</th></tr>
<tr><td>sys:TextLayer.Back.Alpha</td><td>1</td><td>0.0〜1.0;透過度</td><td>バック不透明度。テキストウインドウの背景の濃度。0.0で透明、1.0で不透明。</td></tr>
<tr><td>sys:const.sn.nativeWindow.x</td><td>0</td><td>実数;横座標</td><td rowspan="2">アプリウインドウの座標。画面左上を(0, 0)とする座標。[<a href="tag.htm#window" target="_blank" rel="noopener">window</a>]で変更できる</td></tr>
<tr><td>sys:const.sn.nativeWindow.y</td><td>0</td><td>実数;縦座標</td></tr>
<tr><td>sys:const.sn.save.place</td><td>1</td><td>1〜</td><td>次のセーブplaceを示す</td></tr>
<tr><td>sys:const.sn.sound.BGM.volume</td><td rowspan="4">1</td><td rowspan="4">0.0〜1.0</td><td>BGMの基準音量(buf="BGM"の効果音)<br/>[<a href="tag.htm#volume" target="_blank" rel="noopener">volume</a>]で変更できる</td></tr>
<tr><td>sys:const.sn.sound.SE.volume</td><td>効果音の基準音量(buf="SE"の効果音)<br/>[<a href="tag.htm#volume" target="_blank" rel="noopener">volume</a>]で変更できる</td></tr>
<tr><td>sys:const.sn.sound.SYS.volume</td><td>システムの基準音量(buf="SYS"の効果音)<br/>[<a href="tag.htm#volume" target="_blank" rel="noopener">volume</a>]で変更できる</td></tr>
<tr><td>sys:const.sn.sound.【buf】.volume</td><td>
    システムの基準音量(buf="【buf】"の効果音)<br/>[<a href="tag.htm#volume" target="_blank" rel="noopener">volume</a>]で変更できる<br/>任意のbufの基準音量<br/>
    [<a href="tag.htm#volume" target="_blank" rel="noopener">volume</a>]で変更できる<br/>
    <br/>
    [playse][fadese]系での volume属性や、「save:const.sn.sound.【buf】.volume」は目標音量であり、別物である点に注意
</td></tr>
<tr><td>sys:sn.auto.msecLineWait</td><td>500</td><td>0〜;ミリ秒</td><td>未読テキストの改行待ち時間(ミリ秒)<br/>※ここでの改行とは[l]の事</td></tr>
<tr><td>sys:sn.auto.msecLineWait_Kidoku</td><td>500</td><td>0〜;ミリ秒</td><td>既読テキストの改行待ち時間(ミリ秒)<br/>※ここでの改行とは[l]の事</td></tr>
<tr><td>sys:sn.auto.msecPageWait</td><td>3500</td><td>0〜;ミリ秒</td><td>未読テキストの改ページ待ち時間(ミリ秒)<br/>※ここでの改ページとは[p]の事</td></tr>
<tr><td>sys:sn.auto.msecPageWait_Kidoku</td><td>3500</td><td>0〜;ミリ秒</td><td>既読テキストの改ページ待ち時間(ミリ秒)<br/>※ここでの改ページとは[p]の事</td></tr>
<tr><td>sys:sn.skip.mode</td><td>'s'</td><td>文字列</td><td>スキップモード。<br/>
    sn.skip.enabled = trueの際、改行待ちや改ページ待ちをスキップするかどうかの動作を指定する。<br/>
    'l' …… 改行待ち=する、改ページ待ち=する<br/>
    'p' …… 改行待ち=しない、改ページ待ち=する<br/>
    's' …… 改行待ち=しない、改ページ待ち=しない<br/>
    (初期値="s")</td></tr>
<tr><td>sys:sn.sound.global_volume</td><td>1</td><td>0.0〜1.0</td><td>全体的な音量を設定する。バッファの実際の音量は「sys:const.sn.sound.【buf】.volume」x「save:const.sn.sound.【buf】.volume」x「全体的な音量」の値となる</td></tr>
<tr><td>sys:sn.sound.movie_volume</td><td>1</td><td>0.0〜1.0</td><td>ムービー音量を設定する。バッファの実際の音量はこの「ムービー音量」x「全体的な音量」の値となる</td></tr>
<tr><td>sys:sn.tagCh.canskip</td><td>true</td><td>true、false</td><td>テキストをクリックなどでスキップ可能か</td></tr>
<tr><td>sys:sn.tagCh.doWait</td><td>true</td><td>true、false</td><td>未読テキストにウェイトを掛けるか</td></tr>
<tr><td>sys:sn.tagCh.doWait_Kidoku</td><td>true</td><td>true、false</td><td>既読テキストにウェイトを掛けるか</td></tr>
<tr><td>sys:sn.tagCh.msecWait</td><td>10</td><td>0〜;ミリ秒</td><td>未読テキスト待ち時間(ミリ秒)</td></tr>
<tr><td>sys:sn.tagCh.msecWait_Kidoku</td><td>10</td><td>0〜;ミリ秒</td><td>既読テキスト待ち時間(ミリ秒)</td></tr>
</table>

</p>
<h2 id="reserve_value_tmp" class="w-heading">雑用変数(tmp:)</h2>
<h4>雑用の変数</h4>
<p class="mb2 px1">
    保存しない変数です。セーブデータを読み込んでも変化せず、ゲームを終了すると消え去ります。<br/>
    SKYNovelが「保存する必要は無いけど値を使いたいだろうから変数に」している変数もあります。<br/>
    <br/>
    ※スクリプターが自由に新たに値セット・取得できますが、SKYNovelが値を設定している変数や定数もあります。<br/>
    const.sn.〜、sn.〜という名前はSKYNovelが使いますので、皆さんは新規に作成しないで下さい。<br/>
    以下の表にあるモノを使うの(読み・書き)は全然OKです!<br/>
    (const.sn.〜は必ずしも定数ではなく、一部は実行中にSKYNovelが値を変更する場合があります)<br/>
    <br/>
    冒頭がconstな変数は、書く(設定)することができません。<br/>
    constでない変数は、設定するとその値がシステムに反映されます。<br/>
    例えば「sn.auto.enabled」は自動読みすすみモードかどうかを変更できます。

<table><tr><th>変数名</th><th>初期値</th><th>値域・型</th><th>コメント</th></tr>
<tr><td>const.Date.getDateStr</td><td>取得の瞬間の日時</td><td>"2019/02/10 15:47"形式</td><td>変数参照時の日時を返す</td></tr>
<tr><td>const.Date.getTime</td><td></td><td>0〜;ミリ秒</td><td>JavaScriptの(new Date).getTime()</td></tr>
<tr><td>const.sn.bookmark.json</td><td>'[]'</td><td>json</td><td>SKYNovel内部によるsave:の管理用</td></tr>
<tr><td>const.sn.config.(略)</td><td></td><td></td><td>
    prj.jsonの内容を返す。<br/>
    例えば「const.sn.config.window.width」だと画面の横幅を返す。
</td></tr>
<tr><td>const.sn.displayState</td><td>false</td><td>true、false</td><td>ウインドウ・フルスクリーン状態。trueならフルスクリーン</td></tr>
<tr><td>const.sn.frm.(フレーム名)</td><td>true</td><td>true、false</td><td>[add_frame]でロードされた id属性が存在するか</td></tr>
<tr><td>const.sn.frm.(フレーム名).alpha</td><td>1</td><td>0.0〜1.0;透過度</td><td>フレームの不透明度</td></tr>
<tr><td>const.sn.frm.(フレーム名).x</td><td>0</td><td>実数;横座標</td><td rowspan="2">フレームの座標。画面左上を(0, 0)とする座標。leftやtopでないことに注意</td></tr>
<tr><td>const.sn.frm.(フレーム名).y</td><td>0</td><td>実数;縦座標</td></tr>
<tr><td>const.sn.frm.(フレーム名).scale_x</td><td>1</td><td>true、false</td><td>cssでのtransform: scaleの値</td></tr>
<tr><td>const.sn.frm.(フレーム名).scale_y</td><td>1</td><td>true、false</td><td>cssでのtransform: scaleの値</td></tr>
<tr><td>const.sn.frm.(フレーム名).rotate</td><td>0</td><td>true、false</td><td>cssでのrotate、回転角度(単位:deg 度)、正の値は時計回り</td></tr>
<tr><td>const.sn.frm.(フレーム名).width</td><td>prjのアプリ横幅画面サイズ</td><td>1〜</td><td>フレームの横幅</td></tr>
<tr><td>const.sn.frm.(フレーム名).height</td><td>prjのアプリ縦幅画面サイズ</td><td>1〜</td><td>フレームの縦幅</td></tr>
<tr><td>const.sn.frm.(フレーム名).visible</td><td>true</td><td>true、false</td><td>フレームが表示されているか。visible属性の値を返す</td></tr>
<tr><td>const.sn.isApp</td><td>false</td><td>true、false</td><td>アプリ版か</td></tr>
<tr><td>const.sn.isDbg</td><td>false</td><td>true、false</td><td>デバッグモードか</td></tr>
<tr><td>const.sn.isPackaged</td><td></td><td>true、false</td><td>パッケージされたアプリか(Electron API - app.isPackaged)</td></tr>
<tr><td>const.sn.isDarkMode</td><td>環境による</td><td>true、false</td><td>ダークモードか</td></tr>
<tr><td>const.sn.isDebugger</td><td>true</td><td>true、false</td><td>ブラウザ実行、それもVSCode・npmによる「npm: webタスク」上での実行か</td></tr>
<tr><td>const.sn.isFirstBoot</td><td>false</td><td>true、false</td><td>ゲームがインストールされてから、初めての起動か(起動されるまでデータが空だったか)</td></tr>
<tr><td>const.sn.isKidoku</td><td>true</td><td>true、false</td><td>この変数を参照した位置は既読か。参照「後」必ず既読になる点に注意</td></tr>
<tr><td>const.sn.key.alternate</td><td>false</td><td>true、false</td><td>ALTキー(MacならOptionキー)が押されているか</td></tr>
<tr><td>const.sn.key.back</td><td>false</td><td>true、false</td><td>back 〃</td></tr>
<tr><td>const.sn.key.command</td><td>false</td><td>true、false</td><td>command 〃</td></tr>
<tr><td>const.sn.key.control</td><td>false</td><td>true、false</td><td>control 〃</td></tr>
<tr><td>const.sn.key.end</td><td>false</td><td>true、false</td><td>end 〃</td></tr>
<tr><td>const.sn.key.escape</td><td>false</td><td>true、false</td><td>escape 〃</td></tr>
<tr><td>const.sn.last_page_plain_text</td><td>''</td><td>文字列</td><td>そのページの履歴テキスト(《》文法とルビを含まない)</td></tr>
<tr><td>const.sn.last_page_text</td><td>''</td><td>文字列</td><td>そのページの履歴テキスト(《》文法もそのまま)</td></tr>
<tr><td>const.sn.lay.(レイヤ名)</td><td>true</td><td>true、false</td><td>レイヤが[add_lay]され存在するか</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).alpha</td><td>0.0〜1.0</td><td>0.0〜1.0;透過度</td><td>レイヤの不透明度</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).width</td><td>1</td><td>1〜</td><td>レイヤの横幅。ただし文字レイヤの場合は1、画像レイヤの場合、画像読込後でないと0</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).height</td><td>1</td><td>1〜</td><td>レイヤの縦幅。ただし文字レイヤの場合は1、画像レイヤの場合、画像読込後でないと0</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).visible</td><td>true</td><td>true、false</td><td>レイヤが表示されているか。visible属性の値を返す</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).x</td><td>0</td><td>実数;横座標</td><td rowspan="2">レイヤの座標。画面左上を(0, 0)とする座標。leftやtopでないことに注意</td></tr>
<tr><td>const.sn.lay.(レイヤ名).(foreかback).y</td><td>0</td><td>実数;縦座標</td></tr>
<tr><td>const.sn.Math.PI</td><td>3.141592653589793</td><td>実数</td><td>円周率</td></tr>
<tr><td>const.sn.navigator.language</td><td>(ユーザーの言語)</td><td>文字列</td><td>
    ユーザーが最優先に設定している言語設定(<a href="https://ja.wikipedia.org/wiki/IETF%E8%A8%80%E8%AA%9E%E3%82%BF%E3%82%B0">IETF言語タグ - Wikipedia</a>)を返す。<br/>
    BCP47 で定義された言語バージョン、"jp"、"en"、"en-US"、"fr"、"fr-FR"、"es-ES" など(→<a href="https://developer.mozilla.org/ja/docs/Web/API/Navigator/language">Navigator.language - Web API | MDN</a>)<br/>
    <br/>
    ※AIRNovelにおける「<a href="https://famibee.web.fc2.com/tag_dev/dev.htm#reserve_value" target="_blank">const.flash.system.Capabilities.language</a>」にあたる
</td></tr>
<tr><td>const.sn.needClick2Play</td><td>環境による</td><td>true、false</td><td>ブラウザ実行で、クリックされるまで音声再生が差し止められている状態か。なにかクリックされれば falseになる</td></tr>
<tr><td>const.sn.platform</td><td>環境による</td><td>json</td><td>
    プラットフォーム情報。詳細は<a href="https://github.com/bestiejs/platform.js/blob/master/doc/README.md#platformosfamily" target="_blank" rel="noopener">Platform.js </a>を参照のこと。<br/>
    例えば <a href="https://github.com/bestiejs/platform.js/blob/master/doc/README.md#platformosfamily" target="_blank" rel="noopener">const.sn.platform.os.family</a> だと、「OS X」「Android」などを返す
</td></tr>
<tr><td> <span style="text-decoration: line-through">const.sn.sLog</span>【2019/07/28変名】<br/>
const.sn.log.json
</td><td>"[{'txt':''}]"</td><td>json</td><td>_log.snが_log.htmに渡す用、1ページずつ{}に分割してjson化して返す</td></tr>
<tr><td>const.sn.sound.codecs</td><td>環境による</td><td>json</td><td>
    ゲーム実行環境がこのコーデックをサポートしているか。<br/>
    mp3、m4a、ogg、aac、webm、flac、wavなど
</td></tr>
<tr><td>const.sn.sound.【buf】.playing</td><td>再生状態による</td><td>true、false</td><td>
    サウンドバッファが再生中か<br/>
    任意のbuf属性を指定した[<a href="tag.htm#playse" target="_blank" rel="noopener">playse</a> buf=【buf】] 実行で自動で生まれる変数
</td></tr>
<tr><td>const.sn.aIfStk.length</td><td>1</td><td>1〜</td><td>IFスタックの深さ([if]するたびに増)</td></tr>
<tr><td>const.sn.vctCallStk.length</td><td>0</td><td>0〜</td><td>コールスタックの深さ([call]するたびに増)</td></tr>
<tr><td>sn.auto.enabled</td><td>false</td><td>true、false</td><td>自動読みすすみモードかどうか</td></tr>
<tr><td>sn.button.fontFamily</td><td>"'Hiragino Sans', 'Hiragino Kaku Gothic ProN', '游ゴシック Medium', meiryo, sans-serif"</td><td>文字列</td><td>文字ボタンフォントを指定</td></tr>
<tr><td>sn.event.domdata.(任意)</td><td>''</td><td>場合による</td><td>[<a href="tag.htm#event" target="_blank" rel="noopener">event</a>]でフレーム内のHTML要素に登録したイベントで、そのイベント発生時、HTML要素のdata-(任意)属性で指定された値。使い道は開発者が自由に決めていい</td></tr>
<tr><td>sn.eventArg</td><td>''</td><td>場合による</td><td>[<a href="tag.htm#button" target="_blank" rel="noopener">button</a>]等のイベント発生時、そのボタンタグのarg属性で指定された値。使い道は開発者が自由に決めていい</td></tr>
<tr><td>sn.eventLabel</td><td>''</td><td>場合による</td><td>[<a href="tag.htm#button" target="_blank" rel="noopener">button</a>]等のイベント発生時、そのボタンタグのlabel属性で指定された値。使い道は開発者が自由に決めていい</td></tr>
<tr><td>sn.skip.all</td><td>false</td><td>true、false</td><td>false(初期値)なら既読のみをスキップ</td></tr>
<tr><td>sn.skip.enabled</td><td>false</td><td>true、false</td><td>次の選択肢(/未読)まで進む が有効か</td></tr>
<tr><td>sn.tagL.enabled</td><td>true</td><td>true、false</td><td>頁末まで一気に読み進むか(l無視)</td></tr>
</table>


</p>
<h2 id="cond" class="w-heading">式の評価と条件分岐</h2>
<h4>[if]タグやcond属性について</h4>
<p class="mb2 px1">

     変数の中身を値や他の変数と比較し、その結果によって処理をしたり、しなかったりする事が出来ます。<br/>
     これは<span style="color:red;">非常に重要なテクニックで、変数の使い道の半分はこのため</span>にあります。<br/>
     例えば変数「tmp:好感度」が75の時、<br/>
    <div class="alert alert-def">[title text="割と好かれてる" cond="tmp:好感度 &gt;= 50"]</div>
    という文を処理した時、cond属性の文字列に対し「式の評価」が行なわれます。<br/>
     変数の値を考えると「75 &gt;= 50」です。「&gt;=」に注目すると「75は50より大なり・大きいか、同じ」なので、式は成立します。<br/>
    <div class="alert alert-def">これを「式の評価が真」または「true」と言います。</div>
    「&gt;=」は演算子といいます。色んな種類があります。<br/>
    ・a &gt;= b は「aとbは同じ値・または aがbより大きい なら真」→日本語でいう「aはb以上」<br/>
    ・a &gt; b は「aよりbが小さい なら真」(aとbは同じ値 は負)→日本語でいう「aはbより大きい」<br/>
    ・a &lt;= b は「aとbは同じ値・または aよりbが大きい なら真」→日本語でいう「aはb以下」<br/>
    ・a &lt; b は「aよりbが大きい なら真」(aとbは同じ値 は負)→日本語でいう「aはb未満」<br/>
    ・a == b は「aとbは同じ値」<br/>
    ・a != b は「aとbは違う値」(違っていれば、大きくても小さくても構わない)<br/>
    <br/>
    <span style="color:red;">cond属性はあらゆるタグやマクロに必ずある属性</span>で、「式の評価が真の場合のみ、そのタグ(マクロ)を実行する」という働きがあります。<br/>
     よって<a href="tag.htm#title">[title]</a>によりアプリウインドウのタイトル文字列が設定されます。<br/>
    <br/>
    <br/>
     別の場合、例えば「tmp:好感度」が49の時には[title]は処理されません。式が成立しないからです。<br/>
    <div class="alert alert-def">これを「式の評価が偽」または「false」と言います。</div>
    <br/>
     このように「式を評価」し、処理を変える事をプログラム言語的に「条件分岐」と言います。<br/>
    <br/>

    <hr/>
     よりダイナミックに処理の流れを変える、条件分岐方法があります。<br/>
    <a href="tag.htm#jump">[jump]</a>、<a href="tag.htm#call">[call]</a>に対しcond属性で式の評価を行なうのです。<br/>
     条件が成立したときだけ<a href="tag.htm#jump">[jump]</a>、<a href="tag.htm#call">[call]</a>するわけです。<br/>
    <br/>

    <hr/>
     さらに高級言語によくある、if文もあります。<br/>
     <a href="tag.htm#if">[if]</a>、<a href="tag.htm#elsif">[elsif]</a>、<a href="tag.htm#else">[else]</a>、<a href="tag.htm#endif">[endif]</a>をサポートしています。<br/>
    <br/>
     例えば以下のように記述すると、<br/>
    <div class="alert alert-def">
        [if exp=false]<br/>
            い<br/>
        [elsif exp=true] <br/>
            ろ<br/>
        [else]<br/>
            は<br/>
        [endif]
    </div>
     文字レイヤに「ろ」と表示されます。<br/>
     それぞれのタグの並びはこの通りで無ければなりませんが、<a href="tag.htm#elsif">[elsif]</a>は必要ならいくつあってもいいし、なくてもいいし、<a href="tag.htm#else">[else]</a>も不要ならなくてもいいです。<br/>
    <br/>
     <a href="tag.htm#if">[if]</a>と<a href="tag.htm#elsif">[elsif]</a>などの区間を、「ifブロック」と呼びます。<br/>
     ifブロックでは<span style="color:red;">ラベルの記述「*xxxx」以外なら</span>全ての記述が出来ます。<br/>
     タグやマクロ、<a href="tag.htm#jump">[jump]</a>、<a href="tag.htm#call">[call]</a>によるジャンプやコールも可能です。<br/>
    <br/>
    <div class="alert alert-success">IF文サンプル(<a href="https://famibee.github.io/SKYNovel_gallery/?cur=tag_if" style="color: black;" target="_blank" rel="noopener">別ページで開く</a>)</div>


</p>
<h2 id="calc" class="w-heading">式で使える演算子と関数</h2>
<h4>四則演算以外にも、他の高級言語のような演算子や関数が使えます。</h4>
<p class="mb2 px1">

    式で使える演算子は以下の通りです。<br/>
    【参考】<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Operator_precedence">演算子の優先順位 - JavaScript | MDN</a><br/>
    <ul type="disc">
        <li>【( … )】グループ化(いわゆる括弧)</li>
        <li>【! …】論理 NOT (!)</li>
        <li>【- …】単項 -</li>
        <li>【… ** …】べき乗 (**)</li>
        <li>【… * …】乗算 (*)</li>
        <li>【… / …】除算 (/)</li>
        <li>【… % …】剰余 (%)</li>
        <li>【… + …】加算 (+)</li>
        <li>【… - …】減算(-)</li>
        <li>【… << …】左ビットシフト (<<)</li>
        <li>【… >> …】右ビットシフト</li>
        <li>【… >>> …】符号なし右ビットシフト (>>>)</li>
        <li>【… < …】小なり (<)</li>
        <li>【… <= …】小なりイコール (<=)</li>
        <li>【… > …】大なり (>)</li>
        <li>【… >= …】大なりイコール (>=)</li>
        <li>【… == …】等価 (==)</li>
        <li>【… != …】不等価 (!=)</li>
        <li>【… === …】厳密等価 (===)</li>
        <li>【… !== …】厳密不等価 (!==)</li>
        <li>【… & …】ビット単位 AND (&)</li>
        <li>【… ^ …】ビット単位 XOR (^)</li>
        <li>【… | …】ビット単位 OR (|)</li>
        <li>【… && …】論理 AND (&&)</li>
        <li>【… || …】論理 OR (||)</li>
        <li>【… ? … : …】条件(三項)演算子</li>
    </ul>
    式で使える関数は以下の通りです。<br/>
    <ul type="disc">
        <li>【int()】実数を整数に</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/parseInt">parseInt()</a>】文字列を整数に変換</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number">Number()</a>】文字列を実数に変換</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Boolean">Boolean()</a>】論理値でない値から論理値へ変換</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/ceil">ceil()</a>】与えた数以上の最小の整数</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/floor">floor()</a>】与えられた数値以下の最大の整数</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math/round">round()</a>】与えた数を四捨五入</li>
        <li>【<a href="https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/isNaN">isNaN()</a>】引数が NaN (非数) かどうか</li>
    </ul>


</p>
<h2 id="an2sn" class="w-heading">AIRNovelからの変更点</h2>
<h4>AIRNovelからの変更点をざっくり説明します。</h4>
<p class="mb2 px1">

    <ul type="disc">
    <li>組み込み変数名が変わりました。<br/>旧)save:const.<span class="red" style="font-weight: bold;">an</span>.scriptFn<br/>新)save:const.<span style="color: blue; font-weight: bold;">sn</span>.scriptFn</li>
    <li>定数が変数になったモノも。<br/>例)const.an.eventArg → sn.eventArg</li>
    </ul>
    詳細は当ページの「組み込み変数」関連の記事をご覧下さい。<br/>


</p>
<h2 id="ruby" class="w-heading">ルビ記法</h2>
<h4>タグの他に、《》(二重山括弧)を使用した“ルビ記法”が使用できます。</h4>
<p class="mb2 px1">
    ここではルビを打たれる本文を「親文字」と表記します。<br/>
    →<a href="https://famibee.github.io/SKYNovel_gallery/index.html?cur=ruby" target="_blank" rel="noopener">参考(機能ギャラリー・ルビ記法)</a>

    <ul type="disc">
        <li>
            |(全角縦線、似て非なる文字があるのでこのマニュアルからコピペ推奨)はルビ開始を示す記号で、《》(二重山括弧)はルビを指定します。
            <p class="mb2 px1">
                <p style="background-color: lightgrey;">
                    安全[ruby2 t="剃刀" r="かみそり"]の
                </p>
                は
                <p style="background-color: lightgrey;">
                    安全|剃刀《かみそり》の
                </p>
                と同様です。<br/>
                
                <amp-img src="pic/ruby1.png" width="77" height="147" alt=""></amp-img><br/>
            </p>
        </li>
        <li>
            |(全角縦線)は漢字と平仮名・句読点などの境界なら省略できます。
            <p style="background-color: lightgrey;">
                心を撲《う》たずには
            </p>
        </li>
        <li>
            ルビを半角空白で区切ると、その文字群単位で親文字にルビを振ります。
            <p style="background-color: lightgrey;">
                、所謂《いはゆる》〜(省略)〜廻つた独楽《こ ま》が
            </p>
            <amp-img src="pic/ruby2.png" width="125" height="171" alt=""></amp-img><br/>
            「こ」と「ま」の間に半角空白が入っているので、独に「こ」、楽に「ま」がルビとして振られます。<br/>
            <br/>
        </li>
        <li>
            ルビのルビ揃えは、[lay][span]のr_align属性で文字レイヤに設定しますが、ルビごとに指定することも出来ます。<br/>
            記法は《》(二重山括弧)の中に「r_align属性 + |(全角縦線)+ルビ文字」です。<br/>
            文字レイヤのr_align属性がenter(中付き)だとして……<br/>
            <p style="background-color: lightgrey;">
                雷《いかずち》さらに雷《left|いかずち》さらに雷《right|いかずち》さらに雷《いかずち》を
            </p>
            <amp-img src="pic/ruby3.png" width="383" height="55" alt=""></amp-img><br/>
            <br/>
            left(肩付き)で「先頭親文字から揃え」られ、<br/>
            right(右/下揃え)で「末尾親文字から揃え」られています。<br/>
            省略時は文字レイヤへの[lay][span]のr_align属性に従います。<br/>
            <br/>
        </li>
        <li>
            《*》(半角アスタリスクを一文字)で傍点を打ちます。<br/>
            親文字全てに一つずつ自動で打ちます。<br/>
            ルビ揃えは自動で「center」になります。<br/>
            <br/>
        </li>
        <li>
            《*★》とすると傍点を変更でき、「★」で傍点を打ちます。<br/>
            傍点は文法が破綻しないもの(「》|」以外)なら自由です。<br/>
            <br/>
        </li>
        <li>
            ルビ記法《》内は URLエスケープされます。これにより文法上直接記述できない文字(|や《》や一文字マクロ)も表示できるようになります。<br/>
            |(縦棒)を使用する場合、「%ef%bd%9c」と記述します。<br/>
            《》(二重山括弧)を使用する場合、「%e3%80%8a」「%e3%80%8b」と記述します。<br/>
            「%」を使用する場合、「%25」と記述します。<br/>
            <br/>
        </li>
        <li>
            ルビ揃えや URLエスケープを組み合わせることができます。
            <p style="background-color: lightgrey;">
            「|考えるな《center|Don't%20think,》。|感じる《Feel.》んだ」
            </p>
            <br/>
        </li>
    </ul>


</p>
<h2 id="font" class="w-heading">フォントの導入</h2>
<h4>フォントの導入・指定方法について解説していきます。</h4>
<p class="mb2 px1">
    <h4 style="color: red">【重要】2022-03-09リリースの「VSCode拡張機能 v3.20.1」からは【2.使用する字形だけ入ったフォントファイルを作成】などが自動化されています</h4>
    <p class="mb2 px1">
        <a href="https://famibee.blog.fc2.com/blog-entry-790.html" target="_blank" rel="noopener">電子演劇部 【更新】VSCode拡張機能 v3.20.1:フォントサイズ最適化機能追加</a>
    </p>
    <hr/>

    <h4>1.フォントを準備</h4>
    <p class="mb2 px1">
        ※以下をサンプルとして話を進めます。字形が多いのでだいたい入ってるだろうし。<br/>
        ・<a href="https://forest.watch.impress.co.jp/library/software/ipamjfont/" target="_blank" rel="noopener">「IPAmj明朝フォント」戸籍統一文字などに含まれる6万字の漢字を収録したフォント - 窓の杜</a><br/>
        ・【参考資料】<a href="http://www.hirok-k.com/blog/751.html" target="_blank" rel="noopener">日本語フリーフォントをwebフォント化する4ステップ / hirok-k.com</a><br/>
    </p>
    <h4>2.使用する字形だけ入ったフォントファイルを作成</h4>
    <p class="mb2 px1">
        ・<a href="https://opentype.jp/subsetfontmk.html">サブセットフォントメーカー</a>(Win / Mac版あり)<br/>
            【フォントに格納する文字】へ本文をコピペして、ツールに貼って変換します。<br/>
            ※【書体名を変更する】は使わない<br/>
            ※ただ縦書きフォントでは「──」【……】を渡すと横書き文字が入って上手くいかないので、削除しておく。<br/>
            <br/>
            全ての文字が入ったフォントファイルは大きすぎる。ロード時間も掛かる。<br/>
            上記手順で、「初音館にて」ではサイズが1/100ほどになった。<br/>
            ・ipamjm.woff2<br/>
              23.1MB(全部入り)<br/>
              344 KB(初音館で使用しているモノのみ)<br/>
              343540 /23065440 = 0.014894145<br/>
    </p>
    <h4>3.(可能なら圧縮率の高い)woff2に変換</h4>
    <p class="mb2 px1">
        ・<a href="https://memorva.jp/memo/html/css_webfont_woff_woff2_converter_henkan_soft.php">WebフォントWOFF、WOFF2形式に変換できるフリーソフト</a><br/>
        ・<a href="https://opentype.jp/woffconv.html">WOFFコンバータ</a>(Win / Mac版あり)<br/>
         SKYNovelがサポートするフォント拡張子は「woff2, otf, ttf」です。※ブラウザによる<br/>
    </p>
    <h4>4.生成ファイルをプロジェクトフォルダにコピー</h4>
    <p class="mb2 px1">
        ※どこでもいいが、サンプルでは script フォルダに。
    </p>
    <h4>5.設定画面(またはsetting.sn)の「def_fonts」でフォント名を指定すると、本文に反映される</h4>
    <p class="mb2 px1">
        <amp-img src="pic/font0.jpg" width="500" height="144" layout="responsive"></amp-img>
        sn.button.fontFamily で文字ボタンのフォントを指定できます。<br/>
    </p>
    <h4>6.部分的・一時的に変更したい場合は、</h4>
    <p class="mb2 px1">
        [span style='font-family: QuiMi_mincho;']フォント[span] などと使う。<br/>
        戻すときも同様。<br/>
    </p>
    <h4>7.フォント利用サンプル</h4>
    <p class="mb2 px1">
        フォント利用サンプルがあります。<br/>
        ローカルフォントファイルと、Webフォントを両方使用しています。<br/>
        <a href="https://famibee.blog.fc2.com/blog-entry-661.html">電子演劇部 SKYNovel機能ギャラリー:フォント利用サンプル追加</a>
    </p>





</p>
<h2 id="crypt" class="w-heading">素材や・変数データを暗号化</h2>
<h4>暗号化機能について解説していきます。</h4>
<p class="mb2 px1">
    <h4>1.暗号化する</h4>
    <p class="mb2 px1">
        ※<a href="https://marketplace.visualstudio.com/items?itemName=famibee2.skynovel2" target="_blank" rel="noopener">VSCode用拡張機能 SKYNovel</a> の【開発ツール】の【暗号化】がその機能です。<br/>
        <amp-img src="pic/crypt0.png" width="500" height="360" layout="responsive"></amp-img>
        <br/>
        「暗号化」の「しない」を「する」に変更すると、暗号化します。<br/>
        <amp-img src="pic/crypt1.png" width="500" height="128" layout="responsive"></amp-img>
    </p>
    <h4>2.「snスクリプト」「path.json」「prj.json」などの様子</h4>
    <p class="mb2 px1">
        ※暗号化ファイルは、「prj下」から「crypt_prj下」に変換・出力されます。<br/>
        <amp-img src="pic/crypt2.jpg" width="500" height="1688" layout="responsive"></amp-img>
    </p>
    <h4>3.セーブデータ、ブラウザ版はこの通り。「sys_」とかです。</h4>
    <p class="mb2 px1">
        <amp-img src="pic/crypt3.png" width="1500" height="668" layout="responsive"></amp-img>
    </p>
    <h4>4.セーブデータ、アプリ版はこの通り。</h4>
    <p class="mb2 px1">
        <amp-img src="pic/crypt4.png" width="1456" height="950" layout="responsive"></amp-img>
         暗号化データは「data_.json」です。<br/>
         暗号化アプリリリース時は「data.json」は作らず、暗号化データのみで動作します。<br/>
    </p>


</p>
<h2 id="save_path" class="w-heading">セーブデータの保存場所</h2>
<p class="mb2 px1">
    <h3>A)ブラウザ版</h3>
    <h4>OSに関わらず、ブラウザのローカルストレージに保存されます。</h4>
    <p class="mb2 px1">
        Chrome なら [Application]タブ - [Storage] - [Local Storage]下で、[プロジェクト名]と同じ[Key]の三つ(kidoku・mark・sys)です。<br/>
        <amp-img src="pic/save_path_web.jpg" width="500" height="328" layout="responsive"></amp-img>
    </p>

    <h3>B)アプリ版(通常実行)</h3>
    <h4>1.Macの場合は下記のPathにファイルが保存されます。</h4>
    <p class="mb2 px1">
        /Users/&lt;ユーザー名&gt;/Library/Application Support/&lt;アプリ名&gt;/storage/data.json
    </p>
    <h4>2.Windowsの場合は下記のPathにファイルが保存されます</h4>
    <p class="mb2 px1">
        C:\Users\&lt;ユーザー名&gt;\AppData\Roaming\&lt;アプリ名&gt;\storage\data.json
    </p>
    <h4>3.Linuxの場合は下記のPathにファイルが保存されます</h4>
    <p class="mb2 px1">
        ~/.config/&lt;アプリ名&gt;/storage/data.json
    </p>
    <p class="mb2 px1">
        <amp-img src="pic/save_path_app.jpg" width="500" height="326" layout="responsive"></amp-img>
    </p>

    <h3>C)アプリ版(デバッグ実行)</h3>
    <h4>OSに関わらず、下記のPathにファイルが保存されます。</h4>
    <p class="mb2 px1">
        【プロジェクトフォルダ】/.vscode/storage/<br/>
        <amp-img src="pic/save_path_dbg.png" width="500" height="342" layout="responsive"></amp-img>
    </p>

</p>
<h2 id="on_browser" class="w-heading">ブラウザ版の公開方法</h2>
<p class="mb2 px1">
    <h4>1.必要なもの、以下の三つのみです。</h4>
    <p class="mb2 px1">
        ・web.htm(web/web.jsへのパスが記述されている。必要なら変更)<br/>
        ・web/web.js<br/>
        ・prjフォルダ丸ごと(web.htmと同じフォルダに入れる)<br/>
           ※暗号化した場合は crypt_prjフォルダです。
    </p>
    <h4>2.上記のファイルを、FTPなどで公開します。</h4>
    <p class="mb2 px1">
        必ず実行してテストしましょう。
    </p>


</p>


</section></article>
</main>

<footer class="ampstart-footer flex flex-column items-center pxy3">
    <nav class="ampstart-footer-nav">
        <ul class="list-reset flex flex-wrap mb3">
<li class="px1"><a class="text-decoration-none caps h5" href="https://github.com/ampproject/amp-by-example/issues/new"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="22.2" viewbox="0 0 53 49"><path d="M45 6.9c-1.6 1-3.3 1.6-5.2 2-1.5-1.6-3.6-2.6-5.9-2.6-4.5 0-8.2 3.7-8.2 8.3 0 .6.1 1.3.2 1.9-6.8-.4-12.8-3.7-16.8-8.7C8.4 9 8 10.5 8 12c0 2.8 1.4 5.4 3.6 6.9-1.3-.1-2.6-.5-3.7-1.1v.1c0 4 2.8 7.4 6.6 8.1-.7.2-1.5.3-2.2.3-.5 0-1 0-1.5-.1 1 3.3 4 5.7 7.6 5.7-2.8 2.2-6.3 3.6-10.2 3.6-.6 0-1.3-.1-1.9-.1 3.6 2.3 7.9 3.7 12.5 3.7 15.1 0 23.3-12.6 23.3-23.6 0-.3 0-.7-.1-1 1.6-1.2 3-2.7 4.1-4.3-1.4.6-3 1.1-4.7 1.3 1.7-1 3-2.7 3.6-4.6" class="ampstart-icon ampstart-icon-twitter"/></svg>feedback</a></li>
<li class="px1"><a class="text-decoration-none caps h5" href="https://github.com/ampproject/amp-by-example"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 64.000000 64.000000"><path d="M22.4 1.4C-.8 9-7.4 38.4 10.5 54.9 14.7 58.8 20.4 62 23 62c.5 0 1-1.6 1-3.5 0-3.3-.2-3.5-3.5-3.5-3.5 0-4.2-.5-9-6.6-4.4-5.6-2.3-6.2 3.2-.9 4.2 4 7.5 4.5 9.8 1.2 1.4-2.1 1.4-2.2-.7-3-6-2.3-8.8-4.2-10.2-7.2-2.1-4.3-2.1-12.4 0-15.3.8-1.2 1.2-2.7.9-3.2-1-1.6.5-7 1.8-7 .7 0 2.4.6 3.8 1.4 1.7.9 6 1.4 11.9 1.4s10.2-.5 11.9-1.4c1.4-.8 3.1-1.4 3.8-1.4 1.3 0 2.8 5.4 1.8 7-.3.5.1 2 .9 3.2 1.8 2.5 2.1 10.3.7 14.1-1.4 3.6-5 6.6-9.3 7.8-3.3.9-3.7 1.2-2.8 2.9.5 1 1 4.6 1 7.9 0 3.5.4 6.1 1 6.1 5.2 0 15.8-8.8 19.8-16.5 2.3-4.3 2.7-6.3 2.7-13.5 0-7-.4-9.4-2.4-13.5C57.9 12.2 51.8 6 45.6 3 39.6.2 28.5-.6 22.4 1.4z" class="ampstart-icon"/></svg>github</a></li>
<li class="px1"><a href="https://creativecommons.org/licenses/by/4.0/" rel="nofollow" aria-label="Page Document License"><amp-img src="https://camo.githubusercontent.com/45b46deab81a0adb3164212be341f1dd65111cf3/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d43432532304259253230342e302d6c69676874677265792e737667" alt="License: CC BY 4.0" width="116" height="20" data-canonical-src="https://img.shields.io/badge/License-CC%20BY%204.0-lightgrey.svg" style="max-width:100%;"></amp-img></a></li>
        </ul>
    </nav>
    <small>AMP by Example is a part of Accelerated Mobile Pages Project</small>
</footer>
</body></html>