Last active
April 25, 2022 13:51
-
-
Save mmpataki/dc7503be8b566a8bd07b6813dcebee8c to your computer and use it in GitHub Desktop.
Ia4j gen
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name ia4jgen | |
// @namespace http://tampermonkey.net/ | |
// @version 0.1 | |
// @description Generate ia4j snippets from the opengrok | |
// @author Madhusoodan | |
// @match http://psvglapp01:8080/* | |
// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
console.log('Hello from ia4jgen!') | |
function gc(cls) { | |
return document.getElementsByClassName(cls) | |
} | |
let mouseInTimer, mouseOutTimer; | |
function register(elem, type, popup, popupMaker) { | |
if(!popup.popupInitialized) { | |
popup.addEventListener('mouseenter', () => { | |
clearTimeout(mouseOutTimer) | |
}) | |
popup.addEventListener('mouseleave', () => { | |
mouseOutTimer = setTimeout(() => popup.style.display = "none") | |
}) | |
popup.popupInitialized = true | |
} | |
elem.setAttribute('token', type) | |
elem.setAttribute('tokendata', elem.innerText) | |
elem.addEventListener('mouseenter', function() { | |
clearTimeout(mouseOutTimer) | |
mouseInTimer = setTimeout(() => { | |
popup.style.display = "block" | |
if(elem.children.length == 0) { | |
popupMaker(popup, elem, findMethod(elem, true), findLine(elem)) | |
} | |
elem.style.position = "relative" | |
//popup.remove() | |
//elem.appendChild(popup) | |
popup.style.top = `${elem.offsetTop + elem.offsetHeight}px` | |
popup.style.left = `${elem.offsetLeft + 10}px` | |
}, 600) | |
}) | |
elem.addEventListener('mouseleave', function() { | |
clearTimeout(mouseInTimer) | |
mouseOutTimer = setTimeout(() =>{ | |
popup.style.display = "none" | |
elem.style.position = "" | |
}, 600) | |
}) | |
} | |
function register_arr(elems, type, popup, popupMaker) { | |
for(let i=0; i<elems.length; i++) | |
register(elems[i], type, popup, popupMaker) | |
} | |
let METHOD = "method", LINE = "line"; | |
let parr = window.location.href.substring(window.location.href.indexOf('com/inf')).split('/'); | |
parr.splice(parr.length - 1, 1) | |
let packag = parr.join('.') | |
function findLine(ele) { | |
for(; ele && !(ele.classList && (ele.classList.contains('l') || ele.classList.contains('hl'))); ele = ele.previousSibling); | |
return ele ? +ele.name : -999; | |
} | |
function findMethod(ele, shortName) { | |
while(ele && !ele.getAttribute('token')) ele = ele.parentNode | |
let line = findLine(ele), i=0; | |
while(methods[i].start <= line) i++; | |
return shortName ? methods[i - 1].name : `${packag}.${methods[i - 1].name}` | |
} | |
function render(name, spec, elemCreated, container) { | |
let e; | |
if (!spec.preBuilt) { | |
e = document.createElement(spec.ele); | |
spec.iden && elemCreated(spec.iden, e) | |
if (spec.text) e.innerHTML = spec.text; | |
if (spec.classList) { | |
e.classList = `${name}-` + spec.classList.split(/\s+/).join(` ${name}-`) | |
} | |
spec.attribs && Object.keys(spec.attribs).forEach(key => { | |
e[key] = spec.attribs[key] | |
}) | |
spec.styles && Object.keys(spec.styles).forEach(key => { | |
e.style[key] = spec.styles[key] | |
}) | |
spec.evnts && Object.keys(spec.evnts).forEach(key => { | |
e.addEventListener(key, spec.evnts[key]) | |
}) | |
if (spec.children) { | |
if (spec.children instanceof Function) { | |
spec.children().map(x => e.appendChild(x)) | |
} | |
else spec.children.forEach(child => render(name, child, elemCreated, e)) | |
} | |
} else { | |
e = spec.ele; | |
} | |
if (container) { | |
let lbl; | |
if (spec.label || spec.postlabel) { | |
let rgid = "id_" + Math.random(); | |
e.id = rgid | |
lbl = document.createElement('label') | |
lbl.innerHTML = spec.label || spec.postlabel | |
lbl.setAttribute('for', rgid) | |
} | |
if (spec.label) container.appendChild(lbl) | |
container.appendChild(e) | |
if (spec.postlabel) container.appendChild(lbl) | |
return container; | |
} | |
return e; | |
} | |
let clipboardDiv ; | |
function copyToClip(html) { | |
if (!clipboardDiv) { | |
clipboardDiv = document.createElement("div"); | |
clipboardDiv.style.fontSize = "12pt"; // Prevent zooming on iOS | |
// Reset box model | |
clipboardDiv.style.border = "0"; | |
clipboardDiv.style.padding = "0"; | |
clipboardDiv.style.margin = "0"; | |
// Move element out of screen | |
clipboardDiv.style.position = "fixed"; | |
clipboardDiv.style["right"] = "-9999px"; | |
clipboardDiv.style.top = | |
(window.pageYOffset || document.documentElement.scrollTop) + "px"; | |
// more hiding | |
clipboardDiv.setAttribute("readonly", ""); | |
clipboardDiv.style.opacity = 0; | |
clipboardDiv.style.pointerEvents = "none"; | |
clipboardDiv.style.zIndex = -1; | |
clipboardDiv.setAttribute("tabindex", "0"); // so it can be focused | |
clipboardDiv.innerHTML = ""; | |
document.body.appendChild(clipboardDiv); | |
} | |
clipboardDiv.innerHTML = html; | |
var focused = document.activeElement; | |
clipboardDiv.focus(); | |
window.getSelection().removeAllRanges(); | |
var range = document.createRange(); | |
range.setStartBefore(clipboardDiv.firstChild); | |
range.setEndAfter(clipboardDiv.lastChild); | |
window.getSelection().addRange(range); | |
try { | |
if (document.execCommand("copy")) { | |
alert('Copied to clipboard') | |
} | |
} catch (err) { | |
console.error(err) | |
alert("copy failed, but the config is printed to browser console!"); | |
} | |
focused.focus(); | |
} | |
function commonPopupMaker(popup, elem, events, method, line, position) { | |
let ia4jConfig = JSON.parse(JSON.stringify((instrumentations[findMethod(elem)] || {}).conf || {})) | |
function setOpt(EVENT, val, add) { | |
if(!ia4jConfig[EVENT]) | |
ia4jConfig[EVENT] = [] | |
if(add) | |
ia4jConfig[EVENT].push(val) | |
else | |
ia4jConfig[EVENT].splice(ia4jConfig[EVENT].findIndex(x => x == val), 1) | |
console.log(ia4jConfig) | |
} | |
function generate(elem) { | |
let conf = events.map(event => (ia4jConfig[subst(event.name)] || []).map(action => `~~${subst(event.name)}=>${action}`).join('')).join('') | |
if(conf.trim() != '') { | |
let ret = { title: findMethod(elem, true), code: `ia4j.include${+(new Date())}=${findMethod(elem)}${conf}`, elem, conf: {...ia4jConfig} } | |
console.log(ret) | |
return ret | |
} else { | |
alert('Looks like you have defined no actions for any events') | |
throw 'Looks like you have defined no actions for any events' | |
} | |
} | |
function copy(elem) { | |
let iconf = generate(elem).code | |
copyToClip(iconf) | |
} | |
function save(elem) { | |
instrumentations[findMethod(elem)] = generate(elem) | |
updateInstrumentationView() | |
} | |
function reset() { | |
ia4jConfig={} | |
let cbs = popup.querySelectorAll("input[type='checkbox']") | |
for(let i=0; i<cbs.length; i++) { | |
cbs[i].checked = false | |
} | |
} | |
popup.innerHTML = '' | |
function subst(x) { | |
return eval(`\`${x}\``) | |
} | |
function findCurVal(event, action) { | |
return ia4jConfig[event] && ia4jConfig[event].includes(action) | |
} | |
render('', { | |
ele: 'div', | |
styles: {textAlign: 'left'}, | |
evnts: { | |
click: function(r) { | |
let tag = r.target.tagName.toLowerCase() | |
if(tag == 'input') | |
r.target.setAttribute('checked', true); | |
if(tag != 'label' && tag != 'input') | |
r.stopPropagation() | |
} | |
}, | |
children: [ | |
{ele: 'b', text: method, attribs: {style:'display: block; color: black; margin: 5px 0px'}} | |
].concat( | |
events.map(event => ( | |
{ ele: 'div', styles: {margin: '10px 0px', fontSize: '0.8em', display: 'flex'}, children: [ | |
{ ele: 'div', attribs: { style: "width: 80px" }, children: [ | |
{ ele: 'b', text: `${subst(event.display)}`, styles: { display: 'inline-block', textDecoration: 'underline', color: 'blue'}}, | |
{ ele: 'b', text: '🛈', attribs: {title: subst(event.help)}, styles: { display: 'inline-block', cursor: 'pointer'}}, | |
] | |
}, | |
...(['VALUES', 'NOVALUES', 'JSON', 'STACK','HEAP'] | |
.map(action => ({ele: 'input', attribs: {type:'checkbox', checked: findCurVal(subst(event.name), action)}, postlabel: action, evnts:{change: function() {setOpt(subst(event.name),action,this.checked)}}}))) | |
]} | |
)) | |
).concat([ | |
{ele: 'div', children: [ | |
{ele: 'button', styles:{ margin: '0px 5px 5px 0px'}, text: 'add', evnts: {click: function() {save(elem)} }}, | |
{ele: 'button', styles:{ margin: '0px 5px 5px 0px'}, text: 'copy', evnts: {click: function() {copy(elem)} }}, | |
{ele: 'button', styles:{ margin: '0px 0px 5px 0px'}, text: 'clear', evnts: {click: ()=> {reset()} }} | |
]}, | |
{ele: 'small', text: 'made with ❤ by mpataki', styles: {fontSize: '0.6em', float: 'right'}} | |
]) | |
}, undefined, popup) | |
popup.style.top = `${position.top}px` | |
popup.style.left = `${position.left}ps` | |
} | |
let ENTRY = {name: 'ENTRY', display: "ENTRY", help: "Entry point of the method"} | |
let EXIT = {name: 'EXIT', display: "EXIT", help: "Exit of the method"} | |
let EXCEPTION = {name: 'EXCEPTION', display: "EXCEPTION", help: "When an exception happens in this method"} | |
let ATLINE = {name: 'ATLINE(${line})', display: "ATLINE(${line})", help: "At line ${line}"} | |
function methodInstrument(popup, elem, method, line) { | |
commonPopupMaker(popup, elem, [ENTRY, EXIT, EXCEPTION], method, line, {top: 15, left: 0}) | |
} | |
function lineInstrument(popup, elem, method, line) { | |
commonPopupMaker(popup, elem, [ATLINE], method, line, {top: 0, left: 20}) | |
} | |
let classes = [], methods = []; | |
function findInnerClasses() { | |
let line, stk = [], classParents = []; | |
var n, a=[], xc, walk=document.createTreeWalker( | |
document.getElementsByTagName('pre')[0], | |
NodeFilter.SHOW_TEXT|NodeFilter.SHOW_ELEMENT, | |
xc => (xc.tagName != 'SCRIPT' && xc.parentNode.tagName != 'SCRIPT')); | |
while(xc=walk.nextNode()) { | |
if (xc.tagName === undefined) { | |
for(let c in xc.textContent) { | |
c = xc.textContent[c] | |
let top, cls; | |
switch(c) { | |
case '{': | |
stk.push('{') | |
break; | |
case '}': | |
stk.pop() | |
top = stk[stk.length - 1] | |
if(top != '{') { | |
top = stk.pop() | |
top.end = line | |
switch(top.type) { | |
case 'class': | |
classParents.pop() | |
classes.push(top) | |
break; | |
case 'method': | |
methods.push(top) | |
} | |
} | |
} | |
} | |
} else if(xc.classList) { | |
if(xc.classList.contains('hl') || xc.classList.contains('l')) { | |
line = +xc.name; | |
} else if(xc.classList.contains('xc') && xc.classList.contains('intelliWindow-symbol')) { | |
let clsName = xc.innerText | |
classParents.push(clsName) | |
stk.push({type: 'class', name: classParents.join('$'), start: line}) | |
} else if(xc.classList.contains('xmt') && xc.classList.contains('intelliWindow-symbol')) { | |
let metName = xc.innerText | |
stk.push({type: 'method', name: `${classParents.join('$')}::${metName}`, start: line}) | |
} | |
} | |
} | |
classes.push({name : 'dummy_class', start: Number.POSITIVE_INFINITY}) | |
methods.push({name : 'dummy_method', start: Number.POSITIVE_INFINITY}) | |
console.log(classes.sort((a, b) =>a.start - b.start)) | |
console.log(methods.sort((a, b) =>a.start - b.start)) | |
} | |
console.time('classhunt') | |
findInnerClasses() | |
console.timeEnd('classhunt') | |
let popup = document.createElement('div') | |
popup.style = "padding: 0px 10px; position: absolute; top: 15px; left: 10px; background: white; border: solid 1px black; white-space: initial; display: none; font-size: 0.8em" | |
document.body.appendChild(popup) | |
register_arr(gc('xmt'), METHOD, popup, methodInstrument) | |
register_arr([...gc('l'), ...gc('hl')], LINE, popup, lineInstrument) | |
let fqcn = window.location.href.substring(window.location.href.indexOf('com')).split('/').join('.').replaceAll(/.java(#.*|\?.*)*$/g, "") | |
let cn = fqcn.split('.')[fqcn.split('.').length - 1] | |
let product = window.location.href.split('/')[3], component = window.location.href.split('/')[5] | |
let searchresults = [] | |
// the instru cart | |
let instrumentations = {}, maximized = false, saveBox = render('', {ele: 'div', attribs: {style: 'position: fixed; top: 35px; right: 10px; display: block; flex-direction: column; background: white; border: solid 1px black; font-size: 0.8em; max-height: 90vh; overflow: auto'}}) | |
document.body.appendChild(saveBox) | |
inodes_search(`%ia4jsnips ${fqcn}`).then(results => { | |
console.log(results) | |
if(!results || !results.results) return | |
searchresults = results.results.map(result => { | |
result.content = JSON.parse(result.content) | |
return result | |
}) | |
updateInstrumentationView() | |
}) | |
function ia4jsnipView(result) { | |
return { | |
ele: 'div', styles: { display: 'flex' }, children: [ | |
{ ele: 'b', text: '+', attribs: { style: "margin-right: 5px; cursor: pointer; padding: 0px 3px; border: solid 1px black; height: fit-content; font-family: monospace" }, evnts: { | |
click: function() { | |
this.nextElementSibling.children[1].style.display = this.innerText == '+' ? 'flex' : 'none' | |
this.innerText = this.innerText == '+' ? '-' : '+' | |
} | |
} }, | |
{ | |
ele: 'div', styles: { display: 'flex', flexDirection: 'column' }, children: [ | |
{ele: 'span', children: [ | |
{ ele: 'a', text: result.content.title, attribs: {href: `http://inedctst01:8080/?q=@${result.id}`, target: '_blank', style: "font-weight: bold"}}, | |
{ ele: 'span', text: ' by '}, | |
{ ele: 'a', text: result.owner, attribs: {href: `http://inedctst01:8080/?q=${encodeURIComponent("#inodesapp #viewuser !" + result.owner)}`, target: '_blank', style: "color: seagreen; font-weight: bold"}} | |
]}, | |
{ ele: 'div', styles: { display: 'none', flexDirection: 'column', marginTop: '5px' }, children: [ | |
{ ele: 'div', attribs: {style: 'margin: 5px 0px; display: flex'}, children: [ | |
{ ele: 'div', styles: {flexGrow: 1}, children: result.tags.map(tag => ({ele: 'span', text: tag, attribs: {style: 'padding: 0px 1px; border: solid 1px lightgray; background: #eaeaea; border-radius: 3px; font-size: .8em; margin-right: 5px'}})) }, | |
{ ele: 'div', children: [ | |
{ele: 'span', text: 'copy', styles: {color: 'blue', marginRight: '5px', cursor: 'pointer', fontSize: '0.8em'}, evnts: {click: () => copyToClip(result.content.instrumentation)}}, | |
{ele: 'span', text: 'download', styles: {color: 'blue', cursor: 'pointer', fontSize: '0.8em'}, evnts: {click: () => download('ia4j.props', result.content.instrumentation)}} | |
]} | |
] }, | |
{ ele: 'div', label: 'Problem', styles: {background: 'aliceblue', padding: '0px 5px', flexGrow: 1, marginBottom: '10px', width: '370px', overflow: 'auto'}, text: markdown(result.content.problem)}, | |
{ ele: 'pre', label: 'Instrumentation', styles: {overflow: 'auto', width: '370px'}, text: result.content.instrumentation} | |
]} | |
] | |
} | |
] | |
} | |
} | |
function updateInstrumentationView() { | |
let num = (Object.keys(instrumentations).length || searchresults.length) | |
//saveBox.style.display = num ? 'block' : 'none' | |
saveBox.innerHTML = '' | |
let x = {} | |
render('', | |
!maximized ? | |
{ele: 'div', text: '🛒', attribs: {style: 'position: relative; padding: 10px; cursor: pointer'}, | |
children: !num ? [] : [{ele: 'span', attribs: { style: 'position: absolute; top: 2px; right: 2px; background: orange; padding: 0px 4px; border-radius: 50%' }, text: num}], | |
evnts: {click: function(){ maximized = !maximized; updateInstrumentationView() }}}: | |
{ ele: 'div', styles: {width: '400px', padding: '20px', position: 'relative'}, children: [ | |
{ ele: 'b', text: '-', attribs: { style: "position: absolute; top: 5px; right: 5px; cursor: pointer; padding: 0px 3px; border: solid 1px black; height: fit-content; font-family: monospace" }, evnts: { | |
click: function() { maximized = !maximized; updateInstrumentationView() } | |
} }, | |
{ ele: 'div', children: [ | |
{ele: 'strong', text: `Known ia4j snippets for <u>${cn}</u>`, attribs: {style: "color: #2030a2; font-size: 1.2em"}}, | |
{ ele: 'div', attribs: {style: 'margin: 10px 0px'}, children: searchresults.map(result => ia4jsnipView(result))} | |
] | |
}, | |
{ ele : 'div', attribs: { style: "padding-top: 30px; margin-top: 30px; border-top: solid 1px seagreen;"}, children: [ | |
{ ele: 'strong', text: 'Instrumentation cart', attribs: { style: "display:block; color: #2030a2; font-size: 1.2em" }}, | |
Object.keys(instrumentations).length ? | |
{ ele: 'div', children: [ | |
{ ele: 'div', attribs: {style: 'margin: 10px 0px'}, children: Object.entries(instrumentations).map(([key, instr]) => ({ | |
ele: 'div', styles: {display:'flex'}, children: [ | |
{ele: 'a', text: instr.title, styles: {flexGrow: 1, padding: '0px 10px 5px 0px'}, attribs: {href: `#${findLine(instr.elem)}`}}, | |
{ | |
ele: 'div', | |
styles: {padding: '0px 10px'}, | |
children: Object.keys(instr.conf).map(x => ( | |
{ele: 'b', text: x.substr(0, 3).toLowerCase(), attribs: {style: 'border: solid 1px lightgray; font-size: 0.9em; padding: 1px 2px; margin: 0px 2px; border-radius: 2px', title: `${instr.conf[x].length} actions for ${x}`}} | |
)) | |
}, | |
{ele: 'span', text: '×', styles:{ cursor: 'pointer' }, attribs: { title: 'delete' }, evnts: { | |
click: function() { | |
delete instrumentations[key] | |
setTimeout(() => updateInstrumentationView(), 100) | |
} | |
}}, | |
] | |
})) | |
}, | |
{ ele: 'div', children: [ | |
{ ele: 'button', styles: { margin: '5px 5px 0px 0px' }, text: 'copy', evnts: {click: () => copyToClip(getInstrCode(false))}}, | |
{ ele: 'button', styles: { margin: '5px 5px 0px 0px' }, text: 'download', evnts: {click: () => download('ia4j.props', getInstrCode(true))}}, | |
{ ele: 'button', styles: { margin: '5px 5px 0px 0px' }, text: 'save', evnts: {click: () => x.savedialog.style.display = 'flex'}} | |
]}, | |
{ ele: 'div', iden: "savedialog", attribs: { style: "display: none; flex-direction: column; margin-top: 20px" }, children: [ | |
{ele: 'strong', text: 'save to inodes'}, | |
{ele: 'div', attribs: {style: "flex-grow: 1; margin: 5px 0px"}, children: [ | |
{ele: 'input', iden: 'inodesuid', label: 'username: ', attribs: {style: "background: white; margin-right: 10px"}}, | |
{ele: 'input', iden: 'inodespswd', label: 'password: ', attribs: {type: 'password', style: "background: white"}} | |
]}, | |
{ele: 'input', iden: 'title', label: 'title', attribs: {style: "background: white; margin: 5px 0px"}}, | |
{ele: 'textarea', iden: "problem", label: "Problem (use markdown)", attribs: {style: "flex-grow: 1", rows: 5}}, | |
{ele: 'input', iden: 'tags', label: 'tags', attribs: {style: "background: white; margin: 5px 0px"}}, | |
{ ele: 'div' ,children: [ | |
{ele: 'button', styles: { margin: '5px 5px 0px 0px', width: 'fit-content' }, text: 'post', evnts: {click: () => inodes_post(x.title.value, product, component, x.problem.value, getInstrCode(), x.tags.value.split(/\s+/), x.inodesuid.value, x.inodespswd.value)}}, | |
{ele: 'button', styles: { margin: '5px 5px 0px 0px', width: 'fit-content' }, text: 'cancel', evnts: {click: () => x.savedialog.style.display = 'none'}} | |
]} | |
]} | |
]} | |
: | |
{ele: 'div', attribs: {style: "padding: 20px; color: lightgray"}, text: 'No instrumentations in the cart. Hover on a line / method to create one' } | |
]} | |
]}, (id, ele) => x[id] = ele, saveBox) | |
} | |
function getInstrCode(fullFile) { | |
let header = `# IA4J configuration | |
# created by - ia4jgen | |
# created at - ${new Date().toString()} | |
\n` | |
return (fullFile ? header : '') + Object.values(instrumentations).map(i => i.code).join('\n') + (fullFile ? completeIa4jFile : '') | |
} | |
function download(filename, text) { | |
var element = document.createElement('a'); | |
element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)); | |
element.setAttribute('download', filename); | |
element.style.display = 'none'; | |
document.body.appendChild(element); | |
element.click(); | |
document.body.removeChild(element); | |
} | |
function ajax(method, url, data, uid, passwd) { | |
return new Promise((resolve, reject) => { | |
var xhttp = new XMLHttpRequest(); | |
xhttp.onreadystatechange = function () { | |
if (this.readyState == 4 && this.status == 200) { | |
let json; | |
try { json = JSON.parse(this.responseText); } catch (e) { } | |
resolve({ response: this.responseText, json }) | |
} | |
}; | |
xhttp.onerror = function () { reject({ message: JSON.parse(this.responseText).message, code: this.status }); } | |
xhttp.open(method, `http://inedctst01:8080/${url}`, true); | |
(uid && passwd) && xhttp.setRequestHeader('Authorization', `Basic ${btoa(uid + ":" + passwd)}`) | |
xhttp.setRequestHeader('Content-Type', `application/json`) | |
xhttp.send(data); | |
}); | |
} | |
function get(url) { | |
return ajax("GET", url); | |
} | |
function post(url, data, uid, passwd) { | |
return ajax("POST", url, data, uid, passwd); | |
} | |
function inodes_search(str, offset = 0, pageSize = 100) { | |
return get(`/data?q=${encodeURIComponent(str.replaceAll(/\![-\w]+/g, ""))}&offset=${offset}&pageSize=${pageSize}&fq=tags&fq=type&fq=owner`).then(x => x.json) | |
} | |
// thanks! drawdown.js ;) | |
function markdown(a) { function b(b, c) { a = a.replace(b, c) } function c(a, b) { return "<" + a + ">" + b + "</" + a + ">" } function d(a) { return a.replace(i, function (a, b) { return c("blockquote", d(f(b.replace(/^ *> */gm, "")))) }) } function e(a) { return a.replace(j, function (a, b, d, g, h, i) { var j = c("li", f(i.split(RegExp("\n ?" + b + "(?:(?:\\d+|[a-zA-Z])[.)]|[*\\-+]) +", "g")).map(e).join("</li><li>"))); return "\n" + (d ? "<ol start=\"" + (g ? d + "\">" : parseInt(d, 36) - 9 + "\" style=\"list-style-type:" + (h ? "low" : "upp") + "er-alpha\">") + j + "</ol>" : c("ul", j)) }) } function f(a) { return a.replace(k, function (a, b, d, e, g, h, i, j, k, l) { return b + c(e ? k ? "strong" : "em" : g ? k ? "s" : "sub" : h ? "sup" : i ? "small" : j ? "big" : "code", f(l)) }) } function g(a) { return a.replace(h, "$1") } var h = /\\([\\\|`*_{}\[\]()#+\-~])/g, i = /\n *> *([^]*?)(?=(\n|$){2})/g, j = /\n( *)(?:[*\-+]|((\d+)|([a-z])|[A-Z])[.)]) +([^]*?)(?=(\n|$){2})/g, k = /(^|[^A-Za-z\d\\])(([*_])|(~)|(\^)|(--)|(\+\+)|`)(\2?)([^<]*?)\2\8(?!\2)(?=\W|_|$)/g, l = [], m = 0; return a = "\n" + a + "\n", b(/</g, "<"), b(/>/g, ">"), b(/\t|\r|\uf8ff/g, " "), a = d(a), b(/^([*\-=_] *){3,}$/gm, "<hr/>"), a = e(a), b(/<\/(ol|ul)>\n\n<\1>/g, ""), b(/\n((```|~~~).*\n?([^]*?)\n?\2|(( .*?\n)+))/g, function (a, b, d, e, f) { return l[--m] = c("pre", c("code", e || f.replace(/^ /gm, ""))), m + "\uF8FF" }), b(/((!?)\[(.*?)\]\((.*?)( ".*")?\)|\\([\\`*_{}\[\]()#+\-.!~]))/g, function (a, b, c, d, e, h, i) { return l[--m] = e ? c ? "<img src=\"" + e + "\" alt=\"" + d + "\"/>" : "<a href=\"" + e + "\">" + g(f(d)) + "</a>" : i, m + "\uF8FF" }), b(/\n(( *\|.*?\| *\n)+)/g, function (a, b) { var d = b.match(/^.*\n( *\|( *\:?-+\:?-+\:? *\|)* *\n|)/)[1]; return "\n" + c("table", b.replace(/.*\n/g, function (a, b) { return a == d ? "" : c("tr", a.replace(/\||(.*?[^\\])\|/g, function (a, e, h) { return h ? c(d && !b ? "th" : "td", g(f(e || ""))) : "" })) })) }), b(/(?=^|>|\n)([>\s]*?)(#{1,6}) (.*?)( #*)? *(?=\n|$)/g, function (a, b, d, e) { return b + c("h" + d.length, g(f(e))) }), b(/(?=^|>|\n)\s*\n+([^<]+?)\n+\s*(?=\n|<|$)/g, function (a, b) { return c("p", g(f(b))) }), b(/-\d+\uf8ff/g, function (a) { return l[parseInt(a)] }), a.trim() } | |
function inodes_post(title, product, component, problem, instrumentation, tags, uid, passwd) { | |
function validate(names) { | |
names.forEach(name => { | |
let v = eval(name) | |
if (!v || v.trim() == '') return alert(name + ' is required') | |
}) | |
} | |
validate(['title', 'product', 'component', 'problem', 'instrumentation']) | |
if (!tags.length) { return alert('Tags are required for a post') } | |
post(`/data?changeNote=${encodeURIComponent("initial version")}`, JSON.stringify({ | |
content: JSON.stringify({ title, product, component, problem, instrumentation }), | |
type: 'ia4jsnips', | |
tags: ["ia4jgen"].concat(tags), | |
visibility: ["g-public"], | |
savedVisibility: ['none'] | |
}), uid, passwd).then(_ => showSuccess('Posted successfully')) | |
.catch(e => showError(e.message)) | |
} | |
let completeIa4jFile = ` | |
\n\n | |
enableInstrumentation=true | |
ia4j.masterThreadInterval=10 | |
# Prefix for output directory | |
# Directory may be specified as part of the prefix | |
# On Windows, use double slashes '\\' as delimiter | |
# "_date_time_pid<pid>" would be appended to the prefix below | |
ia4j.traceFilePrefix=/tmp/ia4j/logs | |
# Debugging | |
# logging debug message from ia4j | |
ia4j.debugMode=false | |
# logging debug messages from ia4j timer | |
ia4j.timerDebugMode=false | |
# Remote control features | |
ia4j.remoteControlMode=false | |
ia4j.minControlPort=5551 | |
ia4j.maxControlPort=5600 | |
# If tracing of methods should be started on application startup | |
ia4j.traceOnStartup=true | |
# Track Internal events | |
# Dump all threads from shutdown hook | |
ia4j.dumpThreadsOnShutdown=false | |
# Dump heap from shutdown hook - subjected to maxDumps limit | |
ia4j.dumpHeapOnShutdown=false | |
#Dump threads and heap on enabling command | |
ia4j.heapOnDemand=false | |
ia4j.threadsOnDemand=false | |
# Output content | |
# Maximum number of total dumps (THREADS,HEAP, CMD) that should be collected | |
ia4j.maxDumps=0 | |
ia4j.maxHeapDumps=5 | |
# To use rolling appender for trace ilfe | |
# Specify in MB, a new file will be created after current file becomes approx the specified size | |
# will write to same file if set it to 0 | |
ia4j.traceFileMaxSize=0 | |
# !!Experimental!! | |
# Creates a smaller trace file reducing redundancy of certain fields in trace file | |
ia4j.traceFileCompress=false | |
# Following to control which argument/return value types to be printed using toString() | |
# default contains only java.lang.* (except java.lang.Object) | |
# Separate each by "||" | |
ia4j.printTypes=java.lang.*||java.net.*Socket||java.net.(URL|URI)||java.util.Date | |
` | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment