fix giscus and multilingual mode

This commit is contained in:
Mivinci 2022-11-09 16:03:19 +08:00
parent 0784b32a41
commit 1105d5e939
16 changed files with 424 additions and 211 deletions

View file

@ -90,14 +90,20 @@ a:hover {
2. Correct the odd `em` font sizing in all browsers. 2. Correct the odd `em` font sizing in all browsers.
*/ */
code,
kbd, kbd,
samp, samp,
pre { pre,
code {
--default-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; --default-font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-family: var(--font-mono, --default-font-mono); font-family: var(--font-mono, --default-font-mono);
} }
pre {
overflow-x: auto;
}
/* /*
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297) 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016) 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)

View file

@ -1,3 +1,6 @@
import "./theme"; import { setup_theme_switch } from "./theme"
import "./style"; import "./style";
import "./selectable"; import "./selectable";
setup_theme_switch('theme-switch')

View file

@ -1,39 +1,68 @@
const comment = '{{ .Site.Params.comment.provider }}'
const icon_light = '{{ index .Site.Params.switch 1 }}' const icon_light = '{{ index .Site.Params.switch 1 }}'
const icon_dark = '{{ index .Site.Params.switch 0 }}' const icon_dark = '{{ index .Site.Params.switch 0 }}'
const comment = '{{ .Site.Params.comment }}' const THEME_LIGHT = 'light'
const light = 'light', dark = 'dark' const THEME_DARK = 'dark'
const themeSwitcher = document.getElementById('theme-switcher') /** @type {HTMLElement} */
let toggler
/** @type {HTMLIFrameElement} */
let utterances
/** @type {HTMLIFrameElement} */
let giscus
// set switcher /** @param {string} id */
themeSwitcher.innerHTML = localStorage.theme === light ? icon_light : icon_dark export function setup_theme_switch(id) {
if (!toggler) {
toggler = document.getElementById(id)
}
toggler.innerHTML = localStorage.theme === THEME_LIGHT ? icon_light : icon_dark
toggler.addEventListener('click', switch_theme);
}
themeSwitcher.addEventListener('click', function () { function switch_theme() {
const currentTheme = localStorage.theme const current = localStorage.getItem('theme')
const newTheme = currentTheme === light ? dark : light const next = current === THEME_LIGHT ? THEME_DARK : THEME_LIGHT
// switch global theme switch_minima_theme(current, next)
switchMinimaTheme(currentTheme, newTheme)
// switch utterance theme if necessary switch (comment) {
if (comment === 'utterances') case 'utterances':
switchUtteranceTheme(`github-${newTheme}`) switch_utterances_theme(`github-${next}`)
}); break
case 'giscus':
switch_giscus_theme(next)
break
default:
}
}
function switchMinimaTheme(oldTheme, newTheme) { /**
* @param {string} current
* @param {string} next
*/
function switch_minima_theme(current, next) {
const { classList } = document.documentElement const { classList } = document.documentElement
const text = newTheme === light ? icon_light : icon_dark; const icon = next === THEME_LIGHT ? icon_light : icon_dark;
classList.remove(oldTheme); classList.remove(current);
classList.add(newTheme); classList.add(next);
localStorage.theme = newTheme; localStorage.setItem('theme', next);
themeSwitcher.innerHTML = text; toggler.innerHTML = icon;
} }
const utteranceClassName = '.utterances-frame' /** @param {string} theme */
let utterance; function switch_utterances_theme(theme) {
if (!utterances) {
function switchUtteranceTheme(theme) { utterances = document.querySelector('iframe.utterances-frame')
if (!utterance) utterance = document.querySelector(utteranceClassName) }
utterance.contentWindow.postMessage({type: 'set-theme', theme}, 'https://utteranc.es') utterances.contentWindow.postMessage({ type: 'set-theme', theme }, 'https://utteranc.es')
}
/** @param {string} theme */
function switch_giscus_theme(theme) {
if (!giscus) {
giscus = document.querySelector('iframe.giscus-frame')
}
giscus.contentWindow.postMessage({giscus: {setConfig: {theme}}}, 'https://giscus.app')
} }

View file

@ -40,9 +40,6 @@ params:
greet: Hello :) greet: Hello :)
# subtitle speficies a subtitle displayed right after the site title. # subtitle speficies a subtitle displayed right after the site title.
subtitle: subtitle:
# comment specifies which comment plugin to be used.
# currently available ones: disqus, utterances, giscus.
comment: utterances
# switch specifies two emojis to be used as the button toggling color themes. # switch specifies two emojis to be used as the button toggling color themes.
switch: ["🌚", "🌝"] switch: ["🌚", "🌝"]
# defaultTheme specifies a default theme to be used. # defaultTheme specifies a default theme to be used.
@ -59,35 +56,6 @@ params:
# post pages. If enabled, those you don't want a comment plugin to work on just # post pages. If enabled, those you don't want a comment plugin to work on just
# set `comment` to false in their front matters. # set `comment` to false in their front matters.
commentOnAllPosts: true commentOnAllPosts: true
# disqus specifies the configuration for Disqus.
disqus:
shortname: hugo-minima
# utterances specifies the configuration for Utterances.
# Check out https://utteranc.es for the following three attributes.
utterances:
repo: mivinci/hugo-theme-minima
issueTerm: pathname
label: comment
# giscus specifies the configuration for Giscus.
# Check out https://giscus.app for the following six attributes.
giscus:
repo: mivinci/hugo-theme-minima
repoId: MDEwOlJlcG9zaXRvcnkzODcxMjM2NDU=
category: Comments
categoryId: DIC_kwDOFxMJvc4CScQm
mapping: pathname
inputPostion: buttom
# **DEPRECATED**
# ovo(https://ovo.js.org) is a comment plugin written by the author of Minima but
# is now deprecated out of security issues.
ovo:
server: ""
placeholder: ""
# social is an array containing as many as social accounts to be displayed # social is an array containing as many as social accounts to be displayed
# in the buttom of every page. # in the buttom of every page.
social: social:
@ -100,16 +68,36 @@ params:
- name: "rss" - name: "rss"
url: "/index.xml" url: "/index.xml"
# comment specifies a comment plugin.
comment:
provider: giscus
# check out https://disqus.com/
disqus:
shortname: hugo-minima
# check out https://utteranc.es
utterances:
repo: mivinci/hugo-theme-minima
issueTerm: pathname
label: comment
# check out https://giscus.app
giscus:
repo: mivinci/hugo-theme-minima
repoId: MDEwOlJlcG9zaXRvcnkzODcxMjM2NDU=
category: Comments
categoryId: DIC_kwDOFxMJvc4CScQm
mapping: pathname
inputPosition: buttom # bottom | top
reactions: true
metadata: false
# menu.main is an array containing what is used as the navigator. # menu.main is an array containing what is used as the navigator.
menu: menu:
main: main:
- identifier: tags - identifier: tags
name: "Tags" name: "Tags"
url: "/tags"
weight: 2 weight: 2
- identifier: series - identifier: series
name: "Series" name: "Series"
url: "/series"
weight: 3 weight: 3
# taxonomies defines ways to classify yout posts. Below are some presets that # taxonomies defines ways to classify yout posts. Below are some presets that

View file

@ -4,7 +4,8 @@ title: Math Typesetting
date: 2021-07-18T10:52:59+08:00 date: 2021-07-18T10:52:59+08:00
description: A brief guide to setup KaTeX. description: A brief guide to setup KaTeX.
math: true math: true
categories: ["Markdown", "KaTeX"] tags:
- KaTex
--- ---
Mathematical notation in a Hugo project can be enabled by using third party JavaScript libraries. Mathematical notation in a Hugo project can be enabled by using third party JavaScript libraries.

View file

@ -0,0 +1,263 @@
---
author: Mermaid Team
title: Mermaid Diagrams
date: 2021-07-18T10:52:59+08:00
description: A brief guide to Mermaid syntax.
mermaid: true
tags:
- markdown
- mermaid
---
## Examples
The following are some examples of the diagrams, charts and graphs that can be made using Mermaid. Click here to jump into the [full syntax](http://mermaid-js.github.io/mermaid/).
<!-- <Flowchart> -->
### Flowchart
```
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
```mermaid
flowchart LR
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```
### Sequence diagram
```
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
### Gantt chart
```
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
```mermaid
gantt
section Section
Completed :done, des1, 2014-01-06,2014-01-08
Active :active, des2, 2014-01-07, 3d
Parallel 1 : des3, after des1, 1d
Parallel 2 : des4, after des1, 1d
Parallel 3 : des5, after des3, 1d
Parallel 4 : des6, after des4, 1d
```
### Class diagram
```
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
```mermaid
classDiagram
Class01 <|-- AveryLongClass : Cool
<<Interface>> Class01
Class09 --> C2 : Where am I?
Class09 --* C3
Class09 --|> Class07
Class07 : equals()
Class07 : Object[] elementData
Class01 : size()
Class01 : int chimp
Class01 : int gorilla
class Class10 {
<<service>>
int id
size()
}
```
### State diagram
```
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
```mermaid
stateDiagram-v2
[*] --> Still
Still --> [*]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
### Pie chart
```
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```
```mermaid
pie
"Dogs" : 386
"Cats" : 85.9
"Rats" : 15
```
### User Journey diagram
```
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
```mermaid
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 3: Me
```
### C4 diagram
```
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```
```mermaid
C4Context
title System Context diagram for Internet Banking System
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank, with personal bank accounts.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
```

View file

@ -1,18 +0,0 @@
---
author: Hugo Authors
title: Mermaid Graphs
date: 2021-07-18T10:52:59+08:00
description: A brief guide to setup Mermaid.
mermaid: true
draft: false
categories: ["Markdown", "Mermaid"]
---
Here's a simple mermaid flowchart.
{{<mermaid>}}
graph LR
Start --> Stop
{{</mermaid>}}
For more documentations on Mermaid, check out [mermaid](https://mermaid-js.github.io/mermaid).

View file

@ -14,8 +14,9 @@
</div> </div>
{{ if .Params.tags }} {{ if .Params.tags }}
<div> <div>
{{ range .Params.tags }} {{ range $tag := .Params.tags }}
<a class="ml-1" href="/tags/{{ . }}">#{{ . }}</a> {{ $url := printf "tags/%s" $tag | relLangURL }}
<a class="ml-1" href="{{ $url }}">#{{ . }}</a>
{{ end }} {{ end }}
</div> </div>
{{ end }} {{ end }}
@ -26,32 +27,6 @@
{{ .Content }} {{ .Content }}
</article> </article>
</main> </main>
{{ if or .Params.math .Site.Params.math }} {{ partial "plugin.html" . }}
{{ partial "math.html" . }}
{{ end }}
{{ if or .Params.mermaid .Site.Params.mermaid }}
{{ partial "mermaid.html" . }}
{{ end }}
{{ if or .Params.comment (and .Site.Params.commentOnAllPosts (ne .Params.comment false)) }}
{{ if eq .Site.Params.comment "disqus"}}
{{ partial "disqus.html" . }}
{{ end }}
{{ if eq .Site.Params.comment "utterances"}}
{{ partial "utterances.html" . }}
{{ end }}
{{ if eq .Site.Params.comment "giscus" }}
{{ partial "giscus.html" }}
{{ end }}
{{ if eq .Site.Params.comment "ovo"}}
{{ partial "ovo.html" . }}
{{ end }}
{{ end }}
</div> </div>
{{ end }} {{ end }}

View file

@ -5,7 +5,7 @@
{{ $data := .Data }} {{ $data := .Data }}
{{ range $key, $value := .Data.Terms.ByCount }} {{ range $key, $value := .Data.Terms.ByCount }}
<div class="mb-5 flex justify-between"> <div class="mb-5 flex justify-between">
<a class="self-start" href="{{ $data.Plural | absLangURL }}/{{ $value.Name }}"> <a class="self-start" href="{{ $data.Plural | relLangURL }}/{{ $value.Name }}">
{{ $value.Name }} {{ $value.Name }}
</a> </a>
<span class="">{{ $value.Count }}</span> <span class="">{{ $value.Count }}</span>

View file

@ -1,28 +1,18 @@
<script> {{ $giscus := .Site.Params.comment.giscus }}
const repo = '{{ .Site.Params.giscus.repo }}' <script
const repoId = '{{ .Site.Params.giscus.repoId }}' src="https://giscus.app/client.js"
const category = '{{ .Site.Params.giscus.category }}' data-repo="{{ $giscus.repo }}"
const categoryId = '{{ .Site.Params.giscus.categoryId }}' data-repo-id="{{ $giscus.repoId }}"
const mapping = '{{ .Site.Params.giscus.mapping }}' data-category="{{ $giscus.category }}"
const inputPosition = '{{ .Site.Params.giscus.inputPosition }}' data-category-id="{{ $giscus.categoryId }}"
const theme = localStorage.theme || 'preferred-color-scheme'; data-mapping="{{ $giscus.mapping }}"
data-strict="0"
const s = document.createElement('script') data-reactions-enabled="{{ cond $giscus.reactions 1 0 }}"
s.src = 'https://giscus.app/client.js' data-emit-metadata="{{ cond $giscus.metadata 1 0 }}"
s.async = true data-input-position="{{ $giscus.inputPosition }}"
s.crossOrigin = 'anonymous' data-theme="preferred_color_scheme"
s.setAttribute('data-repo', repo) data-lang="en"
s.setAttribute('data-repo-id', repoId) data-loading="lazy"
s.setAttribute('data-category', category) crossorigin="anonymous"
s.setAttribute('data-category-id', categoryId) async>
s.setAttribute('data-mapping', mapping)
s.setAttribute('data-strict', "0")
s.setAttribute('data-reactions-enabled', "1")
s.setAttribute('data-emit-metadata', "0")
s.setAttribute('data-input-position', inputPosition)
s.setAttribute('data-theme', theme)
s.setAttribute('data-loading', "lazy")
s.setAttribute('data-lang', "en")
document.querySelector('main').appendChild(s)
</script> </script>

View file

@ -29,23 +29,12 @@
{{ end }} {{ end }}
</head> </head>
<script> <script>
// We will default to system theme color if no choice was made. // default to system color scheme.
let theme_2b_used = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; let systemColorScheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
try { try {
if (!('theme' in localStorage)) { document.querySelector('html').classList.add(systemColorScheme);
const default_theme = '{{ .Site.Params.defaultTheme }}'; localStorage.setItem('theme', systemColorScheme);
// For the first time entering this site, use the theme specified in the configuration.
if (default_theme === 'dark' || default_theme === 'light') {
theme_2b_used = default_theme;
}
// Remember the choice.
localStorage.theme = theme_2b_used;
}
document.querySelector('html').classList.add(localStorage.theme);
} catch (e) { } catch (e) {
console.error(e); console.error(e);
} }

View file

@ -5,12 +5,12 @@
{{ if .Site.Params.brand }} {{ if .Site.Params.brand }}
<div class="mr-3 text-3xl"><a href="/">{{ .Site.Params.brand }}</a></div> <div class="mr-3 text-3xl"><a href="/">{{ .Site.Params.brand }}</a></div>
{{ end }} {{ end }}
<div id="theme-switcher" class="text-3xl cursor-pointer">{{ index .Site.Params.switch 1 }}</div> <div id="theme-switch" class="text-3xl cursor-pointer">{{ index .Site.Params.switch 1 }}</div>
</div> </div>
<ul class="flex items-center font-medium <ul class="flex items-center font-medium
whitespace-nowrap overflow-x-auto overflow-y-hidden"> whitespace-nowrap overflow-x-auto overflow-y-hidden">
{{ range .Site.Menus.main }} {{ range .Site.Menus.main }}
<li class="ml-1 mr-1"><a href="{{ .URL | absLangURL }}">{{ T .Identifier | default .Name }}</a></li> <li class="ml-1 mr-1"><a href="{{ .Identifier | relLangURL }}">{{ T .Identifier | default .Name }}</a></li>
{{ end }} {{ end }}
</ul> </ul>
<ul class="flex item-center text-sm font-bold"> <ul class="flex item-center text-sm font-bold">

View file

@ -1,4 +1,7 @@
<script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script> <script
<script> src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"
mermaid.initialize({ startOnLoad: true }); crossorigin="anonymous">
</script>
<script>
mermaid.init({theme: 'dark'}, 'code.language-mermaid')
</script> </script>

View file

@ -1,29 +0,0 @@
<div id="ovo_thread" class="mt-4 mb-4">
<div class="flex flex-col items-center">评论插件加载中 OvO</div>
</div>
<link rel="stylesheet" href="//unpkg.com/@ovojs/ovo/dist/style.css">
<script type="text/javascript">
(function () {
if (window.location.hostname == "localhost")
return;
const script = document.createElement('script');
script.type = 'text/javascript';
script.src = '//unpkg.com/@ovojs/ovo';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0])
.appendChild(script);
script.addEventListener('load', function () {
const target = document.getElementById('ovo_thread');
target.innerHTML = '';
new OvO({
target,
props: {
server: "{{ .Site.Params.ovo.server }}",
placeholder: "{{ .Site.Params.ovo.placeholder }}"
}
})
})
})();
</script>

View file

@ -0,0 +1,23 @@
{{ if or .Params.math .Site.Params.math }}
{{ partial "math.html" . }}
{{ end }}
{{ if or .Params.mermaid .Site.Params.mermaid }}
{{ partial "mermaid.html" . }}
{{ end }}
{{ if or .Params.comment (and .Site.Params.commentOnAllPosts (ne .Params.comment false)) }}
{{ if eq .Site.Params.comment.provider "disqus"}}
{{ partial "disqus.html" . }}
{{ end }}
{{ if eq .Site.Params.comment.provider "giscus" }}
{{ partial "giscus.html" . }}
{{ end }}
{{ if eq .Site.Params.comment.provider "utterances"}}
{{ partial "utterances.html" . }}
{{ end }}
{{ end }}

View file

@ -1,18 +1,8 @@
<script> <script src="https://utteranc.es/client.js"
const repo = '{{ .Site.Params.utterances.repo }}' repo="{{ .Site.Params.utterances.repo }}"
const issueTerm = '{{ .Site.Params.utterances.issueTerm }}' issue-term="{{ .Site.Params.utterances.issueTerm }}"
const theme = localStorage.theme ? `github-${localStorage.theme}` : 'preferred-color-scheme'; label="{{ .Site.Params.utterances.label }}"
const label = '{{ .Site.Params.utterances.label }}' theme="preferred-color-scheme"
crossorigin="anonymous"
const script = document.createElement('script') async>
script.src = 'https://utteranc.es/client.js'
script.async = true
script.crossOrigin = 'anonymous'
script.setAttribute('repo', repo)
script.setAttribute('issue-term', issueTerm)
script.setAttribute('theme', theme)
script.setAttribute('label', label ? label : 'comment')
document.querySelector('main').appendChild(script)
</script> </script>