var API_Meta = API_Meta || {}; API_Meta.Supernotes = { offset: Number.MAX_SAFE_INTEGER, lineCount: -1 }; { try { throw new Error(''); } catch (e) { API_Meta.Supernotes.offset = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - (7)); } } // Supernotes_Templates can be called by other scripts. At this point ScriptCards is the only One Click script that does this. let Supernotes_Templates = { generic: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#ce0f69 !important; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#ce0f69; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ' | ', handoutbuttonstyle: `style='display:inline-block; color:#ce0f69; background-color: transparent;padding: 0px; border: none;'`, whisperStyle: `'background-color:#2b2130; color:#fbfcf0; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#bbb; background-color: transparent;padding: 0px; border: none'`, footer: "" }, dark: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#a980bd; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#a980bd; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ' | ', handoutbuttonstyle: `style='display:inline-block; color:#a980bd; background-color: transparent;padding: 0px; border: none;'`, whisperStyle: `'background-color:#2b2130; color:#fbfcf0; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#bbb; background-color: transparent;padding: 0px; border: none'`, footer: "" }, roll20dark: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#a980bd; font-weight:bold; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#fff; font-weight:bolder; background-color: #e7339d;border-radius: 4px; margin:4px; padding: 2px 6px 2px 6px; border: none; font-family:"proxima nova", sans-serif; ;'`, buttondivider: '', handoutbuttonstyle: `style='display:inline-block; color:#fff; font-weight:bolder; background-color: #e7339d;border-radius: 4px; margin:4px; padding: 2px 6px 2px 6px; border: none;font-family:"nunito black", nunito;'`, whisperStyle: `'background-color:#f9cce7; color:#111; display:block; padding:5px; margin-top:20px;'`, whisperbuttonstyle: `style='display:inline-block; color:#702c91; font-weight:bold; background-color: transparent;padding: 0px; border: none'`, footer: "" }, roll20light: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#702c91; font-weight:bold; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#fff; font-weight:bolder; background-color: #e7339d;border-radius: 4px; margin:4px; padding: 2px 6px 2px 6px; border: none; font-family:"proxima nova", sans-serif; ;'`, buttondivider: '', handoutbuttonstyle: `style='display:inline-block; color:#fff; font-weight:bolder; background-color: #e7339d;border-radius: 4px; margin:4px; padding: 2px 6px 2px 6px; border: none; font-family:"Nunito Black", nunito;'`, whisperStyle: `'background-color:#f9cce7; color:#111; display:block; padding:5px; margin-top:20px;'`, whisperbuttonstyle: `style='display:inline-block; color:#702c91; font-weight:bold; background-color: transparent;padding: 0px; border: none'`, footer: "" }, lcars: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#cc6060; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; border:none; color:black; background-color: #cc6060; border-radius: 10px 0px 0px 10px; padding: 2px 4px 2px 4px;margin-top: 12px; font-size: 10px; font-family: Tahoma, sans-serif; font-stretch: condensed !important; text-transform: uppercase;'`, buttondivider: '', handoutbuttonstyle: `style='display:inline-block; border:none; color:black; background-color: #cc6060; border-radius: 0px 10px 10px 0px; padding: 2px 4px 2px 4px;margin-top: 12px; margin-left:4px; font-size: 10px; font-family: Tahoma, sans-serif; font-stretch: condensed !important; text-transform: uppercase;'`, whisperStyle: `'border-radius: 10px 0px 0px 10px; color:#ffae21; border-color: #ffae21; display:block; border-width: 0px 0px 5px 15px; border-style: solid; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#cc6060; background-color: transparent;padding: 0px; border: none'`, footer: "" }, faraway: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#13f2fc; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#13f2fc; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#13f2fc; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:transparent; color:#feda4a; display:block; border-width: 8px; border-style: solid; border-radius:5px; border-color:#feda4a; padding:15px; margin-top:10px;'`, whisperbuttonstyle: `style='display:inline-block; color:#13f2fc; background-color: transparent;padding: 0px; border: none'`, footer: "" }, strange: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#ff1515; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#ff1515; font-family: "Goblin One"; font-weight:normal; font-size: 10px; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#ff1515; font-family: "Goblin One"; font-weight:normal; font-size: 10px; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:##4f0606; color:#ff1515; display:block; border: 1px solid #000; box-shadow: 0 0 5px #ff1515; padding:5px; margin-top:10px'`, whisperbuttonstyle: `style='display:inline-block; color:#bbb; background-color: transparent;padding: 0px; border: none'`, footer: "" }, gothic: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#ccc; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#ccc; font-size:12px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#ccc; font-size:12px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:#2b2130; color:#ddd; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#aaa; background-color: transparent;padding: 0px; border: none'`, footer: "" }, western: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#000; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#7e2d40; background-color: transparent;padding: 0px; border: none'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#7e2d40; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color:#382d1d; color:#ebcfa9; font-style: italic; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px; margin-top:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#fabe69; background-color: transparent;padding: 0px; border: none'`, footer: "" }, dragon: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#0e3365; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color: #0e3365; font-size:14px; background-color: transparent;padding: 0px; border: none'`, buttondivider: "  •  ", //``, handoutbuttonstyle: `style='display:inline-block; color: #0e3365; font-size:14px; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'display:block; border-width: 5px 0px 5px 0px; border-style: solid; border-color:#58170D; padding:5px; margin-top:9px;'`, whisperbuttonstyle: `style='display:inline-block; color:#0e3365; background-color: transparent;padding: 0px; border: none'`, footer: "" }, wizard: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#58170D; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color: #000; font-size:12px; background-color: transparent;padding: 0px; border: none'`, buttondivider: "  •  ", //``, handoutbuttonstyle: `style='display:inline-block; color: #000; font-size:12px; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color:#E0E5C1; color:#000; display:block; border-width: 1px; border-width: 1px 0px 1px 0px; border-style: solid; border-color:#58170D; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#58170D; background-color: transparent;padding: 0px; border: none'`, footer: "" }, path: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#5e0000; font-weight:bold; background-color: transparent; padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color: #eee; font-size:12px; background-color: #5e0000; padding: 0px 4px 0px 4px; border-style:solid; border-width: 2px 4px 2px 4px; border-color: #d9c484; text-transformation: all-caps; font-family: "gin", impact, "Arial Bold Condensed", sans-serif;'`, buttondivider: "    ", //``, handoutbuttonstyle: `style='display:inline-block; color: #eee; font-size:12px; background-color: #5e0000; padding: 0px 4px 0px 4px; border-style:solid; border-width: 2px 4px 2px 4px; border-color: #d9c484; text-transformation: all-caps; font-family: "gin", impact, "Arial Bold Condensed", sans-serif;'`, whisperStyle: `'background-color:#dbd1bc; color:#000; display:block; border-width: 1px; margin-top:15px; padding:5px; font-size: 15px; font-family: "Good OT", arial, sans-serif;'`, whisperbuttonstyle: `style='display:inline-block; color:#58170D; background-color: transparent; font-weight:bold; padding: 0px; border: none'`, footer: "" }, apoc: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#555; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#000; font-size:14px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: " / ", handoutbuttonstyle: `style='display:inline-block; color:#000; font-size:14px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:#403f3d; color:#ddd; display:block; padding:5px !important; margin:5px; font-family: "Shadows Into Light", Monaco,"Courier New", monospace !important; '`, whisperbuttonstyle: `style='display:inline-block; color:#bbb; background-color: transparent;padding: 0px; border: none'`, footer: `` }, roman: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#7c6f39; font-weight: bold; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#000; font-size:12px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: " | ", handoutbuttonstyle: `style='display:inline-block; color:#000; font-size:12px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-image: url(https://files.d20.io/images/459209597/cdZeKGAy2_NKcU1Wjkjeew/original.jpg); background-repeat: no-repeat; background-size: 100% 100%; background-color:#403f3d; color:#ddd; display:block; padding:8px !important; margin:5px 0px; text-shadow: none; line-height:16px;'`, whisperbuttonstyle: `style='display:inline-block; color:#bbaa55; font-weight: bolder !important; background-color: transparent;padding: 0px; border: none'`, footer: `` }, notebook: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color: red; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:red; font-size:10px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: `/`, handoutbuttonstyle: `style='display:inline-block; color:red; font-size:10px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'color:red; display:block; padding-top:7px; font-family: "Patrick Hand", Monaco,"Courier New", monospace; line-height: 16px;'`, whisperbuttonstyle: `style='display:inline-block; color:#333; background-color: transparent;padding: 0px; border: none'`, footer: "" }, steam: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#056b20; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#056b20; font-size:12px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#056b20; font-size:12px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:#2b2130; color:#fbfcf0; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#fff; background-color: transparent;padding: 0px; border: none'`, footer: "" }, treasure: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#8a4100; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#634401; font-size:14px; font-weight:normal; background-color: transparent;padding: 0px; border: none;'`, buttondivider: ``, handoutbuttonstyle: `style='display:inline-block; color:#401e00; font-size:14px; font-weight:normal; background-color: transparent; padding: 0px; border: none;'`, whisperStyle: `'background-color:#401e00; color:#eee; font-family: Tahoma, serif; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; margin-top:10px;padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#e3b76f; background-color: transparent;padding: 0px; border: none'`, footer: "" }, choices: { boxcode: `
`, titlecode: `
`, textcode: `

`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#eee; hover: yellow; background-color: transparent;padding: 0px; border: none; '`, playerbuttonstyle: `style='display:inline-block; color: #eee; font-size:16px; font-family: "Minion", "Minion Pro", serif; background-color: transparent;padding: 0px; border: none'`, buttondivider: "  ◼  ", //``, handoutbuttonstyle: `style='display:inline-block; color: #eee; font-size:16px; font-family: "Minion", "Minion Pro", serif; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-image: linear-gradient(to bottom,#4b443d,#3f3732,#4b443d); background-color: transparent; color:#f8e8a6; display:block; border-width: 1px; border: 1px solid #4f4841; margin: 20px, -12px, 15px, -12px; padding:10px, 10px'`, whisperbuttonstyle: `style='display:inline-block; color:#eee; background-color: transparent;padding: 0px; border: none'`, footer: "" }, gate3: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#eada8d; background-color: transparent;padding: 0px; border: none; '`, playerbuttonstyle: `style='display:inline-block; color: #eee; font-size:16px; font-family: "Minion", "Minion Pro", serif; background-color: transparent;padding: 0px; border: none'`, buttondivider: "  ◼  ", //``, handoutbuttonstyle: `style='display:inline-block; color: #eee; font-size:16px; font-family: "Minion", "Minion Pro", serif; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-image: linear-gradient(to bottom,#4b443d,#3f3732,#4b443d); background-color: transparent; color:#f8e8a6; display:block; border-width: 1px; border: 1px solid #4f4841; margin: 20px, -12px, 15px, -12px; padding:10px, 10px'`, whisperbuttonstyle: `style='display:inline-block; color:#eee; background-color: transparent;padding: 0px; border: none'`, footer: "" }, crt: { boxcode: `
`, titlecode: `
`, textcode: "
", buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#fff; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block;font-weight:bold; color:white; background-color: transparent;padding: 0px; border: none;font-size: 12px'`, buttondivider: '|', handoutbuttonstyle: `style='display:inline-block;font-weight:bold; color:white; background-color: transparent;padding: 0px; border: none;font-size: 12px'`, whisperStyle: `'background-color:#2b2130; color:#fbfcf0; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#fff; background-color: transparent;padding: 0px; border: none'`, footer: "" }, news: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#222; text-decoration:underline; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block;float:right; margin-top:5px; font-weight:bold; color:#444; background-color: transparent;padding: 0px; border: none;font-size: 12px'`, buttondivider: ' ', handoutbuttonstyle: `style='display:inline-block;float:left; margin-top:5px; font-weight:bold; color:#444; background-color: transparent;padding: 0px; border: none;font-size: 12px'`, whisperStyle: `'background-color: rgba(0, 0, 0, 0.1); color:#444; font-size: 14px;font-family: arial, helvetica, sans-serif; padding:8px; display:block; border: 1px solid #444;'`, whisperbuttonstyle: `style='display:inline-block; color:#444; text-decoration:underline; background-color: transparent; padding: 0px; border: none'`, footer: "" }, scroll: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#7e2d40; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; color:#7e2d40; background-color: transparent;padding: 0px; border: none'`, buttondivider: ' | ', handoutbuttonstyle: `style='display:inline-block; color:#7e2d40; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color:#58170d; color:#d9bf93; display:block; padding:5px'`, whisperbuttonstyle: `style='display:inline-block; color:#fce5bb; background-color: transparent;padding: 0px; border: none'`, footer: "" }, scroll2: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#58170D; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; font-size: 14px !important; color:#58170D; background-color: transparent;padding: 0px; border: none'`, buttondivider: ' | ', handoutbuttonstyle: `style='display:inline-block; font-size: 14px !important; color:#58170D; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color:#241605; color:#eee; box-shadow: 0px 0px 5px 5px #241605; display:block; border-radius:15px; padding:5px; margin: 15px 5px 10px 5px'`, whisperbuttonstyle: `style='display:inline-block; color:#fcdd6d; background-color: transparent;padding: 0px; border: none'`, footer: `` }, vault: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block; color:#111; text-decoration: underline; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; font-size: 15px !important; color:#fef265; text-shadow: 2px 2px 2px #111; background-color: transparent;padding: 0px; border: none'`, buttondivider: `   `, handoutbuttonstyle: `style='display:inline-block; font-size: 15px !important; color:#fef265; text-shadow: 2px 2px 2px #111;background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color: #transparent; background-image: url(https://files.d20.io/images/459209469/UA2E7Vyf-kncA8k1jUuyAg/original.png; color:#111; display:block; text-shadow: none; text-align:center; font-family: "Contrail One"; border-radius:3px; padding:5px; margin: 15px -20px 10px -20px'`, whisperbuttonstyle: `style='display:inline-block; color:#284a73; background-color: transparent;padding: 0px; border: none'`, footer: `` }, osrblue: { boxcode: `
`, titlecode: `
`, textcode: `
`, buttonwrapper: `
`, buttonstyle: `style='display:inline-block !important; color:#333; text-decoration: underline; background-color: transparent;padding: 0px; border: none'`, playerbuttonstyle: `style='display:inline-block; font-size: 14px !important; color:#333; text-decoration: underline; background-color: transparent;padding: 0px; border: none'`, buttondivider: `|`, handoutbuttonstyle: `style='display:inline-block; font-size: 14px !important; color:#333; text-decoration: underline; background-color: transparent;padding: 0px; border: none'`, whisperStyle: `'background-color: #729aa5; color:#eee; display:block; text-align:center; font-family: "Arial"; padding:5px; margin: 15px -20px 10px -20px'`, whisperbuttonstyle: `style='display:inline-block; color:#eee; text-decoration: underline; background-color: transparent;padding: 0px; border: none'`, footer: `` } }; on('ready', function() { if (!_.has(state, 'Supernotes')) { state.Supernotes = { sheet: 'Default', template: 'default', title: 'name', theText: '', sendToPlayers: true, makeHandout: true, darkMode: false }; message = 'Welcome to Supernotes! If this is your first time running it, the script is set to use the Default Roll Template. You can choose a different sheet template below, as well as decide whether you want the script to display a "Send to Players" footer at the end of every GM message. It is currently set to true.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)
[Call of Cthulhu 7th Edition by Roll20](!gmnote --config|callofcthulhu)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)'; sendChat('Supernotes', '/w gm &{template:' + state.Supernotes.template + '}{{' + state.Supernotes.title + '=' + 'Config' + '}} {{' + state.Supernotes.theText + '=' + message + '}}'); } }); on('ready', () => { function parseMarkdown(markdownText) { const htmlText = markdownText .replace(/^### (.*$)/gim, '

$1

') .replace(/^## (.*$)/gim, '

$1

') .replace(/^# (.*$)/gim, '

$1

') .replace(/^\> (.*$)/gim, '
$1
') .replace(/\*\*(.*)\*\*/gim, '$1') .replace(/\*(.*)\*/gim, '$1') .replace(/!\[(.*?)\]\((.*?)\)/gim, "$1") .replace(/\[(.*?)\]\((.*?)\)/gim, "$1") .replace(/\n$/gim, '
') return htmlText.trim() } function cleanText(text,buttonStyle){ text = ((undefined !== text) ? text.replace(/\[([^\]]*?)\]\(([^\)]*?)\)(?$1").replace(/

/gm, "").replace(/<\/p>/gm, "
").replace("padding:5px'>

", "padding:5px'>") : ""); text = text.replace(' str.replace(/%u[0-9a-fA-F]{2,4}/g, (m) => String.fromCharCode(parseInt(m.slice(2), 16))); const version = '0.2.5'; log('Supernotes v' + version + ' is ready! --offset ' + API_Meta.Supernotes.offset + 'To set the template of choice or to toggle the send to players option, Use the command !gmnote --config'); on('chat:message', function(msg) { if ('api' === msg.type && msg.content.match(/^!(gm|pc|self)note\b/)) { let match = msg.content.match(/^!gmnote-(.*)$/); let selectedObject = msg.selected; //################## EXPERIMENTAL TO GET TOKEN ID FROM SUPPLIED VALUE if(msg.content.includes("--token|")){ virtualTokenID = msg.content.split(/--token\|/)[1].split(/\s/)[0]; sendChat ("notes","success. Virtual token id is " + virtualTokenID); if (virtualTokenID.length !== 20 && virtualTokenID.charAt(0) !== "-"){ sendChat ("notes","this is not a token id :" + virtualTokenID); sendChat ("notes","player page id :" + Campaign().get("playerpageid")); selectedObject = findObjs({ _type: "graphic", _id: virtualTokenID, }); log ("selectedObject is " + selectedObject); // selectedObject = theToken[0]; } if (selectedObject){ sendChat ("notes", "number of 'selected' objects is " +selectedObject.length); } else{ sendChat ("notes", "no passed value"); } //sendChat ("notes","virtual ID is " + selectedObject[0].get("_id")); } //################## EXPERIMENTAL TO GET TOKEN ID FROM SUPPLIED VALUE //define command let command = msg.content.split(/\s+--/)[0]; let sender = msg.who; let senderID = msg.playerid; let isGM = playerIsGM(senderID); let messagePrefix = '/w gm '; if (command === '!pcnote') { messagePrefix = ''; } if (command === '!selfnote') { messagePrefix = '/w ' + sender + ' '; } let secondOption = ''; let args = msg.content.split(/\s+--/); let customTemplate = ''; let option = ''; let notitle = false; let id = ''; let tokenImage = ''; let tooltip = ''; let tokenName = ''; let trueToken = []; let tokenID = ''; let handoutTitle = ''; let whisper = ''; let templates = Supernotes_Templates; function sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton) { handoutButton = ((handoutButton) ? handoutButton.replace(/NamePlaceholder/, whom) : handoutButton); if (message === "" && option.match(/^(bio|charnote|token|tooltip)/)) { message = `The information does not exist for the ${option} option` } if (handoutTitle === '') { //Crops out GM info on player messages if (isGM) { //message = (message.includes("-----") ? message.split('-----')[0] + "
" + message.split('-----')[1] + "
" : message); whisper = (message.includes("-----") ? message.split('-----')[1] : ""); message = (message.includes("-----") ? message.split('-----')[0] : message); } if (customTemplate.length > 0) { let chosenTemplate = templates.generic; switch (customTemplate) { case "crt": chosenTemplate = templates.crt; break; case "dark": chosenTemplate = templates.dark; break; case "roll20light": chosenTemplate = templates.roll20light; break; case "roll20dark": chosenTemplate = templates.roll20dark; break; case "scroll": chosenTemplate = templates.scroll; break; case "scroll2": chosenTemplate = templates.scroll2; break; case "vault": chosenTemplate = templates.vault; break; case "osrblue": chosenTemplate = templates.osrblue; break; case "lcars": chosenTemplate = templates.lcars; break; case "faraway": chosenTemplate = templates.faraway; break; case "strange": chosenTemplate = templates.strange; break; case "gothic": chosenTemplate = templates.gothic; break; case "western": chosenTemplate = templates.western; break; case "dragon": chosenTemplate = templates.dragon; break; case "wizard": chosenTemplate = templates.wizard; break; case "path": chosenTemplate = templates.path; break; case "treasure": chosenTemplate = templates.treasure; break; case "steam": chosenTemplate = templates.steam; break; case "gate3": chosenTemplate = templates.gate3; break; case "choices": chosenTemplate = templates.choices; break; case "apoc": chosenTemplate = templates.apoc; break; case "news": chosenTemplate = templates.news; break; case "roman": chosenTemplate = templates.roman; break; case "notebook": chosenTemplate = templates.notebook; break; case "bob": break; default: chosenTemplate = templates.generic; // code block } playerButton = playerButton.split('\n')[1]; playerButton = ((undefined !== playerButton) ? playerButton.replace(/\[(.*?)\]\((.*?)\)/gim, "
$1") : ""); handoutButton = ((undefined !== handoutButton) ? handoutButton.replace(/\[(.*?)\]\((.*?)\)/gim, "$1").replace(" | 0) ? "
" + whisper + "
" : ""); message = cleanText(message,chosenTemplate.buttonstyle); //the following lines attempt to account for numerous Roll20 CSS and HTML oddities. whisper = cleanText(whisper,chosenTemplate.whisperbuttonstyle); whisper= whisper.replace(/<\/span>
/i,"") .replace(/
/i,'') .replace(/

/i,'

') .replace(/(

|<\/p>)/,'') .replace(/>
/i,'>'); // message = ((undefined !== message) ? message.replace(/\[([^\]]*?)\]\(([^\)]*?)\)(?$1").replace(/

/gm, "").replace(/<\/p>/gm, "
").replace("padding:5px'>

", "padding:5px'>") : ""); // message = message.replace('\n

$1") : ""); handoutButton = ((undefined !== handoutButton) ? handoutButton.replace(/\[([^\]]*?)\]\(([^\)]*?)\)(?$1") : ""); whisper = ((whisper.length>0) ? "
" + whisper + "
" : ""); //log ("whisper = " + whisper); return sendChat(whom, messagePrefix + '&{template:' + template + '}{{' + title + '=' + whom + '}} {{' + theText + '=' + message + whisper + playerButton + handoutButton + '}}'); } } else { let noteHandout = findObjs({ type: 'handout', name: handoutTitle }); noteHandout = noteHandout ? noteHandout[0] : undefined; if (!noteHandout) { noteHandout = createObj('handout', { name: handoutTitle, archived: false, inplayerjournals: "", controlledby: "" }); let noteHandoutid = noteHandout.get("_id"); sendChat('Supernotes', `/w gm Supernotes has created a handout named ${handoutTitle}.
Click here to open.`, null, { noarchive: true }); } if (noteHandout) { playerButton = '
Send to Players in Chat'; if (makeHandout) { handoutButton = ((playerButton) ? ' | ' : '
') + 'Make Handout'; } message = message.replace(/\[.*?\]\((.*?\.(jpg|jpeg|png|gif))\)/g, ``); message = message.replace(/\[(.*?)\]\((.*?)\)/g, '$1'); message = message.replace(//g, `\(\d*\)/)) { let reportCount= notes.match(/(?<=\()\d+/);; //log ("reportCount = " + reportCount); let newHeight = reportCount * 20; if (newHeight > 500){newHeight = 500}; if (newHeight < 200){newHeight = 200}; //log ("newHeight = " + newHeight); message = message.replace(/201px/,newHeight+'px'); } //##############TEST FOR VARIABLE IMAGE HEIGHT BASED ON HEIGHT OF REPORT################################################### if (notes.includes('')) { if (notes.includes('!report')) { notes = notes.split('')[0] + ''; } else { notes = notes.split(/
/i)[0] + ''; } } else { playerButton = ''; handoutButton = ''; notes = ''; //'; } /*if (notes.includes('     ')) { notes = notes.split('     ')[0] + '     ' } else { notes = '     ' }*/ //message = '
' + message +'
'; noteHandout.set("gmnotes", gmnote); noteHandout.set("notes", notes + "

" + whom + "

" + message + playerButton + handoutButton) //THIS NEEDS A TOGGLE //if(!tokenImage.includes("marketplace")){noteHandout.set("avatar", tokenImage+"?12345678")} }) } else { sendChat('Supernotes', whom + `No handout named ${handoutTitle} was found.`, null, { noarchive: true }, ) } } } let theToken = selectedObject; args.forEach(a => { if (a === 'notitle') { notitle = true } if (a.includes('id-')) { id = a.split(/id/)[1] } if (a.match(/handout\|.*?\|/)) { handoutTitle = a.match(/handout\|.*?\|/).toString().split('|')[1] } if (a !== command && !(a.includes('id-')) && !(a.includes('handout|')) && a !== 'notitle') { option = a } if (a.includes('template|')) { customTemplate = a.split(/\|/)[1] } }); ((id) ? theToken = [{ "_id": id, "type": "graphic" }] : theToken = selectedObject); if (undefined !== theToken) { trueToken = getObj('graphic', theToken[0]._id); tokenImage = trueToken.get('imgsrc'); tokenTooltip = trueToken.get('tooltip'); tokenName = trueToken.get('name'); tokenID = trueToken.get('_id'); } const template = state.Supernotes.template; const title = state.Supernotes.title; const theText = state.Supernotes.theText; const sendToPlayers = state.Supernotes.sendToPlayers; const makeHandout = state.Supernotes.makeHandout || false; const darkMode = state.Supernotes.darkMode || false; const whisperStyle = ((darkMode) ? `'background-color:#2b2130; color:#fbfcf0; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'` : `'background-color:#fff; color:#000; display:block; border-width: 1px; border-style: solid; border-color:#a3a681; padding:5px'`); const whisperColor = ((darkMode) ? "#2b2130" : "#fbfcf0"); const whisperTextColor = ((darkMode) ? "#fff" : "#000"); const buttonstyle = ((darkMode) ? `style='display:inline-block; color:#a980bd; font-size: 0.9em; background-color: transparent;padding: 0px; border: none'` : `style='display:inline-block; color:#ce0f69; font-size: 0.9em; background-color: transparent;padding: 0px; border: none'`); if (option !== undefined && option.includes('config')) { let templateChoice = option.split('|')[1] if (templateChoice === undefined) { message = 'Current sheet template:
' + state.Supernotes.sheet + '
Send to Players:
' + state.Supernotes.sendToPlayers + '

Choose a template for Supernotes to use.

[Default Template - any sheet](!gmnote --config|default)
[D&D 5th Edition by Roll20](!gmnote --config|dnd5e)
[DnD 5e Shaped](!gmnote --config|5eshaped)
[Pathfinder Community](!gmnote --config|pfcommunity)
[Pathfinder by Roll20](!gmnote --config|pfofficial)
[Pathfinder 2e by Roll20](!gmnote --config|pf2e)
[Starfinder by Roll20](!gmnote --config|starfinder)
[Call of Cthulhu 7th Edition by Roll20](!gmnote --config|callofcthulhu)

[Toggle Send to Players](!gmnote --config|sendtoPlayers)
[Toggle Make Handout button](!gmnote --config|makeHandout)
[Toggle Darkmode](!gmnote --config|darkMode)' sendChat('Supernotes', messagePrefix + '&{template:' + template + '}{{' + title + '=' + 'Config' + '}} {{' + theText + '=' + message + '}}'); } switch (templateChoice) { case 'default': state.Supernotes.sheet = 'Default'; state.Supernotes.template = 'default'; state.Supernotes.title = 'name'; state.Supernotes.theText = ''; sendChat('Supernotes', '/w gm Supernotes set to Default roll template'); break; case 'dnd5e': state.Supernotes.sheet = 'D&D 5th Edition by Roll20'; state.Supernotes.template = 'npcaction'; state.Supernotes.title = 'rname'; state.Supernotes.theText = 'description'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case '5eshaped': state.Supernotes.sheet = 'DnD 5e Shaped'; state.Supernotes.template = '5e-shaped'; state.Supernotes.title = 'title'; state.Supernotes.theText = 'text_big'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'pfcommunity': state.Supernotes.sheet = 'Pathfinder Community'; state.Supernotes.template = 'pf_generic'; state.Supernotes.title = 'name'; state.Supernotes.theText = 'description'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'pfofficial': state.Supernotes.sheet = 'Pathfinder by Roll20'; state.Supernotes.template = 'npc'; state.Supernotes.title = 'name'; state.Supernotes.theText = 'descflag=1}} {{desc'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'pf2e': state.Supernotes.sheet = 'Pathefinder 2e'; state.Supernotes.template = 'rolls'; state.Supernotes.title = 'header'; state.Supernotes.theText = 'notes_show=[[1]]}} {{notes'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'starfinder': state.Supernotes.sheet = 'Starfinder'; state.Supernotes.template = 'sf_generic'; state.Supernotes.title = 'title'; state.Supernotes.theText = 'buttons0'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'callofcthulhu': state.Supernotes.sheet = 'Call of Cthulhu 7th Edition by Roll20'; state.Supernotes.template = 'callofcthulhu'; state.Supernotes.title = 'title'; state.Supernotes.theText = 'roll_bonus'; sendChat('Supernotes', '/w gm Supernotes set to ' + state.Supernotes.sheet); break; case 'sendtoPlayers': if (state.Supernotes.sendToPlayers) { state.Supernotes.sendToPlayers = false } else { state.Supernotes.sendToPlayers = true }; sendChat('Supernotes', '/w gm Send to Players set to ' + state.Supernotes.sendToPlayers); break; case 'makeHandout': if (state.Supernotes.makeHandout) { state.Supernotes.makeHandout = false } else { state.Supernotes.makeHandout = true }; sendChat('Supernotes', '/w gm Make Handout button set to ' + state.Supernotes.makeHandout); break; case 'darkMode': if (state.Supernotes.darkMode) { state.Supernotes.darkMode = false } else { state.Supernotes.darkMode = true }; sendChat('Supernotes', '/w gm darkMode set to ' + state.Supernotes.darkMode); break; } } else { if (option !== undefined && option.includes('help')) { message = 'Supernotes pulls the contents from a token's GM Notes field. If the token represents a character, you can optionally pull in the Bio or GM notes from the character, as well as the avatar, or extract just the image from the bio field. The user can decide whether to whisper the notes to the GM or broadcast them to all players. Finally, there is the option to add a footer to notes whispered to the GM. This footer creates a chat button to give the option of sending the notes on to the players.
This script as written is optimized for the D&D 5th Edition by Roll20 sheet, but can be adapted easily suing the Configuration section below.

Commands:
!gmnote whispers the note to the GM
!pcnote sends the note to all players

Paramaters
--token Pulls notes from the selected token's gm notes field. This is optional. If it is missing, the script assumes --token
--charnote Pulls notes from the gm notes field of the character assigned to a token.
--bio Pulls notes from the bio field of the character assigned to a token.
--avatar Pulls the image from the avatar field of the character assigned to a token.
--image Pulls first image from the bio field of the character assigned to a token, if any exists. Otherwise returns notice that no artwork is available
--images Pulls all images from the bio field of the character assigned to a token, if any exist. Otherwise returns notice that no artwork is available
--image[number] Pulls indexed image from the bio field of the character assigned to a token, if any exist. --image1 will pull the first image, --image2 the second and so on. Otherwise returns first image if available. If no images are available, returns notice that no artwork is available.
--template[templatename] Instead of using the configured sheet roll template, you can choose from between more than 10 custom templates that cover most common genres. Add the template command directly after the main prompt, followed by any of the regular parameters above. The current choices are:
generic. Just the facts, ma'am. Nothing fancy here.
dark. As above, but in reverse.
crt. Retro greenscreen for hacking and cyberpunk. Or for reports on that xenomorph hiding on your ship.
notebook. You know, for kids. Who like to ride bikes. Maybe they attend a school and fight vampires or rescue lost extraterrestrials
gothic. Classic noire horror for contending with Universal monsters or maybe contending with elder gods.
apoc. Messages scrawled on a wall. Crumbling and ancient, like the world that was.
scroll. High fantasy. Or low fantasy—we don't judge.
lcars. For opening hailing frequencies and to boldly split infinitives that no one has split before!
faraway. No animated title crawl, but still has that space wizard feel.
steam. Gears and brass have changed my life.
western. Return with us now to those thrilling days of yesteryear!

--help Displays help.
--config Returns a configuration dialog box that allows you to set which sheet's roll template to use, and to toggle the "Send to Players" footer.


Configuration
When first installed, Supernotes is configured for the default roll template. It will display a config dialog box at startup that will allow you to choose a roll template based on your character sheet of choice, as well as the option to toggle whether you want the "Send to Players" footer button to appear.
You will need to edit the code of the script to create a custom configuration. The pre-installed sheets are:
Default Template
D&D 5th Edition by Roll20
5e Shaped
Pathfinder by Roll20
Pathfinder Community
Pathfinder 2e by Roll20
Starfinder
Call of Cthulhu 7th Edition by Roll20
'; sendMessage('Supernotes', messagePrefix, template, title, theText, message, false); } else { if (!(option + '').match(/^(bio|charnote|tokenimage|tooltip|avatar|imag(e|es|e[1-9]))/)) { option = 'token'; } let playerButton = ''; if (sendToPlayers && (command === '!gmnote' || command === '!selfnote')) { playerButton = '\n[Send to Players](' + msg.content.replace(/!(gm|self)/, "!pc") + ')'; } let handoutButton = ''; if (makeHandout && (command.includes('gmnote') || command.includes('selfnote'))) { handoutButton = ((playerButton) ? ' | ' : '
') + '[Make Handout](' + msg.content.replace(/!(pc|self)/, "!gm") + ' --handout|NamePlaceholder|)'; } else { //handoutButton = '\n[Make Handout](' + msg.content.replace(/!(pc|self)/, "!gm") +')'; } let regex; if (match && match[1]) { regex = new RegExp(`^${match[1]}`, 'i'); } let message = ''; let whom = ''; if (option === 'tooltip') { (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) .map(t => getObj('character', t.get('represents'))) .filter(c => undefined !== c) .forEach(c => { message = tokenTooltip; whom = tokenName; if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); }); } else { if (option === 'tokenimage') { (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) /* .map(t => getObj('character', t.get('represents')))*/ .filter(c => undefined !== c) .forEach(c => { message = ""; whom = tokenName; if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); }); } else { if (option === 'avatar') { (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) .map(t => getObj('character', t.get('represents'))) .filter(c => undefined !== c) .forEach(c => { message = ""; whom = c.get('name'); if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); }); } else { if (option.match(/^imag(e|es|e[1-9])/)) { (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) .map(t => getObj('character', t.get('represents'))) .filter(c => undefined !== c) .forEach(c => c.get('bio', (val) => { if (null !== val && 'null' !== val && val.length > 0) { if (regex) { message = _.filter( decodeUnicode(val).split(/(?:[\n\r]+|)/), (l) => regex.test(l.replace(/<[^>]*>/g, '')) ).join('\r'); message = message.replace("/g); if (artwork === null) { artwork = 'No artwork exists for this character. Consider specifiying avatar.' }; } else { artwork = message.match(/\<.* src.*?\>/g); artwork = String(artwork); if (artwork === null) { artwork = 'No artwork exists for this character. Consider specifiying avatar.' }; imageIndex = option.match(/\d+/g); if (isNaN(imageIndex) || !imageIndex) { imageIndex = 1 } if (imageIndex > (artwork.split(",")).length) { imageIndex = 1 } imageIndex = imageIndex - 1; //corrects from human readable artwork = artwork.split(",")[imageIndex]; } if (('' + artwork).length > 3) { message = artwork; } else { message = 'No artwork exists for this character.'; } if (artwork === "null" || message === "null") { message = 'No artwork exists for this character. Consider specifiying avatar.' }; whom = c.get('name'); //Sends the final message if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); } })); } else { if ((option === 'bio') || (option === 'charnote')) { let suboption = (option === 'charnote') ? 'gmnotes' : 'bio'; (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) .map(t => getObj('character', t.get('represents'))) .filter(c => undefined !== c) .forEach(c => c.get(suboption, (val) => { if (null !== val && 'null' !== val && val.length > 0) { if (regex) { message = _.filter( decodeUnicode(val).split(/(?:[\n\r]+|)/), (l) => regex.test(l.replace(/<[^>]*>/g, '')) ).join('\r'); } else { message = decodeUnicode(val); } whom = c.get('name'); //Crops out GM info on player messages if (command === '!pcnote' || command === '!selfnote') { message = (message.includes("-----") ? message.split('-----')[0] : message); } //Sends the final message if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); } else { if (notitle) { whom = '' } message = `The information does not exist for the ${option} option`; sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); } })); } else { (theToken || []) .map(o => getObj('graphic', o._id)) .filter(g => undefined !== g) .filter((o) => o.get('gmnotes').length > 0) .forEach(o => { if (regex) { message = _.filter(unescape(decodeUnicode(o.get('gmnotes'))).split(/(?:[\n\r]+|)/), (l) => regex.test(l)).join('\r'); } else { message = unescape(decodeUnicode(o.get('gmnotes'))); } whom = o.get('name'); }); //Crops out GM info on player messages if (command === '!pcnote' || command === '!selfnote') { message = (message.includes("-----") ? message.split('-----')[0] : message); } //Sends the final message if (notitle) { whom = ''; } sendMessage(whom, messagePrefix, template, title, theText, message, tokenID, playerButton, handoutButton); } /* Log Block. Turn on for debugging [ `### REPORT###`, `THE MESSAGE =${message}`, `command = ${command}`, // `option = ${option}`, `secondOption = ${secondOption}`, `messagePrefix = ${messagePrefix}`, `whom = ${whom}`, `message =${message}` ].forEach(m => log(m)); */ } } } } } } } }); }); { try { throw new Error(''); } catch (e) { API_Meta.Supernotes.lineCount = (parseInt(e.stack.split(/\n/)[1].replace(/^.*:(\d+):.*$/, '$1'), 10) - API_Meta.Supernotes.offset); } }