Uses 1113K of libraries. Click here for Pure Java version (16926L/89K).
1 | !7 |
2 | |
3 | cm UltrafaST > DynWebServee { |
4 | transient SnippetInstaCache snippetCache; |
5 | |
6 | transient S microNewsSnippetID = #1034192; |
7 | |
8 | transient S downloadURL = |
9 | //"https://github.com/stefan-reich/gazelle-22/releases/download/2022-6-10/gazelle.jar"; |
10 | "https://botcompany.de/jar/1033860?withX30=1&withLibs=1&mainClassForManifest=Starter&name=Gazelle.jar"; |
11 | |
12 | Set<S> allowedWebhookClientIPs() { |
13 | ret asSet(tlftj([[ |
14 | // TradingView.com |
15 | 52.89.214.238 |
16 | 34.212.75.30 |
17 | 54.218.53.128 |
18 | 52.32.178.7 |
19 | // Myself |
20 | 127.0.0.1 |
21 | 161.97.120.94 |
22 | ]])); |
23 | } |
24 | |
25 | start { |
26 | snippetCache = new SnippetInstaCache(microNewsSnippetID); |
27 | print(cachedSnippetIDs := snippetCache.cachedSnippetIDs()); |
28 | dm_registerAs gazAiHomePage(); |
29 | } |
30 | |
31 | void cleanMeUp { dispose snippetCache; } |
32 | |
33 | @Override O html(IWebRequest req) { |
34 | try object redirectToHTTPS(req); |
35 | |
36 | if (req.uriIs("/favicon.ico")) |
37 | ret serveFavIcon(gazelleFavIconSnippet()); |
38 | |
39 | if (req.uriIsIC("/gazelle.jar")) |
40 | ret subBot_serveRedirect(downloadURL, "application/octet-stream"); |
41 | |
42 | if (req.uriIsIC("/webhook")) { |
43 | S clientIP = req.clientIP(); |
44 | if (!contains(allowedWebhookClientIPs(), clientIP)) |
45 | ret subBot_serve500("Not a registered client IP"); |
46 | |
47 | S content = mapGet(req.files(), "postData"); |
48 | appendLineToFile(javaxDataDir("webhook.log"), |
49 | jsonEncode(litorderedmap(+clientIP, date := formatLocalDate(), +content))); |
50 | ret "OK"; |
51 | } |
52 | |
53 | if (req.uriIs("/")) { |
54 | var newsParas = paragraphs(snippetCache.get(microNewsSnippetID)); |
55 | new L<NewsItem> newsObjects; |
56 | LS newsItems = map( |
57 | newsParas, |
58 | item -> { |
59 | PairS p = splitAtFirstColon(item); |
60 | S date = pairA(p), text = pairB(p); |
61 | newsObjects.add(new NewsItem(date, text)); |
62 | ret text + " [" + date + "]"; |
63 | } |
64 | ); |
65 | //pnl(+newsItems); |
66 | |
67 | addAll(newsItems, |
68 | targetBlank("https://agi.topicbox.com/groups/agi/T419e8a952205967e", "News post") + " [2022/1/22]", |
69 | targetBlank("https://agi.topicbox.com/groups/agi/T2dea42566ccf6693", "News post") + " [2022/1/7]", |
70 | targetBlank("https://agi.topicbox.com/groups/agi/T8ca0db34fc106b16/image-recognizers-should-return-mathematical-proofs", "Image recognizers should return mathematical proofs") + " [2021/9/10]", |
71 | 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]" |
72 | ); |
73 | |
74 | new LS headings; |
75 | headings.add(ahref("https://Gaz.AI", "Gaz.AI")); |
76 | |
77 | embedded S heading(S text, S extra default "") { |
78 | headings.add(text); |
79 | ret aname(text, h3(hcombine( |
80 | ahref("#top", himgsnippet(#1103033, |
81 | style := "height: .65em", align := "absmiddle", |
82 | title := "Back to top")), |
83 | text, |
84 | extra))); |
85 | } |
86 | |
87 | S content = |
88 | h1("Gazelle 22 - a new image recognizer") |
89 | + (empty(newsObjects) ? "" |
90 | : p(hcombine(joinNemptiesWithBR( |
91 | first(newsObjects).date + ":", |
92 | first(newsObjects).text), |
93 | ahref("#News", "[More news]")))) |
94 | + aname("Screenshots") + heading("Latest Screenshots") |
95 | |
96 | + new Screenshot(#1103157, |
97 | "2022/9/5", nlToBr_trim([[ |
98 | <b>Gazelle is learning to read.</b> |
99 | (All characters shown are drawn by Gazelle trying to mimic a screenshot.) |
100 | Not all that bad already! |
101 | And it wasn't even trained on Courier. |
102 | And yes, that fancy artwork <i>could</i> be considered a bug. |
103 | ]])) |
104 | |
105 | + new Screenshot(#1103151, |
106 | "2022/9/3", "Which shape is similar to a 5?") |
107 | |
108 | + new Screenshot(#1103149, |
109 | "2022/9/3", "Gazelle's cheat sheet for all shapes in the extended latin alphabet") |
110 | |
111 | + new Screenshot(#1103138, |
112 | "2022/6/30", "Working on a compressed image format (and the demo is a beautiful main program too)") |
113 | |
114 | + new Screenshot(#1103137, |
115 | "2022/6/2", targetBlank("https://www.youtube.com/watch?v=PgZwlmF5epU&ab_channel=StefanReich", "Recognizing Toilet Paper [Video]")) |
116 | |
117 | + new Screenshot(#1103133, |
118 | "2022/5/22", "A more evolved data graph") |
119 | |
120 | + new Screenshot(#1103132, |
121 | "2022/5/17", "First data graph") |
122 | |
123 | + new Screenshot(#1103131, |
124 | "2022/5/6", "Finding topological graph mappings") |
125 | |
126 | + new Screenshot(#1103128, |
127 | "2022/4/28", "A nice, straight-forward motion detector") |
128 | |
129 | + new Screenshot(/*#1103122*/#1103123, |
130 | "2022/4/17", "Segmenting an image by covering it with single color tiles<br>(left: input, right: output scaled up)") |
131 | |
132 | + new Screenshot(#1103121, |
133 | "2022/4/6", "Semi-automatic conversion of left-arrow scripts to Java(X)") |
134 | |
135 | + new Screenshot(#1103119, |
136 | "2022/4/2", "Optimized script compilation time to below 1 ms (displayed value is rounded up!)") |
137 | |
138 | + new Screenshot(#1103118, |
139 | "2022/4/1", "PDF Import (commercial feature)") |
140 | |
141 | + new Screenshot(#1103116, |
142 | "2022/3/30", "Learning fonts!") |
143 | |
144 | + new Screenshot(#1103112, |
145 | "2022/3/26", "Training the computer as a math student... :)") |
146 | |
147 | + new Screenshot(#1103111, |
148 | "2022/3/23", "Finding junctions and line ends in the letter skeletons") |
149 | |
150 | + new Screenshot(#1103110, |
151 | "2022/3/22", "Artifact-free reduction of letters to 1 pixel-wide skeletons!") |
152 | |
153 | + new Screenshot(#1103105, |
154 | "2022/3/17", "Finding a polygon's corners (marked red)") |
155 | |
156 | + new Screenshot(#1103099, |
157 | "2022/3/13", "A 5 point gradient is recognized!") |
158 | |
159 | + new Screenshot(#1103097, |
160 | "2022/3/12", "Rendering some multi-point gradients [gradient detection coming up too]") |
161 | |
162 | + new Screenshot(#1103095, |
163 | "2022/3/11", "Some recognition of... something!? LOL") |
164 | |
165 | + new Screenshot(#1103094, |
166 | "2022/3/10", "Checking in how many fonts (out of 88) a letter is actually different.<br>Turns out \"e\" has the most versions (83) and \"l\" (lowercase L) has the fewest (76).") |
167 | |
168 | + new Screenshot(#1103093, |
169 | "2022/3/8", "Theoretical number of different images at 3*3 pixels and 3 colors") |
170 | + new Screenshot(#1103092, |
171 | "2022/3/8", "Each letter reduced to 3x3 pixels and 3 colors. Can you still tell them apart? (Each letter in the grid is an H, e, l or o.)") |
172 | + new Screenshot(#1103090, |
173 | "2022/3/8", "Each letter was padded into a square") |
174 | + new Screenshot(#1103088, |
175 | "2022/3/8", "Extracted letter matrix ready for learning") |
176 | + new Screenshot(#1103087, |
177 | "2022/3/8", "Segmenter usually finds 5 letters as expected (the word is 'Hello'), but a few fonts still confuse it.") |
178 | + new Screenshot(#1103086, |
179 | "2022/3/7", "Project story editor with hyperlinks & auto-run mechanism for user scripts") |
180 | + new Screenshot(#1103083, |
181 | "2022/3/7", "Gazelle has split a word into invididual letters.") |
182 | + new Screenshot(#1103072, |
183 | "This screenshot shows my cute new scripting language which is very flexible.") |
184 | + new Screenshot(#1103059, |
185 | "Here you see Gazelle's preprocessing filters applied to a screen cam.") |
186 | |
187 | + heading("Quick start (Windows, Mac, Linux)") |
188 | + p("1. Install " |
189 | + targetBlank("https://adoptium.net", "Temurin 17") + " or any recent Java version." |
190 | + " (Their smaller \"" + targetBlank("https://adoptium.net/releases.html", "JRE") + "\" version is fine too. If you already have Java, just go to step 2.)") |
191 | + p("2. Save and double-click " |
192 | + ahref(downloadURL, "Gazelle.jar") + " (it's under 30 MB).") |
193 | |
194 | + heading("What it does") |
195 | + p(joinWithBR( |
196 | "Gazelle 22 watches your screen and recognizes things.", |
197 | "It is being developed right now by " |
198 | + targetBlank("https://BotCompany.de", "Stefan Reich") |
199 | + " at " + ahref("https://gazelle.rocks", "Gaz.AI") + ". " |
200 | + ahref("mailto:info@botcompany.de","Contact.") + " " |
201 | /*+ ahref("https://discord.gg/kcKKZEg", "Discord.")*/)) |
202 | + p(targetBlank("https://code.botcompany.de/1033860", "Source repository") + ". " |
203 | + "Older releases on " + ahref("https://github.com/stefan-reich/gazelle-22", "GitHub") + ".") |
204 | |
205 | + heading("Privacy statement") |
206 | |
207 | + p(joinWithBR( |
208 | "Gazelle 22 runs locally on your machine.", |
209 | "It does not upload any data to any server.", |
210 | "Server connections are made only for downloading program parts and checking for updates.", |
211 | "All code is open source.")) |
212 | |
213 | + heading("News") |
214 | + mapToLines p(newsItems) |
215 | + p("Imprint: Stefan Reich, Dubenhorst 27, 25474 Ellerbek"); |
216 | |
217 | S nav = aname("top", p(hcombine( |
218 | ahref("https://Gaz.AI", himgsnippet(#1102967, |
219 | style := "height: 1em; vertical-align: bottom", |
220 | title := "Gaz.AI Gazelle Logo")), |
221 | joinWithVBar(map(s -> ahrefAnchor(s, s), headings))))); |
222 | |
223 | ret hhtml(hcombine( |
224 | hhead(hcombine( |
225 | htitle("Gazelle 22 - a new image recognizer"), |
226 | hcss_linkColorInherit(), |
227 | hsansserif(), |
228 | hmobilefix() |
229 | )), |
230 | hbody(hfullcenter(hcombine( |
231 | nav, |
232 | content))) |
233 | )); |
234 | } |
235 | |
236 | // almost works except for image scaling / position |
237 | if (req.uriIs("/carousel/")) { |
238 | new HImageCarousel carousel; |
239 | carousel.add(carousel.new Slide(#1103072, "Scriptable", |
240 | "This screenshot shows my cute new scripting language which is very flexible.")); |
241 | carousel.add(carousel.new Slide(#1103059, "Interactive Screen Cam", |
242 | "Here you see Gazelle's preprocessing filters applied to a screen cam.")); |
243 | |
244 | ret hhtml(hhead(carousel.headStuff()) + hbody(carousel.html())); |
245 | } |
246 | |
247 | ret subBot_serve404("Four oh four. Bad URL"); |
248 | } |
249 | |
250 | record noeq Screenshot(S imageID, S date, S text) { |
251 | *(S *imageID, S *text) {} |
252 | |
253 | toString { |
254 | ret hcombine( |
255 | p(hsnippetimg_linkToSameImage(imageID, width := 250, title := "Gazelle 22 screenshot - click to enlarge")), |
256 | pUnlessEmpty(joinNemptiesWithBR(text, squareBracketUnlessEmpty(date))), |
257 | pNbsp() |
258 | ); |
259 | } |
260 | } |
261 | |
262 | srecord NewsItem(S date, S text) {} |
263 | } |
download show line numbers debug dex old transpilations
Travelled to 4 computer(s): bhatertpkbcr, iveijnkanddl, mqqgnosmbjvj, pyentgdyhuwx
No comments. add comment
Snippet ID: | #1032402 |
Snippet name: | gaz.ai home page [LIVE] |
Eternal ID of this version: | #1032402/195 |
Text MD5: | c141b4b3de59b5cc944bcef2ef04fdb3 |
Transpilation MD5: | 5cdbe8e6f50df0584cbc3b0829aeaf14 |
Author: | stefan |
Category: | javax |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2023-02-19 00:48:57 |
Source code size: | 10996 bytes / 263 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 738 / 173106 |
Version history: | 194 change(s) |
Referenced in: | [show references] |