!7 cm UltrafaST > DynWebServee { transient SnippetInstaCache snippetCache; transient S microNewsSnippetID = #1034192; start { snippetCache = new SnippetInstaCache(microNewsSnippetID); print(cachedSnippetIDs := snippetCache.cachedSnippetIDs()); } void cleanMeUp { dispose snippetCache; } @Override O html(IWebRequest req) { try object redirectToHTTPS(req); if (req.uriIs("/favicon.ico")) ret serveFavIcon(gazelleFavIconSnippet()); // almost works except for image scaling / position if (req.uriIs("/carousel/")) { new HImageCarousel carousel; carousel.add(carousel.new Slide(#1103072, "Scriptable", "This screenshot shows my cute new scripting language which is very flexible.")); carousel.add(carousel.new Slide(#1103059, "Interactive Screen Cam", "Here you see Gazelle's preprocessing filters applied to a screen cam.")); ret hhtml(hhead(carousel.headStuff()) + hbody(carousel.html())); } if (req.uriIs("/")) { var newsParas = paragraphs(snippetCache.get(microNewsSnippetID)); new L newsObjects; LS newsItems = map( newsParas, item -> { PairS p = splitAtFirstColon(item); S date = pairA(p), text = pairB(p); newsObjects.add(new NewsItem(date, text)); ret text + " [" + date + "]"; } ); pnl(+newsItems); addAll(newsItems, targetBlank("https://agi.topicbox.com/groups/agi/T419e8a952205967e", "News post") + " [2022/1/22]", targetBlank("https://agi.topicbox.com/groups/agi/T2dea42566ccf6693", "News post") + " [2022/1/7]", targetBlank("https://agi.topicbox.com/groups/agi/T8ca0db34fc106b16/image-recognizers-should-return-mathematical-proofs", "Image recognizers should return mathematical proofs") + " [2021/9/10]", targetBlank("https://agi.topicbox.com/groups/agi/T2771ec3238f217fa/gazelle-looks-at-its-own-logo-and-paints-it-red", "Gazelle looks at its own logo and paints it red") + " [2021/8/20]" ); new LS headings; headings.add(ahref("https://Gaz.AI", "Gaz.AI")); embedded S heading(S text) { headings.add(text); ret aname(text, h3(hcombine( ahref("#top", himgsnippet(#1103033, style := "height: .65em", align := "absmiddle", title := "Back to top")), text))); } S content = h1("Gazelle 22 - a new image recognizer") + (empty(newsObjects) ? "" : p(hcombine(joinNemptiesWithBR( first(newsObjects).date + ":", first(newsObjects).text), ahref("#News", "[More news]")))) + heading("Screenshots") + new Screenshot(#1103088, "2022/3/8", "Extracted letter matrix ready for learning") + new Screenshot(#1103087, "2022/3/8", "Segmenter usually finds 5 letters as expected (the word is 'Hello'), but a few fonts still confuse it.") + new Screenshot(#1103086, "2022/3/7", "Project story editor with hyperlinks & auto-run mechanism for user scripts") + new Screenshot(#1103083, "2022/3/7", "Gazelle has split a word into invididual letters.") + new Screenshot(#1103072, "This screenshot shows my cute new scripting language which is very flexible.") + new Screenshot(#1103059, "Here you see Gazelle's preprocessing filters applied to a screen cam.") + heading("Quick start (Windows, Mac, Linux)") + p("1. Install " + targetBlank("https://adoptium.net", "Temurin 17") + " formerly known as 'Java'." + " (Their smaller \"" + targetBlank("https://adoptium.net/releases.html", "JRE") + "\" version is fine too.)") + p("2. Save and double-click " + ahref("https://github.com/stefan-reich/gazelle-22/releases/download/2022-2-5/Gazelle-22.jar", "Gazelle-22.jar") + " (11 MB).") + heading("What it does") + p(joinWithBR( "Gazelle 22 watches your screen and recognizes things.", "It is being developed right now by " + targetBlank("https://BotCompany.de", "Stefan Reich") + " at " + ahref("https://gazelle.rocks", "Gaz.AI") + ". " + ahref("mailto:info@botcompany.de","Contact.") + " " + ahref("https://discord.gg/kcKKZEg", "Discord."))) + p(targetBlank("https://code.botcompany.de/1033860", "Source repository") + ". " + "Older releases on " + ahref("https://github.com/stefan-reich/gazelle-22", "GitHub") + ".") + heading("Privacy statement") + p(joinWithBR( "Gazelle 22 runs locally on your machine.", "It does not upload any data to any server.", "Server connections are made only for downloading program parts and checking for updates.", "All code, so far, is open source.")) + heading("News") + mapToLines p(newsItems); S nav = aname("top", p(hcombine( ahref("https://Gaz.AI", himgsnippet(#1102967, style := "height: 1em; vertical-align: bottom", title := "Gaz.AI Gazelle Logo")), joinWithVBar(map(s -> ahrefAnchor(s, s), headings))))); ret hhtml(hcombine( hhead(hcombine( htitle("Gazelle 22 - a new image recognizer"), hcss_linkColorInherit(), hsansserif() )), hbody(hfullcenter(hcombine( nav, content))) )); } ret subBot_serve404("Four oh four. Bad URL"); } record noeq Screenshot(S imageID, S date, S text) { *(S *imageID, S *text) {} toString { ret hcombine( p(hsnippetimg_linkToSameImage(imageID, width := 250, title := "Gazelle 22 screenshot - click to enlarge")), pUnlessEmpty(joinNemptiesWithBR(text, squareBracketUnlessEmpty(date))), pNbsp() ); } } srecord NewsItem(S date, S text) {} }