!7 static JTextField tf; static SingleComponentPanel scp; static Canvas canvas; static Q q; // action queue static volatile bool boss; // boss mode (after pressing Escape) static L aiConcepts; !include #1007377 // traits for CirclesAndLines p-subst { aiEnhancements(); aiConcepts = loadAIConcepts(); //final S word = getString(random(aiConcepts), /*"name"*/"globalID"); final S word = "yorqibybrndchtxr"; swing { q = new Q(true); tf = setTextFieldFontSize(jCenteredTextField(word), 20); final ForwardAndBackButtons fb = new ForwardAndBackButtons(tf, f go); JFrame frame = showFrame(northAndCenter( westAndCenter(fb.buttons(), withLeftMargin(tf)), scp = new SingleComponentPanel)); registerEscape(frame, r { boss = true; tf.setText(""); scp.noComponent(); }); centerFrame(frameInnerSize(frame, 800, 600)); addMenu(frame, "Menu!", "Clear Cache", r { clearAICaches() }); addAISuiteMenu(frame); onEnterAndNow(tf, r { fb.submitted(); go(); }); hideConsole(); } } svoid go { boss = false; awt { tf.selectAll(); } final S text = getTextTrim(tf); q.add(r { if (boss) ret; long time = sysNow(); loading { final CirclesAndLines cal = render(text); if (boss) ret; awt { Canvas canvas = cal.makeCanvas(); new CircleDoubleClicker(cal, canvas, voidfunc(Circle c) { S s = firstGlobalID(c.traits()); if (empty(s)) s = first(c.traits()); tf.setText(s); simulateEnter(tf); }); scp.setComponent(centerAndSouth( /*jscroll_centered*/(canvas), setFont(sansSerifBold(20), jcenteredlabel(text)))); } } sleepUntilSys(time+1000); // min display time }); } static CirclesAndLines render(S text) { pcall { text = englishToConceptLanguage(text); } print("Text: " + text); if (possibleGlobalID(text)) { AIConcept c = findWhere(aiConcepts, globalID := text); if (c != null) { print("Have concept (" + c.globalID + " - " + c.name + ")"); ret renderConcept(c); } } new CirclesAndLines cal; for (S s : splitAtPlus(text)) cal.circle_autoVis(s, 0.5, 0.5); autoPositionCircles(cal); ret cal; } static CirclesAndLines renderConcept(AIConcept c) { new CirclesAndLines cal; conceptCircle(cal, c, true); autoPositionCircles(cal); ret cal; } static Circle conceptCircle(CirclesAndLines cal, S conceptID, bool withRelations) { AIConcept c = aiConceptsMap_cached().get(conceptID); if (c == null) ret cal.circle(conceptID + " [?]", 0.5, 0.5); ret conceptCircle(cal, c, withRelations); } static Circle conceptCircle(CirclesAndLines cal, AIConcept c, bool withRelations) { BufferedImage img = getConceptImage(c); Circle cc; print("conceptCircle " + c.globalID + " img: " + (img != null)); if (img != null) cc = cal.circle(img, 0.5, 0.5, c.name); else cc = cal.circle_autoVis(c.name, 0.5, 0.5); cc.addTrait(c.globalID); if (withRelations) findRelations(cal, cc, c); ret cc; } svoid findRelations(CirclesAndLines cal, Circle cc, AIConcept c) { S id = c.globalID; for (S s : trueStatements_cached()) { Lisp l = clParse(s); if (l.size() == 2) { if (eq(l.getString(0), id)) { S label = makeLabel(l.head); Circle dd = conceptCircle(cal, l.getString(1), false); cal.arrow(cc, label, dd); } else if (eq(l.getString(1), id)) { S label = makeLabel(l.head); Circle dd = conceptCircle(cal, l.getString(0), false); cal.arrow(dd, label, cc); } } } } sS makeLabel(S id) { SS map = litmap( "gqlkqsxygqmmptoi", "SHORT FOR", "yppdjirdezcvlhhg", "SYNONYM"); try answer map.get(id); S name = conceptToName(id); new Matches m; if (l(name) > 1) name = dropSuffix(".", name); if (flexMatch("X * Y", name, m)) ret toUpper($1); ret toUpper(name); //ret toUpper(id); }