taglist, mermaid
This commit is contained in:
		
							parent
							
								
									2bfe90b7e6
								
							
						
					
					
						commit
						9d2024b11c
					
				
					 12 changed files with 149 additions and 41 deletions
				
			
		| 
						 | 
					@ -58,7 +58,7 @@ const config: QuartzConfig = {
 | 
				
			||||||
      Plugin.ContentPage({
 | 
					      Plugin.ContentPage({
 | 
				
			||||||
        head: Component.Head(),
 | 
					        head: Component.Head(),
 | 
				
			||||||
        header: [Component.PageTitle(), Component.Spacer(), Component.Darkmode()],
 | 
					        header: [Component.PageTitle(), Component.Spacer(), Component.Darkmode()],
 | 
				
			||||||
        body: [Component.ArticleTitle(), Component.ReadingTime(), Component.TableOfContents(), Component.Content()]
 | 
					        body: [Component.ArticleTitle(), Component.ReadingTime(), Component.TagList(), Component.TableOfContents(), Component.Content()]
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import { resolveToRoot } from "../path"
 | 
					import { resolveToRoot } from "../path"
 | 
				
			||||||
 | 
					import { JSResourceToScriptElement } from "../resources"
 | 
				
			||||||
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
					import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Head({ fileData, externalResources }: QuartzComponentProps) {
 | 
					function Head({ fileData, externalResources }: QuartzComponentProps) {
 | 
				
			||||||
| 
						 | 
					@ -25,7 +26,7 @@ function Head({ fileData, externalResources }: QuartzComponentProps) {
 | 
				
			||||||
    <link rel="preconnect" href="https://fonts.googleapis.com" />
 | 
					    <link rel="preconnect" href="https://fonts.googleapis.com" />
 | 
				
			||||||
    <link rel="preconnect" href="https://fonts.gstatic.com" />
 | 
					    <link rel="preconnect" href="https://fonts.gstatic.com" />
 | 
				
			||||||
    {css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" spa-preserve />)}
 | 
					    {css.map(href => <link key={href} href={href} rel="stylesheet" type="text/css" spa-preserve />)}
 | 
				
			||||||
    {js.filter(resource => resource.loadTime === "beforeDOMReady").map(resource => <script key={resource.src} {...resource} spa-preserve />)}
 | 
					    {js.filter(resource => resource.loadTime === "beforeDOMReady").map(res => JSResourceToScriptElement(res, true))}
 | 
				
			||||||
  </head>
 | 
					  </head>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,23 @@
 | 
				
			||||||
import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
					import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
				
			||||||
import style from "./styles/toc.scss"
 | 
					import style from "./styles/toc.scss"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function TableOfContents({ fileData }: QuartzComponentProps) {
 | 
					
 | 
				
			||||||
 | 
					interface Options {
 | 
				
			||||||
 | 
					  layout: 'modern' | 'quartz-3'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const defaultOptions: Options = {
 | 
				
			||||||
 | 
					  layout: 'quartz-3'
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default ((opts?: Partial<Options>) => {
 | 
				
			||||||
 | 
					  const layout = opts?.layout ?? defaultOptions.layout
 | 
				
			||||||
 | 
					  if (layout === "modern") {
 | 
				
			||||||
 | 
					    return function() {
 | 
				
			||||||
 | 
					      return null // TODO (make this look like nextra)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    function TableOfContents({ fileData }: QuartzComponentProps) {
 | 
				
			||||||
      if (!fileData.toc) {
 | 
					      if (!fileData.toc) {
 | 
				
			||||||
        return null
 | 
					        return null
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
| 
						 | 
					@ -14,8 +30,9 @@ function TableOfContents({ fileData }: QuartzComponentProps) {
 | 
				
			||||||
          </li>)}
 | 
					          </li>)}
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
      </details>
 | 
					      </details>
 | 
				
			||||||
}
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TableOfContents.css = style
 | 
					    TableOfContents.css = style
 | 
				
			||||||
 | 
					    return TableOfContents
 | 
				
			||||||
export default (() => TableOfContents) satisfies QuartzComponentConstructor
 | 
					  }
 | 
				
			||||||
 | 
					}) satisfies QuartzComponentConstructor
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								quartz/components/TagList.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								quartz/components/TagList.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					import { resolveToRoot } from "../path"
 | 
				
			||||||
 | 
					import { QuartzComponentConstructor, QuartzComponentProps } from "./types"
 | 
				
			||||||
 | 
					import { slug as slugAnchor } from 'github-slugger'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function TagList({ fileData }: QuartzComponentProps) {
 | 
				
			||||||
 | 
					  const tags = fileData.frontmatter?.tags
 | 
				
			||||||
 | 
					  const slug = fileData.slug!
 | 
				
			||||||
 | 
					  const baseDir = resolveToRoot(slug)
 | 
				
			||||||
 | 
					  if (tags) {
 | 
				
			||||||
 | 
					    return <ul class="tags">{tags.map(tag => {
 | 
				
			||||||
 | 
					      const display = `#${tag}`
 | 
				
			||||||
 | 
					      const linkDest = baseDir + `/tags/${slugAnchor(tag)}`
 | 
				
			||||||
 | 
					      return <li>
 | 
				
			||||||
 | 
					        <a href={linkDest}>{display}</a>
 | 
				
			||||||
 | 
					      </li>
 | 
				
			||||||
 | 
					    })}</ul>
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    return null
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TagList.css = `
 | 
				
			||||||
 | 
					.tags {
 | 
				
			||||||
 | 
					  list-style: none;
 | 
				
			||||||
 | 
					  display: flex;
 | 
				
			||||||
 | 
					  padding-left: 0;
 | 
				
			||||||
 | 
					  gap: 0.4rem;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & > li {
 | 
				
			||||||
 | 
					    display: inline-block;
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    & > a {
 | 
				
			||||||
 | 
					      border-radius: 8px;
 | 
				
			||||||
 | 
					      border: var(--lightgray) 1px solid;
 | 
				
			||||||
 | 
					      padding: 0.2rem 0.5rem;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default (() => TagList) satisfies QuartzComponentConstructor
 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@ import PageTitle from "./PageTitle"
 | 
				
			||||||
import ReadingTime from "./ReadingTime"
 | 
					import ReadingTime from "./ReadingTime"
 | 
				
			||||||
import Spacer from "./Spacer"
 | 
					import Spacer from "./Spacer"
 | 
				
			||||||
import TableOfContents from "./TableOfContents"
 | 
					import TableOfContents from "./TableOfContents"
 | 
				
			||||||
 | 
					import TagList from "./TagList"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export {
 | 
					export {
 | 
				
			||||||
  ArticleTitle,
 | 
					  ArticleTitle,
 | 
				
			||||||
| 
						 | 
					@ -15,5 +16,6 @@ export {
 | 
				
			||||||
  PageTitle,
 | 
					  PageTitle,
 | 
				
			||||||
  ReadingTime,
 | 
					  ReadingTime,
 | 
				
			||||||
  Spacer,
 | 
					  Spacer,
 | 
				
			||||||
  TableOfContents
 | 
					  TableOfContents,
 | 
				
			||||||
 | 
					  TagList
 | 
				
			||||||
} 
 | 
					} 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,5 @@
 | 
				
			||||||
import path from 'path'
 | 
					import path from 'path'
 | 
				
			||||||
import SlugAnchor from 'github-slugger'
 | 
					import { slug as slugAnchor } from 'github-slugger'
 | 
				
			||||||
 | 
					 | 
				
			||||||
export const slugAnchor = new SlugAnchor()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
function slugSegment(s: string): string {
 | 
					function slugSegment(s: string): string {
 | 
				
			||||||
  return s.replace(/\s/g, '-')
 | 
					  return s.replace(/\s/g, '-')
 | 
				
			||||||
| 
						 | 
					@ -9,7 +7,7 @@ function slugSegment(s: string): string {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function slugify(s: string): string {
 | 
					export function slugify(s: string): string {
 | 
				
			||||||
  const [fp, anchor] = s.split("#", 2)
 | 
					  const [fp, anchor] = s.split("#", 2)
 | 
				
			||||||
  const sluggedAnchor = anchor === undefined ? "" : "#" + slugAnchor.slug(anchor)
 | 
					  const sluggedAnchor = anchor === undefined ? "" : "#" + slugAnchor(anchor)
 | 
				
			||||||
  const withoutFileExt = fp.replace(new RegExp(path.extname(fp) + '$'), '')
 | 
					  const withoutFileExt = fp.replace(new RegExp(path.extname(fp) + '$'), '')
 | 
				
			||||||
  const rawSlugSegments = withoutFileExt.split(path.sep)
 | 
					  const rawSlugSegments = withoutFileExt.split(path.sep)
 | 
				
			||||||
  const slugParts: string = rawSlugSegments
 | 
					  const slugParts: string = rawSlugSegments
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,4 @@
 | 
				
			||||||
import { StaticResources } from "../../resources"
 | 
					import { JSResourceToScriptElement, StaticResources } from "../../resources"
 | 
				
			||||||
import { EmitCallback, QuartzEmitterPlugin } from "../types"
 | 
					import { EmitCallback, QuartzEmitterPlugin } from "../types"
 | 
				
			||||||
import { ProcessedContent } from "../vfile"
 | 
					import { ProcessedContent } from "../vfile"
 | 
				
			||||||
import { render } from "preact-render-to-string"
 | 
					import { render } from "preact-render-to-string"
 | 
				
			||||||
| 
						 | 
					@ -37,9 +37,9 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
 | 
				
			||||||
        const pageResources: StaticResources = {
 | 
					        const pageResources: StaticResources = {
 | 
				
			||||||
          css: [baseDir + "/index.css", ...resources.css],
 | 
					          css: [baseDir + "/index.css", ...resources.css],
 | 
				
			||||||
          js: [
 | 
					          js: [
 | 
				
			||||||
            { src: baseDir + "/prescript.js", loadTime: "beforeDOMReady" },
 | 
					            { src: baseDir + "/prescript.js", loadTime: "beforeDOMReady", contentType: "external" },
 | 
				
			||||||
            ...resources.js,
 | 
					            ...resources.js,
 | 
				
			||||||
            { src: baseDir + "/postscript.js", loadTime: "afterDOMReady", type: 'module' }
 | 
					            { src: baseDir + "/postscript.js", loadTime: "afterDOMReady", moduleType: 'module', contentType: "external" }
 | 
				
			||||||
          ]
 | 
					          ]
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ export const ContentPage: QuartzEmitterPlugin<Options> = (opts) => {
 | 
				
			||||||
              </Body>
 | 
					              </Body>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </body>
 | 
					          </body>
 | 
				
			||||||
          {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(resource => <script key={resource.src} {...resource} />)}
 | 
					          {pageResources.js.filter(resource => resource.loadTime === "afterDOMReady").map(res => JSResourceToScriptElement(res))}
 | 
				
			||||||
        </html>
 | 
					        </html>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        const fp = file.data.slug + ".html"
 | 
					        const fp = file.data.slug + ".html"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,8 @@ export const Katex: QuartzTransformerPlugin = () => ({
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md
 | 
					        // fix copy behaviour: https://github.com/KaTeX/KaTeX/blob/main/contrib/copy-tex/README.md
 | 
				
			||||||
        src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
 | 
					        src: "https://cdn.jsdelivr.net/npm/katex@0.16.7/dist/contrib/copy-tex.min.js",
 | 
				
			||||||
        loadTime: "afterDOMReady"
 | 
					        loadTime: "afterDOMReady",
 | 
				
			||||||
 | 
					        contentType: 'external'
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import { PluggableList } from "unified"
 | 
					import { PluggableList } from "unified"
 | 
				
			||||||
import { QuartzTransformerPlugin } from "../types"
 | 
					import { QuartzTransformerPlugin } from "../types"
 | 
				
			||||||
import { Root, HTML, BlockContent, DefinitionContent } from 'mdast'
 | 
					import { Root, HTML, BlockContent, DefinitionContent, Code } from 'mdast'
 | 
				
			||||||
import { findAndReplace } from "mdast-util-find-and-replace"
 | 
					import { findAndReplace } from "mdast-util-find-and-replace"
 | 
				
			||||||
import { slugify } from "../../path"
 | 
					import { slugify } from "../../path"
 | 
				
			||||||
import rehypeRaw from "rehype-raw"
 | 
					import rehypeRaw from "rehype-raw"
 | 
				
			||||||
| 
						 | 
					@ -11,12 +11,14 @@ export interface Options {
 | 
				
			||||||
  highlight: boolean
 | 
					  highlight: boolean
 | 
				
			||||||
  wikilinks: boolean
 | 
					  wikilinks: boolean
 | 
				
			||||||
  callouts: boolean
 | 
					  callouts: boolean
 | 
				
			||||||
 | 
					  mermaid: boolean
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const defaultOptions: Options = {
 | 
					const defaultOptions: Options = {
 | 
				
			||||||
  highlight: true,
 | 
					  highlight: true,
 | 
				
			||||||
  wikilinks: true,
 | 
					  wikilinks: true,
 | 
				
			||||||
  callouts: true
 | 
					  callouts: true,
 | 
				
			||||||
 | 
					  mermaid: false,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const icons = {
 | 
					const icons = {
 | 
				
			||||||
| 
						 | 
					@ -246,11 +248,38 @@ export const ObsidianFlavoredMarkdown: QuartzTransformerPlugin<Partial<Options>
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (opts.mermaid) {
 | 
				
			||||||
 | 
					        plugins.push(() => {
 | 
				
			||||||
 | 
					          return (tree: Root, _file) => {
 | 
				
			||||||
 | 
					            visit(tree, 'code', (node: Code) => {
 | 
				
			||||||
 | 
					              if (node.lang === 'mermaid') {
 | 
				
			||||||
 | 
					                node.data = {
 | 
				
			||||||
 | 
					                  hProperties: {
 | 
				
			||||||
 | 
					                    className: 'mermaid'
 | 
				
			||||||
 | 
					                  }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      return plugins
 | 
					      return plugins
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					 | 
				
			||||||
    htmlPlugins() {
 | 
					    htmlPlugins() {
 | 
				
			||||||
      return [rehypeRaw]
 | 
					      return [rehypeRaw]
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    externalResources: {
 | 
				
			||||||
 | 
					      js: [{
 | 
				
			||||||
 | 
					        script: `
 | 
				
			||||||
 | 
					import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.esm.min.mjs';
 | 
				
			||||||
 | 
					mermaid.initialize({ startOnLoad: true });
 | 
				
			||||||
 | 
					        `,
 | 
				
			||||||
 | 
					        loadTime: 'afterDOMReady',
 | 
				
			||||||
 | 
					        moduleType: 'module',
 | 
				
			||||||
 | 
					        contentType: 'inline'
 | 
				
			||||||
 | 
					      }]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,7 @@ import { QuartzTransformerPlugin } from "../types"
 | 
				
			||||||
import { Root } from "mdast"
 | 
					import { Root } from "mdast"
 | 
				
			||||||
import { visit } from "unist-util-visit"
 | 
					import { visit } from "unist-util-visit"
 | 
				
			||||||
import { toString } from "mdast-util-to-string"
 | 
					import { toString } from "mdast-util-to-string"
 | 
				
			||||||
import { slugAnchor } from "../../path"
 | 
					import { slug as slugAnchor } from 'github-slugger'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface Options {
 | 
					export interface Options {
 | 
				
			||||||
  maxDepth: 1 | 2 | 3 | 4 | 5 | 6,
 | 
					  maxDepth: 1 | 2 | 3 | 4 | 5 | 6,
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ export const TableOfContents: QuartzTransformerPlugin<Partial<Options> | undefin
 | 
				
			||||||
                toc.push({
 | 
					                toc.push({
 | 
				
			||||||
                  depth: node.depth,
 | 
					                  depth: node.depth,
 | 
				
			||||||
                  text,
 | 
					                  text,
 | 
				
			||||||
                  slug: slugAnchor.slug(text)
 | 
					                  slug: slugAnchor(text)
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,10 +0,0 @@
 | 
				
			||||||
export interface JSResource {
 | 
					 | 
				
			||||||
  src: string
 | 
					 | 
				
			||||||
  loadTime: 'beforeDOMReady' | 'afterDOMReady'
 | 
					 | 
				
			||||||
  type?: 'module'
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export interface StaticResources {
 | 
					 | 
				
			||||||
  css: string[],
 | 
					 | 
				
			||||||
  js: JSResource[]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										28
									
								
								quartz/resources.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								quartz/resources.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					import { randomUUID } from "crypto"
 | 
				
			||||||
 | 
					import { JSX } from "preact/jsx-runtime"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type JSResource = {
 | 
				
			||||||
 | 
					  loadTime: 'beforeDOMReady' | 'afterDOMReady'
 | 
				
			||||||
 | 
					  moduleType?: 'module'
 | 
				
			||||||
 | 
					} & ({
 | 
				
			||||||
 | 
					  src: string
 | 
				
			||||||
 | 
					  contentType: 'external'
 | 
				
			||||||
 | 
					} | {
 | 
				
			||||||
 | 
					  script: string
 | 
				
			||||||
 | 
					  contentType: 'inline'
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function JSResourceToScriptElement(resource: JSResource, preserve?: boolean): JSX.Element {
 | 
				
			||||||
 | 
					  const scriptType = resource.moduleType ?? 'application/javascript'
 | 
				
			||||||
 | 
					  if (resource.contentType === 'external') {
 | 
				
			||||||
 | 
					    return <script key={resource.src} src={resource.src} type={scriptType} spa-preserve={preserve} />
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    const content = resource.script
 | 
				
			||||||
 | 
					    return <script key={randomUUID()} type={scriptType} spa-preserve={preserve}>{content}</script>
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export interface StaticResources {
 | 
				
			||||||
 | 
					  css: string[],
 | 
				
			||||||
 | 
					  js: JSResource[]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue