!7 static int sleepTimeWhenNotFound = 5000; static JFrame frame; static ImageSurface imageSurface; static FindURLBox1 finder; static BoxShot shot; static TimeRange timeRange; concept BoxShot { S imageMD5; byte[] png; new RefL timeRanges; } concept TimeRange { long from, to; *() {} *(long *from) { to = from; } void addNow() { cset(this, to := max(to, now())); } } p { conceptsAndBot(60*1000); awt { finder = new FindURLBox1; frame = showFrame("Find URL Box", jcenteredLabel("-")); frameInnerSize(frame, 500, 70); moveToBottomRightCorner(frame); frame.setAlwaysOnTop(true); awtCalcRegularly(frame, 200, 0, r { final bool b = finder.go(); awt { if (b) { RGBImage img = finder.bestImage(); S since = ""; if (shot != null && timeRange != null) since = ", since " + (now()-timeRange.from)/1000 + "s, " + nth(l(shot.timeRanges)) + " appearance)"; S text = "URL box found in " + finder.recogTime + " ms (" + img.w() + "*" + img.h() + " px" + since + ")"; if (imageSurface == null) { imageSurface = new ImageSurface(img); setFrameContents(frame, jSection(text, new JScrollPane(imageSurface))); } else { imageSurface.setImage(img); setSectionTitle(imageSurface, text); } S imageMD5 = md5OfRGBImage(img); shot = uniq(BoxShot, +imageMD5); if (shot.png == null) shot.png = rgbImageToPNG(img); if (shot.timeRanges.contains(timeRange)) timeRange.addNow(); else shot.timeRanges.add(timeRange = new TimeRange(now())); shot.change(); } else { timeRange = null; if (imageSurface != null) { imageSurface = null; setFrameContents(frame, jcenteredLabel("URL box not found (" + finder.recogTime + " ms)")); } } } if (!b) sleep(sleepTimeWhenNotFound); }); } }