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;
import static x30_pkg.x30_util.DynamicObject;
import java.text.*;
import java.text.NumberFormat;
import java.util.TimeZone;
import java.awt.geom.*;
class main {
static  A updateChain(ChangeTriggerable b, A a) {
  return onChange(a, b);
}
static  A updateChain(Updateable b, A a) {
  return onChange(a, b);
}
static  A updateChain(Runnable b, A a) {
  return onChange(a, b);
}
  static  A updateChain(Object b, A a) {
    onChange(a, changeReceiverToRunnable(b));
    return a;
  }
  static  A updateChain(Object b, A a) {
    onChange(a, changeReceiverToRunnable(b));
    return a;
  }
static  A updateChain(Object b, A l) {
  for (var a : unnullForIteration(l))
    preciseCall(main.class, "updateChain", b, a);
  return l;
}
static  A onChange(A spinner, Object r) {
  return onChange(spinner, toRunnable(r));
}
static  A onChange(A spinner, Runnable r) {
  if (r != null)
    { swing(() -> {  spinner.addChangeListener(changeListener(r)); }); }
  return spinner;
}
static  A onChange(A b, Runnable r) {
  { swing(() -> {  b.addItemListener(itemListener(r)); }); }
  return b;
}
static void onChange(JTextComponent tc, Runnable r) {
  onUpdate(tc, r);
}
static  A onChange(A slider, Runnable r) {
  { swing(() -> {  slider.addChangeListener(changeListener(r)); }); }
  return slider;
}
static  JComboBox onChange(JComboBox cb, ChangeTriggerable r) {
  return onChange(cb, new ChangeTrigger(r));
}
static  JComboBox onChange(JComboBox cb, IVF1 f) {
  if (f != null) addActionListener(cb, () -> f.get(getSelectedItem_typed(cb)));
  return cb;
}
// Note: JComboBox also supports addActionListener.
// Not sure if that would help us any.
static JComboBox onChange(JComboBox cb, Runnable r) {
  if (isEditableComboBox(cb))
    onChange(textFieldFromComboBox(cb), r);
  else
    onSelectedItem(cb, runnableToIVF1(r));
  return cb;
}
static  A onChange(A tabs, Runnable r) {
  { swing(() -> {  tabs.addChangeListener(changeListener(r)); }); }
  return tabs;
}
static  A onChange(Runnable r, A cc) {
  if (cc != null && r != null) { swing(() -> { 
    cc.getSelectionModel().addChangeListener(changeListener(r));
  }); }
  return cc;
}
static  A onChange(A a, ChangeTriggerable b) {
  if (a != null && b != null) a.onChange(new ChangeTrigger(b));
  return a;
}
static  A onChange(A a, Updateable b) {
  if (a != null && b != null) a.onChange(new UpdateTrigger(b));
  return a;
}
static  A onChange(A a, Runnable r) {
  if (a != null && r != null) a.onChange(r);
  return a;
}
static Runnable changeReceiverToRunnable(Object o) {
  if (o instanceof Updateable) return new UpdateTrigger((Updateable) o);
  if (o instanceof ChangeTriggerable) return new ChangeTrigger((ChangeTriggerable) o);
  return (Runnable) o;
}
static String unnullForIteration(String s) {
  return s == null ? "" : s;
}
static  Collection unnullForIteration(Collection l) {
  return l == null ? immutableEmptyList() : l;
}
static  List unnullForIteration(List l) { return l == null ? immutableEmptyList() : l; }
static byte[] unnullForIteration(byte[] l) { return l == null ? emptyByteArray() : l; }
static int[] unnullForIteration(int[] l) { return l == null ? emptyIntArray() : l; }
static char[] unnullForIteration(char[] l) { return l == null ? emptyCharArray() : l; }
static double[] unnullForIteration(double[] l) { return l == null ? emptyDoubleArray() : l; }
static short[] unnullForIteration(short[] l) { return l == null ? emptyShortArray() : l; }
static  Map unnullForIteration(Map l) {
  return l == null ? immutableEmptyMap() : l;
}
static  Iterable unnullForIteration(Iterable i) {
  return i == null ? immutableEmptyList() : i;
}
static  A[] unnullForIteration(A[] a) {
  return a == null ? (A[]) emptyObjectArray() : a;
}
static BitSet unnullForIteration(BitSet b) {
  return b == null ? new BitSet() : b;
}
static Pt unnullForIteration(Pt p) {
  return p == null ? new Pt() : p;
}
//ifclass Symbol
static Symbol unnullForIteration(Symbol s) {
  return s == null ? emptySymbol() : s;
}
//endif
static  Pair unnullForIteration(Pair p) {
  return p != null ? p : new Pair(null, null);
}
static long unnullForIteration(Long l) { return l == null ? 0L : l; }
static boolean preciseCall_debug = false;
static Object preciseCall(Object o, String method, Object... args) { try {
  if (o instanceof Class) {
    _MethodCache cache = callOpt_getCache((Class) o);
    List methods = cache.cache.get(method);
    //L methods = findMethodsNamed2(o, method, true);
    Lowest best = new Lowest();
    if (methods != null) for (Method m : methods) {
      { if (!(isStaticMethod(m))) continue; }
      int score = methodApplicabilityScore(m, args);
      if (score < Integer.MAX_VALUE) {
        if (preciseCall_debug)
          print("Method score: " + m + " " + score);
        best.put(m, score);
      }
    }
    Method m = best.get();
    if (m != null) 
      return invokeMethod(m, null, args);
    
    return call_withVarargs(((Class) o), method, args); // TODO: make this precise too
  } else
    throw todo();
} catch (Exception __e) { throw rethrow(__e); } }
static Runnable toRunnable(final Object o) {
  if (o == null) return null;
  if (o instanceof Runnable) return (Runnable) o;
  
  if (o instanceof String) throw fail("callF_legacy");
  
  return new Runnable() {  public void run() { try {  callF(o) ;
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "callF(o)"; }};
}
static Object swing(Object f) {
  return swingAndWait(f);
}
static void swing(Runnable f) {
  swingAndWait(f);
}
static  A swing(F0 f) {
  return (A) swingAndWait(f);
}
static  A swing(IF0 f) {
  return (A) swingAndWait(f);
}
static ChangeListener changeListener(final Object r) {
  return new ChangeListener() {
    public void stateChanged(ChangeEvent e) {
      pcallF(r);
    }
  };
}
static ItemListener itemListener(final Object r) {
  return new ItemListener() {
    public void itemStateChanged(ItemEvent e) {
      pcallF(r);
    }
  };
}
static void onUpdate(JComponent c, Runnable r) {
  onUpdate(c, (Object) r);
}
static void onUpdate(JTextComponent c, IVF1 r) {
  if (c == null || r == null) return;
  c.getDocument().addDocumentListener(runnableToDocumentListener(() -> r.get(c.getText())));
}
// legacy signature
static void onUpdate(JComponent c, Object r) {
  if (c instanceof JTextComponent)
    ((JTextComponent) c).getDocument().addDocumentListener(runnableToDocumentListener(toRunnable(r)));
  else if (c instanceof ItemSelectable) // JCheckBox and others
    ((ItemSelectable) c).addItemListener(new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        pcallF(r);
      }
    });
  else if (c instanceof JSpinner)
    onChange(((JSpinner) c), r);
  else
    print("Warning: onUpdate doesn't know " + getClassName(c));
}
static void onUpdate(List extends JComponent> l, Object r) {
  for (JComponent c : l)
    onUpdate(c, r);
}
static void addActionListener(JTextField tf, final Runnable action) {
  onEnter(tf, action);
}
static void addActionListener(final JComboBox cb, final Runnable action) {
  if (cb != null) { swing(() -> { 
    cb.addActionListener(actionListener(action));
  }); }
}
static void addActionListener(final AbstractButton b, final Runnable action) {
  if (b != null) { swing(() -> { 
    b.addActionListener(actionListener(action));
  }); }
}
static  A getSelectedItem_typed(JList l) {
  return swing(() -> l.getSelectedValue());
}
static  A getSelectedItem_typed(JComboBox cb) {
  return swing(() -> (A) cb.getSelectedItem());
}
static boolean isEditableComboBox(final JComboBox cb) {
  return cb != null && swing(new F0() { public Boolean get() { try {  return cb.isEditable();  } catch (Exception __e) { throw rethrow(__e); } }
  public String toString() { return "return cb.isEditable();"; }});
}
static JTextField textFieldFromComboBox(JComboBox cb) {
  return (JTextField) cb.getEditor().getEditorComponent();
}
static JComboBox onSelectedItem(final JComboBox cb, final VF1 f) {
  addActionListener(cb, new Runnable() {  public void run() { try { 
    pcallF(f, selectedItem(cb))
  ;
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "pcallF(f, selectedItem(cb))"; }});
  return cb;
}
static JComboBox onSelectedItem(final JComboBox cb, IVF1 f) {
  addActionListener(cb, new Runnable() {  public void run() { try { 
    pcallF(f, selectedItem(cb))
  ;
} catch (Exception __e) { throw rethrow(__e); } }  public String toString() { return "pcallF(f, selectedItem(cb))"; }});
  return cb;
}
static  IVF1 runnableToIVF1(Runnable r) {
  return r == null ? null : a -> r.run();
}
static  List immutableEmptyList() {
  return Collections.emptyList();
}
static byte[] emptyByteArray_a = new byte[0];
static byte[] emptyByteArray() { return emptyByteArray_a; }
static int[] emptyIntArray_a = new int[0];
static int[] emptyIntArray() { return emptyIntArray_a; }
static char[] emptyCharArray = new char[0];
static char[] emptyCharArray() { return emptyCharArray; }
static double[] emptyDoubleArray = new double[0];
static double[] emptyDoubleArray() { return emptyDoubleArray; }
static short[] emptyShortArray = new short[0];
static short[] emptyShortArray() { return emptyShortArray; }
static  Map immutableEmptyMap() {
  return Collections.emptyMap();
}
static Object[] emptyObjectArray_a = new Object[0];
static Object[] emptyObjectArray() { return emptyObjectArray_a; }
static Symbol emptySymbol_value;
static Symbol emptySymbol() {
  if (emptySymbol_value == null) emptySymbol_value = symbol("");
  return emptySymbol_value;
}
static final Map callOpt_cache = newDangerousWeakHashMap();
static Object callOpt_cached(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);
    
    // TODO: (super-rare) case where method exists static and non-static
    // with different args
    
    Method me = cache.findMethod(methodName, args);
    if (me == null || (me.getModifiers() & Modifier.STATIC) == 0) return null;
    return invokeMethod(me, null, args);
  } else {
    Class c = o.getClass();
    _MethodCache cache = callOpt_getCache(c);
    Method me = cache.findMethod(methodName, args);
    if (me == null) return null;
    return invokeMethod(me, o, args);
  }
} catch (Exception __e) { throw rethrow(__e); } }
// no longer synchronizes! (see #1102990)
static _MethodCache callOpt_getCache(Class c) {
  _MethodCache cache = callOpt_cache.get(c);
  if (cache == null)
    callOpt_cache.put(c, cache = new _MethodCache(c));
  return cache;
}
static boolean isStaticMethod(Method m) {
  return methodIsStatic(m);
}
// return Int.MAX_VALUE if not applicable
// Lower score is better
static int methodApplicabilityScore(Method m, Object[] args) {
   Class>[] types = m.getParameterTypes();
   if (types.length != args.length) return Integer.MAX_VALUE;
   int score = 0;
   for (int i = 0; i < types.length; i++) {
     Object a = args[i];
     Class c = types[i];
     if (a == null) ++score;
     else if (c == a.getClass()) {} // perfect match
     else if (isInstanceX(c, a)) ++score;
     else return Integer.MAX_VALUE;
  }
  return score;
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static boolean printAlsoToSystemOut = true;
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