Advertisement Create a free account

[Script] ColorEmote -- Release v0.1.2 -- Long form Colored Emotes based on Character, Token, or Player!

1457998937

Edited 1458001247
Saevar L. "Liquid-Sonic" said: Chris said: Alicia's got a point about adding the Character/Token name into this style setting, although I don't think I am having the problem where the text is set right against the image. I think it might be worth considering a merge of the two current settings (Short and Long), to keep the options from getting out of hand. The "Short" setting is cleaner than my original Heading layout, and if it is rebuilt a little we can accomplish everything with one main configuration and a couple simple toggle options, rather than two complete branches. A minor revision of the markup and CSS would allow you to float the image left, and everything else to the right. Start the text side with the optional "Token/ Character/Player Name" row, along with the Turn Tracker icon. Then the emote content proper can be set below it, with a little padding. (Examples shown, with and without Token Name being displayed). For me, that approach would be preferable to getting outrageous with the number of settings and configurations, all with separate style requirements. Dont suppose I could get a copy of this modification :&lt; Saevar, I am not sure if you wanted the script stylings you saw in the image example I used, or if you are simply talking about my suggestions for Aaron to consider for any updated version of his script. But I will share my "modified" version, in case you do want it. I have only changed a few lines (e.g. switching paddings and margins, and adding a line of code with inline styles to get the player name at the top of the Short From display style). As soon as Aaron makes any updates to his script, you'll want to go with that one. Note that this accommodates the particular configuration I prefer when using the script (Token: First; Short Form; Huge Image; No Vignette). Also, I designed my tokens specifically for use in the ColorEmote setup, adding the white image border. That's not being done by the script. One more note: I've added the "Name" back in to the display space. Since I use the Token First setup, it means I can remove it from the output simply by leaving the "Token Name" blank on the actual token. This is great, if you (like me) like to use this script for NPCs, who are sometimes mysterious and whose names are not known by the players. This is part of the power of using Token-based info rather than character sheet info. // Github: &nbsp; <a href="https://github.com/shdwjk/Roll20API/blob/master/C" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/C</a>... // By: &nbsp; &nbsp; &nbsp; The Aaron, Arcane Scriptomancer // Contact: &nbsp; <a href="https://github.com/shdwjk/Roll20API/blob/master/C" rel="nofollow">https://github.com/shdwjk/Roll20API/blob/master/C</a>... var ColorEmote = ColorEmote || (function() { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; var version = '0.1.2', &nbsp; &nbsp; &nbsp; &nbsp; lastUpdate = 1455714420, &nbsp; &nbsp; &nbsp; &nbsp; schemaVersion = 0.4, &nbsp; &nbsp; &nbsp; &nbsp; symbols = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whitePawn: '&#'+'9830;', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; blackPawn: '&#'+'9830;', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dropDown: '&#'+'9660;' &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; parseOrders = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'character first': ['character','token','player'], &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'token first': ['token','character','player'] &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; imageScales = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'small': '1em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'medium': '2.5em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'large': '4em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'huge': '6em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'gargantuan': '8em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'colossal': '12em' &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; vignetteModes = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'none': { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border':'0', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius':'0', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color':'none' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thin-square':{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border':'.1em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius':'.25em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color':'#cccccc' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thick-square':{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border':'.2em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius':'.25em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color':'#cccccc' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thin-round':{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border':'.1em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius':'100%', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color':'#cccccc' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'thick-round':{ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border':'.2em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius':'100%', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color':'#cccccc' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; defaults = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; css: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border': '1px solid #cccccc', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius': '1em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color': '#006dcc', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'margin': '0 .1em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-weight': 'bold', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '.1em .4em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'color': 'white' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emoteImageContainer: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '0 1em 0 0', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'float': 'left', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'overflow':'hidden' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emoteImage: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'height': 'auto', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'width': 'auto', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'margin-right':'.5em' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emoteHeader: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-bottom': '.2em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '.5em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-size': '1.25em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'text-align': 'center', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'position': 'relative' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emoteBody: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '1em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-size': '1em' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnMarker: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color': '#ffffff', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'color': '#1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-style': 'normal', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'margin-right': '-.25em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '0 .125em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-size': '1.25em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'float': 'right', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border': '.1em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius': '100%', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'box-shadow': '#000000 0 0 .1em' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; emoteMsg: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border': '.2em solid #1d1d1d', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-style': 'italic', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'font-weight':'bold', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius': '.5em', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'margin': '0 0 0 -45px', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding': '0', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'overflow': 'hidden' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; templates = {}, &nbsp; &nbsp; buildTemplates = function() { &nbsp; &nbsp; &nbsp; &nbsp; templates.cssProperty =_.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%=name %&gt;: &lt;%=value %&gt;;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.style = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'style="&lt;%='+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '_.map(css,function(v,k) {'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'return templates.cssProperty({'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'defaults: defaults,'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'templates: templates,'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'name:k,'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'value:v'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '});'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '}).join("")'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ' %&gt;"' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.button = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;a &lt;%= templates.style({'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'defaults: defaults,'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'templates: templates,'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'css: _.defaults(css,defaults.css.button)'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '}) %&gt; href="&lt;%= command %&gt;"&gt;&lt;%= label||"Button" %&gt;&lt;/a&gt;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.emoteImage = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: _.defaults(ccss||{},defaults.css.emoteImageContainer)}) %&gt; &gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;img &lt;%= templates.style({defaults: defaults,templates: templates,css: defaults.css.emoteImage}) %&gt; src="&lt;%=img %&gt;"/&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.turnMarker = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: _.defaults(css,defaults.css.turnMarker)}) %&gt; &gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; symbols.blackPawn+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.output = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: defaults.css.emoteMsg}) %&gt; &gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: _.defaults({},css,defaults.css.emoteHeader)}) %&gt;&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= templates.emoteImage({img: img, defaults: defaults, templates:templates, ccss: {}, css: defaults.css.emoteImage}) %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;% if(isTurn) { %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= templates.turnMarker({defaults: defaults,templates:templates,css:css.turnMarker}) %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;% } %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= name %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="clear:both;"&gt;&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css:_.defaults(css,defaults.css.emoteBody)}) %&gt;&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= message %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; templates.outputShortForm = _.template( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: defaults.css.emoteMsg}) %&gt; &gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div &lt;%= templates.style({defaults: defaults,templates: templates,css: _.defaults({},css,defaults.css.emoteBody)}) %&gt;&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= templates.emoteImage({img: img, defaults: defaults, templates:templates, ccss: {"font-size":"1.25em"}, css: defaults.css.emoteImage}) %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;% if(isTurn) { %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= templates.turnMarker({defaults: defaults,templates:templates,css:_.defaults({"font-size":"1.5625em"},css.turnMarker)}) %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;% } %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="font-style:normal;font-size:1.15em;padding-top:2px;padding-bottom:0.5em;"&gt;&lt;%= name %&gt;&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;%= message %&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="clear:both;"&gt;&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp; setDynamicCSS = function(){ &nbsp; &nbsp; &nbsp; &nbsp; defaults.css.emoteImageContainer = _.defaults(vignetteModes[state.ColorEmote.config.vignetteMode],defaults.css.emoteImageContainer); &nbsp; &nbsp; &nbsp; &nbsp; defaults.css.emoteImageContainer.width = imageScales[state.ColorEmote.config.imageScale]; &nbsp; &nbsp; &nbsp; &nbsp; defaults.css.emoteImageContainer.height = imageScales[state.ColorEmote.config.imageScale]; &nbsp; &nbsp; &nbsp; &nbsp; defaults.css.emoteImage['max-width'] = imageScales[state.ColorEmote.config.imageScale]; &nbsp; &nbsp; &nbsp; &nbsp; defaults.css.emoteImage['max-height'] = imageScales[state.ColorEmote.config.imageScale]; &nbsp; &nbsp; }, &nbsp; &nbsp; getBrightness = function (hex) { &nbsp; &nbsp; &nbsp; var r,g,b; &nbsp; &nbsp; hex = hex.replace('#', ''); &nbsp; &nbsp; r = parseInt(hex.substr(0, 2),16); &nbsp; &nbsp; g = parseInt(hex.substr(2, 2),16); &nbsp; &nbsp; b = parseInt(hex.substr(4, 2),16); &nbsp; &nbsp; return ((r * 299) + (g * 587) + (b * 114)) / 1000; &nbsp; }, &nbsp; &nbsp; counterColor = function(color){ &nbsp; &nbsp; &nbsp; &nbsp; return (getBrightness(color) &lt; (255 / 2)) ? "#FFFFFF" : "#000000"; &nbsp; &nbsp; }, &nbsp; &nbsp; makeOutput = function (name,img,isTurn,message,color){ &nbsp; &nbsp; &nbsp; &nbsp; return templates[(state.ColorEmote.config.shortForm ? 'outputShortForm': 'output')]({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: name, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img: img, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn: isTurn, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: message, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; templates: templates, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaults: defaults, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; css: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'color': counterColor(color), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color': color &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }, &nbsp; &nbsp; makeButton = function(command, label, backgroundColor, color){ &nbsp; &nbsp; &nbsp; &nbsp; return templates.button({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; command: command, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; label: label, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; templates: templates, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaults: defaults, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; css: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color: color, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color': backgroundColor &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }, &nbsp; &nbsp; checkInstall = function() { &nbsp; &nbsp; &nbsp; log('-=&gt; ColorEmote v'+version+' &lt;=- &nbsp;['+(new Date(lastUpdate*1000))+']'); &nbsp; &nbsp; &nbsp; &nbsp; if( ! _.has(state,'ColorEmote') || state.ColorEmote.version !== schemaVersion) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(' &nbsp;&gt; Updating Schema to v'+schemaVersion+' &lt;'); &nbsp; &nbsp; &nbsp; switch(state.ColorEmote && state.ColorEmote.version) { &nbsp; &nbsp; &nbsp; &nbsp; case 0.3: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.parseOrder = 'character first'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.shortForm = false; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* break; // intentional dropthrough */ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'UpdateSchemaVersion': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.version = schemaVersion; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote = { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; version: schemaVersion, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; config: { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; shortForm: false, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parseOrder: 'character first', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; imageScale: 'medium', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; vignetteMode: 'none' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; setDynamicCSS(); &nbsp; &nbsp; &nbsp; &nbsp; buildTemplates(); &nbsp; &nbsp; }, &nbsp; &nbsp; ch = function (c) { &nbsp; &nbsp; &nbsp; &nbsp; var entities = { &nbsp; &nbsp; &nbsp; '&lt;' : 'lt', &nbsp; &nbsp; &nbsp; '&gt;' : 'gt', &nbsp; &nbsp; &nbsp; "'" : '#39', &nbsp; &nbsp; &nbsp; '@' : '#64', &nbsp; &nbsp; &nbsp; '{' : '#123', &nbsp; &nbsp; &nbsp; '|' : '#124', &nbsp; &nbsp; &nbsp; '}' : '#125', &nbsp; &nbsp; &nbsp; '[' : '#91', &nbsp; &nbsp; &nbsp; ']' : '#93', &nbsp; &nbsp; &nbsp; '"' : 'quot', &nbsp; &nbsp; &nbsp; '-' : 'mdash', &nbsp; &nbsp; &nbsp; ' ' : 'nbsp' &nbsp; &nbsp; }; &nbsp; &nbsp; if(_.has(entities,c) ){ &nbsp; &nbsp; &nbsp; return ('&'+entities[c]+';'); &nbsp; &nbsp; } &nbsp; &nbsp; return ''; &nbsp; }, &nbsp; &nbsp; makeConfigOption = function(config,command,text) { &nbsp; &nbsp; &nbsp; &nbsp; var buttonText = (_.isString(config) ? config : (config ? 'On' : 'Off' )), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color = (config ? '#5bb75b' : '#faa732' ); &nbsp; &nbsp; &nbsp; &nbsp; return '&lt;div style="'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border: 1px solid #ccc;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'border-radius: .2em;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'background-color: white;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'margin: 0 1em;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'padding: .1em .3em;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="float:right;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; makeButton(command,buttonText,color)+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="clear:both;"&gt;&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; getConfigOption_ShortForm = function() { &nbsp; &nbsp; &nbsp; &nbsp; return makeConfigOption( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.shortForm, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem-config --toggle-short-form', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;Short Form&lt;/b&gt; determines if the emote should be condensed into just the header space.' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp; getConfigOption_ParseOrder = function() { &nbsp; &nbsp; &nbsp; &nbsp; return makeConfigOption( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.parseOrder+symbols.dropDown, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem-config --set-parse-order ?{Parse Order|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.parseOrder+' (current),'+ state.ColorEmote.config.parseOrder+'|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.keys(parseOrders).join('|')+'}', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;Parse Order&lt;/b&gt; determines the order which images are searched for between Characters, Tokens, and Players.' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp; getConfigOption_ImageScale = function() { &nbsp; &nbsp; &nbsp; &nbsp; return makeConfigOption( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.imageScale+symbols.dropDown, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem-config --set-image-scale ?{Image Scale|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.imageScale+' (current),'+ state.ColorEmote.config.imageScale+'|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.keys(imageScales).join('|')+'}', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;Image Scale&lt;/b&gt; determines the size of the representative image in the header of an emote.' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp; getConfigOption_VignetteMode = function() { &nbsp; &nbsp; &nbsp; &nbsp; return makeConfigOption( &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.vignetteMode+symbols.dropDown, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem-config --set-vignette-mode ?{Vignette Mode|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.vignetteMode+' (current),'+ state.ColorEmote.config.vignetteMode+'|'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.keys(vignetteModes).join('|')+'}', &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;b&gt;Vignette Mode&lt;/b&gt; determines how the representative image is framed and clipped.' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp; getAllConfigOptions = function() { &nbsp; &nbsp; &nbsp; &nbsp; return getConfigOption_ShortForm() + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getConfigOption_ParseOrder() + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getConfigOption_ImageScale() + &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getConfigOption_VignetteMode(); &nbsp; &nbsp; }, &nbsp; &nbsp; showHelp = function(playerid) { &nbsp; &nbsp; &nbsp; &nbsp; var who=getObj('player',playerid).get('_displayname'); &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w "'+who+'" '+ '&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;'+ &nbsp; '&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;'+ &nbsp; &nbsp; 'ColorEmote v'+version+ &nbsp; '&lt;/div&gt;'+ &nbsp; '&lt;div style="padding-left:10px;margin-bottom:3px;"&gt;'+ &nbsp; &nbsp; '&lt;p&gt;ColorEmote provides a long form emote block with a colored background and header based on the Character, Token, or Player speaking. &nbsp;The header contains a representative image for the speaker (Character Avatar, Token Image, or Player Image) as well as the name of the speaker.&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;The speaker is the first one of the following to be found:&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ol&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;An explicit Token or Character ID specified with the bracketed command syntax:'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;pre style="white-space:normal;word-break:normal;word-wrap:normal;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem'+ch('[')+ch('@')+ch('{')+'target'+ch('|')+'token_id'+ch('}')+ch(']')+' Does the things!'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/pre&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;The selected token'+ch("'")+'s character.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;The selected token.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;The character the player is speaking as.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;The player.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ol&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Background color is determined based on what is speaking. &nbsp;The foreground color will be either black or white depending on the brightness of the background color. &nbsp;The background color is chosen using the following methods:&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;&lt;b&gt;Characters&lt;/b&gt; will have the color stored in an attribute named &lt;b&gt;color&lt;/b&gt; or the player color. &nbsp;The &lt;b&gt;color&lt;/b&gt; attribute must be specified in standard html form with the # sign. &nbsp;ex: #ff3322 or #f32 &lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;&lt;b&gt;Tokens&lt;/b&gt; will have their aura2 color.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;li&gt;&lt;b&gt;Players&lt;/b&gt; will have their player color.&lt;/li&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/ul&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;If it is currently the speaker'+ch("'")+'s turn, a black pawn ('+symbols.blackPawn+') on a white circle will be displayed on the right side. (Does not apply to Players speaking.)&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; '&lt;p&gt;Multi-line emote messages may be specified by surrounding them in '+ch('{')+ch('{')+' and '+ch('}')+ch('}')+'. &nbsp;You can insert new lines by pressing shift-enter. &nbsp;Example:&lt;/p&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;pre style="white-space:normal;word-break:normal;word-wrap:normal;"&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '!cem {{ Does the things!&lt;br&gt;&lt;br&gt;But it fails in the usual way... }}'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/pre&gt;'+ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; '&lt;/div&gt;'+ &nbsp; '&lt;b&gt;Commands&lt;/b&gt;'+ &nbsp; '&lt;div style="padding-left:10px;"&gt;'+ &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!cem'+ch('[')+' token_id '+ch('|')+' character_id '+ch(']')+' '+ch('[')+' '+ch('&lt;')+'Message'+ch('&gt;')+' '+ch('|')+' '+ch('{')+ch('{')+' '+ch('&lt;')+'Multi-line Message'+ch('&gt;')+' '+ch('}')+ch('}')+' '+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; '&lt;p&gt;Outputs an Emote. Note that the optional bracketed syntax has no space between the !cem and leading '+ch('[')+'.&lt;/p&gt;'+ &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; '&lt;div style="padding-left:10px;"&gt;'+ &nbsp; &nbsp; '&lt;b&gt;&lt;span style="font-family: serif;"&gt;!wcem'+ch('[')+' token_id '+ch('|')+' character_id '+ch(']')+' '+ch('[')+' '+ch('&lt;')+'Message'+ch('&gt;')+' '+ch('|')+' '+ch('{')+ch('{')+' '+ch('&lt;')+'Multi-line Message'+ch('&gt;')+' '+ch('}')+ch('}')+' '+ch(']')+'&lt;/span&gt;&lt;/b&gt;'+ &nbsp; &nbsp; '&lt;div style="padding-left: 10px;padding-right:20px"&gt;'+ &nbsp; &nbsp; &nbsp; '&lt;p&gt;Identical to !cem except that the output is whispered to the player emoting and the GM.&lt;/p&gt;'+ &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; ( playerIsGM(playerid) &nbsp; &nbsp; &nbsp; &nbsp; ? &nbsp;'&lt;b&gt;Configuration&lt;/b&gt;' + getAllConfigOptions()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : '' &nbsp; &nbsp; )+ '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; }, &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; getCharacterAndTokenTurn = function(){ &nbsp; &nbsp; &nbsp; &nbsp; var token = getObj('graphic',(JSON.parse(Campaign().get('turnorder')||'[]')[0]||{id:null}).id); &nbsp; &nbsp; &nbsp; &nbsp; if(token){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cid: token.get('represents'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tid: token.id &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; return { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cid:null, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tid:null &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; }, &nbsp; &nbsp; performOutput = function(details){ &nbsp; &nbsp; &nbsp; &nbsp; var output=makeOutput(details.name,details.img,details.isTurn,details.message,details.color); &nbsp; &nbsp; &nbsp; &nbsp; if(details.whisper){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w gm '+output); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!playerIsGM(details.playerid)){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+details.who+' '+output); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/direct '+output); &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; }, &nbsp; &nbsp; handleInput = function(msg_orig) { &nbsp; &nbsp; &nbsp; &nbsp; var msg = _.clone(msg_orig), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args, cmd, matches, ctid, turnData, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parsers={}, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; player,character,token,data, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img, name, text, color,who, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn = false, whisper=false &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; &nbsp; &nbsp; &nbsp; &nbsp; if (msg.type !== "api") { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; if(_.has(msg,'inlinerolls')){ &nbsp; &nbsp; &nbsp; msg.content = _.chain(msg.inlinerolls) &nbsp; &nbsp; &nbsp; &nbsp; .reduce(function(m,v,k){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; m['$[['+k+']]']=v.results.total || 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m; &nbsp; &nbsp; &nbsp; &nbsp; },{}) &nbsp; &nbsp; &nbsp; &nbsp; .reduce(function(m,v,k){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return m.replace(k,v); &nbsp; &nbsp; &nbsp; &nbsp; },msg.content) &nbsp; &nbsp; &nbsp; &nbsp; .value(); &nbsp; &nbsp; } &nbsp; &nbsp; args = msg.content &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .replace(/&lt;br\/&gt;\n/g, '&lt;br/&gt;') &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .replace(/(\{\{(.*?)\}\})/g," $2 ") &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .split(/\s+/); &nbsp; &nbsp; &nbsp; &nbsp; cmd=args.shift(); &nbsp; &nbsp; &nbsp; &nbsp; matches=cmd.match(/^(!\S+)\[([^\]]+)\]/); &nbsp; &nbsp; &nbsp; &nbsp; if(matches){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cmd=matches[1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ctid=matches[2]; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; switch(cmd) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case '!wcem': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whisper=true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /* break; // intentional drop thru */ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case '!cem': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( 0 === args.length || _.contains(args,'--help')) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showHelp(msg.playerid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; player=getObj('player',msg.playerid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; turnData=getCharacterAndTokenTurn(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; text=args.join(' '); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // explicit token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(ctid){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character=getObj('character',ctid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token=getObj('graphic',ctid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // selected token's character or token &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( !(character || token) && msg.selected && msg.selected.length){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token=getObj('graphic',(_.find(msg.selected,function(o){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 'graphic'===o._type; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })||{_id:null})._id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character=getObj('character',(token && token.get('represents'))||''); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // speaking as character &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if( !(character || token) ){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character=filterObjs(function(o){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 'character'===o.get('type') &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; && o.id === player.get('speakingas').split(/\|/)[1]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parsers={ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character: function(){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name=character.get('name'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn = character.id === turnData.cid; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color=getAttrByName(character.id,'color'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color=(color && color.match(/#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?/) ? color : player.get('color') ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character.get('defaulttoken',function(dt){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img=character.get('avatar') &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || (JSON.parse(dt||'')||{imgsrc:''}).imgsrc &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; || '<a href="https://app.roll20.net/users/avatar/'+player.get('d20userid')+'/150#.png" rel="nofollow">https://app.roll20.net/users/avatar/'+player.get('d20userid')+'/150#.png</a>'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; performOutput({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; playerid: msg.playerid, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; who: player.get('displayname'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: name, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img: img, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn: isTurn, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color: color, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whisper: whisper, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: text &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token: function(){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name=token.get('name'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img=token.get('imgsrc'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn = token.id === turnData.tid; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color=token.get('aura2_color')||player.get('color'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; performOutput({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; playerid: msg.playerid, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; who: player.get('displayname'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: name, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img: img, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn: isTurn, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color: color, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whisper: whisper, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: text &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; player: function(){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name=player.get('displayname'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img='<a href="https://app.roll20.net/users/avatar/'+player.get('d20userid')+'/150#.png" rel="nofollow">https://app.roll20.net/users/avatar/'+player.get('d20userid')+'/150#.png</a>'; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color=player.get('color'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; performOutput({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; playerid: msg.playerid, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; who: player.get('displayname'), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; name: name, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; img: img, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; isTurn: isTurn, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; color: color, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; whisper: whisper, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; message: text &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; data={ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; character:character, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; token:token, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; player:player &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.find(parseOrders[state.ColorEmote.config.parseOrder],function(k){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(data[k]){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; parsers[k](); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case '!cem-config': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!playerIsGM(msg.playerid)){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; args = _.rest(msg.content.split(/\s+--/)); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.contains(args,'help')) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; showHelp(msg.playerid); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; who=getObj('player',msg.playerid).get('_displayname'); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!args.length) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w "'+who+'" '+ '&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;'+ &nbsp; '&lt;div style="font-weight: bold; border-bottom: 1px solid black;font-size: 130%;"&gt;'+ &nbsp; &nbsp; 'ColorEmote v'+version+ &nbsp; '&lt;/div&gt;'+ &nbsp; &nbsp; '&lt;b&gt;Configuration&lt;/b&gt;'+ &nbsp; &nbsp; getAllConfigOptions()+ '&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _.each(args,function(a){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var opt=a.split(/\s+/); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; switch(opt.shift()) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'toggle-short-form': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.shortForm=!state.ColorEmote.config.shortForm; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w "'+who+'" ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +getConfigOption_ShortForm() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'set-parse-order': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; opt=opt.join(' '); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.has(parseOrders,opt)){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.parseOrder=opt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +getConfigOption_ParseOrder() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div&gt;&lt;b&gt;Unsupported Parse Order:&lt;/div&gt; '+opt+'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'set-image-scale': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.has(imageScales,opt[0])){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.imageScale=opt[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +getConfigOption_ImageScale() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDynamicCSS(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div&gt;&lt;b&gt;Unsupported Image Scale:&lt;/div&gt; '+opt[0]+'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case 'set-vignette-mode': &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.has(vignetteModes,opt[0])){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; state.ColorEmote.config.vignetteMode=opt[0]; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div style="border: 1px solid black; background-color: white; padding: 3px 3px;"&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +getConfigOption_VignetteMode() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDynamicCSS(); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div&gt;&lt;b&gt;Unsupported Vignette Mode:&lt;/div&gt; '+opt[0]+'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sendChat('','/w '+who+' ' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; +'&lt;div&gt;&lt;b&gt;Unsupported Option:&lt;/div&gt; '+a+'&lt;/div&gt;' &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; }, &nbsp; &nbsp; registerEventHandlers = function() { &nbsp; &nbsp; &nbsp; &nbsp; on('chat:message', handleInput); &nbsp; &nbsp; }; &nbsp; &nbsp; return { &nbsp; &nbsp; &nbsp; &nbsp; CheckInstall: checkInstall, &nbsp; &nbsp; &nbsp; &nbsp; RegisterEventHandlers: registerEventHandlers &nbsp; &nbsp; }; &nbsp; &nbsp;&nbsp; }()); on('ready',function() { &nbsp; &nbsp; 'use strict'; &nbsp; &nbsp; ColorEmote.CheckInstall(); &nbsp; &nbsp; ColorEmote.RegisterEventHandlers(); }); &nbsp;
I've found what I believe is a bug: When I use the full hex for a dark background color— e.g. #006600 — the text correctly renders as white. However, when I use the shorthand hex— #060 — the text renders as black (on, in this case, dark green). Thought you'd like to know! Awesome script, as always! :-)
1458221423
The Aaron
Forum Champion
API Scripter
Ah, I'll add that to the list of things to fix, thanks!
Yeap I did want your version of it. Thanks! :)