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 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 javax.imageio.*;
import java.math.*;
import static x30_pkg.x30_util.DynamicObject;
class main {
static void cleanExitOnFrameClose(Window frame) {
  onWindowClosing(frame, runnableThread(new Runnable() {  public void run() { try {  cleanKillVM(); 
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "cleanKillVM();"; }}));
}
static  A onWindowClosing(final A w, final Object r) {
  if (w != null) { swing(new Runnable() {  public void run() { try { 
    w.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
         AutoCloseable __1 = tempRememberListener(w, "removeWindowListener", this); try {
        pcallF(r);
      } finally { _close(__1); }}
    });
  
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "w.addWindowListener(new WindowAdapter {\r\n      public void windowClosing(Wind..."; }}); }
  return w;
}
static Runnable runnableThread(final Runnable r) {
  return new Runnable() {  public void run() { try {  startThread(r) ;
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "startThread(r)"; }};
}
static void cleanKillVM() { try {
  ping();
  assertNotOnAWTThread();
  cleanKillVM_noSleep();
  Object o = new Object();
  synchronized(o) { o.wait(); }
} catch (Exception __e) { throw rethrow(__e); } }
static void cleanKillVM_noSleep() {
  call(getJavaX(), "cleanKill");
}
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 Object swing(Object f) {
  return swingAndWait(f);
}
static  A swing(F0 f) {
  return (A) swingAndWait(f);
}
static  A swing(IF0 f) {
  return (A) swingAndWait(f);
}
static class tempRememberListener_c implements IFieldsToList{
  static final String _fieldOrder = "mainObject removeMethod listener";
  Object mainObject;
  String removeMethod;
  Object listener;
  tempRememberListener_c() {}
  tempRememberListener_c(Object mainObject, String removeMethod, Object listener) {
  this.listener = listener;
  this.removeMethod = removeMethod;
  this.mainObject = mainObject;}
  public String toString() { return shortClassName_dropNumberPrefix(this) + "(" + mainObject + ", " + removeMethod + ", " + listener + ")"; }
public boolean equals(Object o) {
if (!(o instanceof tempRememberListener_c)) return false;
    tempRememberListener_c __1 =  (tempRememberListener_c) o;
    return eq(mainObject, __1.mainObject) && eq(removeMethod, __1.removeMethod) && eq(listener, __1.listener);
}
  public int hashCode() {
    int h = 1262836985;
    h = boostHashCombine(h, _hashCode(mainObject));
    h = boostHashCombine(h, _hashCode(removeMethod));
    h = boostHashCombine(h, _hashCode(listener));
    return h;
  }
  public Object[] _fieldsToList() { return new Object[] {mainObject, removeMethod, listener}; }
}
static AutoCloseable tempRememberListener(Object mainObject, String removeMethod, Object listener) {
  return tempHoldInstance(new tempRememberListener_c(mainObject, removeMethod, listener));
}
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) { return null; } }
static  B pcallF(F1 f, A a) { try {
  return f == null ? null : f.get(a);
} catch (Throwable __e) { return null; } }
static  void pcallF(VF1 f, A a) {
  try {
    { if (f != null) f.get(a); }
  } catch (Throwable __e) { printStackTrace(__e); }
}
static Object pcallF(Runnable r) { try {
  { if (r != null) r.run(); } return null;
} catch (Throwable __e) { return null; } }
static  A pcallF(IF0 f) { try {
  return f == null ? null : f.get();
} catch (Throwable __e) { return null; } }
static  B pcallF(IF1 f, A a) { try {
  return f == null ? null : f.get(a);
} catch (Throwable __e) { return null; } }
static void _close(AutoCloseable c) {
  if (c != null) try {
    c.close();
  } catch (Throwable e) {
    // Some classes stupidly throw an exception on double-closing
    if (c instanceof javax.imageio.stream.ImageOutputStream)
      return;
    else throw rethrow(e);
  }
}
static Thread startThread(Object runnable) {
  return startThread(defaultThreadName(), runnable);
}
static Thread startThread(String name, Runnable runnable) {
  runnable = wrapAsActivity(runnable);
  return startThread(newThread(runnable, name));
}
static Thread startThread(String name, Object runnable) {
  runnable = wrapAsActivity(runnable);
  return startThread(newThread(toRunnable(runnable), name));
}
static Thread startThread(Thread t) {
  
  _registerThread(t);
  
  t.start();
  return t;
}
//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();
// 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); } }
static void assertNotOnAWTThread() {
  assertFalse("Can't do this in AWT thread", isAWTThread());
}
  
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 Class __javax;
static Class getJavaX() { try {
  
  return __javax;
} catch (Exception __e) { throw rethrow(__e); } }
static void __setJavaX(Class j) {
  __javax = j;
  _onJavaXSet();
}
static void _handleError(Error e) {
  call(javax(), "_handleError", e);
}
static void swingAndWait(Runnable r) { try {
  if (isAWTThread())
    r.run();
  else
    EventQueue.invokeAndWait(addThreadInfoToRunnable(r));
} catch (Exception __e) { throw rethrow(__e); } }
static Object swingAndWait(final Object f) {
  if (isAWTThread())
    return callF(f);
  else {
    final Var result = new Var();
    swingAndWait(new Runnable() {  public void run() { try { 
      result.set(callF(f));
    
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "result.set(callF(f));"; }});
    return result.get();
  }
}
static String shortClassName_dropNumberPrefix(Object o) {
  return dropNumberPrefix(shortClassName(o));
}
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 int boostHashCombine(int a, int b) {
  return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
}
static int _hashCode(Object a) {
  return a == null ? 0 : a.hashCode();
}
static AutoCloseable tempHoldInstance(Object o) {
  return holdInstance(o);
}
static Object pcallFunction(Object f, Object... args) {
  try { return callFunction(f, args); } catch (Throwable __e) { printStackTrace(__e); }
  return null;
}
static  A printStackTrace(A e) {
  // we go to system.out now - system.err is nonsense
  print(getStackTrace(e));
  return e;
}
static void printStackTrace() {
  printStackTrace(new Throwable());
}
static void printStackTrace(String msg) {
  printStackTrace(new Throwable(msg));
}
static void printStackTrace(String msg, Throwable e) {
  printStackTrace(new Throwable(msg, e));
}
static String defaultThreadName_name;
static String defaultThreadName() {
  if (defaultThreadName_name == null)
    defaultThreadName_name = "A thread by " + programID();
  return defaultThreadName_name;
}
static Runnable wrapAsActivity(Object r) {
  if (r == null) return null;
  Runnable r2 = toRunnable(r);
  Object mod = dm_current_generic();
  if (mod == null) return r2;
  return new Runnable() {  public void run() { try { 
    AutoCloseable c =  (AutoCloseable) (rcall("enter", mod));
     AutoCloseable __1 = c; try {
    r2.run();
  
} finally { _close(__1); }} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "AutoCloseable c =  (AutoCloseable) (rcall enter(mod));\r\n    temp c;\r\n    r2.r..."; }};
}
// runnable = Runnable or String (method name)
static Thread newThread(Object runnable) {
  return new BetterThread(_topLevelErrorHandling(toRunnable(runnable)));
}
static Thread newThread(Object runnable, String name) {
  if (name == null) name = defaultThreadName();
  return new BetterThread(_topLevelErrorHandling(toRunnable(runnable)), name);
}
static Thread newThread(String name, Object runnable) {
  return newThread(runnable, name);
}
static Runnable toRunnable(final Object o) {
  if (o instanceof Runnable) return (Runnable) o;
  return new Runnable() {  public void run() { try {  callF(o) ;
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "callF(o)"; }};
}
static Map _registerThread_threads;
static Object _onRegisterThread; // voidfunc(Thread)
static Thread _registerThread(Thread t) {
  if (_registerThread_threads == null)
    _registerThread_threads = newWeakHashMap();
  _registerThread_threads.put(t, true);
  vm_generalWeakSubMap("thread2mc").put(t, weakRef(mc()));
  callF(_onRegisterThread, t);
  return t;
}
static void _registerThread() {
  _registerThread(Thread.currentThread());
}
static  Map newWeakHashMap() {
  return _registerWeakMap(synchroMap(new WeakHashMap()));
}
static void newPing() {
  var tl = newPing_actionTL();
  Runnable action = tl == null ? null : tl.get();
  { if (action != null) action.run(); }
}
// TODO: test if android complains about this
static boolean isAWTThread() {
  if (isAndroid()) return false;
  if (isHeadless()) return false;
  return isAWTThread_awt();
}
static boolean isAWTThread_awt() {
  return SwingUtilities.isEventDispatchThread();
}
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 void failIfUnlicensed() {
  assertTrue("license off", licensed());
}
static Thread currentThread() {
  return Thread.currentThread();
}
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 void assertFalse(Object o) {
  if (!(eq(o, false) /*|| isFalse(pcallF(o))*/))
    throw fail(str(o));
}
  
static boolean assertFalse(boolean b) {
  if (b) throw fail("oops");
  return b;
}
static boolean assertFalse(String msg, boolean b) {
  if (b) throw fail(msg);
  return b;
}
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  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) {
    
    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;
}
static Object call_withVarargs(Object o, String method, 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(method, args);
    if (me != null)
      return invokeMethod(me, null, args);
      
    // try varargs
    List methods = cache.cache.get(method);
    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() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
  } else {
    Class c = o.getClass();
    _MethodCache cache = callOpt_getCache(c);
    Method me = cache.findMethod(method, args);
    if (me != null)
      return invokeMethod(me, o, args);
      
    // try varargs
    List methods = cache.cache.get(method);
    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() + "." + method + "(" + joinWithComma(classNames(args)) + ") not found");
  }
} catch (Exception __e) { throw rethrow(__e); } }
static void _onJavaXSet() {}
static Class javax() {
  return getJavaX();
}
static Runnable addThreadInfoToRunnable(final Object r) {
  final Object info = _threadInfo();
  return info == null ? asRunnable(r) : new Runnable() {  public void run() { try {  _inheritThreadInfo(info); callF(r); 
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "_inheritThreadInfo(info); callF(r);"; }};
}
static String dropNumberPrefix(String s) {
  return dropFirst(s, indexOfNonDigit(s));
}
static String shortClassName(Object o) {
  if (o == null) return null;
  Class c = o instanceof Class ? (Class) o : o.getClass();
  String name = c.getName();
  return shortenClassName(name);
}
static String str(Object o) {
  return o == null ? "null" : o.toString();
}
static String str(char[] c) {
  return new String(c);
}
static ThreadLocal> holdInstance_l = new ThreadLocal();
static AutoCloseable holdInstance(Object o) {
  if (o == null) return null;
  listThreadLocalAdd(holdInstance_l, o);
  return new AutoCloseable() {
    public void close() {
      listThreadLocalPopLast(holdInstance_l);
    }
  };
}
static Object callFunction(Object f, Object... args) {
  return callF(f, args);
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile Appendable print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
static boolean print_silent = false; // total mute if set
static Object print_byThread_lock = new Object();
static volatile ThreadLocal