diff --git a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip
index 52042b8a2..59db2cab0 100644
Binary files a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip differ
diff --git a/sources/net.sf.j2s.core/dist/swingjs/timestamp b/sources/net.sf.j2s.core/dist/swingjs/timestamp
index 62e636da7..b06e62268 100644
--- a/sources/net.sf.j2s.core/dist/swingjs/timestamp
+++ b/sources/net.sf.j2s.core/dist/swingjs/timestamp
@@ -1 +1 @@
-20190724061400
+20190814182015
diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip
index 52042b8a2..59db2cab0 100644
Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip differ
diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp
index 62e636da7..b06e62268 100644
--- a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp
+++ b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp
@@ -1 +1 @@
-20190724061400
+20190814182015
diff --git a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip
index 52042b8a2..59db2cab0 100644
Binary files a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip and b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip differ
diff --git a/sources/net.sf.j2s.java.core/doc/Differences.txt b/sources/net.sf.j2s.java.core/doc/Differences.txt
index ead5c418c..7a0e8e569 100644
--- a/sources/net.sf.j2s.java.core/doc/Differences.txt
+++ b/sources/net.sf.j2s.java.core/doc/Differences.txt
@@ -1,10 +1,11 @@
Notes
=====
+updated 8/16/19 -- minor typos and added summary paragraph
updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
updated 5/13/19 -- Mandarin U+79D8 reserved character; Missing Math methods; int and long
updated 5/10/19 -- adds a section on static issues in multi-(duplicate)-applet pages
updated 1/4/19 -- nio
-updated 9/15/18 -- adds integer 1/0 == 0
+updated 9/15/18 -- adds integer 1/0 == Infinity
updated 7/24/18 -- most classes replaced with https://github.com/frohoff/jdk8u-jdk
updated 6/5/17 -- reserved package name "window"
updated 3/11/17 -- myClass.getField
@@ -537,14 +538,14 @@ qualified field and method names
In order to minimize the chance of added SwingJS field and method names colliding with ones
developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
-"secrect") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
+"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
would be if you use that character followed by certain English words in certain classes. For example
\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
missing Math methods
--------------------
-java.lang.Math is worked out, but some methods are missing, eithr because they
+java.lang.Math is worked out, but some methods are missing, either because they
involve long integer value that are inaccessible in JavaScript, or because I just
didn't implement them. This is a result of continued Java development.
It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
@@ -566,7 +567,7 @@ For example, this will definitely NOT work in SwingJS:
this.paint(getGraphics())
-and really should not in Java, either, as it is technically a resource memory leak.
+and really should not work in Java, either, as it is technically a resource memory leak.
Instead, if you really do not want to use repaint(), use this:
@@ -601,7 +602,7 @@ Static classes such as:
which are created using Class.forName are implemented using classes in the swingjs package.
-AWTAccessor and AwtContext need to be customized
+AWTAccessor is not implemented.
AWT component peers and component "ui" user interfaces
@@ -739,7 +740,7 @@ to BigInteger:
* the integer storage bit length to 24, giving 48 for long and leaving
* the last 16 bits clear for the exponent of the double number. This should
* not affect performance significantly. It does increase the storage
- * size by about 33%. By bring an "int" to 3 bytes, we can easily construct
+ * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
* and use byte[] data intended for the original BitSet.
"Easily" may be a bit strong there. This was a serious challenge.
@@ -772,13 +773,11 @@ JEditorPane (JavaScript
)
For the initial implementation, we don't implement infinite undo/redo, and the abstract
document model is much less elaborate. Only PlainDocument (in the form of JSPlainDocument)
-is implemented.
-The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
+is implemented. The Document returned by JTextField.getDocument() is a javax.swing.text.Document.
-all scrolling is handled by HTML5
-javax.swing.AutoScroller is not implemented
+All scrolling is handled by HTML5. javax.swing.AutoScroller is not implemented.
public static methods .stop, .isRunning, .processMouseDragged require true Java threading
-javax.swing.text.View and its subclasses are not implemented.
+and so are not implmented. javax.swing.text.View and its subclasses are not implemented.
The JS document model does not allow two text fields to address the same underlying document.
@@ -792,9 +791,23 @@ Matcher.start(groupID) is not supported.
java.util.Formatter will function correctly for all standard %... patterns.
-integer 1/0 == 0
-----------------
+integer 1/0 == Infinity
+-----------------------
1/0 in Java throws "java.lang.ArithmeticException: / by zero", but in JavaScript is just Infinity.
-
+
+
+Summary
+-------
+
+These are all the known limitations of SwingJS. We have not found any of these limitations
+to be show-stoppers. The primary issue for newcomers to SwingJS is having the source code.
+You must check that source code for all your library jar files is available or, if you
+choose, you will need to decompile those classes. We have used decompilation on some projects,
+and it works just fine. So, technically, all we really need are JAR/class files. But the
+source is by far superior. It's generally prettier, and it has the license information that
+may or may not be present with the JAR or class files. Use class files at your own risk.
+
+Bob Hanson
+2019.08.16
diff --git a/sources/net.sf.j2s.java.core/src/javax/swing/JFrame.java b/sources/net.sf.j2s.java.core/src/javax/swing/JFrame.java
index 291225a69..acce0093f 100644
--- a/sources/net.sf.j2s.java.core/src/javax/swing/JFrame.java
+++ b/sources/net.sf.j2s.java.core/src/javax/swing/JFrame.java
@@ -170,7 +170,7 @@ public void add(Component comp, Object constraints) {
*/
protected boolean rootPaneCheckingEnabled = false;
- private boolean _boundsFrozen;
+ private boolean 秘boundsFrozen;
/**
* Constructs a new frame that is initially invisible.
@@ -915,15 +915,15 @@ protected String paramString() {
+ ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
}
- public void _freezeBounds(int w, int h) {
+ public void 秘freezeBounds(int w, int h) {
setSize(w, h);
- _boundsFrozen = true;
+ 秘boundsFrozen = true;
resizable = false;
}
@Override
public void reshape(int x, int y, int width, int height) {
- if (!_boundsFrozen)
+ if (!秘boundsFrozen)
super.reshape(x, y, width, height);
}
diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSGraphics2D.java b/sources/net.sf.j2s.java.core/src/swingjs/JSGraphics2D.java
index f0e55133b..4897a9c1f 100644
--- a/sources/net.sf.j2s.java.core/src/swingjs/JSGraphics2D.java
+++ b/sources/net.sf.j2s.java.core/src/swingjs/JSGraphics2D.java
@@ -790,9 +790,13 @@ public boolean hitClip(int x, int y, int width, int height) {
return clipRect.intersects(x, y, width, height);
}
+ private int alpha;
private void setGraphicsColor(Color c) {
if (c == null)
return; // this was the case with a JRootPanel graphic call
+ int a = c.getAlpha();
+ if (a != alpha)
+ ctx.globalAlpha = (alpha = a) / 256F;
ctx.fillStyle = ctx.strokeStyle = JSToolkit.getCSSColor(c);
}
@@ -1010,13 +1014,8 @@ public void drawImage(BufferedImage img, BufferedImageOp op, int x, int y) {
}
public void setAlpha(float f) {
- /**
- * @j2sNative
- *
- * this.ctx.globalAlpha = f;
- */
- {
- }
+ ctx.globalAlpha = f;
+ alpha = (int) Math.floor(f * 256 + 0.0039);
}
public HTML5Canvas getCanvas() {
@@ -1056,17 +1055,7 @@ public int mark() {
// note: This method is referred to in JComponent.java j2snative block as mark$
ctx.save();
Object[] map = new Object[SAVE_MAX];
-
- float alpha = 0;
- /**
- * @j2sNative
- *
- * alpha = this.ctx.globalAlpha;
- *
- */
- {
- }
- map[SAVE_ALPHA] = Float.valueOf(alpha);
+ map[SAVE_ALPHA] = Float.valueOf(ctx.globalAlpha);
map[SAVE_COMPOSITE] = alphaComposite;
map[SAVE_STROKE] = currentStroke;
map[SAVE_TRANSFORM] = transform;
@@ -1089,8 +1078,9 @@ public void reset(int n0) {
Object[] map = HTML5CanvasContext2D.pop(ctx);
setComposite((Composite) map[SAVE_COMPOSITE]);
Float alpha = (Float) map[SAVE_ALPHA];
- if (alpha != null)
+ if (alpha != null) {
setAlpha(alpha.floatValue());
+ }
setStroke((Stroke) map[SAVE_STROKE]);
setTransform((AffineTransform) map[SAVE_TRANSFORM]);
setFont((Font) map[SAVE_FONT]);
diff --git a/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5CanvasContext2D.java b/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5CanvasContext2D.java
index 60bf6700e..0ced65e96 100644
--- a/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5CanvasContext2D.java
+++ b/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5CanvasContext2D.java
@@ -16,6 +16,8 @@ public class ImageData {
public String font, fillStyle, strokeStyle;
+ public float globalAlpha;
+
public abstract void drawImage(DOMNode img, int sx,
int sy, int swidth, int sheight, int dx, int dy, int dwidth, int dheight);
diff --git a/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSComponentUI.java b/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSComponentUI.java
index 280b55377..07a563393 100644
--- a/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSComponentUI.java
+++ b/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSComponentUI.java
@@ -147,6 +147,10 @@
public class JSComponentUI extends ComponentUI
implements JSEventHandler, PropertyChangeListener, ChangeListener, DropTargetPeer {
+ public interface Embeddable {
+ Object getEmbedded(String type);
+ }
+
private static final int MENUITEM_OFFSET = 11;
final J2SInterface J2S = JSUtil.J2S;
diff --git a/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSFrameUI.java b/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSFrameUI.java
index 0f061e29e..ab653c857 100644
--- a/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSFrameUI.java
+++ b/sources/net.sf.j2s.java.core/src/swingjs/plaf/JSFrameUI.java
@@ -44,7 +44,7 @@
* @author hansonr
*
*/
-public class JSFrameUI extends JSWindowUI implements FramePeer {
+public class JSFrameUI extends JSWindowUI implements FramePeer, JSComponentUI.Embeddable {
private static final Insets ZERO_INSETS = new Insets(0, 0, 0, 0);
@@ -111,24 +111,11 @@ public DOMNode updateDOMNode() {
h = defaultHeight;
DOMNode.setSize(frameNode, w, h);
DOMNode.setTopLeftAbsolute(frameNode, 0, 0);
- String fname = frame.getName();
- DOMNode node = DOMNode.getElement(fname + "-div");
+ DOMNode node = (DOMNode) getEmbedded("init");
if (node != null) {
embeddingNode = node;
- doEmbed = (DOMNode.getWidth(embeddingNode) > 0);
+ doEmbed = (DOMNode.getWidth(node) > 0);
isHidden = !doEmbed;
- if (doEmbed) {
- frame.setUndecorated(true);
- frame.setLocation(0, 0);
- } else {
- DOMNode.setStyles(embeddingNode, "position", "relative", "overflow", "hidden");
- }
-
- int ew = DOMNode.getWidth(node);
- int eh = DOMNode.getHeight(node);
- if (ew > 0 && eh > 0) {
- frame._freezeBounds(ew, eh);
- }
}
setWindowClass();
if (!frame.isUndecorated()) {
@@ -182,6 +169,46 @@ public DOMNode updateDOMNode() {
return domNode;
}
+ /**
+ * Note: DO NOT CHANGE THE NAME OF THIS METHOD
+ *
+ * @param frame
+ * @param type
+ * one of: "name", "node", "init", "dim"
+ * @return
+ */
+ @Override
+ @SuppressWarnings("unused")
+ public Object getEmbedded(String type) {
+ String name = frame.getName();
+ DOMNode node = DOMNode.getElement(name + "-div");
+ if (node == null)
+ return null;
+ switch (type) {
+ case "name":
+ return name;
+ case "node":
+ return node;
+ case "dim":
+ return new Dimension(DOMNode.getWidth(node), DOMNode.getHeight(node));
+ case "init":
+ if (node == null)
+ return null;
+ Dimension dim = (Dimension) getEmbedded("dim");
+ if (dim.width > 0) {
+ frame.setUndecorated(true);
+ frame.setLocation(0, 0);
+ String resize = DOMNode.getStyle(node, "resize");
+ if (resize == "none")
+ frame.秘freezeBounds(dim.width, dim.height);
+ } else {
+ DOMNode.setStyles(node, "position", "relative", "overflow", "hidden");
+ }
+ return node;
+ }
+ return null;
+ }
+
@Override
protected boolean isFrameIndependent() {
return !doEmbed;
diff --git a/sources/net.sf.j2s.java.core/src/test/Test_Array.java b/sources/net.sf.j2s.java.core/src/test/Test_Array.java
index 606517abe..4f31c2faf 100644
--- a/sources/net.sf.j2s.java.core/src/test/Test_Array.java
+++ b/sources/net.sf.j2s.java.core/src/test/Test_Array.java
@@ -11,6 +11,12 @@ class Test_Array extends Test_ {
static int y;
static {
+
+
+ int[][] ia = (int[][])c33def2b;
+ int[][] ib = ia.clone();
+ assert("[[I".equals(ib.getClass().getName()));
+
int x = 3;
y = x;
Test_Array[] a = new Test_Array[3];
@@ -82,8 +88,10 @@ public static void main(String[] args) {
double[] da = new double[3];
System.out.println(da[iI]);
assert (ii3[2] == 1 && j == 1);
+
System.out.println("Test_Array OK");
}
+
}
\ No newline at end of file
diff --git a/sources/net.sf.j2s.java.core/src/test/Test_Interval.java b/sources/net.sf.j2s.java.core/src/test/Test_Interval.java
new file mode 100644
index 000000000..1a04aaceb
--- /dev/null
+++ b/sources/net.sf.j2s.java.core/src/test/Test_Interval.java
@@ -0,0 +1,223 @@
+package test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Random;
+
+class Test_Interval extends Test_ {
+
+ static int[] i0 = new int[0];
+
+ static int[][] a = new int[][] {
+ { 1, 7 },
+ { 2, 4 },
+ { 3, 5 },
+ { 3, 6 },
+ { 4, 5 },
+ { 7, 8 },
+ { 9, 10 }
+
+ };
+
+ public static void main(String[] args) {
+
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
+ int[] ap = new int[] { 10, 20, 30, 40, 50, 50, 50, 60, 70, 80, 90, 100, 110, 120 };
+
+ System.out.println(findClosestPoint(ap, 11, true)); // 0
+ System.out.println(findClosestPoint(ap, 11, false)); // 1
+ System.out.println(findClosestPoint(ap, 51, true)); // 6
+ System.out.println(findClosestPoint(ap, 51, false)); // 7
+ System.out.println(findClosestPoint(ap, 130, true));// -1
+ System.out.println(findClosestPoint(ap, 130, false)); // -1
+ System.out.println(findClosestPoint(ap, 0, true)); // -1
+ System.out.println(findClosestPoint(ap, 0, false)); // -1
+ System.out.println(findClosestPoint(ap, 30, true)); // 2
+ System.out.println(findClosestPoint(ap, 60, true)); // 7
+ System.out.println(findClosestPoint(ap, 50, true)); // 6
+ System.out.println(findClosestPoint(ap, 50, false)); // 4
+
+ assert (findClosestPoint(ap, 11, true) == 0);
+ assert (findClosestPoint(ap, 11, false) == 1);
+ assert (findClosestPoint(ap, 51, true) == 6);
+ assert (findClosestPoint(ap, 51, false) == 7);
+ assert (findClosestPoint(ap, 130, true) == -1);
+ assert (findClosestPoint(ap, 130, false) == -1);
+ assert (findClosestPoint(ap, 0, true) == -1);
+ assert (findClosestPoint(ap, 0, false) == -1);
+ assert (findClosestPoint(ap, 30, true) == 2);
+ assert (findClosestPoint(ap, 60, true) == 7);
+ assert (findClosestPoint(ap, 50, true) == 6);
+ assert (findClosestPoint(ap, 50, false) == 4);
+
+ new Test_Interval().findIntervals(a, 3);
+ new Test_Interval().findIntervals(a, 5);
+ new Test_Interval().findIntervals(a, 9);
+
+ System.out.println("Test_Interval OK");
+ }
+
+ private static Interval[] ints;
+
+ private void findIntervals(int[][] a, int pos) {
+ try {
+ Thread.sleep(500);
+ } catch (InterruptedException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ Random rand = new Random();
+ int n = a.length;
+ Interval[] intervals = new Interval[n];
+ for (int i = 0; i < n;) {
+ int r = rand.nextInt(n);
+ if (intervals[r] == null) {
+ intervals[r] = new Interval(a[i][0], a[i][1], i);
+ i++;
+ }
+ }
+ System.out.println("=====");
+ //dumpIntervals(intervals);
+ System.out.println("-----");
+ ints = intervals;
+ Arrays.sort(intervals, new IComparator());
+ linkIntervals(intervals);
+ //dumpIntervals(intervals);
+ List result = new ArrayList<>();
+ findInterval(intervals, pos, result);
+ for (int i = 0; i < result.size(); i++)
+ System.out.println(pos + " " + result.get(i));
+
+ }
+
+ private void findInterval(Interval[] intervals, int pos, List result) {
+ Interval ithis = findClosestInterval(intervals, pos);
+ while (ithis != null) {
+ if (ithis.end >= pos)
+ result.add(ithis);
+ ithis = ithis.containedBy;
+ }
+ }
+
+ private Interval findClosestInterval(Interval[] l, int pos) {
+ int low = 0;
+ int high = l.length - 1;
+ int mid = 0;
+ while (low <= high) {
+ mid = (low + high) >>> 1;
+ int f = l[mid].begin;
+ switch (Long.signum(f - pos)) {
+ case -1:
+ low = mid + 1;
+ continue;
+ case 1:
+ high = mid - 1;
+ continue;
+ case 0:
+ while (++mid <= high && l[mid].begin == pos) {
+ ;
+ }
+ mid--;
+ return l[mid];
+ }
+ }
+ return (high < 0 || low >= l.length ? null : l[high]);
+ }
+
+ static void dumpIntervals(Interval[] intervals) {
+ for (int i = 0; i < intervals.length; i++) {
+ System.out.println(intervals[i]);
+ }
+ System.out.println("");
+ }
+
+ public void linkIntervals(Interval[] intervals) {
+ if (intervals.length < 2)
+ return;
+ int maxEnd = intervals[0].end;
+ for (int i = 1, n = intervals.length; i < n; i++) {
+ Interval ithis = intervals[i];
+ if (ithis.begin <= maxEnd)
+ ithis.containedBy = getContainedBy(intervals, i);
+ if (ithis.end > maxEnd)
+ maxEnd = ithis.end;
+ }
+
+ }
+
+ private Interval getContainedBy(Interval[] intervals, int i) {
+ Interval ithis = intervals[i];
+ while (--i >= 0) {
+ Interval ilast = intervals[i];
+ if (ithis.begin <= ilast.end) {
+ return ilast;
+ }
+ }
+ return null;
+ }
+
+ class Interval {
+ int begin, end, index;
+ Interval containedBy;
+
+ Interval(int begin, int end, int index) {
+ this.begin = begin;
+ this.end = end;
+ this.index = index;
+ }
+
+ @Override
+ public String toString() {
+ return "I" + index + " begin:" + begin + " end:" + end + " cont:"
+ + (containedBy == null ? "?" : containedBy.index);
+ }
+
+ }
+
+ class IComparator implements Comparator {
+
+ @Override
+ public int compare(Interval a, Interval b) {
+ int val = (a.begin < b.begin ? -1 : a.begin > b.begin ? 1 : a.end > b.end ? 1 : a.end < b.end ? -1 : 0);
+ return val;
+ }
+
+ }
+
+ static private int findClosestPoint(int[] l, int pos, boolean isStart) {
+ int low = 0;
+ int high = l.length - 1;
+ int mid = 0;
+ while (low <= high) {
+ mid = (low + high) >>> 1;
+ int f = l[mid];
+ switch (Long.signum(f - pos)) {
+ case -1:
+ low = mid + 1;
+ continue;
+ case 1:
+ high = mid - 1;
+ continue;
+ case 0:
+ if (isStart) {
+ while (--mid >= low && (f = l[mid]) != -1 && f == pos) {
+ ;
+ }
+ ++mid;
+ } else {
+ while (++mid <= high && (f = l[mid]) != -1 && f == pos) {
+ ;
+ }
+ mid--;
+ }
+ return mid;
+ }
+ }
+ // -1 here?
+ System.out.println(isStart + " " + low + " " + mid + " " + high);
+ return (high < 0 || low >= l.length ? -1 : isStart ? high : low);
+ }
+
+}
\ No newline at end of file
diff --git a/sources/net.sf.j2s.java.core/srcjs/js/j2sClazz.js b/sources/net.sf.j2s.java.core/srcjs/js/j2sClazz.js
index c1ff62d00..8b7136c4d 100644
--- a/sources/net.sf.j2s.java.core/srcjs/js/j2sClazz.js
+++ b/sources/net.sf.j2s.java.core/srcjs/js/j2sClazz.js
@@ -9,6 +9,7 @@
// TODO: still a lot of references to window[...]
+// BH 2019.07.27 fixes array(intArray).clone
// BH 2019.07.09 adds Java String.trim()
// BH 2019.05.21 changes Clazz.isClassDefined to Clazz._isClassDefined for compression
// BH 2019.05.13 fixes for Math.getExponent, Math.IEEERemainder, Array.equals(Object)
@@ -214,7 +215,7 @@ var _array = function(baseClass, paramType, ndims, params, isClone) {
}
params.push(paramType);
var nbits = 0;
- if (ndims != 0) {
+ if (ndims != 0 && !(isClone && Array.isArray(params[1]))) {
switch (prim) {
case "B":
nbits = 8;
@@ -4423,11 +4424,8 @@ sp.contains$S = function(a) {return this.indexOf(a) >= 0} // bh added
sp.compareTo$ = sp.compareTo$S = sp.compareTo$TT = function(a){return this > a ? 1 : this < a ? -1 : 0} // bh added
sp.toCharArray$=function(){
-var result=new Array(this.length);
-for(var i=0;i= 0} // bh added
sp.compareTo$ = sp.compareTo$S = sp.compareTo$TT = function(a){return this > a ? 1 : this < a ? -1 : 0} // bh added
sp.toCharArray$=function(){
-var result=new Array(this.length);
-for(var i=0;i