diff --git a/components.js b/components.js
index a0d23dbd7c..40b4b251e1 100644
--- a/components.js
+++ b/components.js
@@ -1,2 +1,2 @@
-var components = {"core":{"meta":{"path":"components/prism-core.js","option":"mandatory"},"core":"Core"},"themes":{"meta":{"path":"themes/{id}.css","link":"index.html?theme={id}","exclusive":true},"prism":{"title":"Default","option":"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{"title":"Okaidia","owner":"ocodia"},"prism-twilight":{"title":"Twilight","owner":"remybach"},"prism-coy":{"title":"Coy","owner":"tshedor"},"prism-solarizedlight":{"title":"Solarized Light","owner":"hectormatos2011 "},"prism-tomorrow":{"title":"Tomorrow Night","owner":"Rosey"}},"languages":{"meta":{"path":"components/prism-{id}","noCSS":true,"examplesPath":"examples/prism-{id}","addCheckAll":true},"markup":{"title":"Markup","alias":["html","xml","svg","mathml","ssml","atom","rss"],"aliasTitles":{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","ssml":"SSML","atom":"Atom","rss":"RSS"},"option":"default"},"css":{"title":"CSS","option":"default","modify":"markup"},"clike":{"title":"C-like","option":"default"},"javascript":{"title":"JavaScript","require":"clike","modify":"markup","optional":"regex","alias":"js","option":"default"},"abap":{"title":"ABAP","owner":"dellagustin"},"abnf":{"title":"ABNF","owner":"RunDevelopment"},"actionscript":{"title":"ActionScript","require":"javascript","modify":"markup","owner":"Golmote"},"ada":{"title":"Ada","owner":"Lucretia"},"agda":{"title":"Agda","owner":"xy-ren"},"al":{"title":"AL","owner":"RunDevelopment"},"antlr4":{"title":"ANTLR4","alias":"g4","owner":"RunDevelopment"},"apacheconf":{"title":"Apache Configuration","owner":"GuiTeK"},"apex":{"title":"Apex","require":["clike","sql"],"owner":"RunDevelopment"},"apl":{"title":"APL","owner":"ngn"},"applescript":{"title":"AppleScript","owner":"Golmote"},"aql":{"title":"AQL","owner":"RunDevelopment"},"arduino":{"title":"Arduino","require":"cpp","owner":"dkern"},"arff":{"title":"ARFF","owner":"Golmote"},"asciidoc":{"alias":"adoc","title":"AsciiDoc","owner":"Golmote"},"aspnet":{"title":"ASP.NET (C#)","require":["markup","csharp"],"owner":"nauzilus"},"asm6502":{"title":"6502 Assembly","owner":"kzurawel"},"autohotkey":{"title":"AutoHotkey","owner":"aviaryan"},"autoit":{"title":"AutoIt","owner":"Golmote"},"bash":{"title":"Bash","alias":"shell","aliasTitles":{"shell":"Shell"},"owner":"zeitgeist87"},"basic":{"title":"BASIC","owner":"Golmote"},"batch":{"title":"Batch","owner":"Golmote"},"bbcode":{"title":"BBcode","alias":"shortcode","aliasTitles":{"shortcode":"Shortcode"},"owner":"RunDevelopment"},"birb":{"title":"Birb","require":"clike","owner":"Calamity210"},"bison":{"title":"Bison","require":"c","owner":"Golmote"},"bnf":{"title":"BNF","alias":"rbnf","aliasTitles":{"rbnf":"RBNF"},"owner":"RunDevelopment"},"brainfuck":{"title":"Brainfuck","owner":"Golmote"},"brightscript":{"title":"BrightScript","owner":"RunDevelopment"},"bro":{"title":"Bro","owner":"wayward710"},"bsl":{"title":"BSL (1C:Enterprise)","alias":"oscript","aliasTitles":{"oscript":"OneScript"},"owner":"Diversus23"},"c":{"title":"C","require":"clike","owner":"zeitgeist87"},"csharp":{"title":"C#","require":"clike","alias":["cs","dotnet"],"owner":"mvalipour"},"cpp":{"title":"C++","require":"c","owner":"zeitgeist87"},"cil":{"title":"CIL","owner":"sbrl"},"clojure":{"title":"Clojure","owner":"troglotit"},"cmake":{"title":"CMake","owner":"mjrogozinski"},"coffeescript":{"title":"CoffeeScript","require":"javascript","alias":"coffee","owner":"R-osey"},"concurnas":{"title":"Concurnas","alias":"conc","owner":"jasontatton"},"csp":{"title":"Content-Security-Policy","owner":"ScottHelme"},"crystal":{"title":"Crystal","require":"ruby","owner":"MakeNowJust"},"css-extras":{"title":"CSS Extras","require":"css","modify":"css","owner":"milesj"},"cypher":{"title":"Cypher","owner":"RunDevelopment"},"d":{"title":"D","require":"clike","owner":"Golmote"},"dart":{"title":"Dart","require":"clike","owner":"Golmote"},"dataweave":{"title":"DataWeave","owner":"machaval"},"dax":{"title":"DAX","owner":"peterbud"},"dhall":{"title":"Dhall","owner":"RunDevelopment"},"diff":{"title":"Diff","owner":"uranusjr"},"django":{"title":"Django/Jinja2","require":"markup-templating","alias":"jinja2","owner":"romanvm"},"dns-zone-file":{"title":"DNS zone file","owner":"RunDevelopment","alias":"dns-zone"},"docker":{"title":"Docker","alias":"dockerfile","owner":"JustinBeckwith"},"ebnf":{"title":"EBNF","owner":"RunDevelopment"},"editorconfig":{"title":"EditorConfig","owner":"osipxd"},"eiffel":{"title":"Eiffel","owner":"Conaclos"},"ejs":{"title":"EJS","require":["javascript","markup-templating"],"owner":"RunDevelopment","alias":"eta","aliasTitles":{"eta":"Eta"}},"elixir":{"title":"Elixir","owner":"Golmote"},"elm":{"title":"Elm","owner":"zwilias"},"etlua":{"title":"Embedded Lua templating","require":["lua","markup-templating"],"owner":"RunDevelopment"},"erb":{"title":"ERB","require":["ruby","markup-templating"],"owner":"Golmote"},"erlang":{"title":"Erlang","owner":"Golmote"},"excel-formula":{"title":"Excel Formula","alias":["xlsx","xls"],"owner":"RunDevelopment"},"fsharp":{"title":"F#","require":"clike","owner":"simonreynolds7"},"factor":{"title":"Factor","owner":"catb0t"},"firestore-security-rules":{"title":"Firestore security rules","require":"clike","owner":"RunDevelopment"},"flow":{"title":"Flow","require":"javascript","owner":"Golmote"},"fortran":{"title":"Fortran","owner":"Golmote"},"ftl":{"title":"FreeMarker Template Language","require":"markup-templating","owner":"RunDevelopment"},"gml":{"title":"GameMaker Language","alias":"gamemakerlanguage","require":"clike","owner":"LiarOnce"},"gcode":{"title":"G-code","owner":"RunDevelopment"},"gdscript":{"title":"GDScript","owner":"RunDevelopment"},"gedcom":{"title":"GEDCOM","owner":"Golmote"},"gherkin":{"title":"Gherkin","owner":"hason"},"git":{"title":"Git","owner":"lgiraudel"},"glsl":{"title":"GLSL","require":"c","owner":"Golmote"},"go":{"title":"Go","require":"clike","owner":"arnehormann"},"graphql":{"title":"GraphQL","optional":["markdown"],"owner":"Golmote"},"groovy":{"title":"Groovy","require":"clike","owner":"robfletcher"},"haml":{"title":"Haml","require":"ruby","optional":["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],"owner":"Golmote"},"handlebars":{"title":"Handlebars","require":"markup-templating","owner":"Golmote"},"haskell":{"title":"Haskell","alias":"hs","owner":"bholst"},"haxe":{"title":"Haxe","require":"clike","owner":"Golmote"},"hcl":{"title":"HCL","owner":"outsideris"},"hlsl":{"title":"HLSL","require":"c","owner":"RunDevelopment"},"http":{"title":"HTTP","optional":["css","javascript","json","markup"],"owner":"danielgtaylor"},"hpkp":{"title":"HTTP Public-Key-Pins","owner":"ScottHelme"},"hsts":{"title":"HTTP Strict-Transport-Security","owner":"ScottHelme"},"ichigojam":{"title":"IchigoJam","owner":"BlueCocoa"},"icon":{"title":"Icon","owner":"Golmote"},"ignore":{"title":".ignore","owner":"osipxd","alias":["gitignore","hgignore","npmignore"],"aliasTitles":{"gitignore":".gitignore","hgignore":".hgignore","npmignore":".npmignore"}},"inform7":{"title":"Inform 7","owner":"Golmote"},"ini":{"title":"Ini","owner":"aviaryan"},"io":{"title":"Io","owner":"AlesTsurko"},"j":{"title":"J","owner":"Golmote"},"java":{"title":"Java","require":"clike","owner":"sherblot"},"javadoc":{"title":"JavaDoc","require":["markup","java","javadoclike"],"modify":"java","optional":"scala","owner":"RunDevelopment"},"javadoclike":{"title":"JavaDoc-like","modify":["java","javascript","php"],"owner":"RunDevelopment"},"javastacktrace":{"title":"Java stack trace","owner":"RunDevelopment"},"jolie":{"title":"Jolie","require":"clike","owner":"thesave"},"jq":{"title":"JQ","owner":"RunDevelopment"},"jsdoc":{"title":"JSDoc","require":["javascript","javadoclike","typescript"],"modify":"javascript","optional":["actionscript","coffeescript"],"owner":"RunDevelopment"},"js-extras":{"title":"JS Extras","require":"javascript","modify":"javascript","optional":["actionscript","coffeescript","flow","n4js","typescript"],"owner":"RunDevelopment"},"json":{"title":"JSON","alias":"webmanifest","aliasTitles":{"webmanifest":"Web App Manifest"},"owner":"CupOfTea696"},"json5":{"title":"JSON5","require":"json","owner":"RunDevelopment"},"jsonp":{"title":"JSONP","require":"json","owner":"RunDevelopment"},"jsstacktrace":{"title":"JS stack trace","owner":"sbrl"},"js-templates":{"title":"JS Templates","require":"javascript","modify":"javascript","optional":["css","css-extras","graphql","markdown","markup"],"owner":"RunDevelopment"},"julia":{"title":"Julia","owner":"cdagnino"},"keyman":{"title":"Keyman","owner":"mcdurdin"},"kotlin":{"title":"Kotlin","alias":["kt","kts"],"aliasTitles":{"kts":"Kotlin Script"},"require":"clike","owner":"Golmote"},"latex":{"title":"LaTeX","alias":["tex","context"],"aliasTitles":{"tex":"TeX","context":"ConTeXt"},"owner":"japborst"},"latte":{"title":"Latte","require":["clike","markup-templating","php"],"owner":"nette"},"less":{"title":"Less","require":"css","optional":"css-extras","owner":"Golmote"},"lilypond":{"title":"LilyPond","require":"scheme","alias":"ly","owner":"RunDevelopment"},"liquid":{"title":"Liquid","owner":"cinhtau"},"lisp":{"title":"Lisp","alias":["emacs","elisp","emacs-lisp"],"owner":"JuanCaicedo"},"livescript":{"title":"LiveScript","owner":"Golmote"},"llvm":{"title":"LLVM IR","owner":"porglezomp"},"lolcode":{"title":"LOLCODE","owner":"Golmote"},"lua":{"title":"Lua","owner":"Golmote"},"makefile":{"title":"Makefile","owner":"Golmote"},"markdown":{"title":"Markdown","require":"markup","optional":"yaml","alias":"md","owner":"Golmote"},"markup-templating":{"title":"Markup templating","require":"markup","owner":"Golmote"},"matlab":{"title":"MATLAB","owner":"Golmote"},"mel":{"title":"MEL","owner":"Golmote"},"mizar":{"title":"Mizar","owner":"Golmote"},"mongodb":{"title":"MongoDB","owner":"airs0urce","require":"javascript"},"monkey":{"title":"Monkey","owner":"Golmote"},"moonscript":{"title":"MoonScript","alias":"moon","owner":"RunDevelopment"},"n1ql":{"title":"N1QL","owner":"TMWilds"},"n4js":{"title":"N4JS","require":"javascript","optional":"jsdoc","alias":"n4jsd","owner":"bsmith-n4"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","owner":"stephanmax"},"naniscript":{"title":"Naninovel Script","owner":"Elringus","alias":"nani"},"nasm":{"title":"NASM","owner":"rbmj"},"neon":{"title":"NEON","owner":"nette"},"nginx":{"title":"nginx","owner":"westonganger","require":"clike"},"nim":{"title":"Nim","owner":"Golmote"},"nix":{"title":"Nix","owner":"Golmote"},"nsis":{"title":"NSIS","owner":"idleberg"},"objectivec":{"title":"Objective-C","require":"c","alias":"objc","owner":"uranusjr"},"ocaml":{"title":"OCaml","owner":"Golmote"},"opencl":{"title":"OpenCL","require":"c","modify":["c","cpp"],"owner":"Milania1"},"oz":{"title":"Oz","owner":"Golmote"},"parigp":{"title":"PARI/GP","owner":"Golmote"},"parser":{"title":"Parser","require":"markup","owner":"Golmote"},"pascal":{"title":"Pascal","alias":"objectpascal","aliasTitles":{"objectpascal":"Object Pascal"},"owner":"Golmote"},"pascaligo":{"title":"Pascaligo","owner":"DefinitelyNotAGoat"},"pcaxis":{"title":"PC-Axis","alias":"px","owner":"RunDevelopment"},"peoplecode":{"title":"PeopleCode","alias":"pcode","owner":"RunDevelopment"},"perl":{"title":"Perl","owner":"Golmote"},"php":{"title":"PHP","require":"markup-templating","owner":"milesj"},"phpdoc":{"title":"PHPDoc","require":["php","javadoclike"],"modify":"php","owner":"RunDevelopment"},"php-extras":{"title":"PHP Extras","require":"php","modify":"php","owner":"milesj"},"plsql":{"title":"PL/SQL","require":"sql","owner":"Golmote"},"powerquery":{"title":"PowerQuery","alias":["pq","mscript"],"owner":"peterbud"},"powershell":{"title":"PowerShell","owner":"nauzilus"},"processing":{"title":"Processing","require":"clike","owner":"Golmote"},"prolog":{"title":"Prolog","owner":"Golmote"},"promql":{"title":"PromQL","owner":"arendjr"},"properties":{"title":".properties","owner":"Golmote"},"protobuf":{"title":"Protocol Buffers","require":"clike","owner":"just-boris"},"pug":{"title":"Pug","require":["markup","javascript"],"optional":["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],"owner":"Golmote"},"puppet":{"title":"Puppet","owner":"Golmote"},"pure":{"title":"Pure","optional":["c","cpp","fortran"],"owner":"Golmote"},"purebasic":{"title":"PureBasic","require":"clike","alias":"pbfasm","owner":"HeX0R101"},"purescript":{"title":"PureScript","require":"haskell","alias":"purs","owner":"sriharshachilakapati"},"python":{"title":"Python","alias":"py","owner":"multipetros"},"q":{"title":"Q (kdb+ database)","owner":"Golmote"},"qml":{"title":"QML","require":"javascript","owner":"RunDevelopment"},"qore":{"title":"Qore","require":"clike","owner":"temnroegg"},"r":{"title":"R","owner":"Golmote"},"racket":{"title":"Racket","require":"scheme","alias":"rkt","owner":"RunDevelopment"},"jsx":{"title":"React JSX","require":["markup","javascript"],"optional":["jsdoc","js-extras","js-templates"],"owner":"vkbansal"},"tsx":{"title":"React TSX","require":["jsx","typescript"]},"reason":{"title":"Reason","require":"clike","owner":"Golmote"},"regex":{"title":"Regex","owner":"RunDevelopment"},"renpy":{"title":"Ren'py","alias":"rpy","owner":"HyuchiaDiego"},"rest":{"title":"reST (reStructuredText)","owner":"Golmote"},"rip":{"title":"Rip","owner":"ravinggenius"},"roboconf":{"title":"Roboconf","owner":"Golmote"},"robotframework":{"title":"Robot Framework","alias":"robot","owner":"RunDevelopment"},"ruby":{"title":"Ruby","require":"clike","alias":"rb","owner":"samflores"},"rust":{"title":"Rust","owner":"Golmote"},"sas":{"title":"SAS","optional":["groovy","lua","sql"],"owner":"Golmote"},"sass":{"title":"Sass (Sass)","require":"css","owner":"Golmote"},"scss":{"title":"Sass (Scss)","require":"css","optional":"css-extras","owner":"MoOx"},"scala":{"title":"Scala","require":"java","owner":"jozic"},"scheme":{"title":"Scheme","owner":"bacchus123"},"shell-session":{"title":"Shell session","require":"bash","alias":["sh-session","shellsession"],"owner":"RunDevelopment"},"smali":{"title":"Smali","owner":"RunDevelopment"},"smalltalk":{"title":"Smalltalk","owner":"Golmote"},"smarty":{"title":"Smarty","require":"markup-templating","owner":"Golmote"},"sml":{"title":"SML","alias":"smlnj","aliasTitles":{"smlnj":"SML/NJ"},"owner":"RunDevelopment"},"solidity":{"title":"Solidity (Ethereum)","alias":"sol","require":"clike","owner":"glachaud"},"solution-file":{"title":"Solution file","alias":"sln","owner":"RunDevelopment"},"soy":{"title":"Soy (Closure Template)","require":"markup-templating","owner":"Golmote"},"sparql":{"title":"SPARQL","require":"turtle","owner":"Triply-Dev","alias":"rq"},"splunk-spl":{"title":"Splunk SPL","owner":"RunDevelopment"},"sqf":{"title":"SQF: Status Quo Function (Arma 3)","require":"clike","owner":"RunDevelopment"},"sql":{"title":"SQL","owner":"multipetros"},"stan":{"title":"Stan","owner":"RunDevelopment"},"iecst":{"title":"Structured Text (IEC 61131-3)","owner":"serhioromano"},"stylus":{"title":"Stylus","owner":"vkbansal"},"swift":{"title":"Swift","require":"clike","owner":"chrischares"},"t4-templating":{"title":"T4 templating","owner":"RunDevelopment"},"t4-cs":{"title":"T4 Text Templates (C#)","require":["t4-templating","csharp"],"alias":"t4","owner":"RunDevelopment"},"t4-vb":{"title":"T4 Text Templates (VB)","require":["t4-templating","vbnet"],"owner":"RunDevelopment"},"tap":{"title":"TAP","owner":"isaacs","require":"yaml"},"tcl":{"title":"Tcl","owner":"PeterChaplin"},"tt2":{"title":"Template Toolkit 2","require":["clike","markup-templating"],"owner":"gflohr"},"textile":{"title":"Textile","require":"markup","optional":"css","owner":"Golmote"},"toml":{"title":"TOML","owner":"RunDevelopment"},"turtle":{"title":"Turtle","alias":"trig","aliasTitles":{"trig":"TriG"},"owner":"jakubklimek"},"twig":{"title":"Twig","require":"markup","owner":"brandonkelly"},"typescript":{"title":"TypeScript","require":"javascript","optional":"js-templates","alias":"ts","owner":"vkbansal"},"typoscript":{"title":"TypoScript","alias":"tsconfig","aliasTitles":{"tsconfig":"TSConfig"},"owner":"dkern"},"unrealscript":{"title":"UnrealScript","alias":["uscript","uc"],"owner":"RunDevelopment"},"vala":{"title":"Vala","require":"clike","optional":"regex","owner":"TemplarVolk"},"vbnet":{"title":"VB.Net","require":"basic","owner":"Bigsby"},"velocity":{"title":"Velocity","require":"markup","owner":"Golmote"},"verilog":{"title":"Verilog","owner":"a-rey"},"vhdl":{"title":"VHDL","owner":"a-rey"},"vim":{"title":"vim","owner":"westonganger"},"visual-basic":{"title":"Visual Basic","alias":["vb","vba"],"aliasTitles":{"vba":"VBA"},"owner":"Golmote"},"warpscript":{"title":"WarpScript","owner":"RunDevelopment"},"wasm":{"title":"WebAssembly","owner":"Golmote"},"wiki":{"title":"Wiki markup","require":"markup","owner":"Golmote"},"xeora":{"title":"Xeora","require":"markup","alias":"xeoracube","aliasTitles":{"xeoracube":"XeoraCube"},"owner":"freakmaxi"},"xml-doc":{"title":"XML doc (.net)","require":"markup","modify":["csharp","fsharp","vbnet"],"owner":"RunDevelopment"},"xojo":{"title":"Xojo (REALbasic)","owner":"Golmote"},"xquery":{"title":"XQuery","require":"markup","owner":"Golmote"},"yaml":{"title":"YAML","alias":"yml","owner":"hason"},"yang":{"title":"YANG","owner":"RunDevelopment"},"zig":{"title":"Zig","owner":"RunDevelopment"}},"plugins":{"meta":{"path":"plugins/{id}/prism-{id}","link":"plugins/{id}/"},"line-highlight":{"title":"Line Highlight","description":"Highlights specific lines and/or line ranges."},"line-numbers":{"title":"Line Numbers","description":"Line number at the beginning of code lines.","owner":"kuba-kubula"},"show-invisibles":{"title":"Show Invisibles","description":"Show hidden characters such as tabs and line breaks.","optional":["autolinker","data-uri-highlight"]},"autolinker":{"title":"Autolinker","description":"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},"wpd":{"title":"WebPlatform Docs","description":"Makes tokens link to WebPlatform.org documentation. The links open in a new tab."},"custom-class":{"title":"Custom Class","description":"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.","owner":"dvkndn","noCSS":true},"file-highlight":{"title":"File Highlight","description":"Fetch external files and highlight them with Prism. Used on the Prism website itself.","noCSS":true},"show-language":{"title":"Show Language","description":"Display the highlighted language in code blocks (inline code does not show the label).","owner":"nauzilus","noCSS":true,"require":"toolbar"},"jsonp-highlight":{"title":"JSONP Highlight","description":"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).","noCSS":true,"owner":"nauzilus"},"highlight-keywords":{"title":"Highlight Keywords","description":"Adds special CSS classes for each keyword matched in the code. For example, the keyword if will have the class keyword-if as well. You can have fine grained control over the appearance of each keyword by providing your own CSS rules.","owner":"vkbansal","noCSS":true},"remove-initial-line-feed":{"title":"Remove initial line feed","description":"Removes the initial line feed in code blocks.","owner":"Golmote","noCSS":true},"inline-color":{"title":"Inline color","description":"Adds a small inline preview for colors in style sheets.","require":"css-extras","owner":"RunDevelopment"},"previewers":{"title":"Previewers","description":"Previewers for angles, colors, gradients, easing and time.","require":"css-extras","owner":"Golmote"},"autoloader":{"title":"Autoloader","description":"Automatically loads the needed languages to highlight the code blocks.","owner":"Golmote","noCSS":true},"keep-markup":{"title":"Keep Markup","description":"Prevents custom markup from being dropped out during highlighting.","owner":"Golmote","optional":"normalize-whitespace","noCSS":true},"command-line":{"title":"Command Line","description":"Display a command line with a prompt and, optionally, the output/response from the commands.","owner":"chriswells0"},"unescaped-markup":{"title":"Unescaped Markup","description":"Write markup without having to escape anything."},"normalize-whitespace":{"title":"Normalize Whitespace","description":"Supports multiple operations to normalize whitespace in code blocks.","owner":"zeitgeist87","optional":"unescaped-markup","noCSS":true},"data-uri-highlight":{"title":"Data-URI Highlight","description":"Highlights data-URI contents.","owner":"Golmote","noCSS":true},"toolbar":{"title":"Toolbar","description":"Attach a toolbar for plugins to easily register buttons on the top of a code block.","owner":"mAAdhaTTah"},"copy-to-clipboard":{"title":"Copy to Clipboard Button","description":"Add a button that copies the code block to the clipboard when clicked.","owner":"mAAdhaTTah","require":"toolbar","noCSS":true},"download-button":{"title":"Download Button","description":"A button in the toolbar of a code block adding a convenient way to download a code file.","owner":"Golmote","require":"toolbar","noCSS":true},"match-braces":{"title":"Match braces","description":"Highlights matching braces.","owner":"RunDevelopment"},"diff-highlight":{"title":"Diff Highlight","description":"Highlights the code inside diff blocks.","owner":"RunDevelopment","require":"diff"},"filter-highlight-all":{"title":"Filter highlightAll","description":"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.","owner":"RunDevelopment","noCSS":true},"treeview":{"title":"Treeview","description":"A language with special styles to highlight file system tree structures.","owner":"Golmote"}}};
+var components = {"core":{"meta":{"path":"components/prism-core.js","option":"mandatory"},"core":"Core"},"themes":{"meta":{"path":"themes/{id}.css","link":"index.html?theme={id}","exclusive":true},"prism":{"title":"Default","option":"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{"title":"Okaidia","owner":"ocodia"},"prism-twilight":{"title":"Twilight","owner":"remybach"},"prism-coy":{"title":"Coy","owner":"tshedor"},"prism-solarizedlight":{"title":"Solarized Light","owner":"hectormatos2011 "},"prism-tomorrow":{"title":"Tomorrow Night","owner":"Rosey"}},"languages":{"meta":{"path":"components/prism-{id}","noCSS":true,"examplesPath":"examples/prism-{id}","addCheckAll":true},"markup":{"title":"Markup","alias":["html","xml","svg","mathml","ssml","atom","rss"],"aliasTitles":{"html":"HTML","xml":"XML","svg":"SVG","mathml":"MathML","ssml":"SSML","atom":"Atom","rss":"RSS"},"option":"default"},"css":{"title":"CSS","option":"default","modify":"markup"},"clike":{"title":"C-like","option":"default"},"javascript":{"title":"JavaScript","require":"clike","modify":"markup","optional":"regex","alias":"js","option":"default"},"abap":{"title":"ABAP","owner":"dellagustin"},"abnf":{"title":"ABNF","owner":"RunDevelopment"},"actionscript":{"title":"ActionScript","require":"javascript","modify":"markup","owner":"Golmote"},"ada":{"title":"Ada","owner":"Lucretia"},"agda":{"title":"Agda","owner":"xy-ren"},"al":{"title":"AL","owner":"RunDevelopment"},"antlr4":{"title":"ANTLR4","alias":"g4","owner":"RunDevelopment"},"apacheconf":{"title":"Apache Configuration","owner":"GuiTeK"},"apex":{"title":"Apex","require":["clike","sql"],"owner":"RunDevelopment"},"apl":{"title":"APL","owner":"ngn"},"applescript":{"title":"AppleScript","owner":"Golmote"},"aql":{"title":"AQL","owner":"RunDevelopment"},"arduino":{"title":"Arduino","require":"cpp","owner":"dkern"},"arff":{"title":"ARFF","owner":"Golmote"},"asciidoc":{"alias":"adoc","title":"AsciiDoc","owner":"Golmote"},"aspnet":{"title":"ASP.NET (C#)","require":["markup","csharp"],"owner":"nauzilus"},"asm6502":{"title":"6502 Assembly","owner":"kzurawel"},"autohotkey":{"title":"AutoHotkey","owner":"aviaryan"},"autoit":{"title":"AutoIt","owner":"Golmote"},"bash":{"title":"Bash","alias":"shell","aliasTitles":{"shell":"Shell"},"owner":"zeitgeist87"},"basic":{"title":"BASIC","owner":"Golmote"},"batch":{"title":"Batch","owner":"Golmote"},"bbcode":{"title":"BBcode","alias":"shortcode","aliasTitles":{"shortcode":"Shortcode"},"owner":"RunDevelopment"},"birb":{"title":"Birb","require":"clike","owner":"Calamity210"},"bison":{"title":"Bison","require":"c","owner":"Golmote"},"bnf":{"title":"BNF","alias":"rbnf","aliasTitles":{"rbnf":"RBNF"},"owner":"RunDevelopment"},"brainfuck":{"title":"Brainfuck","owner":"Golmote"},"brightscript":{"title":"BrightScript","owner":"RunDevelopment"},"bro":{"title":"Bro","owner":"wayward710"},"bsl":{"title":"BSL (1C:Enterprise)","alias":"oscript","aliasTitles":{"oscript":"OneScript"},"owner":"Diversus23"},"c":{"title":"C","require":"clike","owner":"zeitgeist87"},"csharp":{"title":"C#","require":"clike","alias":["cs","dotnet"],"owner":"mvalipour"},"cpp":{"title":"C++","require":"c","owner":"zeitgeist87"},"cil":{"title":"CIL","owner":"sbrl"},"clojure":{"title":"Clojure","owner":"troglotit"},"cmake":{"title":"CMake","owner":"mjrogozinski"},"coffeescript":{"title":"CoffeeScript","require":"javascript","alias":"coffee","owner":"R-osey"},"concurnas":{"title":"Concurnas","alias":"conc","owner":"jasontatton"},"csp":{"title":"Content-Security-Policy","owner":"ScottHelme"},"crystal":{"title":"Crystal","require":"ruby","owner":"MakeNowJust"},"css-extras":{"title":"CSS Extras","require":"css","modify":"css","owner":"milesj"},"cypher":{"title":"Cypher","owner":"RunDevelopment"},"d":{"title":"D","require":"clike","owner":"Golmote"},"dart":{"title":"Dart","require":"clike","owner":"Golmote"},"dataweave":{"title":"DataWeave","owner":"machaval"},"dax":{"title":"DAX","owner":"peterbud"},"dhall":{"title":"Dhall","owner":"RunDevelopment"},"diff":{"title":"Diff","owner":"uranusjr"},"django":{"title":"Django/Jinja2","require":"markup-templating","alias":"jinja2","owner":"romanvm"},"dns-zone-file":{"title":"DNS zone file","owner":"RunDevelopment","alias":"dns-zone"},"docker":{"title":"Docker","alias":"dockerfile","owner":"JustinBeckwith"},"ebnf":{"title":"EBNF","owner":"RunDevelopment"},"editorconfig":{"title":"EditorConfig","owner":"osipxd"},"eiffel":{"title":"Eiffel","owner":"Conaclos"},"ejs":{"title":"EJS","require":["javascript","markup-templating"],"owner":"RunDevelopment","alias":"eta","aliasTitles":{"eta":"Eta"}},"elixir":{"title":"Elixir","owner":"Golmote"},"elm":{"title":"Elm","owner":"zwilias"},"etlua":{"title":"Embedded Lua templating","require":["lua","markup-templating"],"owner":"RunDevelopment"},"erb":{"title":"ERB","require":["ruby","markup-templating"],"owner":"Golmote"},"erlang":{"title":"Erlang","owner":"Golmote"},"excel-formula":{"title":"Excel Formula","alias":["xlsx","xls"],"owner":"RunDevelopment"},"fsharp":{"title":"F#","require":"clike","owner":"simonreynolds7"},"factor":{"title":"Factor","owner":"catb0t"},"firestore-security-rules":{"title":"Firestore security rules","require":"clike","owner":"RunDevelopment"},"flow":{"title":"Flow","require":"javascript","owner":"Golmote"},"fortran":{"title":"Fortran","owner":"Golmote"},"ftl":{"title":"FreeMarker Template Language","require":"markup-templating","owner":"RunDevelopment"},"gml":{"title":"GameMaker Language","alias":"gamemakerlanguage","require":"clike","owner":"LiarOnce"},"gcode":{"title":"G-code","owner":"RunDevelopment"},"gdscript":{"title":"GDScript","owner":"RunDevelopment"},"gedcom":{"title":"GEDCOM","owner":"Golmote"},"gherkin":{"title":"Gherkin","owner":"hason"},"git":{"title":"Git","owner":"lgiraudel"},"glsl":{"title":"GLSL","require":"c","owner":"Golmote"},"go":{"title":"Go","require":"clike","owner":"arnehormann"},"graphql":{"title":"GraphQL","optional":["markdown"],"owner":"Golmote"},"groovy":{"title":"Groovy","require":"clike","owner":"robfletcher"},"haml":{"title":"Haml","require":"ruby","optional":["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],"owner":"Golmote"},"handlebars":{"title":"Handlebars","require":"markup-templating","owner":"Golmote"},"haskell":{"title":"Haskell","alias":"hs","owner":"bholst"},"haxe":{"title":"Haxe","require":"clike","owner":"Golmote"},"hcl":{"title":"HCL","owner":"outsideris"},"hlsl":{"title":"HLSL","require":"c","owner":"RunDevelopment"},"http":{"title":"HTTP","optional":["css","javascript","json","markup"],"owner":"danielgtaylor"},"hpkp":{"title":"HTTP Public-Key-Pins","owner":"ScottHelme"},"hsts":{"title":"HTTP Strict-Transport-Security","owner":"ScottHelme"},"ichigojam":{"title":"IchigoJam","owner":"BlueCocoa"},"icon":{"title":"Icon","owner":"Golmote"},"ignore":{"title":".ignore","owner":"osipxd","alias":["gitignore","hgignore","npmignore"],"aliasTitles":{"gitignore":".gitignore","hgignore":".hgignore","npmignore":".npmignore"}},"inform7":{"title":"Inform 7","owner":"Golmote"},"ini":{"title":"Ini","owner":"aviaryan"},"io":{"title":"Io","owner":"AlesTsurko"},"j":{"title":"J","owner":"Golmote"},"java":{"title":"Java","require":"clike","owner":"sherblot"},"javadoc":{"title":"JavaDoc","require":["markup","java","javadoclike"],"modify":"java","optional":"scala","owner":"RunDevelopment"},"javadoclike":{"title":"JavaDoc-like","modify":["java","javascript","php"],"owner":"RunDevelopment"},"javastacktrace":{"title":"Java stack trace","owner":"RunDevelopment"},"jolie":{"title":"Jolie","require":"clike","owner":"thesave"},"jq":{"title":"JQ","owner":"RunDevelopment"},"jsdoc":{"title":"JSDoc","require":["javascript","javadoclike","typescript"],"modify":"javascript","optional":["actionscript","coffeescript"],"owner":"RunDevelopment"},"js-extras":{"title":"JS Extras","require":"javascript","modify":"javascript","optional":["actionscript","coffeescript","flow","n4js","typescript"],"owner":"RunDevelopment"},"json":{"title":"JSON","alias":"webmanifest","aliasTitles":{"webmanifest":"Web App Manifest"},"owner":"CupOfTea696"},"json5":{"title":"JSON5","require":"json","owner":"RunDevelopment"},"jsonp":{"title":"JSONP","require":"json","owner":"RunDevelopment"},"jsstacktrace":{"title":"JS stack trace","owner":"sbrl"},"js-templates":{"title":"JS Templates","require":"javascript","modify":"javascript","optional":["css","css-extras","graphql","markdown","markup"],"owner":"RunDevelopment"},"julia":{"title":"Julia","owner":"cdagnino"},"keyman":{"title":"Keyman","owner":"mcdurdin"},"kotlin":{"title":"Kotlin","alias":["kt","kts"],"aliasTitles":{"kts":"Kotlin Script"},"require":"clike","owner":"Golmote"},"latex":{"title":"LaTeX","alias":["tex","context"],"aliasTitles":{"tex":"TeX","context":"ConTeXt"},"owner":"japborst"},"latte":{"title":"Latte","require":["clike","markup-templating","php"],"owner":"nette"},"less":{"title":"Less","require":"css","optional":"css-extras","owner":"Golmote"},"lilypond":{"title":"LilyPond","require":"scheme","alias":"ly","owner":"RunDevelopment"},"liquid":{"title":"Liquid","owner":"cinhtau"},"lisp":{"title":"Lisp","alias":["emacs","elisp","emacs-lisp"],"owner":"JuanCaicedo"},"livescript":{"title":"LiveScript","owner":"Golmote"},"llvm":{"title":"LLVM IR","owner":"porglezomp"},"lolcode":{"title":"LOLCODE","owner":"Golmote"},"lua":{"title":"Lua","owner":"Golmote"},"makefile":{"title":"Makefile","owner":"Golmote"},"markdown":{"title":"Markdown","require":"markup","optional":"yaml","alias":"md","owner":"Golmote"},"markup-templating":{"title":"Markup templating","require":"markup","owner":"Golmote"},"matlab":{"title":"MATLAB","owner":"Golmote"},"mel":{"title":"MEL","owner":"Golmote"},"mizar":{"title":"Mizar","owner":"Golmote"},"mongodb":{"title":"MongoDB","owner":"airs0urce","require":"javascript"},"monkey":{"title":"Monkey","owner":"Golmote"},"moonscript":{"title":"MoonScript","alias":"moon","owner":"RunDevelopment"},"n1ql":{"title":"N1QL","owner":"TMWilds"},"n4js":{"title":"N4JS","require":"javascript","optional":"jsdoc","alias":"n4jsd","owner":"bsmith-n4"},"nand2tetris-hdl":{"title":"Nand To Tetris HDL","owner":"stephanmax"},"naniscript":{"title":"Naninovel Script","owner":"Elringus","alias":"nani"},"nasm":{"title":"NASM","owner":"rbmj"},"neon":{"title":"NEON","owner":"nette"},"nginx":{"title":"nginx","owner":"westonganger","require":"clike"},"nim":{"title":"Nim","owner":"Golmote"},"nix":{"title":"Nix","owner":"Golmote"},"nsis":{"title":"NSIS","owner":"idleberg"},"objectivec":{"title":"Objective-C","require":"c","alias":"objc","owner":"uranusjr"},"ocaml":{"title":"OCaml","owner":"Golmote"},"opencl":{"title":"OpenCL","require":"c","modify":["c","cpp"],"owner":"Milania1"},"oz":{"title":"Oz","owner":"Golmote"},"parigp":{"title":"PARI/GP","owner":"Golmote"},"parser":{"title":"Parser","require":"markup","owner":"Golmote"},"pascal":{"title":"Pascal","alias":"objectpascal","aliasTitles":{"objectpascal":"Object Pascal"},"owner":"Golmote"},"pascaligo":{"title":"Pascaligo","owner":"DefinitelyNotAGoat"},"patterns":{"title":"Patterns","owner":"RunDevelopment"},"pcaxis":{"title":"PC-Axis","alias":"px","owner":"RunDevelopment"},"peoplecode":{"title":"PeopleCode","alias":"pcode","owner":"RunDevelopment"},"perl":{"title":"Perl","owner":"Golmote"},"php":{"title":"PHP","require":"markup-templating","owner":"milesj"},"phpdoc":{"title":"PHPDoc","require":["php","javadoclike"],"modify":"php","owner":"RunDevelopment"},"php-extras":{"title":"PHP Extras","require":"php","modify":"php","owner":"milesj"},"plsql":{"title":"PL/SQL","require":"sql","owner":"Golmote"},"powerquery":{"title":"PowerQuery","alias":["pq","mscript"],"owner":"peterbud"},"powershell":{"title":"PowerShell","owner":"nauzilus"},"processing":{"title":"Processing","require":"clike","owner":"Golmote"},"prolog":{"title":"Prolog","owner":"Golmote"},"promql":{"title":"PromQL","owner":"arendjr"},"properties":{"title":".properties","owner":"Golmote"},"protobuf":{"title":"Protocol Buffers","require":"clike","owner":"just-boris"},"pug":{"title":"Pug","require":["markup","javascript"],"optional":["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],"owner":"Golmote"},"puppet":{"title":"Puppet","owner":"Golmote"},"pure":{"title":"Pure","optional":["c","cpp","fortran"],"owner":"Golmote"},"purebasic":{"title":"PureBasic","require":"clike","alias":"pbfasm","owner":"HeX0R101"},"purescript":{"title":"PureScript","require":"haskell","alias":"purs","owner":"sriharshachilakapati"},"python":{"title":"Python","alias":"py","owner":"multipetros"},"q":{"title":"Q (kdb+ database)","owner":"Golmote"},"qml":{"title":"QML","require":"javascript","owner":"RunDevelopment"},"qore":{"title":"Qore","require":"clike","owner":"temnroegg"},"r":{"title":"R","owner":"Golmote"},"racket":{"title":"Racket","require":"scheme","alias":"rkt","owner":"RunDevelopment"},"jsx":{"title":"React JSX","require":["markup","javascript"],"optional":["jsdoc","js-extras","js-templates"],"owner":"vkbansal"},"tsx":{"title":"React TSX","require":["jsx","typescript"]},"reason":{"title":"Reason","require":"clike","owner":"Golmote"},"regex":{"title":"Regex","owner":"RunDevelopment"},"renpy":{"title":"Ren'py","alias":"rpy","owner":"HyuchiaDiego"},"rest":{"title":"reST (reStructuredText)","owner":"Golmote"},"rip":{"title":"Rip","owner":"ravinggenius"},"roboconf":{"title":"Roboconf","owner":"Golmote"},"robotframework":{"title":"Robot Framework","alias":"robot","owner":"RunDevelopment"},"ruby":{"title":"Ruby","require":"clike","alias":"rb","owner":"samflores"},"rust":{"title":"Rust","owner":"Golmote"},"sas":{"title":"SAS","optional":["groovy","lua","sql"],"owner":"Golmote"},"sass":{"title":"Sass (Sass)","require":"css","owner":"Golmote"},"scss":{"title":"Sass (Scss)","require":"css","optional":"css-extras","owner":"MoOx"},"scala":{"title":"Scala","require":"java","owner":"jozic"},"scheme":{"title":"Scheme","owner":"bacchus123"},"shell-session":{"title":"Shell session","require":"bash","alias":["sh-session","shellsession"],"owner":"RunDevelopment"},"smali":{"title":"Smali","owner":"RunDevelopment"},"smalltalk":{"title":"Smalltalk","owner":"Golmote"},"smarty":{"title":"Smarty","require":"markup-templating","owner":"Golmote"},"sml":{"title":"SML","alias":"smlnj","aliasTitles":{"smlnj":"SML/NJ"},"owner":"RunDevelopment"},"solidity":{"title":"Solidity (Ethereum)","alias":"sol","require":"clike","owner":"glachaud"},"solution-file":{"title":"Solution file","alias":"sln","owner":"RunDevelopment"},"soy":{"title":"Soy (Closure Template)","require":"markup-templating","owner":"Golmote"},"sparql":{"title":"SPARQL","require":"turtle","owner":"Triply-Dev","alias":"rq"},"splunk-spl":{"title":"Splunk SPL","owner":"RunDevelopment"},"sqf":{"title":"SQF: Status Quo Function (Arma 3)","require":"clike","owner":"RunDevelopment"},"sql":{"title":"SQL","owner":"multipetros"},"stan":{"title":"Stan","owner":"RunDevelopment"},"iecst":{"title":"Structured Text (IEC 61131-3)","owner":"serhioromano"},"stylus":{"title":"Stylus","owner":"vkbansal"},"swift":{"title":"Swift","require":"clike","owner":"chrischares"},"t4-templating":{"title":"T4 templating","owner":"RunDevelopment"},"t4-cs":{"title":"T4 Text Templates (C#)","require":["t4-templating","csharp"],"alias":"t4","owner":"RunDevelopment"},"t4-vb":{"title":"T4 Text Templates (VB)","require":["t4-templating","vbnet"],"owner":"RunDevelopment"},"tap":{"title":"TAP","owner":"isaacs","require":"yaml"},"tcl":{"title":"Tcl","owner":"PeterChaplin"},"tt2":{"title":"Template Toolkit 2","require":["clike","markup-templating"],"owner":"gflohr"},"textile":{"title":"Textile","require":"markup","optional":"css","owner":"Golmote"},"toml":{"title":"TOML","owner":"RunDevelopment"},"turtle":{"title":"Turtle","alias":"trig","aliasTitles":{"trig":"TriG"},"owner":"jakubklimek"},"twig":{"title":"Twig","require":"markup","owner":"brandonkelly"},"typescript":{"title":"TypeScript","require":"javascript","optional":"js-templates","alias":"ts","owner":"vkbansal"},"typoscript":{"title":"TypoScript","alias":"tsconfig","aliasTitles":{"tsconfig":"TSConfig"},"owner":"dkern"},"unrealscript":{"title":"UnrealScript","alias":["uscript","uc"],"owner":"RunDevelopment"},"vala":{"title":"Vala","require":"clike","optional":"regex","owner":"TemplarVolk"},"vbnet":{"title":"VB.Net","require":"basic","owner":"Bigsby"},"velocity":{"title":"Velocity","require":"markup","owner":"Golmote"},"verilog":{"title":"Verilog","owner":"a-rey"},"vhdl":{"title":"VHDL","owner":"a-rey"},"vim":{"title":"vim","owner":"westonganger"},"visual-basic":{"title":"Visual Basic","alias":["vb","vba"],"aliasTitles":{"vba":"VBA"},"owner":"Golmote"},"warpscript":{"title":"WarpScript","owner":"RunDevelopment"},"wasm":{"title":"WebAssembly","owner":"Golmote"},"wiki":{"title":"Wiki markup","require":"markup","owner":"Golmote"},"xeora":{"title":"Xeora","require":"markup","alias":"xeoracube","aliasTitles":{"xeoracube":"XeoraCube"},"owner":"freakmaxi"},"xml-doc":{"title":"XML doc (.net)","require":"markup","modify":["csharp","fsharp","vbnet"],"owner":"RunDevelopment"},"xojo":{"title":"Xojo (REALbasic)","owner":"Golmote"},"xquery":{"title":"XQuery","require":"markup","owner":"Golmote"},"yaml":{"title":"YAML","alias":"yml","owner":"hason"},"yang":{"title":"YANG","owner":"RunDevelopment"},"zig":{"title":"Zig","owner":"RunDevelopment"}},"plugins":{"meta":{"path":"plugins/{id}/prism-{id}","link":"plugins/{id}/"},"line-highlight":{"title":"Line Highlight","description":"Highlights specific lines and/or line ranges."},"line-numbers":{"title":"Line Numbers","description":"Line number at the beginning of code lines.","owner":"kuba-kubula"},"show-invisibles":{"title":"Show Invisibles","description":"Show hidden characters such as tabs and line breaks.","optional":["autolinker","data-uri-highlight"]},"autolinker":{"title":"Autolinker","description":"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},"wpd":{"title":"WebPlatform Docs","description":"Makes tokens link to WebPlatform.org documentation. The links open in a new tab."},"custom-class":{"title":"Custom Class","description":"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.","owner":"dvkndn","noCSS":true},"file-highlight":{"title":"File Highlight","description":"Fetch external files and highlight them with Prism. Used on the Prism website itself.","noCSS":true},"show-language":{"title":"Show Language","description":"Display the highlighted language in code blocks (inline code does not show the label).","owner":"nauzilus","noCSS":true,"require":"toolbar"},"jsonp-highlight":{"title":"JSONP Highlight","description":"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).","noCSS":true,"owner":"nauzilus"},"highlight-keywords":{"title":"Highlight Keywords","description":"Adds special CSS classes for each keyword matched in the code. For example, the keyword if will have the class keyword-if as well. You can have fine grained control over the appearance of each keyword by providing your own CSS rules.","owner":"vkbansal","noCSS":true},"remove-initial-line-feed":{"title":"Remove initial line feed","description":"Removes the initial line feed in code blocks.","owner":"Golmote","noCSS":true},"inline-color":{"title":"Inline color","description":"Adds a small inline preview for colors in style sheets.","require":"css-extras","owner":"RunDevelopment"},"previewers":{"title":"Previewers","description":"Previewers for angles, colors, gradients, easing and time.","require":"css-extras","owner":"Golmote"},"autoloader":{"title":"Autoloader","description":"Automatically loads the needed languages to highlight the code blocks.","owner":"Golmote","noCSS":true},"keep-markup":{"title":"Keep Markup","description":"Prevents custom markup from being dropped out during highlighting.","owner":"Golmote","optional":"normalize-whitespace","noCSS":true},"command-line":{"title":"Command Line","description":"Display a command line with a prompt and, optionally, the output/response from the commands.","owner":"chriswells0"},"unescaped-markup":{"title":"Unescaped Markup","description":"Write markup without having to escape anything."},"normalize-whitespace":{"title":"Normalize Whitespace","description":"Supports multiple operations to normalize whitespace in code blocks.","owner":"zeitgeist87","optional":"unescaped-markup","noCSS":true},"data-uri-highlight":{"title":"Data-URI Highlight","description":"Highlights data-URI contents.","owner":"Golmote","noCSS":true},"toolbar":{"title":"Toolbar","description":"Attach a toolbar for plugins to easily register buttons on the top of a code block.","owner":"mAAdhaTTah"},"copy-to-clipboard":{"title":"Copy to Clipboard Button","description":"Add a button that copies the code block to the clipboard when clicked.","owner":"mAAdhaTTah","require":"toolbar","noCSS":true},"download-button":{"title":"Download Button","description":"A button in the toolbar of a code block adding a convenient way to download a code file.","owner":"Golmote","require":"toolbar","noCSS":true},"match-braces":{"title":"Match braces","description":"Highlights matching braces.","owner":"RunDevelopment"},"diff-highlight":{"title":"Diff Highlight","description":"Highlights the code inside diff blocks.","owner":"RunDevelopment","require":"diff"},"filter-highlight-all":{"title":"Filter highlightAll","description":"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.","owner":"RunDevelopment","noCSS":true},"treeview":{"title":"Treeview","description":"A language with special styles to highlight file system tree structures.","owner":"Golmote"}}};
if (typeof module !== 'undefined' && module.exports) { module.exports = components; }
\ No newline at end of file
diff --git a/components.json b/components.json
index e2e9845a97..99767de1e0 100644
--- a/components.json
+++ b/components.json
@@ -831,6 +831,10 @@
"title": "Pascaligo",
"owner": "DefinitelyNotAGoat"
},
+ "patterns": {
+ "title": "Patterns",
+ "owner": "RunDevelopment"
+ },
"pcaxis": {
"title": "PC-Axis",
"alias": "px",
diff --git a/components/prism-patterns.js b/components/prism-patterns.js
new file mode 100644
index 0000000000..8079900a67
--- /dev/null
+++ b/components/prism-patterns.js
@@ -0,0 +1,365 @@
+(function (Prism) {
+
+ /**
+ * A pattern is an immutable object
+ * @typedef {{ readonly source: string; readonly flags: Flags }} Pattern
+ *
+ * @typedef {'g' | 'i' | 'm' | 's' | 'u' | 'y'} Flag
+ * @typedef {{ readonly [key in Flag]?: boolean }} Flags
+ * @typedef {{ [key in Flag]?: boolean }} MutableFlags
+ */
+
+ /** @type {readonly Flag[]} */
+ var FLAG_KEYS = ['g', 'i', 'm', 's', 'u', 'y'];
+ /** @type {Flags} */
+ var EMPTY_FLAGS = {};
+ var NO_MATCH = '[^\\s\\S]';
+
+ /**
+ * An internal helper function to convert the given value to a pattern.
+ *
+ * @param {string | Pattern} pattern
+ * @returns {Pattern}
+ */
+ function internalToPattern(pattern) {
+ if (typeof pattern === 'string') {
+ return p(pattern);
+ } else {
+ return pattern;
+ }
+ }
+
+ /**
+ * Creates a new pattern from the given source and optional flags.
+ *
+ * @param {string} source
+ * @param {Flags} [flags]
+ * @returns {Pattern}
+ */
+ function p(source, flags) {
+ return { source: source, flags: flags || EMPTY_FLAGS };
+ }
+
+ /**
+ * Converts the given pattern to a `RegExp` object.
+ *
+ * @param {string | Pattern} pattern
+ * @returns {RegExp}
+ */
+ function toRegExp(pattern) {
+ pattern = internalToPattern(pattern);
+
+ var patternFlags = pattern.flags;
+ var flags = '';
+ if (patternFlags !== EMPTY_FLAGS) {
+ FLAG_KEYS.forEach(function (f) {
+ if (patternFlags[f]) {
+ flags += f;
+ }
+ });
+ }
+ return RegExp(pattern.source, flags);
+ }
+
+ /**
+ * This will parse the given source and replace parts of it with the given replacer function. The replaced source
+ * will be returned.
+ *
+ * The replacer will be called for every detected token. Tokens can be differentiated by assigning the content of
+ * the token a capturing group and whether this group was matched in the replacer.
+ * By default, the replacer will be called for:
+ *
+ * 1. Back references. The content of the group will be number of the referenced group.
+ * Note: This will also contain all octal escapes except for `\0`.
+ * 2. Capturing groups. The content of the group will simply be `(`.
+ * 3. All other escape sequences which start with a backslash but there won't be a capturing group for it.
+ * 4. All character classes (e.g. `[a-z\d]`) but there won't be a capturing group for it.
+ *
+ * You can add additional tokens which will be parsed before the default tokens.
+ *
+ * The replacer will be called with the following arguments:
+ *
+ * 1. The matched string.
+ * 2. The capturing groups of the additional tokens.
+ * 3. The capturing group of backreferences.
+ * 4. The capturing group of capturing groups.
+ * 5. The index of the match.
+ * 6. The whole input string.
+ *
+ * @param {string} source
+ * @param {string} additionalTokens
+ * @param {(m: string, ...other: any[]) => string} replacer
+ * @returns {string}
+ * @example
+ * const source = replaceSource(
+ * /(foo|[a-z])\1/.source,
+ * '(foo)',
+ * (m, foo, backRef, group, index, input) => {
+ * if (foo) return 'bar';
+ * return m;
+ * }
+ * );
+ * console.log(source); // (bar|[a-z])\1
+ */
+ function replaceSource(source, additionalTokens, replacer) {
+ var tokens = (additionalTokens || NO_MATCH) + '|' + /\\(?:0|([1-9]\d{0,2})|\D)|(\((?!\?))|\[[^\]]*\]/.source;
+ return source.replace(RegExp(tokens, 'g'), replacer)
+ }
+
+ /**
+ * Replaces all placeholders in the given pattern with the associated replacement in the given replacement array
+ * and returns the result as a new pattern.
+ *
+ * Placeholder have to be of the form `` where the placeholder is the given placeholder pattern. The
+ * matched string by the placeholder will be the key in the replacements record to get the associated replacement.
+ *
+ * The pattern of each inserted replacement will be wrapped with a non-capturing group. Backreferences in
+ * the given pattern and inserted replacements will be adjusted, so that they still reference the same group as
+ * before this operation.
+ *
+ * Escaped placeholders (e.g. `\<2>` or ``), placeholders inside character classes (e.g. `[a-z<2>]`),
+ * and placeholders in replacements will not be replaced.
+ *
+ * If the flags of any two replacements or of the given pattern are contradictory (e.g. the given pattern requires
+ * the `i` flag while a replacement forbids it) an error will be thrown. The given pattern and the replacements are
+ * not allowed to use octal escapes (e.g. `\2` in `/(a)\2/i`) and backreferences cannot be declared before the
+ * referenced capturing group (e.g. `/\1(a)/` is not allowed).
+ *
+ * Note: This method will __NOT__ verify whether any of the given patterns are valid regular expressions.
+ *
+ * @param {string | Pattern} pattern
+ * @param {string} placeholder The placeholder pattern. This regular expression cannot contain capturing groups.
+ * @param {Readonly> | Readonly>} replacements
+ */
+ function generalTemplate(pattern, placeholder, replacements) {
+ pattern = internalToPattern(pattern);
+
+ /** @type {string} */
+ var source = pattern.source;
+ /** @type {MutableFlags} */
+ var flags = pattern.flags;
+
+ /** Whether the current flags set is actually mutable. */
+ var mutable = false;
+
+ /** The current number of processed groups in the base pattern. */
+ var baseGroupCount = 0;
+ /** The current number of added groups to the base pattern. */
+ var addedGroupCount = 0;
+ /**
+ * A map from the number of a capturing group in the base pattern to the number of that capturing group in the
+ * final pattern. Groups will be assigned a different number because the replacements might add their own
+ * groups.
+ *
+ * @type {Record}
+ */
+ var baseGroupMap = {};
+
+
+ /**
+ * Returns the source of the given replacement and adds the flags of the replacement to the current set of
+ * flags.
+ *
+ * @param {string} key
+ * @returns {string}
+ */
+ function getReplacement(key) {
+ /** @type {string | Pattern | undefined} */
+ var rep = replacements[key];
+
+ if (rep == undefined && !Prism.MIN) {
+ throw new Error('There is no replacement for <' + key + '>.');
+ }
+
+ rep = internalToPattern(rep);
+ handleReplacementFlags(key, rep.flags);
+ return processReplacementSource(key, rep.source);
+ }
+
+ /**
+ * Adds the flags of a replacement to the current set of flags.
+ *
+ * @param {string} key
+ * @param {Flags} repFlags
+ * @returns {void}
+ */
+ function handleReplacementFlags(key, repFlags) {
+ if (repFlags !== EMPTY_FLAGS) {
+ if (flags === EMPTY_FLAGS) {
+ // Just copy the replacement's flags, they're immutable after all.
+ flags = repFlags;
+ } else if (flags !== repFlags) {
+ // The basic idea is that we go through every flag and check whether we need to change the current
+ // flags. If so, we make the flags mutable, if not mutable already, and set the flag.
+ FLAG_KEYS.forEach(function (f) {
+ var rf = repFlags[f];
+ if (rf != undefined) {
+ var ff = flags[f];
+ if (ff == undefined) {
+ // create a mutable copy of the flags
+ if (!mutable) {
+ mutable = true;
+ flags = Prism.util.clone(flags);
+ }
+ // set new flag
+ flags[f] = rf;
+ } else if (rf !== ff) {
+ // Contradiction. This happens if two incompatible patterns are combined.
+ // E.g. a case sensitive and a case insensitive pattern
+ if (!Prism.MIN) {
+ throw new Error('<' + key + '> requires the ' + f + ' flag to be ' + rf
+ + ' in contradiction with current flags.');
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * Returns the adjusted source of the given replacement source. This will adjust the backreferences in the
+ * replacement and count the number of capturing groups in the replacement.
+ *
+ * @param {string} key
+ * @param {string} repSource
+ * @returns {string}
+ */
+ function processReplacementSource(key, repSource) {
+ var offset = baseGroupCount + addedGroupCount;
+ var groupCount = 0;
+
+ repSource = '(?:' + replaceSource(repSource, '',
+ /**
+ * @param {string} m
+ * @param {string} [backRef]
+ * @param {string} [group]
+ */
+ function (m, backRef, group) {
+ if (backRef) {
+ var ref = +backRef;
+ // This reference might refer to a group which has yet to appear or to no group at all in the
+ // case of an octal escape. For more information, see `getBackReference`.
+ if (ref > groupCount && !Prism.MIN) {
+ throw new Error('Invalid backreference \\' + backRef + ' in replacement <' + key + '>.');
+ }
+ return '\\' + (ref + offset);
+ }
+ if (group) {
+ groupCount++;
+ }
+ return m;
+ }) + ')';
+
+ addedGroupCount += groupCount;
+
+ return repSource;
+ }
+
+ /**
+ * Returns a adjusted backreference which points to the same group as the given backreference.
+ *
+ * Back reference have to be adjusted because replacements might introduce new groups which change the number
+ * of the referenced capturing group.
+ *
+ * @param {string} backRef
+ * @returns {string}
+ */
+ function getBackReference(backRef) {
+ var newRef = baseGroupMap[backRef];
+ // The reference might refer to a group which has yet to appear. A "forward reference" so to say.
+ // Example: /\1(a)/
+ // For whatever reason, this is actually a valid RegExp and will work. References to groups which aren't
+ // matched will be replaced with the empty string, so the above example will match the string "a".
+ // The problem with these "forward reference" is that we don't know the new index of the referenced group
+ // yet, so `newRef` will be undefined.
+ // Note: `newRef` will also be undefined for octal escapes (e.g. /\3/) but those shouldn't be used anyway.
+ if (!newRef && !Prism.MIN) {
+ throw new Error('Invalid backreference \\' + backRef);
+ }
+ return '\\' + newRef;
+ }
+
+ source = replaceSource(source, '<(' + placeholder + ')>',
+ /**
+ * @param {string} m
+ * @param {string} [key]
+ * @param {string} [backRef]
+ * @param {string} [group]
+ */
+ function (m, key, backRef, group) {
+ if (key) {
+ return getReplacement(key);
+ }
+ if (backRef) {
+ return getBackReference(backRef);
+ }
+ if (group) {
+ baseGroupCount++;
+ baseGroupMap[baseGroupCount] = baseGroupCount + addedGroupCount;
+ }
+ return m;
+ });
+
+ return p(source, flags);
+ }
+
+ /**
+ * This is a specialization of the general template method for arrays.
+ *
+ * Only number placeholders (e.g. `<<0>>` and `<<12>>` but not `<<01>>`) will be valid.
+ *
+ * @param {string | Pattern} pattern
+ * @param {readonly (string | Pattern)[]} replacements
+ * @returns {Pattern}
+ */
+ function template(pattern, replacements) {
+ if (!Prism.MIN) {
+ // Verify that the pattern is a valid regular expression.
+ RegExp(internalToPattern(pattern).source);
+
+ // Verify that all replacements are valid regular expressions.
+ replacements.forEach(function (r) {
+ RegExp(internalToPattern(r).source);
+ });
+ }
+ return generalTemplate(pattern, '0|[1-9]\\d*', replacements);
+ }
+
+ /**
+ * Creates a nested version of the given pattern where the string `<>` within the pattern will be replaced
+ * with the pattern itself. This will be done recursively `depth` times.
+ *
+ * This operation does not changes the flags of the pattern.
+ *
+ * @param {string | Pattern} pattern
+ * @param {number} depth
+ * @returns {Pattern}
+ */
+ function nested(pattern, depth) {
+ var replacement;
+
+ if (depth >= 1) {
+ replacement = nested(pattern, depth - 1);
+ } else {
+ if (!Prism.MIN) {
+ // Verify that the pattern is a valid regular expression.
+ RegExp(internalToPattern(pattern).source);
+ }
+
+ replacement = NO_MATCH;
+ }
+
+ return generalTemplate(pattern, 'self', { self: replacement });
+ }
+
+ // exports
+
+ Object.defineProperties(Prism.languages.patterns = {}, {
+ pattern: { value: p },
+ toRegExp: { value: toRegExp },
+ template: { value: template },
+ nested: { value: nested }
+ });
+
+}(Prism));
diff --git a/components/prism-patterns.min.js b/components/prism-patterns.min.js
new file mode 100644
index 0000000000..6c78299177
--- /dev/null
+++ b/components/prism-patterns.min.js
@@ -0,0 +1 @@
+!function(l){var s=["g","i","m","s","u","y"],g={},u="[^\\s\\S]";function v(n){return"string"==typeof n?p(n):n}function p(n,r){return{source:n,flags:r||g}}function E(n,r,e){var t=(r||u)+"|\\\\(?:0|([1-9]\\d{0,2})|\\D)|(\\((?!\\?))|\\[[^\\]]*\\]";return n.replace(RegExp(t,"g"),e)}function t(n,r,e){var t=(n=v(n)).source,u=n.flags,f=!1,o=0,c=0,a={};function i(n){var r=e[n];return function(n,t){t!==g&&(u===g?u=t:u!==t&&s.forEach(function(n){var r=t[n];if(null!=r){var e=u[n];null==e&&(f||(f=!0,u=l.util.clone(u)),u[n]=r)}}))}(0,(r=v(r)).flags),function(n,r){var t=o+c,u=0;return r="(?:"+E(r,"",function(n,r,e){return r?"\\"+(+r+t):(e&&u++,n)})+")",c+=u,r}(0,r.source)}return p(t=E(t,"<("+r+")>",function(n,r,e,t){return r?i(r):e?function(n){return"\\"+a[n]}(e):(t&&(a[++o]=o+c),n)}),u)}Object.defineProperties(l.languages.patterns={},{pattern:{value:p},toRegExp:{value:function(n){var r=(n=v(n)).flags,e="";return r!==g&&s.forEach(function(n){r[n]&&(e+=n)}),RegExp(n.source,e)}},template:{value:function(n,r){return t(n,"0|[1-9]\\d*",r)}},nested:{value:function n(r,e){return t(r,"self",{self:1<=e?n(r,e-1):u})}}})}(Prism);
\ No newline at end of file
diff --git a/gulpfile.js/index.js b/gulpfile.js/index.js
index db351b96d9..15a9695f98 100644
--- a/gulpfile.js/index.js
+++ b/gulpfile.js/index.js
@@ -59,7 +59,12 @@ function inlineRegexSource() {
function minifyJS() {
return [
inlineRegexSource(),
- uglify()
+ replace(/\bPrism.MIN\b/g, 'true'),
+ uglify({
+ compress: {
+ dead_code: true
+ }
+ })
];
}
diff --git a/package.json b/package.json
index 5bd991ae84..0025134b47 100755
--- a/package.json
+++ b/package.json
@@ -9,6 +9,7 @@
"start": "http-server -c-1",
"test:aliases": "mocha tests/aliases-test.js",
"test:core": "mocha tests/core/**/*.js",
+ "test:lib": "mocha tests/lib/**/*.js",
"test:dependencies": "mocha tests/dependencies-test.js",
"test:examples": "mocha tests/examples-test.js",
"test:identifiers": "mocha tests/identifier-test.js",
@@ -16,7 +17,7 @@
"test:patterns": "mocha tests/pattern-tests.js",
"test:plugins": "mocha tests/plugins/**/*.js",
"test:runner": "mocha tests/testrunner-tests.js",
- "test": "npm run test:runner && npm run test:core && npm run test:dependencies && npm run test:languages && npm run test:plugins && npm run test:aliases && npm run test:patterns && npm run test:examples && npm run test:identifiers"
+ "test": "npm run test:runner && npm run test:core && npm run test:lib && npm run test:dependencies && npm run test:languages && npm run test:plugins && npm run test:aliases && npm run test:patterns && npm run test:examples && npm run test:identifiers"
},
"repository": {
"type": "git",
diff --git a/tests/examples-test.js b/tests/examples-test.js
index 0a4f3e4164..e03692d5df 100644
--- a/tests/examples-test.js
+++ b/tests/examples-test.js
@@ -11,6 +11,7 @@ describe('Examples', function () {
const ignore = new Set([
// these are libraries and not languages
'markup-templating',
+ 'patterns',
't4-templating',
// this does alter some languages but it's mainly a library
'javadoclike'
diff --git a/tests/lib/patterns.js b/tests/lib/patterns.js
new file mode 100644
index 0000000000..419e916071
--- /dev/null
+++ b/tests/lib/patterns.js
@@ -0,0 +1,223 @@
+'use strict';
+
+const { assert } = require('chai');
+const PrismLoader = require('../helper/prism-loader');
+
+
+describe('prism-patterns', function () {
+
+ const Prism = PrismLoader.createInstance('patterns');
+ const {
+ pattern,
+ toRegExp,
+ template,
+ nested
+ } = Prism.languages.patterns;
+
+
+ function assertPattern(actual, expected) {
+ assert.equal(String(toRegExp(actual)), String(expected));
+ }
+
+ it('should convert to RegExp', function () {
+ assertPattern(pattern('foo'), /foo/);
+ assertPattern(pattern('foo', {}), /foo/);
+ assertPattern(pattern('foo', { i: undefined }), /foo/);
+ assertPattern(pattern('foo', { i: false }), /foo/);
+ assertPattern(pattern('foo', { i: true }), /foo/i);
+ assertPattern(pattern('foo', { u: true, i: true, g: true }), /foo/giu);
+ });
+
+ describe('template', function () {
+
+ it('should work for patterns without groups', function () {
+ assertPattern(
+ template(/a<0>*<1>/.source, [
+ 'ba?',
+ 'bar'
+ ]),
+ /a(?:ba?)*(?:bar)/
+ );
+
+ assertPattern(
+ template(pattern(/a<0>*<1>/.source, { i: true }), [
+ '01?',
+ '123'
+ ]),
+ /a(?:01?)*(?:123)/i
+ );
+
+ assertPattern(
+ template(/\s<0>*<1>/.source, [
+ '\\w',
+ pattern('bar', { i: true })
+ ]),
+ /\s(?:\w)*(?:bar)/i
+ );
+ });
+
+ it('should work for patterns with groups and backreferences', function () {
+ assertPattern(
+ template(/Begin (foo|bar) <0> End \1/.source, [
+ /(["'])(?:(?!\1)[\s\S])*\1/.source,
+ ]),
+ /Begin (foo|bar) (?:(["'])(?:(?!\2)[\s\S])*\2) End \1/
+ );
+ assertPattern(
+ template(/(a)<0>\1(b)<0>\2 \1/.source, [
+ /(A)\1(B)/.source,
+ ]),
+ /(a)(?:(A)\2(B))\1(b)(?:(A)\5(B))\4 \1/
+ );
+ });
+
+ it('should handle escape sequences and character classes correctly', function () {
+ assertPattern(
+ template(/(a)\(\\[()[()]<0>\1/.source, [
+ /(A)\1(B)/.source,
+ ]),
+ /(a)\(\\[()[()](?:(A)\2(B))\1/
+ );
+ assertPattern(
+ template(/<0>(b)\1/.source, [
+ /(a)\(\\[()[()]\1/.source,
+ ]),
+ /(?:(a)\(\\[()[()]\1)(b)\2/
+ );
+ });
+
+ it('should work with \\0', function () {
+ assertPattern(
+ template(/(a)<0>\0\1/.source, [
+ /(A)\1(B)/.source,
+ ]),
+ /(a)(?:(A)\2(B))\0\1/
+ );
+ });
+
+ it('should ignore escaped and invalid placeholders', function () {
+ assertPattern(
+ template(/\<0><0\>[<0>]/.source, ['bar']),
+ /\<0><0\>[<0>]/
+ );
+ });
+
+ it('should throw for contradictory flags', function () {
+ assert.throw(() => {
+ template(pattern('<0>', { i: true }), [
+ pattern('foo', { i: false })
+ ]);
+ });
+ assert.throw(() => {
+ template('<0><1>', [
+ pattern('foo', { i: false }),
+ pattern('bar', { i: true })
+ ]);
+ });
+ });
+
+ it('should throw for undefined replacements', function () {
+ assert.throw(() => {
+ template('<0>', []);
+ });
+ assert.throw(() => {
+ template('<0>', [undefined]);
+ });
+ assert.throw(() => {
+ template('<4>', ['foo', , , , , , , 'bar']);
+ });
+ });
+
+ it('should throw for early backreferences and octal escapes', function () {
+ // invalid template pattern
+ assert.throw(() => {
+ template('(a)\\2(b)<0>', ['foo']);
+ });
+ assert.throw(() => {
+ template('\\2<0>', ['foo']);
+ });
+
+ // invalid replacements
+ assert.throw(() => {
+ template('<0>', ['(a)\\2(b)']);
+ });
+ assert.throw(() => {
+ template('<0>', ['\\2']);
+ });
+ });
+
+ it('should throw for invalid patterns', function () {
+ // invalid template pattern
+ assert.throw(() => {
+ template('(?:|<0>', ['foo']);
+ });
+ assert.throw(() => {
+ template('a?+<0>', ['foo']);
+ });
+
+ // invalid replacements
+ assert.throw(() => {
+ template('<0>', ['(?:|<0>']);
+ });
+ assert.throw(() => {
+ // even if the replacement isn't used
+ template('<0>', ['foo', 'a?+']);
+ });
+ });
+
+ });
+
+ describe('nested', function () {
+
+ it('should work for patterns without groups', function () {
+ assertPattern(nested(/[^{}]|{*}/.source, 1), /[^{}]|{(?:[^{}]|{(?:[^\s\S])*})*}/);
+ assertPattern(nested(pattern(/[^{}]|{*}/.source), 1), /[^{}]|{(?:[^{}]|{(?:[^\s\S])*})*}/);
+ assertPattern(nested(pattern(/[^{}]|{*}/.source, { i: true }), 1), /[^{}]|{(?:[^{}]|{(?:[^\s\S])*})*}/i);
+
+ // verify that the implementation doesn't blow up the pattern exponentially
+ assertPattern(
+ nested(/a|/.source, 0),
+ /a|(?:[^\s\S])/
+ );
+ assertPattern(
+ nested(/a|/.source, 1),
+ /a|(?:a|(?:[^\s\S]))/
+ );
+ assertPattern(
+ nested(/a|/.source, 2),
+ /a|(?:a|(?:a|(?:[^\s\S])))/
+ );
+ assertPattern(
+ nested(/a|/.source, 3),
+ /a|(?:a|(?:a|(?:a|(?:[^\s\S]))))/
+ );
+ });
+
+ it('should work for patterns with capturing groups and backreferences', function () {
+ assertPattern(
+ nested(/[^{}"']|(["'])(?:(?!\1)[^\\]|\\.)\1|{*}/.source, 1),
+ /[^{}"']|(["'])(?:(?!\1)[^\\]|\\.)\1|{(?:[^{}"']|(["'])(?:(?!\2)[^\\]|\\.)\2|{(?:[^\s\S])*})*}/
+ );
+ });
+
+ it('should throw for octal escapes', function () {
+ assert.throw(() => {
+ nested(/[^{}]\1|{*}/.source);
+ });
+ assert.throw(() => {
+ nested(/[^{}]\4|{*}/.source);
+ });
+ });
+
+ it('should throw for invalid patterns', function () {
+ assert.throw(() => {
+ nested('(?:|');
+ });
+ assert.throw(() => {
+ nested('a?+');
+ });
+ });
+
+ });
+
+});