Warning : session_start(): open(/var/lib/php/sessions/sess_umpjsr9hm8g83p2g2sfvqc2pbm, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning : session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import java.util.function.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.imageio.*;
import java.math.*;
import java.time.Duration;
import java.lang.invoke.VarHandle;
import java.lang.invoke.MethodHandles;
// TODO: fix interaction with line spans made by show-snippet.php
// Transpile & reload-in-eleu #1008705 after changing this
// TODO: use Map attributesForCharRanges
// and generate HTML properly from that
import java.awt.geom.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import static x30_pkg.x30_util.DynamicObject;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
class main {
static class JavaXHyperlinker {
boolean targetBlank = false;
abstract static class PeepHole {
List tok;
int cIdx;
String prevPrev, prev, token, next;
void explain(String text) { explain(cIdx, text); }
abstract void explain(int i, String text);
void link(String url) { link(cIdx, url); }
abstract void link(int i, String url);
}
// only a single token allowed on LHS
Map shortFor = litmap(
"BigInt", "BigInteger",
"$1", "m.unq(0)",
"$2", "m.unq(1)",
"$3", "m.unq(2)",
"LS", "List",
"sclass", "static class",
"asclass", "abstract static class",
"svoid", "static void",
"SS", "Map",
"S", "String",
"ret", "return",
"L", "List",
"Cl", "Collection",
"O", "Object",
"sO", "static Object",
"sS", "static String",
"fO", "final Object",
"fS", "final String",
"sS", "static String",
"sbool", "static boolean",
"fbool", "final boolean",
"bool", "boolean",
"Int", "Integer",
"cast", "casting to the type required on the left-hand side",
"°", "()",
"ItIt", "IterableIterator",
"ES", "Ext (string plus extended information)",
"CloseableItIt", "CloseableIterableIterator",
"LPairS", "List>",
"ISegmenter", "IF1>",
"dbl", "double");
String explFunc = "anonymous function declaration (similar to Java 8 lambdas)";
String explPNoconsole = "Main program including Substance L&F, started in non-AWT thread, hiding the console";
// any number of tokens allowed on LHS
Map tokenExplanations = litmap(
"cm", "cm summons the last version of a module in Stefan's OS (cm originally stood for 'compact module')",
"~.", "short for accessing a field or calling a method by reflection",
"beaConcept", "a BEA concept is just a concept (database-enabled Java class) derived from BEAObject (the AGI base class)",
"== null ?:", "short for: == null ? null :",
"p-exp {", "main program with automatic upgrade",
"mapLike", "a function that takes a global function name as first argument and can be called like this: (...)",
"mapMethodLike", "a function that takes a method or field name as first argument and can be called like this: (...)",
"func(", explFunc, "func{", explFunc,
//"f(", explFunc, "f{", explFunc,
"voidfunc", "anonymous function declaration without return value (similar to Java 8 lambdas)",
"ctex", "ctex rethrows exceptions as RuntimeExceptions so you don't have to declare them",
"p {", "short for: public static void main(String[] args)",
"p-experiment {", "Main program with a nice big console & auto-restart",
"p-substance {", "Main program including Substance L&F, started in AWT thread",
"p-subst {", "Main program including Substance L&F, started in non-AWT thread",
"p-noconsole {", explPNoconsole,
"pn {", explPNoconsole,
"answer {", "Answer function - static S answer(S s) { new Matches m; ...; null; }",
"time {", "Run the code block and print how long it took",
"cprint {", "A module with default class name derived from DynPrintLog",
"semiauto {", "In a semiauto block, JavaX automatically adds a ; to (almost) every line",
"autosemi {", "In an autosemi block, JavaX automatically adds a ; to (almost) every line",
"Clusters", "Clusters is short for Map >",
"temp", "temp is like try (...) extending to the end of the current block",
"pcall {", "protected call - try { ... } catch { print exception }",
"r {", "r { ... } is short for: new Runnable() { public void run() { ... } }",
"runnable {", "runnable { ... } is short for: new Runnable() { public void run() { ... } }",
"pcall-short {", "protected call, shorter output - try { ... } catch { printShortException }",
"LPair<", "LPair<...> is short for: L>",
"visualize {", "Visualisation method for an OS module; returns a Swing component",
"visualize as", "define a visualization for the module",
"enhanceFrame {", "Method that changes properties of an OS module's frame",
"run {", "short for: public void run()",
"start {", "Method that is run when an OS module is loaded",
"enter {", "Methods in a module should be marked 'enter' for bookkeeping",
"vf<", "reference to function as voidfunc",
"compact module", "try to save memory by reusing code between modules",
"cmodule", "cmodule = compact module for Stefan's OS. compact = try to save memory by reusing code between modules",
"cmodule2", "cmodule2 = compact module for Stefan's OS (newer version). compact = try to save memory by reusing code between modules",
"rThread {", "Runnable in a new thread",
"shit(", "short for: return with print",
"shit:", "short for: return with print",
":=", "the := operator translates to a simple comma, but converts an identifier on its left-hand side into a string",
"noeq", "don't auto-generate equals+hashCode methods",
"for single (", "for single is for ping + singletonUnlessNull",
"selfType", "selfType is replaced with the enclosing class's name",
"runnable class", "short for: class X implementing Runnable { run { ... }}",
"aka", "In JavaX, methods can have multiple names");
Map sc, sf;
StringTree2 tokenExplanationsTree;
List> explainers = new ArrayList();
NotTooOften ntoClearCaches = nto_mins(5);
JavaXHyperlinker() {
maybeClearCaches();
tokenExplanationsTree = stringTree2_javaTok(tokenExplanations);
}
void maybeClearCaches() {
ntoClearCaches.dO(() -> clearCaches());
}
String codeToHTML(String code) { return codeToHTML(code, true); }
String codeToHTML(String code, boolean real) {
maybeClearCaches();
List tok = javaTok(code);
Map links = new HashMap(); // token index -> sf snippet ID
Map explanations = new HashMap(); // token index -> explanation text
putMultipleKeys(explanations, allPlus(4, jfindAll(tok, "void q {")),
"Function will execute in module's queue");
// Go over all tokens and colorize
Map styles = new HashMap();
tokensToColors(tok, styles);
// Go over code tokens, generate links and explanations
Matches m = new Matches();
for (int i = 1; i < l(tok); i += 2) {
String t = tok.get(i);
String prev = get(tok, i-2), prevPrev = get(tok, i-4);
String next = get(tok, i+2);
String sfID = sf.get(t);
PeepHole ph = new PeepHole() {
void explain(int i, String text) { explanations.put(i, text); }
void link(int i, String url) { links.put(i, url); }
};
ph.tok = tok;
ph.cIdx = i;
ph.prevPrev = prevPrev;
ph.prev = prev;
ph.token = t;
ph.next = next;
pcallFAll(explainers, ph);
// please include functions
if (eq(t, "include") && eq(next, "functions")) {
i += 4;
String name;
while (i < l(tok) && isIdentifier(name = get(tok, i))) {
mapPut(links, i, sf.get(name));
i += 2;
}
continue;
}
if (startsWith(t, "lambda", m) && isInteger(m.rest()) && isIdentifier(next))
explanations.put(i, ("lambda reference to a " + (m.rest()) + "-argument function"));
if (eq(t, "is") && isIdentifier(next))
explanations.put(i, "synonym of 'implements'");
if (eq(t, "methodLambda0") && isIdentifier(next))
explanations.put(i, ("short for: x -> x." + next + "() (with a fresh variable instead of x)"));
if (eqOneOf(t, "lambda0", "l0") && isIdentifier(next))
explanations.put(i, ("short for: -> " + next + "()"));
if (eq(t, "swappable") && isIdentifier(next))
explanations.put(i, "swappable functions can be exchanged per object instance");
if (eq(t, "main") && isIdentifier(next))
explanations.put(i, "reference to the current 'main' class (where all the standard functions are held, not always called 'main')");
if (eq(t, "autoDispose") && isIdentifier(next))
explanations.put(i, "autoDispose adds a cleanMeUp method that properly disposes of this variable");
if (eq(t, "optional") && isIdentifier(next))
explanations.put(i, "optional parameter (null if omitted)");
if (eq(t, "macro") && isIdentifier(next))
explanations.put(i, "define a macro called '" + next + "', visible until the end of the enclosing block (or until redefined)");
if (eq(t, "virtual") && isIdentifier(next))
explanations.put(i, "\"virtual\" represents a type that is not visible in this realm, so it is transpiled to just Object");
if (eq(t, "concept") && isIdentifier(next))
explanations.put(i, "A concept is like a Java class, but persistable");
if (eq(t, "flexeq") && isIdentifier(next))
explanations.put(i, "flexeq is a fix for records inside parameterized classes");
if (eq(t, "switchable") && isIdentifier(next))
explanations.put(i, "A field that can be changed through the module's popup menu");
if (eq(t, "embedded") && isIdentifier(next))
explanations.put(i, "\"embedded\" allows you to put a function where they would not normally be allowed");
if (eq(t, "visual") && isIdentifier(next))
explanations.put(i, "short definition of the visualize() function");
if (eq(t, "dm_q") && isIdentifier(next))
explanations.put(i, "Function reference delegating to module queue");
if (eq(t, "!") && isIdentifier(prev) && neq(next, "="))
explanations.put(i, "! is short for .get()");
/*if (eq(t, "!") && containsNewLine(get(tok, i-1)) && isInteger(next))
explanations.put(i, "Translator invocation");*/
if (eq(t, "#") && isIdentifier(next))
explanations.put(i, "# makes an identifier local to the scope");
if (eq(t, "f") && isIdentifier(next))
explanations.put(i, "f references a static function in the main class");
if (eq(t, "r") && isIdentifier(next))
explanations.put(i, "short for: r { " + next + "() }");
if (eqOneOf(t, "rThread", "rThreadEnter") && isIdentifier(next))
explanations.put(i, "short for: " + t + " { " + next + "() }");
if (eq(t, "dispose") && isIdentifier(next))
explanations.put(i, "short for: cleanUp(" + next + "); " + next + " = null;");
if (eq(t, "*") && eq(next, "("))
explanations.put(i, "Short syntax for a constructor declaration");
if (eq(t, "thread") && eq(next, "{"))
explanations.put(i, "Start a new thread with the following code");
if (eq(t, "module") && isIdentifier(next))
explanations.put(i, "A module is a class that can be loaded in Stefan's OS");
if (eq(t, "record") && isIdentifier(next))
explanations.put(i, "A record is a value-based class");
if (eq(t, "srecord") && isIdentifier(next))
explanations.put(i, "An srecord is a static value-based class");
if (eqOneOf(t, "cached", "simplyCached") && isIdentifier(next))
explanations.put(i, "A function that caches its return value");
if (eq(t, "thread") && isQuoted(next))
explanations.put(i, "Start a new thread with the following name & code");
if (eq(t, "if") && isQuoted(next)) { try {
List tok2 = tok_subListWithoutBorderNTokens(tok, i, i+3);
tok_expandIfQuoted(tok2);
explanations.put(i, "short for: " + join(tok2));
} catch (Throwable __e) { pcallFail(__e); }}
if (eq(t, "html") && eq(next, "{"))
explanations.put(i, "short for: static Object html(String uri, final Map params) ctex {");
if (eq(t, "try") && eq(next, "answer"))
doublePut(explanations, i, i+2, "\"try answer\" returns the expression if it isn't null or empty");
if (isSingleQuoteIdentifier(t))
explanations.put(i, "string constant, " + quote(fromSingleQuoteIdentifier(t)));
if (eq(t, "event") && isIdentifier(next))
explanations.put(i, "declare a function called " + next + "() plus helpers for adding listeners");
if (eqOneOf(t, "null", "false", "true", "this")
&& eq(next, ";")
&& tok_tokenBeforeLonelyReturnValue(tok, i-2))
doublePut(explanations, i, i+2, "short for: return " + t + ";");
String e = shortFor.get(t);
if (e != null)
mapPut(explanations, i, "short for: " + e);
// link to standard function
if (!explanations.containsKey(i) && sfID != null) {
if (eqOneOf(prev, "f", "r", "rThread", "function")
|| startsWith(prev, "lambda")
|| isIdentifier(next) && eqGet(tok, i+4, "(")
|| eqOneOf(next, "(", "°")
&& (neq(prev, ".") || eq(prevPrev, "main") && neq(get(tok, i-6), "."))
|| eq(prev, "{") && eq(next, "}") && eq(prevPrev, "postProcess")
|| eq(prev, ":") && eq(prevPrev, ":"))
links.put(i, sfID);
}
List fewTokens = codeTokens(subList(tok, i-1, i+2*5));
Pair p = stringTreeLeafValue2(tokenExplanationsTree, fewTokens);
if (p != null) {
//print(struct(p));
int lastCodeToken = i+p.b*2-2;
if (eq(get(tok, lastCodeToken), "{")) lastCodeToken -= 2;
mapPutInRange(explanations, i, lastCodeToken+1, p.a);
}
if (isQuoted(t) && eq(prev, "(") && isIdentifier(prevPrev)
&& isMechFunction(prevPrev))
mapPut(links, i, neatMechListURL(unquote(t)));
//mapPut(explanations, i, tokenExplanations.get(t));
mapPut(links, i, sc.get(t));
}
// go over tokens, output HTML characters
StringBuilder out = new StringBuilder();
Map titles = getSnippetTitles(filter(__22 -> isSnippetID(__22), values(links)));
for (int i = 0; i < l(tok); i++) {
String t = tok.get(i);
if (empty(t)) continue;
String id = links.get(i), ex = explanations.get(i);
String style = styles.get(i);
if (t.startsWith("[[") && t.endsWith("]]")) {
String explanation = "[[...]] denotes a multi-line string constant (as in Lua)";
out.append(dottedSpan("[[", explanation));
String inner = htmlencode(dropPrefix("[[", dropSuffix("]]", t)));
out.append(span(inner, "style" , "background-color: #77FF77"));
out.append(dottedSpan("]]", explanation));
continue;
}
if (t.startsWith("[=[") && t.endsWith("]=]")) {
String explanation = "[=[...]=] denotes a multi-line string constant (as in Lua)";
out.append(dottedSpan("[=[", explanation));
String inner = htmlencode(dropPrefix("[=[", dropSuffix("]=]", t)));
out.append(span(inner, "style" , "background-color: #77FF77"));
out.append(dottedSpan("]=]", explanation));
continue;
}
String enc = htmlencode(t);
out.append(id != null
? ahref(makeLink(real, id), enc,
"title" , isSnippetID(id) ? titles.get(fsI(id)) : ex, "style" , "text-decoration: none; color: black; border-bottom: dotted 1px", "target" , targetBlank ? "_blank" : null)
: ex != null ? dottedSpan(enc, ex)
: style != null ? span(enc, "style", style)
: enc);
}
String html = str(out);
html = dynamize_noEncode(html);
return html;
}
// id can be a URL
String makeLink(boolean real, String id) {
if (isRelativeOrAbsoluteURL(id)) return id;
if (real)
return longSnippetLink(id);
return "/" + psI(id);
}
void clearCaches() {
stdFunctions_clearCache();
sc = standardClassesMap();
sf = stdFunctions_cached();
//sf.putAll(tok_findStandardFunctionDefinitions(javaTokSnippet(#1022367)));
}
boolean isMechFunction(String s) {
return startsWithOneOf(s, "mech", "mL");
}
void tokensToColors(List tok, Map styles) {
for (int i = 0; i < l(tok); i += 2)
if (tok_whitespaceContainsJavaComments(tok.get(i)))
styles.put(i, "color: #666666");
}
void addExplainer(IVF1 explainer) {
explainers.add(explainer);
}
}
static Explain explain(String input, String rules, String className) {
Object parseResult = parse1(input, rules);
List e = (List) (call(parseResult, "explain", className));
if (e == null) return null;
return new Explain(parseResult, e);
}
static HashMap litmap(Object... x) {
HashMap map = new HashMap();
litmap_impl(map, x);
return map;
}
static void litmap_impl(Map map, Object... x) {
if (x != null) for (int i = 0; i < x.length-1; i += 2)
if (x[i+1] != null)
map.put(x[i], x[i+1]);
}
static NotTooOften nto_mins(double minutes) {
return new NotTooOften(minutes*60);
}
static StringTree2 stringTree2_javaTok(Map entries) {
StringTree2 tree = new StringTree2();
for (String key : keys(entries))
addToStringTree(tree, javaTokC(key), entries.get(key));
return tree;
}
// TODO: extended multi-line strings
static int javaTok_n, javaTok_elements;
static boolean javaTok_opt = false;
static List javaTok(String s) {
++javaTok_n;
ArrayList tok = new ArrayList();
int l = s == null ? 0 : s.length();
int i = 0;
while (i < l) {
int j = i;
char c, d;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
d = j+1 >= l ? '\0' : s.charAt(j+1);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (c == '/' && d == '*') {
do ++j; while (j < l && !regionMatches(s, j, "*/"));
j = Math.min(j+2, l);
} else if (c == '/' && d == '/') {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
tok.add(javaTok_substringN(s, i, j));
i = j;
if (i >= l) break;
c = s.charAt(i);
d = i+1 >= l ? '\0' : s.charAt(i+1);
// scan for non-whitespace
// Special JavaX syntax: 'identifier
if (c == '\'' && Character.isJavaIdentifierStart(d) && i+2 < l && "'\\".indexOf(s.charAt(i+2)) < 0) {
j += 2;
while (j < l && Character.isJavaIdentifierPart(s.charAt(j)))
++j;
} else if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
int c2 = s.charAt(j);
if (c2 == opener || c2 == '\n' && opener == '\'') { // allow multi-line strings, but not for '
++j;
break;
} else if (c2 == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || s.charAt(j) == '\'')); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (c == '[' && d == '[') {
do ++j; while (j < l && !regionMatches(s, j, "]]"));
j = Math.min(j+2, l);
} else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !regionMatches(s, j, "]=]"));
j = Math.min(j+3, l);
} else
++j;
tok.add(javaTok_substringC(s, i, j));
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
javaTok_elements += tok.size();
return tok;
}
static List javaTok(List tok) {
return javaTokWithExisting(join(tok), tok);
}
static void putMultipleKeys(Map map, Collection keys, B value) {
if (map == null || keys == null) return;
for (A key : keys)
map.put(key, value);
}
static List allPlus(final int x, List l) {
return map(l, new F1() { public Integer get(Integer i) { try { return i+x; } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "i+x"; }});
}
static List jfindAll(List tok, String pat) { return jfindAll(tok, pat, null); }
static List jfindAll(List tok, String pat, ITokCondition condition) {
return jfindAll(tok, jfind_preprocess(javaTok(pat)), condition);
}
// tokPat must be jfind_preprocess'd
static List jfindAll(List tok, List tokPat) { return jfindAll(tok, tokPat, null); }
static List jfindAll(List tok, List tokPat, ITokCondition condition) {
TokCondition cond = toTokCondition(condition);
String[] toks = toStringArray(codeTokensOnly(tokPat));
int i = -1;
List l = new ArrayList();
while ((i = findCodeTokens(tok, i+1, false, toks, cond)) >= 0)
l.add(i);
return l;
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(short[] a) { return a == null ? 0 : a.length; }
static int l(long[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(double[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Iterator i) { return iteratorCount_int_close(i); } // consumes the iterator && closes it if possible
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static long l(File f) { return f == null ? 0 : f.length(); }
static int l(IMultiMap mm) { return mm == null ? 0 : mm.size(); }
static int l(IntSize o) { return o == null ? 0 : o.size(); }
// get purpose 1: access a list/array/map (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
// seems to conflict with other signatures
/*static B get(Map map, A key) {
ret map != null ? map.get(key) : null;
}*/
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o == null) return null;
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
makeAccessible(f);
return f.get(o);
}
if (o instanceof DynamicObject)
return getOptDynOnly(((DynamicObject) o), field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(String field, Object o) {
return get_raw(o, field);
}
static Object get_raw(Object o, String field) { try {
if (o == null) return null;
Field f = get_findField(o.getClass(), field);
makeAccessible(f);
return f.get(o);
} catch (Exception __e) { throw rethrow(__e); } }
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
makeAccessible(f);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
static Object get(String field, Object o) {
return get(o, field);
}
static boolean get(BitSet bs, int idx) {
return bs != null && bs.get(idx);
}
static void pcallFAll(Collection l, Object... args) {
if (l != null) for (Object f : cloneList(l)) pcallF(f, args);
}
static void pcallFAll(Iterator it, Object... args) {
while (it.hasNext()) pcallF(it.next(), args);
}
static boolean eq(Object a, Object b) {
return a == b || a != null && b != null && a.equals(b);
}
// a little kludge for stuff like eq(symbol, "$X")
static boolean eq(Symbol a, String b) {
return eq(str(a), b);
}
static boolean isIdentifier(String s) {
return isJavaIdentifier(s);
}
static void mapPut(Map map, A key, B value) {
if (map != null && key != null && value != null) map.put(key, value);
}
static void mapPut(Map map, Pair p) {
if (map != null && p != null) map.put(p.a, p.b);
}
static boolean startsWith(String a, String b) {
return a != null && a.startsWith(unnull(b));
}
static boolean startsWith(String a, char c) {
return nemptyString(a) && a.charAt(0) == c;
}
static boolean startsWith(String a, String b, Matches m) {
if (!startsWith(a, b)) return false;
if (m != null) m.m = new String[] {substring(a, strL(b))};
return true;
}
static boolean startsWith(List a, List b) {
if (a == null || listL(b) > listL(a)) return false;
for (int i = 0; i < listL(b); i++)
if (neq(a.get(i), b.get(i)))
return false;
return true;
}
static boolean isInteger(String s) {
int n = l(s);
if (n == 0) return false;
int i = 0;
if (s.charAt(0) == '-')
if (++i >= n) return false;
while (i < n) {
char c = s.charAt(i);
if (c < '0' || c > '9') return false;
++i;
}
return true;
}
static boolean eqOneOf(Object o, Object... l) {
if (l != null) for (Object x : l) if (eq(o, x)) return true; return false;
}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
// supports the usual quotings (", variable length double brackets) except ' quoting
static boolean isQuoted(String s) {
if (isNormalQuoted(s)) return true; // use the exact version
return isMultilineQuoted(s);
}
static List tok_subListWithoutBorderNTokens(List tok, int i, int j) {
List tok2 = cloneSubList(tok, i & (~1), j | 1);
tok2.set(0, "");
tok2.set(l(tok2)-1, "");
return tok2;
}
static String tok_expandIfQuoted(String s) { return applyTranspilationFunction(__23 -> tok_expandIfQuoted(__23), s); }
static void tok_expandIfQuoted(List tok) {
jreplace(tok, "if || ",
"if (matchOneOf(s, m, $2, $5))");
// "bla * bla | blubb * blubb"
jreplace_dyn(tok, "if ", new F2, Integer, String>() { public String get(List tok, Integer cIdx) { try {
String s = unquote(tok.get(cIdx+2));
//print("multimatch: " + quote(s));
List l = new ArrayList();
for (String pat : splitAtJavaToken(s, "|")) {
//print("multimatch part: " + quote(pat));
if (pat.contains("..."))
l.add("matchX(" + quote(trim(pat)) + ", s, m)");
else if (javaTok(pat).contains("*"))
l.add("match(" + quote(trim(pat)) + ", s, m)");
else
l.add("match(" + quote(trim(pat)) + ", s)");
}
return "if (" + join(" || ", l) + ")";
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "S s = unquote(tok.get(cIdx+2));\r\n //print(\"multimatch: \" + quote(s));\r\n ..."; }}, new TokCondition() { public boolean get(final List tok, final int i) {
return javaTokC(unquote(tok.get(i+3))).contains("|");
}});
tok_transpileIfQuoted_dollarVars(tok);
// "...bla..."
jreplace(tok, "if ", "if (find3plusRestsX($2, s, m))",
new TokCondition() { public boolean get(final List tok, final int i) {
return startsAndEndsWith(unquote(tok.get(i+3)), "...");
}});
// "bla..."
jreplace(tok, "if ", "if (matchStartX($2, s, m))",
new TokCondition() { public boolean get(final List tok, final int i) {
return unquote(tok.get(i+3)).endsWith("...");
}});
// "bla"
jreplace(tok, "if ", "if (match($2, s))",
new TokCondition() { public boolean get(final List tok, final int i) {
return !javaTokC(unquote(tok.get(i+3))).contains("*");
}});
// "bla * bla"
jreplace(tok, "if ", "if (match($2, s, m))");
jreplace(tok, "if match ", "if (match($3, s, m))");
}
public static String join(String glue, Iterable strings) {
if (strings == null) return "";
if (strings instanceof Collection) {
if (((Collection) strings).size() == 1) return strOrEmpty(first((Collection) strings));
}
StringBuilder buf = new StringBuilder();
Iterator i = strings.iterator();
if (i.hasNext()) {
buf.append(strOrEmpty(i.next()));
while (i.hasNext())
buf.append(glue).append(strOrEmpty(i.next()));
}
return buf.toString();
}
public static String join(String glue, String... strings) {
return join(glue, Arrays.asList(strings));
}
public static String join(String glue, Object... strings) {
return join(glue, Arrays.asList(strings));
}
static String join(Iterable strings) {
return join("", strings);
}
static String join(Iterable strings, String glue) {
return join(glue, strings);
}
public static String join(String[] strings) {
return join("", strings);
}
static String join(String glue, Pair p) {
return p == null ? "" : str(p.a) + glue + str(p.b);
}
static void pcallFail(Throwable e) {
pcallPolicyForThread().handlePcallFail(e);
}
static void pcallFail(String msg) {
pcallFail(new Throwable(msg));
}
static void doublePut(Map map, A key1, A key2, B value) {
map.put(key1, value);
map.put(key2, value);
}
static boolean isSingleQuoteIdentifier(String s) {
if (l(s) < 2 || s.charAt(0) != '\'' || !Character.isJavaIdentifierStart(s.charAt(1))) return false;
for (int i = 2; i < l(s); i++)
if (!Character.isJavaIdentifierPart(s.charAt(i))) return false;
return true;
}
static String quote(Object o) {
if (o == null) return "null";
return quote(str(o));
}
static String quote(String s) {
if (s == null) return "null";
StringBuilder out = new StringBuilder((int) (l(s)*1.5+2));
quote_impl(s, out);
return out.toString();
}
static void quote_impl(String s, StringBuilder out) {
out.append('"');
int l = s.length();
for (int i = 0; i < l; i++) {
char c = s.charAt(i);
if (c == '\\' || c == '"')
out.append('\\').append(c);
else if (c == '\r')
out.append("\\r");
else if (c == '\n')
out.append("\\n");
else if (c == '\t')
out.append("\\t");
else if (c == '\0')
out.append("\\0");
else
out.append(c);
}
out.append('"');
}
static String fromSingleQuoteIdentifier(String s) {
return isSingleQuoteIdentifier(s) ? substring(s, 1) : s;
}
static boolean tok_tokenBeforeLonelyReturnValue(List tok, int i) {
String t = get(tok, i);
if (l(t) == 1 && "{};".contains(t) || eq(t, "else")) return true;
if (!eq(t, ")")) return false;
int level = 0;
while (i > 0) {
if (eq(tok.get(i), ")")) ++level;
if (eq(tok.get(i), "(")) --level;
if (level == 0) return eq(get(tok, i-2), "if");
i -= 2;
}
return false;
}
static boolean eqGet(List l, int i, Object o) {
return eq(get(l, i), o);
}
static boolean eqGet(Map map, A key, Object o) {
return eq(mapGet(map, key), o);
}
static List codeTokens(List tok) {
return codeTokensOnly(tok);
}
static List subList(List l, int startIndex) {
return subList(l, startIndex, l(l));
}
static List subList(int startIndex, List l) {
return subList(l, startIndex);
}
static List subList(int startIndex, int endIndex, List l) {
return subList(l, startIndex, endIndex);
}
static List subList(List l, int startIndex, int endIndex) {
if (l == null) return null;
int n = l(l);
startIndex = Math.max(0, startIndex);
endIndex = Math.min(n, endIndex);
if (startIndex > endIndex) return ll();
if (startIndex == 0 && endIndex == n) return l;
return l.subList(startIndex, endIndex);
}
static Pair stringTreeLeafValue2(StringTree2 tree, List items) {
int i = 0;
while (tree != null && i < l(items)) {
if (tree.leafValue != null)
return pair(tree.leafValue, i);
tree = tree.children.get(items.get(i));
++i;
}
return null;
}
static void mapPutInRange(Map map, int start, int end, A value) {
if (map != null && value != null)
for (int i = start; i < end; i++)
map.put(i, value);
}
static String neatMechListURL(String listName) {
return "http://botcompany.de/mech/raw/list/" + urlencode(listName);
}
static String unquote(String s) {
if (s == null) return null;
if (startsWith(s, '[')) {
int i = 1;
while (i < s.length() && s.charAt(i) == '=') ++i;
if (i < s.length() && s.charAt(i) == '[') {
String m = s.substring(1, i);
if (s.endsWith("]" + m + "]"))
return s.substring(i+1, s.length()-i-1);
}
}
return unquoteSingleOrDoubleQuotes(s);
}
static boolean getSnippetTitles_verbose = false;
static Map getSnippetTitles(Collection ids) { try {
if (empty(ids)) return new HashMap();
String url = tb_mainServer() + "/tb-int/get-titles.php";
String ids2 = join(" ", parseSnippetIDs(ids));
return trimValues(transformKeys(jsonDecodeMap(
doPost(mapPlus(standardCredentialsMap(), "ids" , ids2),
url)), new F1() { public Object get(String id) { try { return fsI(id); } catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "fsI(id)"; }}));
} catch (Exception __e) { throw rethrow(__e); } }
static List filter(Iterable c, Object pred) {
if (pred instanceof F1) return filter(c, (F1 ) pred);
List x = new ArrayList();
if (c != null) for (Object o : c)
if (isTrue(callF(pred, o)))
x.add(o);
return x;
}
static List filter(Object pred, Iterable c) {
return filter(c, pred);
}
static List filter(Iterable c, F1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(F1 pred, Iterable c) {
return filter(c, pred);
}
//ifclass IF1
static List filter(Iterable c, IF1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(B[] c, IF1 pred) {
List x = new ArrayList();
if (c != null) for (B o : c)
if (pred.get(o))
x.add(o);
return x;
}
static List filter(IF1 pred, Iterable c) {
return filter(c, pred);
}
//endif
public static boolean isSnippetID(String s) {
try {
parseSnippetID(s);
return true;
} catch (RuntimeException e) {
return false;
}
}
static Collection values(Map map) {
return map == null ? emptyList() : map.values();
}
// convenience shortcut for values_gen
static Collection values(Object map) {
return values((Map) map);
}
static Collection values(MultiMap mm) {
return mm == null ? emptyList() : concatLists(values(mm.data));
}
static boolean empty(Collection c) { return c == null || c.isEmpty(); }
static boolean empty(Iterable c) { return c == null || !c.iterator().hasNext(); }
static boolean empty(CharSequence s) { return s == null || s.length() == 0; }
static boolean empty(Map map) { return map == null || map.isEmpty(); }
static boolean empty(Object[] o) { return o == null || o.length == 0; }
static boolean empty(BitSet bs) { return bs == null || bs.isEmpty(); }
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
if (o instanceof byte[]) return empty((byte[]) o);
if (o == null) return true;
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(Iterator i) { return i == null || !i.hasNext(); }
static boolean empty(double[] a) { return a == null || a.length == 0; }
static boolean empty(float[] a) { return a == null || a.length == 0; }
static boolean empty(int[] a) { return a == null || a.length == 0; }
static boolean empty(long[] a) { return a == null || a.length == 0; }
static boolean empty(byte[] a) { return a == null || a.length == 0; }
static boolean empty(short[] a) { return a == null || a.length == 0; }
static boolean empty(IMultiMap mm) { return mm == null || mm.size() == 0; }
static boolean empty(File f) { return getFileSize(f) == 0; }
static boolean empty(Rect r) { return !(r != null && r.w != 0 && r.h != 0); }
static boolean empty(Chain c) { return c == null; }
static boolean empty(AppendableChain c) { return c == null; }
static boolean empty(IntSize l) { return l == null || l.size() == 0; }
static String dottedSpan(String contents, String title) {
return span(contents, "title", title, "style" , "border-bottom: dotted 1px");
}
static String htmlencode(Object o) {
return htmlencode(str(o));
}
static String htmlencode(String s) {
if (s == null) return "";
StringBuilder out = new StringBuilder(Math.max(16, s.length()));
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c > 127 || c == '"' || c == '<' || c == '>' || c == '&') {
int cp = s.codePointAt(i);
out.append("");
out.append(intToHex_flexLength(cp));
out.append(';');
i += Character.charCount(cp)-1;
} else
out.append(c);
}
return out.toString();
}
static String dropPrefix(String prefix, String s) {
return s == null ? null : s.startsWith(prefix) ? s.substring(l(prefix)) : s;
}
static String dropSuffix(String suffix, String s) {
return nempty(suffix) && endsWith(s, suffix) ? s.substring(0, l(s)-l(suffix)) : s;
}
static String span(Object contents, Object... params) {
return hfulltag("span", contents, params);
}
static String span() {
return span("");
}
static String ahref(String link, Object contents, Object... params) {
return link == null ? str(contents) : href(link, contents, params);
}
static String fsI(String id) {
return formatSnippetID(id);
}
static String fsI(long id) {
return formatSnippetID(id);
}
static String str(Object o) {
return o == null ? "null" : o.toString();
}
static String str(char[] c) {
return c == null ? "null" : new String(c);
}
static String str(char[] c, int offset, int count) {
return new String(c, offset, count);
}
static ThreadLocal dynamize_linkParams = new ThreadLocal();
static String dynamize_noEncode(String html) {
List tok = htmlTok(html);
Pattern p = Pattern.compile(regexp_findSnippetIDs());
for (int i = 0; i < l(tok); i += 2) {
Matcher m = p.matcher(tok.get(i).replace("", "&~~~"));
StringBuffer buf = new StringBuffer();
while (m.find()) {
String id = m.group(1);
String link = m.group();
try {
link = ahref(snippetLink(id), link,
concatArrays(new Object[] {"title" , getSnippetTitle_cached(id)}, dynamize_linkParams.get()));
} catch (Throwable __e) { pcallFail(__e); }
mreplace(m, buf, link);
}
m.appendTail(buf);
String s = str(buf).replace("&~~~", "");
tok.set(i, s);
}
dynamize_linkParams.set(null);
return join(tok);
}
static boolean isRelativeOrAbsoluteURL(String s) {
return isAbsoluteURL(s) || isRelativeURL(s);
}
static String longSnippetLink(String id) {
return tb_mainServer() + "/tb/show-snippet.php?id=" + parseSnippetID(id);
}
static long psI(String snippetID) {
return parseSnippetID(snippetID);
}
static Map stdFunctions_cached_map; // name -> snippet ID
static Lock stdFunctions_cached_lock = lock();
static Map stdFunctions_cached() {
Lock __0 = stdFunctions_cached_lock; lock(__0); try {
if (stdFunctions_cached_map == null)
stdFunctions_cached_map = stdFunctions_uncached();
return stdFunctions_cached_map;
} finally { unlock(__0); } }
static synchronized void stdFunctions_clearCache() {
stdFunctions_cached_map = null;
}
// name -> id
static Map standardClassesMap() {
return standardClassesMap_uncached();
}
static boolean startsWithOneOf(String s, String... l) {
for (String x : l) if (startsWith(s, x)) return true; return false;
}
static boolean startsWithOneOf(String s, Matches m, String... l) {
for (String x : l) if (startsWith(s, x, m)) return true; return false;
}
static boolean tok_whitespaceContainsJavaComments(String s) {
int l = l(s)-1;
for (int j = 0; j < l; j++)
if (s.charAt(j) == '/') {
char d = s.charAt(j+1);
if (d == '*' || d == '/') return true;
}
return false;
}
static Object parse1_parser;
static Object parse1(String text, String rules) {
return parse1(javaTok(text), rules);
}
// only parse, no explain
static synchronized Object parse1(List tok, String rules) {
if (parse1_parser == null)
parse1_parser = run_overBot(/*"#1002472"*/ "#1002719");
//setOpt(parse1_parser, "debug", true);
return call(parse1_parser, "parse", tok, rules);
}
static Object call(Object o) {
return callF(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
//ret call_cached(o, method, args);
return call_withVarargs(o, method, args);
}
static Set keys(Map map) {
return map == null ? new HashSet() : map.keySet();
}
// convenience shortcut for keys_gen
static Set keys(Object map) {
return keys((Map) map);
}
static Set keys(IMultiMap mm) {
return mm.keySet();
}
static void addToStringTree(StringTree2 tree, List tokC, A leafValue) {
if (leafValue == null) return;
if (empty(tokC)) { tree.leafValue = leafValue; return; }
String s = first(tokC);
StringTree2 t = tree.getOrAdd(s);
addToStringTree(t, dropFirst(tokC), leafValue);
}
static List javaTokC(String s) {
if (s == null) return null;
int l = s.length();
ArrayList tok = new ArrayList();
int i = 0;
while (i < l) {
int j = i;
char c, d;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
d = j+1 >= l ? '\0' : s.charAt(j+1);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (c == '/' && d == '*') {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (c == '/' && d == '/') {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
i = j;
if (i >= l) break;
c = s.charAt(i);
d = i+1 >= l ? '\0' : s.charAt(i+1);
// scan for non-whitespace
if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener || s.charAt(j) == '\n') { // end at \n to not propagate unclosed string literal errors
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (c == '[' && d == '[') {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
tok.add(javaTok_substringC(s, i, j));
i = j;
}
return tok;
}
static boolean regionMatches(String a, int offsetA, String b, int offsetB, int len) {
return a != null && b != null && a.regionMatches(offsetA, b, offsetB, len);
}
static boolean regionMatches(String a, int offsetA, String b) {
return regionMatches(a, offsetA, b, 0, l(b));
}
static String javaTok_substringN(String s, int i, int j) {
if (i == j) return "";
if (j == i+1 && s.charAt(i) == ' ') return " ";
return s.substring(i, j);
}
static String javaTok_substringC(String s, int i, int j) {
return s.substring(i, j);
}
static List javaTokWithExisting(String s, List existing) {
++javaTok_n;
int nExisting = javaTok_opt && existing != null ? existing.size() : 0;
ArrayList tok = existing != null ? new ArrayList(nExisting) : new ArrayList();
int l = s.length();
int i = 0, n = 0;
while (i < l) {
int j = i;
char c, d;
// scan for whitespace
while (j < l) {
c = s.charAt(j);
d = j+1 >= l ? '\0' : s.charAt(j+1);
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
++j;
else if (c == '/' && d == '*') {
do ++j; while (j < l && !s.substring(j, Math.min(j+2, l)).equals("*/"));
j = Math.min(j+2, l);
} else if (c == '/' && d == '/') {
do ++j; while (j < l && "\r\n".indexOf(s.charAt(j)) < 0);
} else
break;
}
if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j))
tok.add(existing.get(n));
else
tok.add(javaTok_substringN(s, i, j));
++n;
i = j;
if (i >= l) break;
c = s.charAt(i);
d = i+1 >= l ? '\0' : s.charAt(i+1);
// scan for non-whitespace
// Special JavaX syntax: 'identifier
if (c == '\'' && Character.isJavaIdentifierStart(d) && i+2 < l && "'\\".indexOf(s.charAt(i+2)) < 0) {
j += 2;
while (j < l && Character.isJavaIdentifierPart(s.charAt(j)))
++j;
} else if (c == '\'' || c == '"') {
char opener = c;
++j;
while (j < l) {
if (s.charAt(j) == opener /*|| s.charAt(j) == '\n'*/) { // allow multi-line strings
++j;
break;
} else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
}
} else if (Character.isJavaIdentifierStart(c))
do ++j; while (j < l && (Character.isJavaIdentifierPart(s.charAt(j)) || "'".indexOf(s.charAt(j)) >= 0)); // for stuff like "don't"
else if (Character.isDigit(c)) {
do ++j; while (j < l && Character.isDigit(s.charAt(j)));
if (j < l && s.charAt(j) == 'L') ++j; // Long constants like 1L
} else if (c == '[' && d == '[') {
do ++j; while (j+1 < l && !s.substring(j, j+2).equals("]]"));
j = Math.min(j+2, l);
} else if (c == '[' && d == '=' && i+2 < l && s.charAt(i+2) == '[') {
do ++j; while (j+2 < l && !s.substring(j, j+3).equals("]=]"));
j = Math.min(j+3, l);
} else
++j;
if (n < nExisting && javaTokWithExisting_isCopyable(existing.get(n), s, i, j))
tok.add(existing.get(n));
else
tok.add(javaTok_substringC(s, i, j));
++n;
i = j;
}
if ((tok.size() % 2) == 0) tok.add("");
javaTok_elements += tok.size();
return tok;
}
static boolean javaTokWithExisting_isCopyable(String t, String s, int i, int j) {
return t.length() == j-i
&& s.regionMatches(i, t, 0, j-i); // << could be left out, but that's brave
}
static List map(Iterable l, Object f) { return map(f, l); }
static List map(Object f, Iterable l) {
List x = emptyList(l);
if (l != null) for (Object o : l)
{ ping(); x.add(callF(f, o)); }
return x;
}
// map: func(key, value) -> list element
static List map(Map map, Object f) {
List x = new ArrayList();
if (map != null) for (Object _e : map.entrySet()) { ping();
Map.Entry e = (Map.Entry) _e;
x.add(callF(f, e.getKey(), e.getValue()));
}
return x;
}
static List map(Object f, Object[] l) { return map(f, asList(l)); }
static List map(Object[] l, Object f) { return map(f, l); }
static List map(Object f, Map map) {
return map(map, f);
}
static List map(Iterable l, F1 f) { return map(f, l); }
static List map(F1 f, Iterable l) {
List x = emptyList(l);
if (l != null) for (A o : l)
{ ping(); x.add(callF(f, o)); }
return x;
}
static List map(IF1 f, Iterable l) { return map(l, f); }
static List map(Iterable l, IF1 f) {
List x = emptyList(l);
if (l != null) {
var it = l.iterator();
if (it.hasNext()) {
var pingSource = pingSource();
do {
ping(pingSource);
x.add(f.get(it.next()));
} while (it.hasNext());
}
}
return x;
}
static List map(IF1 f, A[] l) { return map(l, f); }
static List map(A[] l, IF1 f) {
List x = emptyList(l);
if (l != null) for (A o : l)
{ ping(); x.add(f.get(o)); }
return x;
}
static List map(Map map, IF2 f) {
List x = new ArrayList();
if (map != null) for (Map.Entry e : map.entrySet()) { ping();
x.add(f.get(e.getKey(), e.getValue()));
}
return x;
}
// new magic alias for mapLL - does it conflict?
static List map(IF1 f, A data1, A... moreData) {
List x = emptyList(l(moreData)+1);
x.add(f.get(data1));
if (moreData != null) for (A o : moreData)
{ ping(); x.add(f.get(o)); }
return x;
}
static RuntimeException rethrow(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
throw t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static RuntimeException rethrow(String msg, Throwable t) {
throw new RuntimeException(msg, t);
}
static int jfind(String s, String in) {
return jfind(javaTok(s), in);
}
static int jfind(List tok, String in) {
return jfind(tok, 1, in);
}
static int jfind(List tok, int startIdx, String in) {
return jfind(tok, startIdx, in, (ITokCondition) null);
}
static int jfind(List tok, String in, Object condition) {
return jfind(tok, 1, in, condition);
}
static int jfind(List tok, String in, IIntPred condition) { return jfind(tok, 1, in, condition); }
static int jfind(List tok, int startIndex, String in, IIntPred condition) {
return jfind(tok, startIndex, in, tokCondition(condition));
}
static int jfind(List tok, String in, ITokCondition condition) { return jfind(tok, 1, in, condition); }
static int jfind(List tok, int startIndex, String in, ITokCondition condition) {
return jfind(tok, startIndex, in, (Object) condition);
}
static int jfind(List tok, int startIdx, String in, Object condition) {
//LS tokin = jfind_preprocess(javaTok(in));
return jfind(tok, startIdx, javaTokForJFind_array(in), condition);
}
// assumes you preprocessed tokin
static int jfind(List tok, List tokin) {
return jfind(tok, 1, tokin);
}
static int jfind(List tok, int startIdx, List tokin) {
return jfind(tok, startIdx, tokin, null);
}
static int jfind(List tok, int startIdx, String[] tokinC, Object condition) {
return findCodeTokens(tok, startIdx, false, tokinC, condition);
}
static int jfind(List tok, int startIdx, List tokin, Object condition) {
return jfind(tok, startIdx, codeTokensAsStringArray(tokin), condition);
}
static List jfind_preprocess(List tok) {
for (String type : litlist("quoted", "id", "int"))
replaceSublist(tok, ll("<", "", type, "", ">"), ll("<" + type + ">"));
replaceSublist(tok, ll("\\", "", "*"), ll("\\*"));
return tok;
}
static TokCondition toTokCondition(ITokCondition condition) {
return condition == null ? null : condition instanceof TokCondition ? (TokCondition) condition : new TokCondition() {
public boolean get(List tok, int i) {
return condition.get(tok, i);
}
};
}
static String[] toStringArray(Collection c) {
String[] a = new String[l(c)];
Iterator it = c.iterator();
for (int i = 0; i < l(a); i++)
a[i] = it.next();
return a;
}
static String[] toStringArray(Object o) {
if (o instanceof String[])
return (String[]) o;
else if (o instanceof Collection)
return toStringArray((Collection) o);
else
throw fail("Not a collection or array: " + getClassName(o));
}
static List codeTokensOnly(List tok) {
int n = l(tok);
List l = emptyList(n/2);
for (int i = 1; i < n; i += 2)
l.add(tok.get(i));
return l;
}
static int findCodeTokens(List tok, String... tokens) {
return findCodeTokens(tok, 1, false, tokens);
}
static int findCodeTokens(List tok, boolean ignoreCase, String... tokens) {
return findCodeTokens(tok, 1, ignoreCase, tokens);
}
static int findCodeTokens(List tok, int startIdx, boolean ignoreCase, String... tokens) {
return findCodeTokens(tok, startIdx, ignoreCase, tokens, null);
}
static HashSet findCodeTokens_specials = lithashset("*", "", "", "", "\\*");
static int findCodeTokens_bails, findCodeTokens_nonbails;
static interface findCodeTokens_Matcher {
boolean get(String token);
}
static int findCodeTokens(List tok, int startIdx, boolean ignoreCase, String[] tokens, Object condition) {
int end = tok.size()-tokens.length*2+2, nTokens = tokens.length;
int i = startIdx | 1;
findCodeTokens_Matcher[] matchers = new findCodeTokens_Matcher[nTokens];
IContentsIndexedList2 indexedList = tok instanceof IContentsIndexedList2 ? (IContentsIndexedList2) tok : null;
TreeSet indices = null;
int indicesOfs = 0;
for (int j = 0; j < nTokens; j++) {
String p = tokens[j];
findCodeTokens_Matcher matcher;
if (p.equals("*"))
matcher = t -> true;
else if (p.equals(""))
matcher = t -> isQuoted(t);
else if (p.equals(""))
matcher = t -> isIdentifier(t);
else if (p.equals(""))
matcher = t -> isInteger(t);
else if (p.equals("\\*"))
matcher = t -> t.equals("*");
else if (ignoreCase)
matcher = t -> eqic(p, t);
else {
matcher = t -> t.equals(p);
if (indexedList != null) {
TreeSet indices2 = indexedList.indicesOf_treeSetOfHasIndex(p);
if (indices2 == null) return -1;
if (indices == null || indices2.size() < indices.size()) {
// found shorter list
indices = indices2;
indicesOfs = j;
}
}
}
matchers[j] = matcher;
}
// go over shortest index
if (indices != null) {
int min = i+indicesOfs*2;
SortedSet tailSet = min == 1 ? indices : indices.tailSet(new HasIndex(min));
outer: for (HasIndex h : tailSet) {
int idx = h.idx-indicesOfs*2;
if (idx >= end) break;
for (int j = 0; j < nTokens; j++) try {
if (!matchers[j].get(tok.get(idx+j*2)))
continue outer;
} catch (IndexOutOfBoundsException e) {
print("fct indicesOfs=" + indicesOfs + ", h=" + h + ", idx=" + idx);
throw e;
}
if (condition == null || checkTokCondition(condition, tok, idx-1))
return idx;
}
return -1;
}
outer: for (; i < end; i += 2) {
for (int j = 0; j < nTokens; j++)
if (!matchers[j].get(tok.get(i+j*2)))
continue outer;
if (condition == null || checkTokCondition(condition, tok, i-1)) // pass N index
return i;
}
return -1;
}
static int iteratorCount_int_close(Iterator i) { try {
int n = 0;
if (i != null) while (i.hasNext()) { i.next(); ++n; }
if (i instanceof AutoCloseable) ((AutoCloseable) i).close();
return n;
} catch (Exception __e) { throw rethrow(__e); } }
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field makeAccessible(Field f) {
try {
f.setAccessible(true);
} catch (Throwable e) {
// Note: The error reporting only works with Java VM option --illegal-access=deny
vmBus_send("makeAccessible_error", e, f);
}
return f;
}
static Method makeAccessible(Method m) {
try {
m.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, m);
}
return m;
}
static Constructor makeAccessible(Constructor c) {
try {
c.setAccessible(true);
} catch (Throwable e) {
vmBus_send("makeAccessible_error", e, c);
}
return c;
}
static Object getOptDynOnly(DynamicObject o, String field) {
if (o == null || o.fieldValues == null) return null;
return o.fieldValues.get(field);
}
static RuntimeException asRuntimeException(Throwable t) {
if (t instanceof Error)
_handleError((Error) t);
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static ArrayList cloneList(Iterable l) {
return l instanceof Collection ? cloneList((Collection) l) : asList(l);
}
static ArrayList cloneList(Collection l) {
if (l == null) return new ArrayList();
synchronized(collectionMutex(l)) {
return new ArrayList (l);
}
}
static Object pcallF(Object f, Object... args) {
return pcallFunction(f, args);
}
static A pcallF(F0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static B pcallF(F1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static void pcallF(VF1 f, A a) {
try {
{ if (f != null) f.get(a); }
} catch (Throwable __e) { pcallFail(__e); }
}
static Object pcallF(Runnable r) {
try { { if (r != null) r.run(); } } catch (Throwable __e) { pcallFail(__e); } return null;
}
static A pcallF(IF0 f) {
try { return f == null ? null : f.get(); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static B pcallF(IF1 f, A a) {
try { return f == null ? null : f.get(a); } catch (Throwable __e) { pcallFail(__e); } return null;
}
static boolean isJavaIdentifier(String s) {
if (empty(s) || !Character.isJavaIdentifierStart(s.charAt(0)))
return false;
for (int i = 1; i < s.length(); i++)
if (!Character.isJavaIdentifierPart(s.charAt(i)))
return false;
return true;
}
static String unnull(String s) {
return s == null ? "" : s;
}
static Collection unnull(Collection l) {
return l == null ? emptyList() : l;
}
static List unnull(List l) { return l == null ? emptyList() : l; }
static int[] unnull(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnull(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnull(double[] l) { return l == null ? emptyDoubleArray() : l; }
static float[] unnull(float[] l) { return l == null ? emptyFloatArray() : l; }
static Map unnull(Map l) {
return l == null ? emptyMap() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static A[] unnull(A[] a) {
return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static Pt unnull(Pt p) {
return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnull(Symbol s) {
return s == null ? emptySymbol() : s;
}
//endif
static Pair unnull(Pair p) {
return p != null ? p : new Pair(null, null);
}
static int unnull(Integer i) { return i == null ? 0 : i; }
static long unnull(Long l) { return l == null ? 0L : l; }
static double unnull(Double l) { return l == null ? 0.0 : l; }
static boolean nemptyString(String s) {
return s != null && s.length() > 0;
}
static String substring(String s, int x) {
return substring(s, x, strL(s));
}
static String substring(String s, int x, int y) {
if (s == null) return null;
if (x < 0) x = 0;
int n = s.length();
if (y < x) y = x;
if (y > n) y = n;
if (x >= y) return "";
return s.substring(x, y);
}
// convenience method for quickly dropping a prefix
static String substring(String s, CharSequence l) {
return substring(s, lCharSequence(l));
}
static int strL(String s) {
return s == null ? 0 : s.length();
}
static int listL(Collection l) {
return l == null ? 0 : l.size();
}
static boolean isNormalQuoted(String s) {
int l = l(s);
if (!(l >= 2 && s.charAt(0) == '"' && lastChar(s) == '"')) return false;
int j = 1;
while (j < l)
if (s.charAt(j) == '"')
return j == l-1;
else if (s.charAt(j) == '\\' && j+1 < l)
j += 2;
else
++j;
return false;
}
static boolean isMultilineQuoted(String s) {
if (!startsWith(s, "[")) return false;
int i = 1, n = s.length();
while (i < n && s.charAt(i) == '=') ++i;
return i < n && s.charAt(i) == '[';
}
static List cloneSubList(List l, int startIndex, int endIndex) {
return newSubList(l, startIndex, endIndex);
}
static List cloneSubList(List l, int startIndex) {
return newSubList(l, startIndex);
}
static String applyTranspilationFunction(IVF1> f, String s) {
if (f == null) return s;
List tok = javaTok(s);
f.get(tok);
return join(tok);
}
static String jreplace(String s, String in, String out) {
return jreplace(s, in, out, null);
}
static String jreplace(String s, String in, String out, Object condition) {
List tok = javaTok(s);
return jreplace(tok, in, out, condition) ? join(tok) : s;
}
// leaves tok properly tokenized
// returns true iff anything was replaced
static boolean jreplace(List tok, String in, String out) {
return jreplace(tok, in, out, false, true, null);
}
static boolean jreplace(List tok, String in, String out, Object condition) {
return jreplace(tok, in, out, false, true, condition);
}
static boolean jreplace(List tok, String in, ITokCondition condition, String out) {
return jreplace(tok, in, out, (Object) condition);
}
static boolean jreplace(List tok, String in, String out, IF2, Integer, Boolean> condition) {
return jreplace(tok, in, out, (Object) condition);
}
static boolean jreplace(List tok, String in, String out, boolean ignoreCase, boolean reTok, Object condition) {
String[] toks = javaTokForJFind_array(in);
int lTokin = toks.length*2+1;
boolean anyChange = false;
int i = -1;
for (int n = 0; n < 10000; n++) { // TODO: don't need this check anymore
i = findCodeTokens(tok, i+1, ignoreCase, toks, condition);
if (i < 0)
return anyChange;
List subList = tok.subList(i-1, i+lTokin-1); // N to N
String expansion = jreplaceExpandRefs(out, subList);
int end = i+lTokin-2;
clearAllTokens(tok, i, end); // C to C
tok.set(i, expansion);
if (reTok) // would this ever be false??
reTok(tok, i, end);
i = end;
anyChange = true;
}
throw fail("woot? 10000! " + quote(in) + " => " + quote(out));
}
static boolean jreplace_debug = false;
// out: func(L tok, int cIndex) -> S
// condition: func(L tok, int nIndex) -> S [yeah it's inconsistent]
static String jreplace_dyn(String s, String in, Object out) {
return jreplace_dyn(s, in, out, null);
}
static String jreplace_dyn(String s, String in, Object out, Object condition) {
List tok = javaTok(s);
jreplace_dyn(tok, in, out, condition);
return join(tok);
}
// leaves tok properly tokenized
// returns true iff anything was replaced
static boolean jreplace_dyn(List tok, String in, Object out) {
return jreplace_dyn(tok, in, out, false, true, null);
}
static boolean jreplace_dyn(List tok, String in, IF0 out) {
return jreplace_dyn(tok, in, if0ToIF2(out));
}
static boolean jreplace_dyn(List tok, String in, ITokCondition cond, IF0 out) {
return jreplace_dyn(tok, in, cond, if0ToIF2(out));
}
static boolean jreplace_dyn(List tok, String in, IF1 out) {
return jreplace_dyn(tok, in, (_tok, cIdx) -> out.get(cIdx));
}
static boolean jreplace_dyn(List tok, String in, IF2, Integer, String> out) {
return jreplace_dyn(tok, in, (Object) out);
}
static boolean jreplace_dyn(List tok, String in, IF2, Integer, String> out, IF2, Integer, Boolean> condition) {
return jreplace_dyn(tok, in, (Object) out, (Object) condition);
}
static boolean jreplace_dyn(List tok, String in, Object out, Object condition) {
return jreplace_dyn(tok, in, out, false, true, condition);
}
static boolean jreplace_dyn(List tok, String in, Object out, boolean ignoreCase, boolean reTok, Object condition) {
List tokin = javaTok(in);
jfind_preprocess(tokin);
String[] toks = toStringArray(codeTokensOnly(tokin));
boolean anyChange = false;
for (int n = 0; n < 10000; n++) {
int i = findCodeTokens(tok, 1, ignoreCase, toks, condition);
if (i < 0)
return anyChange;
String expansion = (String) (callF(out, tok, i));
int end = i+l(tokin)-2;
clearAllTokens(tok, i, end); // C to C
tok.set(i, expansion);
if (reTok) // would this ever be false??
reTok(tok, i, end);
anyChange = true;
}
throw fail("woot? 10000! " + quote(in) + " => " + quote(out));
}
static List splitAtJavaToken(String s, String splitToken) {
return splitByJavaToken(s, splitToken);
}
static String trim(String s) { return s == null ? null : s.trim(); }
static String trim(StringBuilder buf) { return buf.toString().trim(); }
static String trim(StringBuffer buf) { return buf.toString().trim(); }
// "i call you $name"
static void tok_transpileIfQuoted_dollarVars(List tok) {
jreplace_dyn(tok, "if ", new F2, Integer, String>() { public String get(List tok, Integer cIdx) { try {
String pat = unquote(tok.get(cIdx+2));
List vars = new ArrayList();
String pat2 = dollarVarsToStars(pat, vars);
int iCurly = cIdx+4;
tok_statementToBlock(tok, iCurly);
tokAppend_reTok(tok, iCurly, joinWithSpace(mapWithIndexStartingAt1(vars,
(i, var) -> ("S " + var + " = $" + i + ";"))));
return ("if (match(" + (quote(pat2)) + ", s, m))");
} catch (Exception __e) { throw rethrow(__e); } }
public String toString() { return "S pat = unquote(tok.get(cIdx+2));\r\n new LS vars;\r\n S pat2 = dollarVarsT..."; }}, new TokCondition() { public boolean get(final List tok, final int i) {
return containsDollarVars(unquote(tok.get(i+3)));
}});
}
static boolean startsAndEndsWith(String a, char c) {
return startsWith(a, c) && endsWith(a, c) && l(a) >= 2;
}
static boolean startsAndEndsWith(String a, String b) {
return startsWith(a, b) && endsWith(a, b) && l(a) >= l(b)*2;
}
static String strOrEmpty(Object o) {
return o == null ? "" : str(o);
}
static Object first(Object list) {
return first((Iterable) list);
}
static A first(List list) {
return empty(list) ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static Pair first(Map map) {
return mapEntryToPair(first(entrySet(map)));
}
static Pair first(MultiMap mm) {
if (mm == null) return null;
var e = first(mm.data.entrySet());
if (e == null) return null;
return pair(e.getKey(), first(e.getValue()));
}
static A first(IterableIterator i) {
return first((Iterator ) i);
}
static A first(Iterator i) {
return i == null || !i.hasNext() ? null : i.next();
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static Character first(String s) { return empty(s) ? null : s.charAt(0); }
static Character first(CharSequence s) { return empty(s) ? null : s.charAt(0); }
static A first(Pair p) {
return p == null ? null : p.a;
}
static Byte first(byte[] l) { return empty(l) ? null : l[0]; }
static Double first(double[] l) { return empty(l) ? null : l[0]; }
static A first(A[] l, IF1 pred) {
return firstThat(l, pred);
}
static A first(Iterable l, IF1 pred) {
return firstThat(l, pred);
}
static A first(IF1 pred, Iterable l) {
return firstThat(pred, l);
}
static A first(AppendableChain a) {
return a == null ? null : a.element;
}
static PCallPolicy pcallPolicyForThread() {
var policy = pcallPolicyForThread_tl().get();
if (policy != null) return policy;
return defaultPCallPolicy();
}
static B mapGet(Map map, A a) {
return map == null || a == null ? null : map.get(a);
}
static B mapGet(A a, Map map) {
return map == null || a == null ? null : map.get(a);
}
static List ll(A... a) {
ArrayList l = new ArrayList(a.length);
if (a != null) for (A x : a) l.add(x);
return l;
}
static Pair pair(A a, B b) {
return new Pair(a, b);
}
static Pair pair(A a) {
return new Pair(a, a);
}
static String urlencode(String x) {
try {
return URLEncoder.encode(unnull(x), "UTF-8");
} catch (UnsupportedEncodingException e) { throw new RuntimeException(e); }
}
static String unquoteSingleOrDoubleQuotes(String s) {
if (s == null) return null;
if (s.length() > 1) {
char c = s.charAt(0);
if (c == '\"' || c == '\'') {
int l = endsWith(s, c) ? s.length()-1 : s.length();
StringBuilder sb = new StringBuilder(l-1);
for (int i = 1; i < l; i++) {
char ch = s.charAt(i);
if (ch == '\\') {
char nextChar = (i == l - 1) ? '\\' : s.charAt(i + 1);
// Octal escape?
if (nextChar >= '0' && nextChar <= '7') {
String code = "" + nextChar;
i++;
if ((i < l - 1) && s.charAt(i + 1) >= '0'
&& s.charAt(i + 1) <= '7') {
code += s.charAt(i + 1);
i++;
if ((i < l - 1) && s.charAt(i + 1) >= '0'
&& s.charAt(i + 1) <= '7') {
code += s.charAt(i + 1);
i++;
}
}
sb.append((char) Integer.parseInt(code, 8));
continue;
}
switch (nextChar) {
case '\"': ch = '\"'; break;
case '\\': ch = '\\'; break;
case 'b': ch = '\b'; break;
case 'f': ch = '\f'; break;
case 'n': ch = '\n'; break;
case 'r': ch = '\r'; break;
case 't': ch = '\t'; break;
case '\'': ch = '\''; break;
// Hex Unicode: u????
case 'u':
if (i >= l - 5) {
ch = 'u';
break;
}
int code = Integer.parseInt(
"" + s.charAt(i + 2) + s.charAt(i + 3)
+ s.charAt(i + 4) + s.charAt(i + 5), 16);
sb.append(Character.toChars(code));
i += 5;
continue;
default:
ch = nextChar; // added by Stefan
}
i++;
}
sb.append(ch);
}
return sb.toString();
}
}
return s; // not quoted - return original
}
static String tb_mainServer_default = "https://code.botcompany.de:9898";
static Object tb_mainServer_override; // func -> S
static String tb_mainServer() {
if (tb_mainServer_override != null) return (String) callF(tb_mainServer_override);
return trim(loadTextFile(tb_mainServer_file(),
tb_mainServer_default));
}
static File tb_mainServer_file() {
return getProgramFile("#1001638", "mainserver.txt");
}
static boolean tb_mainServer_isDefault() {
return eq(tb_mainServer(), tb_mainServer_default);
}
public static List parseSnippetIDs(Collection snippetIDs) {
List l = new ArrayList();
for (String id : snippetIDs)
l.add(str(parseSnippetID(id)));
return l;
}
static Map trimValues(Map map) {
Map map2 = similarEmptyMap(map);
for (A key : keys(map))
map2.put(key, trim(map.get(key)));
return map2;
}
static Map transformKeys(Map map, Object f) {
HashMap m = new HashMap();
for (Object key : keys(map))
m.put(callF(f, key), map.get(key));
return m;
}
static Map jsonDecodeMap(String s) {
Object o = jsonDecode(s);
if (o instanceof List && empty((List) o))
return new HashMap();
if (o instanceof Map)
return (Map) o;
else
throw fail("Not a JSON map: " + s);
}
static ThreadLocal doPost_silently = new ThreadLocal();
static ThreadLocal doPost_timeout = new ThreadLocal();
static ThreadLocal> doPost_extraHeaders = new ThreadLocal();
static String doPost(String url, Map urlParameters) {
return doPost(urlParameters, url);
}
static String doPost(Map urlParameters, String url) {
return doPost(makePostData(urlParameters), url);
}
static String doPost(String urlParameters, String url) { try {
URL _url = new URL(url);
ping();
return doPost(urlParameters, _url.openConnection(), _url);
} catch (Exception __e) { throw rethrow(__e); } }
static String doPost(String urlParameters, URLConnection conn, URL url) { try {
boolean silently = isTrue(optParam(doPost_silently));
Long timeout = optParam(doPost_timeout);
Map extraHeaders = optPar(doPost_extraHeaders);
setHeaders(conn);
for (String key : keys(extraHeaders)) {
conn.setRequestProperty(key, extraHeaders.get(key));
}
int l = lUtf8(urlParameters);
if (!silently)
print("Sending POST request: " + hideCredentials(url) + " (" + l + " bytes)");
// connect and do POST
if (timeout != null) setURLConnectionTimeouts(conn, timeout);
((HttpURLConnection) conn).setRequestMethod("POST");
conn.setDoOutput(true);
conn.setRequestProperty("Content-Length", str(l));
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
writer.write(urlParameters);
writer.flush();
String contents = loadPage_utf8(conn, url, false);
writer.close();
return contents;
} catch (Exception __e) { throw rethrow(__e); } }
static Map mapPlus(Map m, Object... data) {
m = cloneMap(m);
litmap_impl(m, data);
return m;
}
static Map standardCredentialsMap() {
String user = standardCredentialsUser();
String pass = standardCredentialsPass();
if (nempty(user) && nempty(pass))
return litmap("_user" , user, "_pass" , pass);
return litmap();
}
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
if (o instanceof ThreadLocal) // TODO: remove this
return isTrue(((ThreadLocal) o).get());
throw fail(getClassName(o));
}
static boolean isTrue(Boolean b) {
return b != null && b.booleanValue();
}
static Map> callF_cache = newDangerousWeakHashMap();
static A callF(F0 f) {
return f == null ? null : f.get();
}
static B callF(F1 f, A a) {
return f == null ? null : f.get(a);
}
static A callF(IF0 f) {
return f == null ? null : f.get();
}
static B callF(IF1 f, A a) {
return f == null ? null : f.get(a);
}
static B callF(A a, IF1 f) {
return f == null ? null : f.get(a);
}
static C callF(F2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static C callF(IF2 f, A a, B b) {
return f == null ? null : f.get(a, b);
}
static void callF(VF1 f, A a) {
if (f != null) f.get(a);
}
static void callF(A a, IVF1 f) {
if (f != null) f.get(a);
}
static void callF(IVF1 f, A a) {
if (f != null) f.get(a);
}
static Object callF(Runnable r) { { if (r != null) r.run(); } return null; }
static Object callF(Object f, Object... args) {
return safeCallF(f, args);
}
static Object safeCallF(Object f, Object... args) {
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
}
if (f == null) return null;
Class c = f.getClass();
ArrayList methods;
synchronized(callF_cache) {
methods = callF_cache.get(c);
if (methods == null)
methods = callF_makeCache(c);
}
int n = l(methods);
if (n == 0) {
if (f instanceof String)
throw fail("Legacy call: " + f);
throw fail("No get method in " + getClassName(c));
}
if (n == 1) return invokeMethod(methods.get(0), f, args);
for (int i = 0; i < n; i++) {
Method m = methods.get(i);
if (call_checkArgs(m, args, false))
return invokeMethod(m, f, args);
}
throw fail("No matching get method in " + getClassName(c));
}
// used internally
static ArrayList callF_makeCache(Class c) {
ArrayList l = new ArrayList();
Class _c = c;
do {
for (Method m : _c.getDeclaredMethods())
if (m.getName().equals("get")) {
makeAccessible(m);
l.add(m);
}
if (!l.isEmpty()) break;
_c = _c.getSuperclass();
} while (_c != null);
callF_cache.put(c, l);
return l;
}
public static long parseSnippetID(String snippetID) {
long id = Long.parseLong(shortenSnippetID(snippetID));
if (id == 0) throw fail("0 is not a snippet ID");
return id;
}
static ArrayList emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
static ArrayList emptyList(int capacity) {
return new ArrayList(max(0, capacity));
}
// Try to match capacity
static ArrayList emptyList(Iterable l) {
return l instanceof Collection ? emptyList(((Collection) l).size()) : emptyList();
}
static ArrayList emptyList(Object[] l) {
return emptyList(l(l));
}
// get correct type at once
static ArrayList emptyList(Class c) {
return new ArrayList();
}
static List concatLists(Iterable ... lists) {
List l = new ArrayList();
if (lists != null) for (Iterable list : lists)
addAll(l, list);
return l;
}
static List concatLists(Collection extends Iterable > lists) {
List l = new ArrayList();
if (lists != null) for (Iterable list : lists)
addAll(l, list);
return l;
}
static RuntimeException fail() { throw new RuntimeException("fail"); }
static RuntimeException fail(Throwable e) { throw asRuntimeException(e); }
static RuntimeException fail(Object msg) { throw new RuntimeException(String.valueOf(msg)); }
static RuntimeException fail(Object... objects) { throw new Fail(objects); }
static RuntimeException fail(String msg) { throw new RuntimeException(msg == null ? "" : msg); }
static RuntimeException fail(String msg, Throwable innerException) { throw new RuntimeException(msg, innerException); }
static String getType(Object o) {
return getClassName(o);
}
static long getFileSize(String path) {
return path == null ? 0 : new File(path).length();
}
static long getFileSize(File f) {
return f == null ? 0 : f.length();
}
static String intToHex_flexLength(int i) {
return Integer.toHexString(i);
}
static boolean nempty(Collection c) {
return !empty(c);
}
static boolean nempty(CharSequence s) {
return !empty(s);
}
static boolean nempty(Object[] o) { return !empty(o); }
static boolean nempty(byte[] o) { return !empty(o); }
static boolean nempty(int[] o) { return !empty(o); }
static boolean nempty(BitSet bs) { return !empty(bs); }
static boolean nempty(Map m) {
return !empty(m);
}
static boolean nempty(Iterator i) {
return i != null && i.hasNext();
}
static boolean nempty(IMultiMap mm) { return mm != null && mm.size() != 0; }
static boolean nempty(Object o) { return !empty(o); }
static boolean nempty(Rect r) { return r != null && r.w != 0 && r.h != 0; }
static boolean nempty(IntSize l) { return l != null && l.size() != 0; }
static boolean endsWith(String a, String b) {
return a != null && a.endsWith(b);
}
static boolean endsWith(String a, char c) {
return nempty(a) && lastChar(a) == c;
}
static boolean endsWith(String a, String b, Matches m) {
if (!endsWith(a, b)) return false;
m.m = new String[] {dropLast(l(b), a)};
return true;
}
static String hfulltag(String tag) {
return hfulltag(tag, "");
}
static String hfulltag(String tag, Object contents, Object... params) {
return hopeningTag(tag, params) + str(contents) + "" + tag + ">";
}
static String href(String link, Object contents, Object... params) {
if (link == null) return str(contents);
return hfulltag("a", contents, arrayPlus(params, "href", link));
}
static String formatSnippetID(String id) {
return "#" + parseSnippetID(id);
}
static String formatSnippetID(long id) {
return "#" + id;
}
static List htmlTok(String s) {
return htmlcoarsetok(s);
}
static String regexp_findSnippetIDs() {
return "(?:#|\\blib\\s+|(?:^|\\n)\\s*!)([0-9]+)";
}
static String snippetLink(String id) {
return empty(id) ? id : snippetLink(parseSnippetID(id));
}
static String snippetLink(long id) {
return "https://code.botcompany.de/" + id;
}
static Object[] concatArrays(Object[]... arrays) {
int l = 0;
for (Object[] a : arrays) l += l(a);
Object[] x = new Object[l];
int i = 0;
for (Object[] a : arrays) if (a != null) {
System.arraycopy(a, 0, x, i, l(a));
i += l(a);
}
return x;
}
static SnippetTitles getSnippetTitle_cached_cache = new SnippetTitles();
static String getSnippetTitle_cached(String id) {
return getSnippetTitle_cached_cache.get(id);
}
static void getSnippetTitle_cached_put(String id, String title) {
getSnippetTitle_cached_cache.put(id, title);
}
static boolean getSnippetTitle_cached_has(String id) {
return getSnippetTitle_cached_cache.has(id);
}
static String getSnippetTitle_cached_probe(String id) {
return getSnippetTitle_cached_cache.probe(id);
}
static void mreplace(Matcher m, StringBuffer buf, String s) {
m.appendReplacement(buf, Matcher.quoteReplacement(s));
}
static boolean isAbsoluteURL(String s) {
return isURL(s);
}
// does not detect relative urls starting with a letter
static boolean isRelativeURL(String s) {
return startsWithOneOf(s, "/", "./", "../");
}
static void lock(Lock lock) { try {
ping();
if (lock == null) return;
try {
vmBus_send("locking", lock, "thread" , currentThread());
lock.lockInterruptibly();
vmBus_send("locked", lock, "thread" , currentThread());
} catch (InterruptedException e) {
Object reason = vm_threadInterruptionReasonsMap().get(currentThread());
print("Locking interrupted! Reason: " + strOr(reason, "Unknown"));
printStackTrace(e);
rethrow(e);
}
// NO call to ping here! Make sure lock is always released.
} catch (Exception __e) { throw rethrow(__e); } }
static void lock(Lock lock, String msg) {
print("Locking: " + msg);
lock(lock);
}
static void lock(Lock lock, String msg, long timeout) {
print("Locking: " + msg);
lockOrFail(lock, timeout);
}
static ReentrantLock lock() {
return fairLock();
}
static Map stdFunctions_uncached() {
return stdFunctions_uncached(new HashMap());
}
static Map stdFunctions_uncached(Map map) {
for (var snippetID : stdFunctionListSnippetIDs())
parseStdFunctionsList(loadSnippet(snippetID), map);
return map;
}
static void unlock(Lock lock, String msg) {
if (lock == null) return;
lock.unlock();
vmBus_send("unlocked", lock, "thread" , currentThread());
print("Unlocked: " + msg); // print afterwards to make sure the lock is always unlocked
}
static void unlock(Lock lock) {
if (lock == null) return;
lock.unlock();
vmBus_send("unlocked", lock, "thread" , currentThread());
}
static Map standardClassesMap_uncached() {
Map map = new HashMap();
for (String snippetID : standardClassesSnippetIDs())
for (String line : tlft_j(loadSnippet(snippetID))) {
int idx = line.indexOf('/');
map.put(takeFirst(idx, line), substring(line, idx+1));
}
return map;
}
static Class run_overBot(String progID) {
Class main = hotwire_overBot(progID);
callMain(main);
return main;
}
static Object call_withVarargs(Object o, String methodName, Object... args) { try {
if (o == null) return null;
if (o instanceof Class) {
Class c = (Class) o;
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findStaticMethod(methodName, args);
if (me != null)
return invokeMethod(me, null, args);
// try varargs
List methods = cache.cache.get(methodName);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
{ if (!(isStaticMethod(m))) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, null, newArgs);
}
throw fail("Method " + c.getName() + "." + methodName + "(" + formatArgumentClasses(args) + ") not found");
} else {
Class c = o.getClass();
_MethodCache cache = callOpt_getCache(c);
Method me = cache.findMethod(methodName, args);
if (me != null)
return invokeMethod(me, o, args);
// try varargs
List methods = cache.cache.get(methodName);
if (methods != null) methodSearch: for (Method m : methods) {
{ if (!(m.isVarArgs())) continue; }
Object[] newArgs = massageArgsForVarArgsCall(m, args);
if (newArgs != null)
return invokeMethod(m, o, newArgs);
}
throw fail("Method " + c.getName() + "." + methodName + "(" + formatArgumentClasses(args) + ") not found");
}
} catch (Exception __e) { throw rethrow(__e); } }
static String[] dropFirst(int n, String[] a) {
return drop(n, a);
}
static String[] dropFirst(String[] a) {
return drop(1, a);
}
static Object[] dropFirst(Object[] a) {
return drop(1, a);
}
static List dropFirst(List l) {
return dropFirst(1, l);
}
static List dropFirst(int n, Iterable i) { return dropFirst(n, toList(i)); }
static List dropFirst(Iterable i) { return dropFirst(toList(i)); }
static List dropFirst(int n, List l) {
return n <= 0 ? l : new ArrayList(l.subList(Math.min(n, l.size()), l.size()));
}
static List dropFirst(List l, int n) {
return dropFirst(n, l);
}
static String dropFirst(int n, String s) { return substring(s, n); }
static String dropFirst(String s, int n) { return substring(s, n); }
static String dropFirst(String s) { return substring(s, 1); }
static Chain dropFirst(Chain c) {
return c == null ? null : c.next;
}
// legacy mode
//sbool ping_actions_shareable = true;
static volatile boolean ping_pauseAll = false;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions = false;
static Map ping_actions = newWeakHashMap();
static ThreadLocal ping_isCleanUpThread = new ThreadLocal();
// ignore pingSource if not PingV3
static boolean ping(PingSource pingSource) { return ping(); }
// always returns true
static boolean ping() {
//ifdef useNewPing
newPing();
//endifdef
if (ping_pauseAll || ping_anyActions) ping_impl(true /* XXX */);
//ifndef LeanMode ping_impl(); endifndef
return true;
}
// returns true when it slept
static boolean ping_impl(boolean okInCleanUp) { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) { // don't allow sharing ping_actions
if (!okInCleanUp && !isTrue(ping_isCleanUpThread.get()))
failIfUnlicensed();
Object action = null;
synchronized(ping_actions) {
if (!ping_actions.isEmpty()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Exception __e) { throw rethrow(__e); } }
// unclear semantics as to whether return null on null
static ArrayList asList(A[] a) {
return a == null ? new ArrayList () : new ArrayList (Arrays.asList(a));
}
static ArrayList asList(char[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (var i : a) l.add(i);
return l;
}
static ArrayList asList(byte[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (var i : a) l.add(i);
return l;
}
static ArrayList asList(int[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(long[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (long i : a) l.add(i);
return l;
}
static ArrayList asList(float[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (float i : a) l.add(i);
return l;
}
static ArrayList asList(double[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (double i : a) l.add(i);
return l;
}
static ArrayList asList(short[] a) {
if (a == null) return null;
ArrayList l = emptyList(a.length);
for (short i : a) l.add(i);
return l;
}
static ArrayList asList(Iterator it) {
ArrayList l = new ArrayList();
if (it != null)
while (it.hasNext())
l.add(it.next());
return l;
}
// disambiguation
static ArrayList asList(IterableIterator s) {
return asList((Iterator) s);
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static ArrayList asList(Enumeration e) {
ArrayList l = new ArrayList();
if (e != null)
while (e.hasMoreElements())
l.add(e.nextElement());
return l;
}
static ArrayList asList(ReverseChain c) {
return c == null ? emptyList() : c.toList();
}
static List asList(Pair p) {
return p == null ? null : ll(p.a, p.b);
}
// assumptions:
// -pingSource() stays constant within a stack frame (so you can cache it)
// -all changes happen with tempSetPingSource
// -multiple threads can share a PingSource
static PingSource pingSource() {
return pingSource_tl().get();
}
static PingSource pingSource(Thread thread) {
return pingSource_tl().get(thread);
}
static void _handleError(Error e) {
//call(javax(), '_handleError, e);
}
static ITokCondition tokCondition(IIntPred condition) {
return condition == null ? null : (tok, nIdx) -> condition.get(nIdx);
}
static Map