Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image Upload data

1308
LINES

< > BotCompany Repo | #1016323 - Blog Bot [DOMAIN BOT]

JavaX module (desktop) [tags: butter use-pretranspiled] - homepage

Libraryless. Click here for Pure Java version (5402L/51K).

!7

static new ThreadLocal<Bool> youtubeOff;

static int perPage = 20;
sbool pkiValidation = true;

sS rawSelfLink(S uri) { ret "/blog" + addSlashPrefix(uri); }

html {
  S vis = registerVisitor();
  
  S domain = domain();
  print("domain: " + domain);
  
  if (eqic(domain, "code.botcompany.de")) {
    long snippetID = parseLong(dropSlashPrefix(uri));
    ret hrefresh(snippetID == 0
      ? "http://code.botcompany.de:8081/tb/snippets.php"
      : "http://code.botcompany.de:8081/tb/show-snippet.php?id=" + snippetID);
  }
  
  if (swic(domain, "javax.")) {
    pcall {
      O result = callHtmlMethod2(getBot(#1020398), uri, params);
      print("Result: " + className(result));
      ret result;
    }
  }
  
  if (eqic(domain, "recognizer.botcompany.de"))
    ret subBot_serveRedirect("https://botcompany.de/files/1400260/chess-board-recognizer-0.2.jar");
    
  if (eqic(domain, "discord-fan.botcompany.de"))
    ret subBot_serveRedirect("https://botcompany.de/files/1400274/Discord-Fan.jar");
    
  if (eqic(domain, "stefans-os.botcompany.de"))
    ret subBot_serveRedirect("https://botcompany.de/1013826/raw");
    
  if (eqicOneOf(domain, "jumpcut.botcompany.de", "ajc.botcompany.de"))
    ret subBot_serveRedirect("https://botcompany.de/files/1400263/AutoJumpCut-Installer-0.6-win32.exe");
  
  if (pkiValidation && startsWith(uri, "/.well-known/pki-validation/"))
    ret subBot_serveText(loadTextFile(userDir("validation.txt")));

  if (isAGIBlueDomain(domain))
    ret eleu_serveSubBot(#1023558, uri, params);
    
  tempSetThreadLocal(youtubeOff, eq("1", params.get('youtubeOff))
    || eqOneOf(params.get('youtube), "0", "off", "no"));
  O[] linkStyle = litobjectarray("style", "color: inherit; text-decoration: underline");
  
  uri = dropPrefix("/", uri);
  int page = startsWithDigit(uri) ? parseFirstInt(uri) : 1;
  S date = params.get('date);
  
  LS allPosts = ll(
    textPost("2019/09/13", "Whenever my language bores me",
    
    p([[...I extend it. (Have I said that before? Deja vu!)]]) +
    
    p([[Let's say I am annoyed by the inability to nest a function inside a function in Java. So I invent the "embedded" keyword.]]) +
    
    pre(htmlJavaIdentifierTooltips([[
sS bla() {
  S x = "hello";
  embedded S calc() { ret x + " " + x; }
  ret calc() + " " + calc();
}
]],
  "sS", "short for: static String",
  "S", "short for: String",
  "ret", "short for: return")) +

    p("In this useless but instructive example, I embed the function " + tt("calc") + " in the function " + tt("bla") + " with access to the local variable " + tt("x") + [[.]]) +
    
    p([[How is it translated? Using a function of ]] + targetBlank("http://code.botcompany.de/1025200", "a mere 21 lines") + [[ and an anonymous inner class. (Nota bene: It's currently more or less limited to a single embedded function per "mother".)]]) +
    
    p(targetBlank("http://code.botcompany.de/1025201", "Example with translation to Java."))),
    
    imagePost("2019/09/10", "A programming language that makes DOOM levels",
    #1102659, "50%",
    
    p("This is such a wonder. A compiler written in Java compiling a slightly weird, but interesting Logo-inspired special purpose language into actual DOOM levels. Our AI could produce DOOM levels for us from just a simple description.")
    
    + p("Oh, ah... " + targetBlank("https://jmtd.net/wadc/", b("link")) + ".")),
    
    textPost("2019/09/01", "This program is a Discord fan",
    
    p(youtubi("CvcafQ6YTlQ"))),
    
    imagePost("2019/08/31", "Beta Software!",
    #1102549, "50%",
    
    p("But a " + targetBlank("http://recognizer.botcompany.de", "good one") + ".")),
    
    textPost("2019/09/01", "Constructs that Java needed",
    
    p("Question-dot.") +
    pre([[c ?. setDoubleBuffered(b);]]) +
    p(b("=>")) +
    pre([[if (c != null) c.setDoubleBuffered(c);]])),
    
    textPost("2019/09/01", "Zero Training Time Neural Networks",
    
    p("New invention.")),
    
    imagePost("2019/09/01", "Paging The Reflex",
    #1102552, "50%",
    
    p("&nbsp;")),
    
    imagePost("2019/08/31", "Unix just doesn't understand me...",
    #1102550, "50%",
    
    p("Huh."),
    left := true),
    
    imagePost("2019/08/26", "Chess Board Recognition",
    #1102266, "35%",
    
    p("Coming up.")),
    
    textPost("2019/08/18", "You can help train desktop image segmentation",
    
    p(youtubi("W6eJSCGEkSE"))),
    
    textPost("2019/08/15", "Giraffe v3&mdash;now stores information",
    
    p(youtubi("gbQNejT1xdk"))),
    
    textPost("2019/08/12", "Building a simple translator in agi.blue",
    
    p("The demo is word-based, but we have a function for efficient phrase-based translation too.") +
    
    youtubi("w2gJ63tvTW8")),
    
    textPost("2019/08/12", "An array with O(log n) time for all operations",
    
    p("I invented a new data structure (I think). It's an array (variable-size list) where each add, remove, update and random access completes in O(log n) time.") +
    
    p("I call it a " + targetBlank("http://code.botcompany.de/1024413", "Log-N array") + ". The implementation uses an order statistic red-black tree. This could be nice for handling long token lists during JavaX transpilation.")),
    
    imagePost("2019/08/11", "Today I wrote a whole bot",
    #1101842, "25%",
    
    p("...live on stream. Sadly, frame rate dropped to 6 frames a minute at some point. Hopefully fixed next time. " + targetBlank("https://www.twitch.tv/videos/465661725", "Video here.")
    + " " + targetBlank("http://code.botcompany.de/1024415", "Code made."))),
    
    textPost("2019/08/10", "Live Coding For Nerds",
    
    p("Stefan Reich builds agi.blue, the Google-killing AI database & chat bot making platform. New functions built: Inter-slice links, Delete page, Checkboxes.")
    + youtubi("7ZRvktYYHuk")),
    
    textPost("2019/08/09", "I did my first live-coding stream",
    
    p([[...and now it is ]] + targetBlank("https://www.twitch.tv/stefanreich", "lost") + [[ because I didn't click "Save broadcast". Was fun though, thx to Lemon for participating.]])
    
    + p([[And of course, code got made. Specifically, agi.blue slices now have ]] + targetBlank("https://agi.blue/?slice=jbmjskptrptihmzk", "owners") + ".")),
    
    textPost("2019/08/04", "\"Be Thankful\"",
    
    p("Randall Brown &amp; band (including me).") +
    
    youtubi("debRuSo8CZk")),
    
    textPost("2019/08/04", "Why AGI.blue beats Google",
    
    p("Because White-Box.") +
    
    youtubi("bwUE_XJMbok")),
    
    imagePost("2019/08/01", "Let's make programs",
      #1101823, "40%",
    
      p("...that understand everything.")),
    
    textPost("2019/07/28", "Revamping agi.blue",
    
    p(targetBlank("https://agi.blue", "agi.blue") + " now has a query language that looks like this:")
    
    + pre([[
word types / is plural of / $x
$y / is a / $x
return $y
]])

   + p("This example " + targetBlank("https://agi.blue/bot/query?query=word+types+%2F+is+plural+of+%2F+%24x%0A%24y+%2F+is+a+%2F+%24x%0Areturn+%24y", "queries the database") + " for a random " + targetBlank(agiBlue_linkForPhrase("word type"), "word type") + ".")),
   
    /*textPost("2019/07/26", "Devastating HTTPS bug in JDK 11+12; fix might be coming",
    
    p("This really needs to be fixed. Can't upgrade my web server. "+ ahref("http://botcompany.de:8081/ssl-bugreport.tgz", "Demonstration for download."))
    
    + p("Update: This seems to be fixed in JDK 13 which is nearing general release. Very nice!")),*/
    
    imagePost("2019/07/25", "GBot googles in your Discord",
    #1101771, "20%",
    
    p("Hey ho, we got " + targetBlank("https://discordbots.org/bot/602481480266153984", "our bot") + " approved. You can " + targetBlank("https://discordapp.com/api/oauth2/authorize?client_id=602481480266153984&scope=bot&permissions=0", "invite it") + " to your Discord group if you have one.")),
    
    textPost("2019/07/14", "Coarse Procedures &amp; Power Words",
    
    p(targetBlank("http://code.botcompany.de/1023890", "Coarse Procedures.") + " " + targetBlank("http://code.botcompany.de/1023964", "Power Words.")) +
    
    + p("Concepts we need.")),
    
    textPost("2019/07/08", "AI Does Simple Reading Comprehension",
    
    p("Consider this text:")
    
    + pre([[
First, I wake up. Then, I get dressed.
I walk to school. I do not ride a bike.
]] + targetBlank("https://lingua.com/english/reading/my-day/", "[...]") + [[

Question 1: What happens first?

  1 Get dressed   2 Wake up
  3 Eat lunch     4 Walk to school
  
[+4 more questions]
]])

    + p(targetBlank("http://code.botcompany.de/1023742", "Program that solves this.") + " (One screen of code as always.)")
    + p("The engine is pretty generic. It works by correlating words in the text, the question and the answer. The only additional information we put in is a list of \"important words\"&mdash;this time in the form of " + i(targetBlank("https://www.vogella.com/tutorials/JavaRegularExpressions/article.html", "regular expressions")) + ":")
    
    + pre_htmlEncode([["(?<!not )like", "not like", "dinner", "school", "bed"]])
    
    + p([[The first expression matches on "like", but not on "not like" which avoids some confusion.]])
    
    + p([[(Why do we have to put in these regular expressions? Well, the AI is young, so we help it out a little bit. The semantic knowledge the AI gathers in these exercises will eventually allow it to function without human help.)]])
    
    + p("Now on to more challenges!")),
  
    imagePost("2019/06/30", targetBlank("https://agi.blue", "agi.blue") + " &mdash; " + targetBlank("http://an-agi-is-a-web-server.agi.blue", "An AGI is a web server"),
    #1101682, "25%",
      p(targetBlank("https://agi.blue", "agi.blue") + ". Ask anything.")
    + p(youtubi("b6jtRdV3Ev8"))
    + p("Yeah it's pretty empty. Let's fill it! Just talk. No limits.")),
    
    imagePost("2019/06/27", "We can now build bots for Gitter",
    #1101680, "50%",
    p("Integrating with the world. " + targetBlank("https://gitter.im/qanda-api/Lobby", "A friend's room") + " with some bots.")
    + p("My " + targetBlank("http://tinybrain.de/1023546", "JavaX Gitter implementation") + " which is about a million times shorter than anyone else's&mdash;only one screen of code.")),
    
    imagePost("2019/06/23", "When bots work together",
    #1101670, "15%",
    p("Hello Monkey &amp; Gazelle."),
    left := true),
    
    textPost("2019/06/13", "My Fiverr Intro",

    p("Yeah it's unscripted. Geniuses work like that.")
    
    + youtubi("hHsnHuDRGOQ")),
    
    textPost("2019/06/11", "Android assistant is coming back",
    
    p("...now with multi-user support. Download " + ahref("http://android.tinybrain.de", "here") + ".")
    
    + p("No it's not in the play store. Blame Google.")),
    
    textPost("2019/06/15", "Proof that StackOverflow is broken",
    
    p(targetBlank("https://stackoverflow.com/questions/56605840/how-to-stream-a-windows-contents-to-a-video-file-using-gstreamer", "Original post.") + " Oh my! It is on the wrong subsite. What do they do? Do they move it? No&mdash;they lock it. Classic StackOverflow admin malfunction.")
    
    + p("So we " + targetBlank("https://superuser.com/questions/1449094/how-to-stream-a-windows-contents-to-a-video-file-using-gstreamer", "move it ourselves") + ". What will happen next?")),
    
    /*textPost("2019/05/31", "Julian Assange is being killed",
    
    p("UK government " + ahref("https://www.youtube.com/watch?v=tJPbZuaqh8w", "finishes the job") + ".")),*/

    textPost("2019/05/17", "The 3 mental spaces",
    
    p("Human, computer, objective.")
    + youtubi("W3mm7GUN7dE")),
    
    textPost("2019/05/15", "I want to build a team now",
    
    p("No more working alone!")),
    
    textPost("2019/05/15", "Our brains have 2 parts",
    
    p("...and they're (probably) not the ones you think.")
    + youtubi("qIEuvJSy06o")),
    
    /*textPost("2019/05/02", "Beer &amp; Hamburg",
    
    p("Blubb") +
    youtubi("muTDaOiTwC8")),*/

    textPost("2019/05/02", "Phrase Corrector",
    
    p("Approaching AI, chapter 915423") +
    youtubi("qVjndUIivoY")),
    
    textPost("2019/04/30", "One User Second",
    
    p("...should be enough time for a bot to respond.") +
    youtubi("F9FCV8SVpnA")),
    
    textPost("2019/04/29", "The two fundamental ways to make a chat bot",
    
    p("") +
    youtubi("l7Nbk7qAR5M")),
    
    textPost("2019/04/23", "Recognizing things on a screen",
    
    p("More edutainment for your pleasure!")
    + youtubi("tq6uBfbAClc")),
    
    /*textPost("2019/04/23", "Is society stable?",
    
    p("An important question!")
    + youtubi("IcfuXjQh3Bs")),*/
    
    textPost("2019/04/19", "First easter without a death wish",
    p("Now if that isn't a change. Videos about AI coming.")),
    
    imagePost("2019/04/04", "Whenever my language bores me",
    #1101627, "40%",
    p("...I shorten it. Let's say I want to make a big input field with full persistence and switchable font size (like you see on the right). Then I write " + ahref("http://tinybrain.de/1022742", "this") + ":")
+ [[<pre style="clear: both"><span title="compact module (sharing common code)" style="border-bottom: dotted 1px">cmodule</span> BigInput {
  <span title="short for: String" style="border-bottom: dotted 1px">S</span> text; // auto-persisted string field
  <span title="A field that can be changed through the module's popup menu" style="border-bottom: dotted 1px">switchable</span> int fontSize = 40;
  <span title="short definition of the visualize() function" style="border-bottom: dotted 1px">visual</span> <a title="setFontSize" style="text-decoration: none; color: black; border-bottom: dotted 1px" href="http://tinybrain.de:8080/tb/show-snippet.php?id=1007197">setFontSize</a>(fontSize, <a title="dm_textArea - synonym of dm_fieldTextArea" style="text-decoration: none; color: black; border-bottom: dotted 1px" href="http://tinybrain.de:8080/tb/show-snippet.php?id=1021496">dm_textArea</a>(<span title="string constant, &#34;text&#34;" style="border-bottom: dotted 1px">'text</span>));
}</pre>]]
    + p("(I just created the 2 new JavaX syntax constructs " + ahref("http://tinybrain.de/1022743", "'switchable'") + " and " + ahref("http://tinybrain.de/1022746", "'visual'") + " in like 10 minutes. Hover over the source code for more info.) &mdash;" + ahref("http://botcompany.de/1004590/raw/1101628", "Automatic popup menu."))
    ),
    
    textPost("2019/03/31", "New stuff to test",
    p("If " + ahref("https://botcompany.de/files/1400204/dialog-kit-dummy.jar", "this") + " runs, you're read-d-dy for making a bot. (Actual software coming up.)")),
    
    /*textPost("2019/03/27", "New domain",
    
    p("dialogkit.xyz [in preparation] - in two minutes to your bot. And it's free")),*/
    
    textPost("2019/03/27", "From dialog to chat bot 101",
    p("(In a few steps, that is.)")
    + pre([[
What time is it?
It's 5:30
Why did you say that?
Because you asked me what time it is.
]])),

    imagePost("2019/03/26", "Bots now available 'standalone'",
    #1101625, "50%",
    p("One huge jar file. Includes a GUI and a database. And learns from the cloud while running.")),
    
    imagePost("2019/03/24", "Gazelle",
    #1101622, "30%",
    
    p("...will explain itself (as a general principle)."), left := true),
    
    textPost("2019/03/17", "First professional bot being built",
    p("Not sure if I'm allowed to tell you more yet... :-)")),
    
    textPost("2019/03/22", "My OS is really happy with 8 GB of RAM",
    p("...and any Windows installation. Enough space for AI experiments&mdash;and enough space for memory-hungry Firefox. " + ahref("https://www.botcompany.de/files/1400170/Stefans%20OS%20Installer.exe", "Try it out") + " yourself!")),
    
    imagePost("2019/03/11", "Accommodating human stuttering",
    #1101580, "35%",
    p([[Yes, it's all automatic. The original rule is just matching for ]] + ahref("http://gazelle.botcompany.de/rule/caehawgpuyqsdiig", [["what's the rule count"]]) + ".")),
    
    textPost("2019/03/07", "Coder muscle flexing :)",
    
    p("Sometimes I just have to do this&mdash;coming up with a really intelligent little solution for common coding questions that, oddly, don't seem to have an answer yet.")
    
    + p("Like this one: " + ahref("https://codereview.stackexchange.com/questions/106761/find-if-the-prefix-of-the-string-exists-in-the-values-of-the-hash-table/214969#214969", "How to find out efficiently whether a prefix of a string is contained in a tree set") + ".")
    
    + p("PS: Haha, now StackOverflow is saying they want to delete the answer. I was improving on another answer which apparently is not being deleted? StackOverflow is complete madness as I have said before.")),
    
    textPost("2019/03/07", "Mini-investment needed",
    p("Sorry... I can't <i>always</i> turn water to wine. Need some grapes. " + ahref("https://www.meetup.com/Artificial-Intelligence-Meetup/messages/boards/thread/52050719", "Details."))),
    
    textPost("2019/03/06", "I just made Gazelle scalable",
    p("10,000 rules shouldn't be a problem at all. We do want " + ahref("https://en.wikipedia.org/wiki/Artificial_general_intelligence", "AGI") + ", don't we?")),
    
    imagePost("2019/03/03", "Gazelle is offended",
    #1101557, "15%",
    p("No further comment."), left := true),
    
    imagePost("2019/03/02", "Gazelle's Auto-Math Module",
    #1101549, "30%",
    p("Given these example dialogs:")
    + pre_rtrim([[
  10 games of 2 minutes each => that makes 20 minutes
  30 games of 3 minutes each => that makes 90 minutes
    ]])
    + p("Gazelle understands what kind of calculation you mean and performs it for you on new input.")),
    
    imagePost("2019/02/24", "Gazelle Learns",
    #1101499, "50%",
    
    p("Come join us over at " + targetBlank(nextGenBotsDiscordInvite(), "Discord") + "."),
      left := true),
    
    textPost("2019/02/22", "New Discord Group",
    
    p(targetBlank("https://discordapp.com/invite/SEAjPqk", "See you there!"))),
    
    imagePost("2019/02/16", "Analyzing Wikipedia",
    #1101493, "50%",
    p("Nothing can stop this.")
    + p("In other news, my current cash level (for the rest of the month) is roundabout 10 €. Money is such a great invention!")),
    
    imagePost("2019/02/15", "Gazelle growing",
    #1101483, "50%",
    p(b("Here soon.")), left := true),
    
    imagePost("2019/02/11", "A new logic engine",
    #1101482, "40%",
    
    p("A logic engine is what makes machines talk.")
    + p("This new one I'm making is really impressive.")
    + p([[The new engine merges syntax and semantics; allows humans to teach the machine how to think easily; and it doesn't require a full model of the language in question (say, English).]])
    + p([[Surely it needs a cool code name, right? How about... uhm... <b>"Gazelle"</b>? "Panther"? Goldfish? Rubber duck? Something!]])
    + p("Either way: <b>Expect demos soon.</b> Until then, enjoy the chewing gazelle.")),
    
    textPost("2019/02/08", "Who smokes dope?",
    
    p("Input:")
    + pre("I visited the pope. He smokes dope.")
    + p("Output:")
    + pre("I visited {the pope} [*1]. He [1] smokes dope.")
    + p([[([*1], [1] and the curly braces mean that "he" points to "the pope".)]])
    + p(ahref("http://tinybrain.de/1021323", "Function that does this."))),
    
    textPost("2019/02/06", "Ways to eat pizza",
    
    p(targetBlank("http://mattmahoney.net/", "Matt Mahoney") + [[ recently gave this little example of ways in which language is ambiguous:]])
    
    + pre([[
I ate pizza with a fork.
I ate pizza with pepperoni.
I ate pizza with Bob.
]])

     + p([[I was inspired to make a program to interpret these different meanings of the word "with". I used the 3 lines as training examples, then made some new examples for testing.]])

     + p([[My program is a logic engine that takes the following rules:]])

     + pre([[
// Some reasonings that everybody will understand.
// Sorry for the curly braces, we have to help out the parser a tiny bit.
// First, the 3 different cases of what "pizza with..." can mean.

  I ate pizza with pepperoni.
  => {I ate pizza} and {the pizza had pepperoni on it}.
  
  I ate pizza with Bob.
  => {I ate pizza} and {Bob was with me}.
  
  I ate pizza with a fork.
  => I used a fork to eat pizza.
  
// Now some more easy rules.
  
  I used a fork to eat pizza.
  => I used a fork.
  
  I used a fork.
  => A fork is a tool.
  
  The pizza had pepperoni on it.
  => Pepperoni is edible.
  
  Bob was with me.
  => Bob is a person.

// Some VERY basic mathematical logic

  $A and $B.
  => $A.
  
  $A and $B.
  => $B.

// Tell the machine what is not plausible

  Mom is edible. => fail
  Mom is a tool. => fail
  anchovis are a tool. => fail
  anchovis are a person. => fail
  ducks are a tool. => fail
  ducks are a person. => fail
  my hands are edible. => fail
  my hands are a person. => fail
]])

   + p([[The logic engine performs some analogy reasoning using the rules stated above. Note that most of the rules don't distinguish between variable and non-variable parts, this is usually inferred automatically.]])

   + p([[That's it! Now we give the program the following new inputs:]])

   + pre([[
  I ate pizza with mom.
  I ate pizza with anchovis.
  I ate pizza with ducks.
  I ate pizza with my hands.
]])

  + p([[...and it comes up with these clarifications:]])

  + pre([[
I ate pizza with anchovis. => I ate pizza and the pizza had anchovis on it.
I ate pizza with ducks.    => I ate pizza and the pizza had ducks on it.
I ate pizza with mom.      => I ate pizza and mom was with me.
I ate pizza with my hands. => I used my hands to eat pizza.
]])

  + p([[
So nice! It's all correct. Sure, nobody would say "the pizza had ducks on it", but that is the most reasonable interpretation of the rather bizarre input sentence after the program eliminated the other two options (ducks as a tool or ducks as a person).]])

  + p([[If you remove the line that says ducks are not persons, the program will correctly add the interpretation "I ate pizza and ducks were with me."]])

  + p(targetBlank("http://tinybrain.de/1021251", "Full program in my fancy language."))

  + p([[In addition to the results, the program also shows some lines of reasoning, e.g. failed lines:]])

  + pre([[
Interpretation: I ate pizza and the pizza had mom on it.
   => I ate pizza.
   => the pizza had mom on it.
     => mom is edible.
       => fail
]])

   + p([[and successful lines:]])

   + pre([[
Interpretation: I used my hands to eat pizza.
   => I used my hands.
     => my hands are a tool.
]])

   + p([[Why did I make a specific program for this puzzle? Well, it's not a special-purpose program really. It's a general-purpose logic engine that supports problems of a certain complexity. Like a child understands everything as long as it's not too complicated. The plan is to make increasingly more capable logic engines until we can solve everything.]])

    + p([[The program itself is ]] + targetBlank("http://tinybrain.de/1021251", "&lt;100 lines") + [[ (not counting rules and input), but of course it uses some powerful library functions.]])),

    imagePost("2019/09/04", "New Module Preview",
    #1101481, "50%",
    
    p("Comin' up.")),
    
    textPost("2019/02/03", "English to Rule",
    
      p("<b>Input</b> (plain English, not executable):")
    + pre("If something is heavy, it weighs many grams")
    + p("This should be converted to this <b>rule</b> which is executable:")
    + pre("fact($something is heavy) => fact($something weighs many grams)")
    + p("<b>Actual program</b> that does the conversion:")
    + pre(ahref("http://tinybrain.de/1021228", "ai_ifToFactRule_2") + [[(
  "If something is heavy, it weighs many grams",
  litciset("it"),       // pronouns
  litciset("something") // nouns
)
]])
    + p("As you see, the only customization the function requires is a list of pronouns and nouns.")
    + p("Finally, we can <b>test</b> the new rule.")
    + pre([[
ai_applyFactToFactRules(
  "fact($something is heavy) => fact($something weighs many grams)",
  "John is heavy")
]])
    + p("which yields:")
    + pre([=[[John weighs many grams]]=])
    ),
    
    textPost("2019/02/03", "Switching back to Chrome",
    
    p("YouTube is unusable on Firefox. It's " + ahref("https://www.tubefilter.com/2018/07/25/youtube-slow-firefox-chris-peterson/", "probably deliberate") + ". That's what you get from a monopoly...")),
    
    textPost("2019/01/23", "Machine Asks Questions",
    
      p("Artificial philosopher in the making.")
    + p(youtubi("3OD8l25EJ90"))),
    
    textPost("2019/01/20", "Collaboration with AIRIS?",
    
    p("Here's an " + targetBlank("https://github.com/berickcook/AIRIS_Public", "interesting project") + " for reinforcement learning which, just possibly, may be a good addition to my software infrastructure.") +
    
    p("There is a language gap to bridge (Python/JavaX), but that's what we went to university for, didn't we?")),
    
    textPost("2019/01/12", "The Best Play List",
    
    p("Just thought I'd share this. " + targetBlank("https://www.youtube.com/watch?v=TcVv-hfsMy8&index=1&list=PLI8CaFciVcxjC2o0RQsnKc4Nf4l31e8Xd", "A literal remix heaven") + " by The Reflex.")),
    
    textPost("2019/01/09", "JavaX vs Smalltalk [the programming language]",
    
    p([[You see, I do know a bit of history. I was part of the Smalltalk
    movement 'cause yeah, that thing has a tremendous charme. Miles ahead of everything.]])
    + p([[In fact, it just dawned on me, JavaX offers a lot of the fabulous Smalltalk experience&mdash;an integrated virtual machine where
    source, runnable code, GUIs and orthogonally persistent data intersect each other.]])
    + p([[So where did Smalltalk ]] + a("fail", title := [[IMO, Smalltalk relied too much on a monolithic "system image" to hold both code and data, making code versioning and distribution very hard.]]) + [[? Mouse over for more info. And no, JavaX does not suffer from the same problem.]])),
    
    textPost("2019/01/06", "Tabs++ (or: avoiding the complexity problem)",
    
    p(youtubi("FoAJLMbctoQ"))),
    
    textPost("2019/01/04", "Why a Java OS? The \"Kilroy\" Demo",
    
    p("Because a next generation OS just has more smartness.")
    
    + p(youtubi("2AdbbSf3y-M"))),
    
    textPost("2019/01/02", "Frantic action",
    
    p("I want to finish the big project now: the talking operating system.")),
    
    textPost("2019/01/01", "I should be a CEO",
    
    p("I'm the right man for the job. I understand technology, people&mdash;and I understand the madness that money represents. Also I don't have to do " + ahref("https://www.thisisinsider.com/elon-musk-reportedly-terrified-tesla-staff-with-his-firing-sprees-2018-12?utm_source=quora&utm_medium=referral", "this") + ".")),
    
    /*textPost("2018/12/31", "Cryptography is scary",
    
    p("...but I got it working fine&mdash;see this website's nice new HTTPS certificate (check the lock icon in your browser) which will be good for another full year.")),*/
    
    imagePost("2018/12/30", [[The "Third Wave of AI"]],
    #1101469, "",
    
    p([[In the generally quite rotten IT industry, there is now talk of a "third wave of AI". And, interestingly,
    this time they float pretty much <b>the ideas I have been pushing for the last 5 years</b>.]])
    
    + p([[Although of course it's fair to say I still have a lot of tricks in petto they didn't even conceive yet.]])
    
    + p([[So is now the time for change?]])),
    
    /*textPost("2018/12/30", "I have 4 servers now",
    p([[...registered with 4 different companies, no less. (Diversify!) All nice little Linux v-servers. Interestingly, the hosting companies are all German&mdash;for unknown reasons, American v-servers are crazy expensive.]])
    
    + p([[In fact, for less than 10 bucks, I can rent a decently fast server for one month. By running a single shell script, I get it up and running, including a VNC-based GUI and my fabulous Java OS. Tell me again why I would need the Amazon cloud?]])),*/
    
    textPost("2018/12/22", "Humanity is still cursed",
                
                p("You realize that right? That humanity is nowhere near as free, enlightened and happy as it could be?")
                
                + p("The main reason is that they still believe in \"competition\" instead of collaboration... so almost nobody gets anything done.")
                + p("Happy Christmas! (?)"))
                
                , textPost("2018/12/19", "More information about JavaX",
                
                p(ahref("http://javax.botcompany.de/", "Finally... :)")))
                
                , textPost("2018/12/14", "Downloads Fixed",
                
                p("So sorry&mdash;there was a bug in the download files causing installation to fail for new users. Now fixed!"))
                
                , textPost("2018/12/13", "Teaching Colors, Hands-Free",
                
                p(youtubi("JhBhqdpuFf8")))
                
                , imagePost("2018/12/10", [["Alexa Mode" Works]],
                #1101451, "60%",
                p([["Alexa Mode" means the computer always listens. Standard feature of my OS.]]), left := true)
                
                , imagePost("2018/12/10", "New Language",
                #1101450, "60%",
                p("It's a lower-level natural language. Can you read it?"))
                
                , imagePost("2018/12/09", "Circle Finder",
                #1101449, "30%",
                
                p("God I love image recognition. ")
                
                + p(targetBlank("http://tinybrain.de/1020191", "Source.") + " Ships as part of my operating system."), left := true)
                
                , imagePost("2018/12/06", "Nice little reload buttons",
                #1101445, "23%",
                
                p("Whenever there is new code, one click suffices to get it.")
                
                + p("In other news, I am looking for a part-time Java job (maybe). Anyway... something's gotta happen."))

                , textPost("2018/12/04", "Onboarding Demo",
                
                p(youtubi("l09WeK6uHSE")))
                
                , textPost("2018/12/04", "Ordering computers from the universe",
                
                p("Can it work?"))
                
                , textPost("2018/12/02", "Computer insults me",
                
                p("New frontier in computer science. " + targetBlank("http://tinybrain.de/1019961", 35, linkStyle) + " code lines.")
                
                + p(youtubi("XTN0Z60_k00")))
                
                , imagePost("2018/12/02", "My own VNC clone",
                #1101444, "30%",
                p(targetBlank("http://tinybrain.de/1019894", "Comes for free", style := "color: inherit; text-decoration: underline") + " with my OS. Both sides can be behind firewalls. " + targetBlank("http://tinybrain.de/1019873", "GIF recorder", style := "color: inherit; text-decoration: underline") + " also included."))
                
                , imagePost("2018/11/28", "Defeating Java Class Loaders",
                #1101439, "40%",
                p("<b>Java is great</b>, but its need for class loaders means it's somewhat hard to add code at runtime.")
                
                + p(targetBlank("http://javax.tinybrain.de", "<b>JavaX</b>", style := "color: inherit") + " comes to the solution! I have implemented an arsenal of tricks that turn Java into something just about as flexible as JavaScript&mdash;while retaining the full power and speed of the Java VM.")
                
                + p("In fact, in JavaX, we write and ship only source code; all compilation is done on the fly.") +
                
                + p("We can pretty much do the \"holy trinity\": maximum speed, complete freedom of assembly and compact code size&mdash;all at once.")
                
                + p("Also, JavaX has \"zero-effort deployment\": Every new line of code you write anywhere is available everywhere immediately. (If you want that.)")
                
                + p("As proof for JavaX's elegance, here's the " + targetBlank("http://tinybrain.de/1016081", "27 lines source code") + " of the module on the right."))
                
                , textPost("2018/11/27", "Why are my dreams better than reality?",
                p("I have the greatest dreams... then I wake up to a rather lame reality. How is that even possible?"))
                
                , imagePost("2018/11/25", "Much News!",
                #1101430, "50%",
                p(ahref("https://www.botcompany.de/1015408/raw/1400152/Stefans%20OS%20Installer.exe", "OS") + " becomes a Cluster OS.")
                + p("(Meaning, you can treat 3 PCs as one.)"))
                
                , imagePost("2018/11/17", "OS Chat Bot v1",
                #1101424, "35%",
                p("Come on! Talk to me!"), left := true)
                
                /*, textPost("2018/11/25", "Microsoft Meditation",
                p(youtubi("nWbD1bFqvOE"))
                + p("6 minutes."))*/
                
                , textPost("2018/11/11", "Eyebrow Detection",
                
                  p(youtubi("-XafiqgFM9k"))
                + p("I promised&mdash;and I delivered :)")
                + p("(This is an example of how even the smallest facial expressions can be used for making a better user interface.)"))
                
                , textPost("2018/11/10", "Some Live Programming",
                
                  p(youtubi("U2Kl4FY-jcE"))
                + p("Bad audio, good content."))
                
                , textPost("2018/11/10", "AI Testers Wanted!",
                
                p("All you need is a Windows, Linux or Apple PC and some enthusiasm. We make voice assistants that will ease your life and provide a lot of entertainment.")
                
                + p("To participate, either " + targetBlank("http://download.tinybrain.de", "download") + ", " + targetBlank("mailto:info@botcompany.de", "mail") + " or " + targetBlank("https://github.com/stefan-reich/StefansOS/issues", "create issues") + "."))
                
                , imagePost("2018/11/06", "Checking Log Files",
                #1101418, "50%",
                p("This task may seem trivial to you, but actually it is a key to computer intelligence."))
                
                , textPost("2018/11/04", "To Andrzej",
                
                p(youtubi("https://www.youtube.com/watch?v=9P1fF0liFtU")))
                
                , textPost("2018/10/30", "Next meetup on Nov 15", 
                
                p(targetBlank("https://www.meetup.com/Artificial-Intelligence-Meetup/events/255936823/", "Hamburg.") + " Hoping to prepare a fully intelligent machine until then :D"))
                
                , textPost("2018/10/28", "Making a Voice Activity Detection",

                p("Another one day project. OK, maybe two... I'm squeezing some other AI things in."))
                
                , textPost("2018/10/28", "I'm disappointed with YouTube views",

                p("1 view on the latest video? Really?"))
                
                , textPost("2018/10/27", "Making a face recognition",

                p("Now things get real.")
                + p(youtubi("FXJVO2fWztk", 450)))
                
                , imagePost("2018/10/25", "Sensory Status: +3",
                #1101412, "30%",

                p(b("Internet, Vision, Sound.") + " (A robot's basic needs.)"),
                left := true)
                
             /*   , textPost("2018/10/23", "Creator Awards once again awards the wrong creators",
                
                p("What can you say... Americans."))*/
                
                , imagePost("2018/10/21", "Faking The Linux Task Bar",
                #1101408, "50%",
                
                p("Anything's possible."))
                
                , imagePost("2018/10/15", "JavaX makes the impossible possible",
                #1101403, "30%",
                
                p("Here: Automatically measuring the RAM consumption of individual modules within one Java VM."),
                left := true)
                
                , textPost("2018/10/14", "Speech recognition works",
                
                  p(youtubi("yFEiIWW-heE", 450, 450*9/16))
                + p("Who says you need Google for everything?"))
                
                , imagePost("2018/10/10", "Making my own speech recognition",
                #1101401, "15%",
                p("It may be possible."))
                
                , textPost("2018/10/04", "We are making a bot net",
                p("...of the good kind. In fact, you are part of it <i>right now</i>.")
                + p("(It works through JavaScript in the browser. We're not using it yet though, you're just on idle.)"))

                , textPost("2018/10/03", "Let's sign stuff!",
                p("I propose to use asymmetric cryptographic keys for <i>testifying</i> that a certain thing actually happened.")
                +p("In JavaX, making a public+private key pair is just a single function call:")
                
                +hsourcecode([[pki_newKeyPair()]])
                
                +p("...which means we can have as many key pairs as we like.")
                +p("For example, you can use one specific key (or multiple) to sign your personal quotes. The signed data will speak for itself if one knows that the key is yours.")
                
                +hsourcecode([[
                On October 3rd 2018, I truly said: Oh screw this!

Edgar the 3rd himself

sig: MC0CFQCWUB9j0c+8e8wagTNmMXs/cq7tuAIUEoXOBbRvw343wOdunTY47rKrUDE=
signer: publickey:MIIBtzCCASwGByqGSM44BAEwggEfAoGBAP1/U4E [...] F9Kg=
]]))
             
                + aname('creatorawards, textPost("2018/09/29", "Applying for Creator Awards",
                p(youtubi("ZTiqIEbhB8A", 300))
                + p("Thanks to Andrzej for video production!")))

                , textPost("2019/09/25", "Dogs Are Telepathic",
                p(targetBlank("https://www.sheldrake.org/files/pdfs/papers/JSE_Vol14.pdf", "Proof.") + " Maybe bots can be too?"))
                
                , imagePost("2019/09/20", "Programming In Facts",
                #1101379, "55%",
                p([[German, this time.]]))
                
                , imagePost("2019/09/04", "Bot Simulator",
                #1101378, "75%",
                p(b([[Version 1.]])), left := true)
                
                , imagePost("2018/08/28", "Voice-to-voice bot",
                #1101376, "50%",
                p([[We now have voice recognition &amp; speech output combined into the ]] + targetBlank("http://t.me/Hello_Computer", "Telegram bot") + [[. Actual sci-fi!]])
                + p([[(PS: The bot said "Good evening dudes".)]])
                + p([[PPS: The Rubik's cube will have to wait a little...
                building foundations first.]]))
                
                , imagePost("2018/08/18", "Teaching the Rubik's cube to the bot",
                #1101372, "30%",
                p("It's a good idea and just about right complexity-wise."),
                left := true)
                
                , imagePost("2018/08/18", "Nice trend",
                #1101371, "",
                p("Changing history " + targetBlank("http://aimeetup.tinybrain.de", "on Tuesday") + "."))
                
                , imagePost("2018/08/17", "The Study Of Rules",
                #1101367, "50%",
                p("It's the duality&mdash;executing &amp; thinking&mdash;that makes this project work."))
                
                , imagePost("2018/08/14", "Bot Tests Human",
                #1101366, "30%",
                p("It's only fair that they test us first.")
                + p("(Yeah it's a joke post.) Next up: The other way around!"),
                left := true)
                
                , textPost("2018/08/13", "The Levels Of AI",
                p(b("Level 1: Literal.") + " Just make some responses. How are you? => I'm good/I have some problems")
                + p(b("Level 2: Battle it out.") + " Take the rules of level 1 and have them compete against each other. (There are also meta-rules.)")
                + p(b("Level 3: Fact management.") + " Some things are true, others aren't. Manage this.")
                + p("That's pretty much it. Now we just need a lot of rules to work with. Oh, and there's a very good parser for German &amp; English.")
                + p(targetBlank("https://www.meetup.com/Artificial-Intelligence-Meetup/events/253736347/", "Meeting.")))
                
                , imagePost("2018/08/10", "How much",
                #1101365, "40%",
                p("...is an AGI? 'cause we deliver."))
                
                , imagePost("2018/08/09", "Learning from longer exchanges",
                #1101364, "50%",
                p("Getting somewhere.")
                + p("If you could talk to an AI about any topic&mdash;which one would you choose?"))
                
                , imagePost("2018/08/07", "Politics",
                #1101363, "50%",
                p("Bot knows (sadly)."),
                left := true)
                
                , imagePost("2018/08/05", "Bot decides",
                #1101362, "45%",
                p("Who knows what it will do next?"))
                
                , textPost("2018/08/04", "Let's improve the onboarding",
                p(targetBlank("http://t.me/Hello_Computer", "Channel") + "'s waiting dudes."))
                
                , imagePost("2018/08/02", "How the AI is programmed",
                #1101361, "30%",
                
p([[<b>v1 - Make a basic logic using a bastard language</b> located somewhere
     between Prolog and plain English (mostly it's just the latter).]])

                  + pre_trim([[
input(I'm a scammer!)
  && fact(a scammer scams people)
  && relationX(scams people, scam people)
  => output(You scam people?!)
]]) +

p([[<b>v2 - Add some $ signs and turn spaces into underscores</b>
     (making the pattern dynamic).]]) + pre_trim([[

input(I'm a $scammer!)
  && fact(a $scammer $scams_people)
  && relationX($scams_people, $scam_people)
  => output(You $scam_people?!)
]])            + p([[<b>v3 - Find out what relationX is</b> (that's not that hard).]])

               + p_b([[v4 - Interpret this stuff.]])

               + pre([[DONE]])
               
               + p([[Estimated time frame: ]] + b([[2 days]]))
               
               + p("Edit (2018/08/03): And it's done (see picture)."))
                
                , textPost("2018/08/02", "I'm beating them",
                p("IBM and all the other guys.")
                
              + p("My fabulous " + targetBlank("http://tinybrain.de/1017686", "English Parser") + " just got better, you can now help it out by using some brackets, like this:")
                
                +pre("{This time of night} it's usually quite cool."))
                
                , textPost("2018/07/31", "I still contribute to StackOverflow",
                p("...even though " + targetBlank("https://stackoverflow.com/a/51618656/947488", "that place") + " is the living hell for any sane person. I'm not even allowed to ask questions anymore because <i>they hate dissidents</i>."))
                
                , imagePost("2018/07/31", "Bot Initiative",
                #1101360, "45%",
                p("Shurely an important part."))
 
                , imagePost("2018/07/28", "Bot needs more logic!",
                #1101359, "45%",
                p("We're getting there though."),
                left := true)

                /*, textPost("2018/07/27", "What is AI?",
                p("AI is " + i("puzzling stuff out") + ".")
                + p("(You know which meaning of \"puzzling\" is intended here, right? If yes: Then you're a " + i("good puzzler") + ".)")
                + p("So that's what we build: a " + i("puzzling engine") + "."))*/
                
                , imagePost("2018/07/27", "Telegram shaping up",
                #1101358, "45%",
                p(targetBlank("http://t.me/Hello_Computer", "Participate!")))

                , textPost("2018/07/27", "I should collect money for a new notebook",
                p([["What, you're doing AI with 4 gigabytes?"]])
                + p("Yes, that's right. And 512 MB actually go to the GPU, so yeah... it's tight."))
                
                , textPost("2018/07/26", "The Simplifier",
                p("Another working AI component. Takes any sentence or phrase, like:")
                + pre("smart combinations of various fast methods")
                + p("and outputs:")
+ pre(trim([[
1. combinations
2. combinations of methods
3. smart combinations
4. combinations of fast methods
5. smart combinations of methods
6. combinations of various methods
7. smart combinations of fast methods
8. combinations of various fast methods
9. smart combinations of various methods
10. smart combinations of various fast methods
]]))
                + p("Neat, right? And very useful."))
                
                , textPost("2018/07/22", "Setting Up Telegram",
                p([[There'll be ]] + targetBlank("http://t.me/Hello_Computer", "a channel") + [[ and a bot.]]))
                
                
                , textPost("2018/07/22", "The implications of this project",
                p([[I'm not sure if you have thought this through yet. This is a project that <i>makes computers think</i>.]]))
                
                , imagePost("2018/07/20", "A few more steps",
                #1101357, "45%",
                p([[...and you'll have the dialog engine you're all waiting for.]]))

                /*, textPost("2018/07/22", "The StackOverflow War",
                p("StackOverflow is completely intolerable if you try to actually work on it. The trolls are in charge there.")
                + p("There is a " + targetBlank("https://meta.stackexchange.com/questions/187661/mirrors-of-stack-overflow", "legal way") + " to mirror the site, so: Let's do it! I'm downloading the first archive as we speak. Huge stuff though, gigabytes over gigabytes..."))*/
                
                , textPost("2018/07/18", "English+German Parsers Work",
                  p("Input:")
                + pre("\"Confessions of a Burglar Video\"")
                + p("(It's the name of a video on YouTube.) So... is the video confessing&mdash;or the burglar? Let's ask the parser.")
                + pre(rtrim([[
1. Confessions {of {a {Burglar Video}}}
2. {Confessions {of {a Burglar}}} Video
                ]]))
                + p("Yup, it has found the 2 grammatical possibilities. Next up: Semantic analysis to rate these against each other."))
                
                , textPost("2018/07/18", "500 installations coming up",
                p([[We're reaching a nice number of JavaX-enabled computers. And no, they're not all mine.]]))

                , imagePost("2018/07/12", "Perfect Parser Coming Up",
                #1101356, "45%",
                p([[English&mdash;no problem.]]))

                , imagePost("2018/07/12", "The Magic OS",
                #1101353, "45%",
                p([[In my OS, every computer can control any other one&mdash;if the "victim" deliberately chooses this (it's a separate module you have to load explicitly, so don't worry).]])
                + p("The communication process behind this is protected using automatic cryptographic signatures."))

                , imagePost("2018/07/10", "Teaching Puns To The AI...",
                #1101352, "45%",
                
                p("52 days to world domination."))
                
                , textPost("2018/07/10", "News from Zuckerberg",
                p(youtubi("_zCDvOsdL9Q", 400)))

                , textPost("2018/07/07", "56 days",
                p("until Stefan's OS takes the world."))
                
                /*, imagePost("2018/07/05", "News From Israel",
                #1101349, "30%",
                p(targetBlank("https://www.aljazeera.com/indepth/inpictures/israeli-forces-assault-palestinians-prepare-demolish-village-180704141245982.html", "Great country.")),
                picLink := "https://www.aljazeera.com/indepth/inpictures/israeli-forces-assault-palestinians-prepare-demolish-village-180704141245982.html")*/
                
                , imagePost("2018/07/02", "Dead Lock-Immune Operating System",
                #1101348, "30%", p(targetBlank("http://tinybrain.de/1016805", "Code.")), left := true)

                /*, textPost("2018/07/02", "Dear Kirill from the Android team,",
                
hParagraphsFromEmptyLines([[I have to get these things off my chest.

    1. I used to work at Google. I quit in 2009 because they wanted to waste me.

    2. I make an operating system in Java that is ALL THAT ANDROID SHOULD HAVE BEEN.

    3. I tried to install WhatsApp on a friend's Android phone yesterday and IT SIMPLY DID NOT WORK.

3b. I got kicked off the Play Store because I dynamically load code from un-servers (non-Google-servers). So it's a fight? Guess who'll win.

    4. In my Java OS, ALL MODULES RUN IN ONE VM AND IT'S NOT A PROBLEM.

4b. No, the Java process does not get "wonky" over time as misinformed programmers baselessly claim. They just have more deadlocks than I do (my deadlocks are <a target="_blank" href="http://tinybrain.de/1016805">fixed by the OS</a>).

    5. I have an idea for a better Swing PLAF interface. Just two components: a painter and a "clicker" (event handler). Easy & really transparent.

    6. My OS has <b>orthogonal persistence</b> which is... slightly easier than your persistence approach.

Cheers.

Stefan]]))*/
                
                /*, textPost("2018/06/30", "Something must be wrong with reality",
                  p("The movies we watch have a better plot than the life we actually live. How is that possible?"))*/
                  
                , textPost("2018/06/30", "We're doing it again",
                  invtag('div, style := "float: right; margin-left: 20px; margin-bottom: 20px",
                    youtubi("lAkuJXGldrM", 300))
                  + p("Stefan's OS has a greater impact than Windows 95. You just wait and see!"))
                
                , textPost("2018/06/27", "Computer checks its own voice",
                  p(youtubi("ZRkGdIvW5lM", 600)))

                , imagePost("2018/06/23", "Stefan's OS v5",
                   #1101335, "30%",
                   p("See who else is online, world wide (if you load the module).")
                 + p([[Also notice the "AI bar" at the top which is a novel invention.]]))
                   
                , textPost("2018/06/23", "We are solving the software security crisis",
                p("The solution is "+ b("source code inspection") + ", and " + ahref("http://javax.tinybrain.de", b("JavaX")) + " makes it practical."))
                
                , textPost("2018/06/23", "We will now do the Super-Automation",
                   p("The operating system is the optimal place to automate everything&mdash;it sees everything and it can act upon information. Also loading and even making dynamic code on the fly is trivial in my OS."))
                   
                , textPost("2018/06/25", "If your language isn't perfect&mdash;how about changing it?",
                p("Let's say " + b("vanilla Java is too verbose") + ". (Everybody knows this.) Instead of this:")
                + pre("class ShowBackgroundImage extends DynModule {")
                + p("I want to type (and see) only this:")
                + pre("class ShowBackgroundImage &gt; DynModule {")
                + p(b("In JavaX") + ", that takes " + b("exactly one line") + " in the " + targetBlank("http://tinybrain.de/759", b("translator")) + ":")
                + pre(htmlencode([[jreplace(tok, "class <id> > <id> {", "class $2 extends $4 {");]]))
                + p("And this easily, my language has been extended.")
                + p(b(targetBlank("http://tinybrain.de/1016607", "Proof that this works."))))

                , textPost("2018/06/20", "Collaboration!",
                    p(targetBlank("http://www.ort-des-talents.de/", "BrainCircle.")))
                
                , textPost("2018/06/20", "Stefan's OS v4",
                    p(ahref("https://www.botcompany.de:8443/1013826/raw", "Numerous small improvements") + ". Finds memory leaks automatically (!). Ability to make \"alternative brains\" (multiple distinct instances of OS on a machine). Still compatible with Windows, Linux and Mac."))
                
                , imagePost("2018/06/19", "Reading my mails",
                  #1101332, "30%",
                  p("Not pretty (where are the graphic designers?), but it works.")
                  + p(ahref("http://tinybrain.de/1016066", "Source code") + " (39 lines)")
                  , left := true)
                
                , imagePost("2018/06/18", "First operating system that learns",
                  #1101331, "30%",
                  p(b([[What is the world?]])), left := false)
                
                , imagePost("2018/06/18", "Advantages of a Java-based OS: Free Profiling",
                  #1101328, "30%",
                  p([[You get so many <b>inspection capabilities</b> for free in my OS.]])
                  + p([[For example, you can always find out what the CPU  is doing, down to every single line of code. And this incurs no performance overhead when not used.]]), left := true)
                
                , textPost("2018/06/17", "Memory leak eliminated", p("Gotcha.") + p("I told you Java is stable!"))
                
                , imagePost("2018/06/16", "Further chasing the memory",
                  #1101327, "30%",
                  p([[It has to be going somewhere. ]] + ahref("http://mail.openjdk.java.net/pipermail/discuss/2018-June/thread.html", "jdk-discuss") + [[ informed (list is moderated, read: another time waster).]]), left := true)
                
                , imagePost("2018/06/16", "New Look&amp;Feel",
                  #1016391, "30%",
                  p([[Pretty, isn't it. Look&amp;Feel is called ]] + ahref("http://jtattoo.net", "JTattoo") + [[.]]) + p([[Image was made with the automatic screenshot module on a very old Windows 7 machine where my OS runs flawlessly.]]), left := true)
                
                , textPost("2018/06/15", "Fixing the last memory leaks in Java 10", [[
                <p>I submitted this <a href="https://bugs.java.com/bugdatabase/view_bug.do?bug_id=JDK-8204963">bug report</a> to Oracle, and I'm making
                super-fancy functions like <a href="http://tinybrain.de/1016334">cleanDefunctACCsInAllThreads</a> that automatically fix
                memory leaks other Java programmers have never heard of.</p>
                <p>We will sail memory leak-free! :)</p>
                ]]) + [[

                <!-- A single blog post -->
                <section class="post">
                    <header class="post-header">
                        <img width="48" height="48" title="Stefan Reich's avatar" class="post-avatar" src="]] + snippetImgLink(#1101324) + [[">

                        <h2 class="post-title">New Module: YouTube Downloader</h2>

                        <p class="post-meta">
                            By <a href="mailto:info@botcompany.de" class="post-author">Stefan Reich</a> @ 2018/06/14
                        </p>
                    </header>
                    
                    <div class="post-description" style="clear: both">
                        <div style="float: right; width: 50%">
                            <a href="https://botcompany.de/1004590/raw/1101311">
                                <img title=""
                                     class="pure-img-responsive"
                                     src="https://botcompany.de/1004590/raw/1101311" style="width: 100%">
                            </a>
                        </div>
                            
                        <p>
                            Today we launched <b>bla bla bla</b>.
                        </p>
                        <p>&nbsp;</p>
                        <p>(No, seriously&mdash;we actually did. There is an awesome YouTube downloader in my <a href="http://exe.tinybrain.de/">operating system</a>. I'm just too lazy to write.)</p>
                        <p>Now I need an awesome screenshot module and an awesome auto-upload-to-blog module.</p>
                    </div>
                </section>
  ]]); // end of posts
  
  if (nempty(date))
    allPosts = dropFirst(allPosts, indexOfFirstThat(allPosts,
      post -> cmp(regexpFirstMatch("20\\d\\d/\\d\\d?/\\d\\d?", post), date) <= 0));
  
  LS posts = subList(allPosts, (page-1)*perPage, page*perPage);
  bool hasPrev = page > 1, hasNext = l(allPosts) > page*perPage;
  
  S nav = !hasNext && !hasPrev ? "" 
    : hsection(joinNempties(" | ", 
      hasPrev ? ahref(rawSelfLink(str(page-1)), "Last page") : "",
      ahref("http://javax.botcompany.de/1020398/raw/contact", "Imprint"),
      hasNext ? ahref(rawSelfLink(str(page+1)), "Next page") : ""),
    class := "post", style := "text-align: right");
    
  S html = [[
<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>BotCompany.de</title>
    
    <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/pure-min.css" crossorigin="anonymous">
    
    <link rel="stylesheet" href="https://unpkg.com/purecss@1.0.0/build/grids-responsive-min.css">
    <link rel="stylesheet" href="css/layouts/blog.css">
]] + html_nextGenBots_discordWidget() + [[
</head>
<body>

]] + [[<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js?tracking=1&always=1"></script>]] + [[

<div id="layout" class="pure-g">
    <div class="sidebar pure-u-1 pure-u-md-1-4">
        <div class="header">
            <h1 class="brand-title"><a href="https://www.BotCompany.de">Bot]] + html_invisibleSpace() + [[Company</a></h1>
            <h2 class="brand-tagline">English &amp; German Chat Bots</h2>

            <nav class="nav">
                ]] + tag('ul,
                    li(a("FIVERR", class := "pure-button", href := "http://fiverr.tinybrain.de"), class := "nav-item")
                + " " +
                    li(a("JAVAX", class := "pure-button", href := "http://javax.botcompany.de"), class := "nav-item")
                + " " +
                  li(a("GERMAN DEMO BOT", class := "pure-button", href := "http://www.web-woody-lab.de/", target := "_blank"), class := "nav-item")
                + " " +
                    li(a("DISCORD GROUP", class := "pure-button", href := "https://discordapp.com/invite/SEAjPqk", target := "_blank"), class := "nav-item")

/*                + " " +
                   li(a("Download Windows", class := "pure-button", href := "https://www.botcompany.de/files/1400170/Stefans%20OS%20Installer.exe"), class := "nav-item")
                + " " +
                   + li(a("Download Mac/Linux", title := "Install Java first (from java.com)", class := "pure-button", href := "https://www.botcompany.de/files/1400169/Stefans%20OS.jar"), class := "nav-item")*/
                   
                + " " +
                  li(a("agi.blue", class := "pure-button", href := "https://agi.blue/"), class := "nav-item")
            
                + " " +
                      li(a("Videos", class := "pure-button", href := "http://youtube.tinybrain.de/"), class := "nav-item")
                    //, class := "nav-list")
                  + " " +
                      li(a("Meetings", class := "pure-button", target := "_blank", href := "http://aimeetup.tinybrain.de/"), class := "nav-item")
                  + " " +
                      li(a("Slides", class := "pure-button", target := "_blank", href := "https://slides.com/stefanreich"), class := "nav-item")
                  + " " +
                      li(a("GBot", class := "pure-button", target := "_blank", href := "https://discordbots.org/bot/602481480266153984"), class := "nav-item")
                    , class := "nav-list")
                + [[
            </nav>
            
            <p>&nbsp;</p>
            <p><a style="text-decoration: none; color: white" href="https://www.botcompany.de:8443/1013826/raw"><b>Stefan's OS</b></a><br> is an inspiring Java program you can <a style="text-decoration: underline; color: white" href="https://www.botcompany.de:8443/1013826/raw">try out</a> in Windows, Mac OS or Linux.</p>
            
            ]] + p("&nbsp;") + youtubi("I6m-My1MxRk", 150)             
            + "<br>"
            + small("(good music)") +  [[
        </div>
    </div>

    <div class="content pure-u-1 pure-u-md-3-4">
        <div>
            <div class="posts">
                <!--<h1 class="content-subhead">Recent News</h1>-->
                ]]
                
                + hcss(autoUnindent([[
                  pre { margin-left: 20px; }
                  tt, pre { font-weight: bold; }
                ]]))
                + nav
                  
                + lines(posts)
                
                + nav

                + [[
                
            </div>

            <div class="footer">
                <div class="pure-menu pure-menu-horizontal">
                    <ul>
                        <li class="pure-menu-item" id="visitors"></li>
                        <li class="pure-menu-item"><a href="https://www.botcompany.de:8443/1013826/raw" class="pure-menu-link">More</a></li>
                        <li class="pure-menu-item"><a href="http://youtube.tinybrain.de/" class="pure-menu-link">YouTube</a></li>
                        <li class="pure-menu-item"><a href="http://javax.botcompany.de/1020398/raw/contact" class="pure-menu-link">Impressum</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

</body>
</html>
]];

  ret html.replace("\"css/layouts/blog.css\"", htmlQuote(rawSnippetURL(#1016322, "text/css")))
  .replaceFirst(regexpQuote("<body>"), "<body>" + hSilentComputatorWithFlag("homepage"));
}

sS textPost(S date, S title, S text) {
  ret invtag('section, class := "post", style := "clear: both",
    invtag('header, class := "post-header",
      invtag('img, width := 48, height := 48,
        title := "Stefan Reich",
        class := "post-avatar",
        src := snippetImgLink(#1101324))
      + [[
      <h2 class="post-title">]] + title + [[</h2>

                        <p class="post-meta">
                            By <a href="mailto:info@botcompany.de" class="post-author">Stefan Reich</a> @ ]] + ahref(hquery(+date), date) + [[
                        </p>
]]) + [[
                    <div class="post-description">
                    ]] + text + [[
                    </div>]]);
}

sS imagePost(S date, S title, S imageID, S width, S text, O... opt) {
  bool left = optParam(opt, 'left, false);
  S picLink = stringParam(opt, 'picLink);
  ret textPost(date, title, 
    invtag('div, style := "float: " + (left ? "left" : "right") + "; width: " + width + "; margin-bottom: 30px; margin-" + (left ? "right" : "left") + ": 30px;", ahref(or2(picLink, snippetImageLink(imageID)),
    invTag('img, title := "",
      class := "pure-img-responsive",
      src := snippetImageLink(imageID),
      style := "width: 100%")))
  + text);
}

sS youtubi(S url) {
  ret isTrue(youtubeOff!) ? "" : youtubeEmbed_newer(url);
}

sS youtubi(S url, int width) {
  ret isTrue(youtubeOff!) ? "" : youtubeEmbed_newer(url, width);
}

sS youtubi(S url, int width, int height) {
  ret isTrue(youtubeOff!) ? "" : youtubeEmbed_newer(url, width, height);
}

download  show line numbers  debug dex   

Travelled to 11 computer(s): aoiabmzegqzx, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, tslmcundralx, tvejysmllsmz

No comments. add comment

Snippet ID: #1016323
Snippet name: Blog Bot [DOMAIN BOT]
Eternal ID of this version: #1016323/794
Text MD5: 050f407a3c091739402fc1fee3e9820f
Transpilation MD5: 00b39d21c79ed27ccf5fc841d83d4c09
Author: stefan
Category: javax / html
Type: JavaX module (desktop)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2019-09-13 14:22:56
Source code size: 65746 bytes / 1308 lines
Pitched / IR pitched: No / No
Views / Downloads: 3214 / 8145
Version history: 793 change(s)
Referenced in: [show references]