diff --git a/aprsd/web/admin/static/css/prism.css b/aprsd/web/admin/static/css/prism.css
index 8511262..e088b7f 100644
--- a/aprsd/web/admin/static/css/prism.css
+++ b/aprsd/web/admin/static/css/prism.css
@@ -1,189 +1,4 @@
-/* PrismJS 1.24.1
-https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+log&plugins=show-language+toolbar */
-/**
- * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
- * Based on https://github.com/chriskempson/tomorrow-theme
- * @author Rose Pritchard
- */
-
-code[class*="language-"],
-pre[class*="language-"] {
- color: #ccc;
- background: none;
- font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
- font-size: 1em;
- text-align: left;
- white-space: pre;
- word-spacing: normal;
- word-break: normal;
- word-wrap: normal;
- line-height: 1.5;
-
- -moz-tab-size: 4;
- -o-tab-size: 4;
- tab-size: 4;
-
- -webkit-hyphens: none;
- -moz-hyphens: none;
- -ms-hyphens: none;
- hyphens: none;
-
-}
-
-/* Code blocks */
-pre[class*="language-"] {
- padding: 1em;
- margin: .5em 0;
- overflow: auto;
-}
-
-:not(pre) > code[class*="language-"],
-pre[class*="language-"] {
- background: #2d2d2d;
-}
-
-/* Inline code */
-:not(pre) > code[class*="language-"] {
- padding: .1em;
- border-radius: .3em;
- white-space: normal;
-}
-
-.token.comment,
-.token.block-comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
- color: #999;
-}
-
-.token.punctuation {
- color: #ccc;
-}
-
-.token.tag,
-.token.attr-name,
-.token.namespace,
-.token.deleted {
- color: #e2777a;
-}
-
-.token.function-name {
- color: #6196cc;
-}
-
-.token.boolean,
-.token.number,
-.token.function {
- color: #f08d49;
-}
-
-.token.property,
-.token.class-name,
-.token.constant,
-.token.symbol {
- color: #f8c555;
-}
-
-.token.selector,
-.token.important,
-.token.atrule,
-.token.keyword,
-.token.builtin {
- color: #cc99cd;
-}
-
-.token.string,
-.token.char,
-.token.attr-value,
-.token.regex,
-.token.variable {
- color: #7ec699;
-}
-
-.token.operator,
-.token.entity,
-.token.url {
- color: #67cdcc;
-}
-
-.token.important,
-.token.bold {
- font-weight: bold;
-}
-.token.italic {
- font-style: italic;
-}
-
-.token.entity {
- cursor: help;
-}
-
-.token.inserted {
- color: green;
-}
-
-div.code-toolbar {
- position: relative;
-}
-
-div.code-toolbar > .toolbar {
- position: absolute;
- top: .3em;
- right: .2em;
- transition: opacity 0.3s ease-in-out;
- opacity: 0;
-}
-
-div.code-toolbar:hover > .toolbar {
- opacity: 1;
-}
-
-/* Separate line b/c rules are thrown out if selector is invalid.
- IE11 and old Edge versions don't support :focus-within. */
-div.code-toolbar:focus-within > .toolbar {
- opacity: 1;
-}
-
-div.code-toolbar > .toolbar > .toolbar-item {
- display: inline-block;
-}
-
-div.code-toolbar > .toolbar > .toolbar-item > a {
- cursor: pointer;
-}
-
-div.code-toolbar > .toolbar > .toolbar-item > button {
- background: none;
- border: 0;
- color: inherit;
- font: inherit;
- line-height: normal;
- overflow: visible;
- padding: 0;
- -webkit-user-select: none; /* for button */
- -moz-user-select: none;
- -ms-user-select: none;
-}
-
-div.code-toolbar > .toolbar > .toolbar-item > a,
-div.code-toolbar > .toolbar > .toolbar-item > button,
-div.code-toolbar > .toolbar > .toolbar-item > span {
- color: #bbb;
- font-size: .8em;
- padding: 0 .5em;
- background: #f5f2f0;
- background: rgba(224, 224, 224, 0.2);
- box-shadow: 0 2px 0 0 rgba(0,0,0,0.2);
- border-radius: .5em;
-}
-
-div.code-toolbar > .toolbar > .toolbar-item > a:hover,
-div.code-toolbar > .toolbar > .toolbar-item > a:focus,
-div.code-toolbar > .toolbar > .toolbar-item > button:hover,
-div.code-toolbar > .toolbar > .toolbar-item > button:focus,
-div.code-toolbar > .toolbar > .toolbar-item > span:hover,
-div.code-toolbar > .toolbar > .toolbar-item > span:focus {
- color: inherit;
- text-decoration: none;
-}
+/* PrismJS 1.29.0
+https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+json+json5+log&plugins=show-language+toolbar */
+code[class*=language-],pre[class*=language-]{color:#ccc;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto}:not(pre)>code[class*=language-],pre[class*=language-]{background:#2d2d2d}:not(pre)>code[class*=language-]{padding:.1em;border-radius:.3em;white-space:normal}.token.block-comment,.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#999}.token.punctuation{color:#ccc}.token.attr-name,.token.deleted,.token.namespace,.token.tag{color:#e2777a}.token.function-name{color:#6196cc}.token.boolean,.token.function,.token.number{color:#f08d49}.token.class-name,.token.constant,.token.property,.token.symbol{color:#f8c555}.token.atrule,.token.builtin,.token.important,.token.keyword,.token.selector{color:#cc99cd}.token.attr-value,.token.char,.token.regex,.token.string,.token.variable{color:#7ec699}.token.entity,.token.operator,.token.url{color:#67cdcc}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.token.inserted{color:green}
+div.code-toolbar{position:relative}div.code-toolbar>.toolbar{position:absolute;z-index:10;top:.3em;right:.2em;transition:opacity .3s ease-in-out;opacity:0}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:0 0;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{color:#bbb;font-size:.8em;padding:0 .5em;background:#f5f2f0;background:rgba(224,224,224,.2);box-shadow:0 2px 0 0 rgba(0,0,0,.2);border-radius:.5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;text-decoration:none}
diff --git a/aprsd/web/admin/static/js/prism.js b/aprsd/web/admin/static/js/prism.js
index f232b27..2b957cb 100644
--- a/aprsd/web/admin/static/js/prism.js
+++ b/aprsd/web/admin/static/js/prism.js
@@ -1,2247 +1,12 @@
-/* PrismJS 1.24.1
+/* PrismJS 1.29.0
https://prismjs.com/download.html#themes=prism-tomorrow&languages=markup+css+clike+javascript+json+json5+log&plugins=show-language+toolbar */
-///
-
-var _self = (typeof window !== 'undefined')
- ? window // if in browser
- : (
- (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope)
- ? self // if in worker
- : {} // if in node js
- );
-
-/**
- * Prism: Lightweight, robust, elegant syntax highlighting
- *
- * @license MIT
- * @author Lea Verou
- * @namespace
- * @public
- */
-var Prism = (function (_self) {
-
- // Private helper vars
- var lang = /\blang(?:uage)?-([\w-]+)\b/i;
- var uniqueId = 0;
-
- // The grammar object for plaintext
- var plainTextGrammar = {};
-
-
- var _ = {
- /**
- * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the
- * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load
- * additional languages or plugins yourself.
- *
- * By setting this value to `true`, Prism will not automatically highlight all code elements on the page.
- *
- * You obviously have to change this value before the automatic highlighting started. To do this, you can add an
- * empty Prism object into the global scope before loading the Prism script like this:
- *
- * ```js
- * window.Prism = window.Prism || {};
- * Prism.manual = true;
- * // add a new