From 019804d2c03d971e49d277cb6f8e72b266a7abbe Mon Sep 17 00:00:00 2001 From: sigonasr2 Date: Sat, 20 Aug 2022 12:26:16 -0500 Subject: [PATCH] 7 matches instead of 20 Co-authored-by: sigonasr2 --- bin/sigPlace.class | Bin 17561 -> 24468 bytes out/DIRECTORY_LISTING | 36 + out/articles/DIRECTORY_LISTING | 34 + ...ove Live! Custom Arcade Controller.article | 7 + ...ive! Custom Arcade Controller.article.html | 194 +++++ out/articles/curabitur vel tempus ex.article | 11 + .../curabitur vel tempus ex.article.html | 198 ++++++ out/articles/sigplace1.article | 486 +++++++++++++ out/articles/sigplace1.article.html | 673 ++++++++++++++++++ out/articles/test articles/DIRECTORY_LISTING | 33 + out/articles/test articles/test1.article | 5 + out/articles/test articles/test1.article.html | 192 +++++ out/articles/test articles/test2.article | 5 + out/articles/test articles/test2.article.html | 192 +++++ out/articles/test articles/test3.article | 5 + out/articles/test articles/test3.article.html | 192 +++++ out/codeBackground | 40 ++ out/error.html | 50 ++ out/images/DIRECTORY_LISTING | 29 + out/images/Love_Live!_Logo.png | Bin 0 -> 12167 bytes out/images/github.webp | Bin 0 -> 7270 bytes out/otherpage.html | 567 +++++++++++++++ out/reset.css | 47 ++ out/sig.css | 479 +++++++++++++ out/testfile.html | 51 ++ out/uploadform.html | 51 ++ sigPlace.jar | Bin 69533 -> 73239 bytes sigPlace.java | 2 +- 28 files changed, 3578 insertions(+), 1 deletion(-) create mode 100644 out/DIRECTORY_LISTING create mode 100644 out/articles/DIRECTORY_LISTING create mode 100644 out/articles/Love Live! Custom Arcade Controller.article create mode 100644 out/articles/Love Live! Custom Arcade Controller.article.html create mode 100644 out/articles/curabitur vel tempus ex.article create mode 100644 out/articles/curabitur vel tempus ex.article.html create mode 100644 out/articles/sigplace1.article create mode 100644 out/articles/sigplace1.article.html create mode 100644 out/articles/test articles/DIRECTORY_LISTING create mode 100644 out/articles/test articles/test1.article create mode 100644 out/articles/test articles/test1.article.html create mode 100644 out/articles/test articles/test2.article create mode 100644 out/articles/test articles/test2.article.html create mode 100644 out/articles/test articles/test3.article create mode 100644 out/articles/test articles/test3.article.html create mode 100644 out/codeBackground create mode 100644 out/error.html create mode 100644 out/images/DIRECTORY_LISTING create mode 100644 out/images/Love_Live!_Logo.png create mode 100644 out/images/github.webp create mode 100644 out/otherpage.html create mode 100644 out/reset.css create mode 100644 out/sig.css create mode 100644 out/testfile.html create mode 100644 out/uploadform.html diff --git a/bin/sigPlace.class b/bin/sigPlace.class index b21d2c14269d1fc61a8b9986620599f77bd44413..db303be6dcce98961dced5f7cd0d6104fb777108 100644 GIT binary patch literal 24468 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%0Dn|v@xX}HTgdu_MPqb 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 literal 17561 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 o=Y%{V&GPi + + + + + + + + +

Directory Listing for /

🗎reset.css 2022-08-20T17:25:47.863330702Z niconiconii 1092
+
📁articles 2022-08-20T17:25:48.359324585Z niconiconii 4096
+
🗎uploadform.html 2022-08-20T17:25:48.291325424Z niconiconii 1863
+
🗎error.html 2022-08-20T17:25:48.291325424Z niconiconii 1828
+
🗎sig.css 2022-08-20T17:25:48.279325571Z niconiconii 11140
+
🗎testfile.html 2022-08-20T17:25:48.291325424Z niconiconii 1783
+
🗎otherpage.html 2022-08-20T17:25:48.307325226Z niconiconii 88526
+
📁images 2022-08-20T17:25:48.355324635Z niconiconii 4096
+
🗎codeBackground 2022-08-20T17:25:48.287325473Z niconiconii 2635
+ + +
+
+ +
+ +
+ diff --git a/out/articles/DIRECTORY_LISTING b/out/articles/DIRECTORY_LISTING new file mode 100644 index 0000000..37a0e99 --- /dev/null +++ b/out/articles/DIRECTORY_LISTING @@ -0,0 +1,34 @@ + + + + + + + + + +

Directory Listing for /articles/

🗎sigplace1.article 2022-08-20T17:25:48.259325819Z niconiconii 80858
+
🗎Love Live! Custom Arcade Controller.article.html 2022-08-20T17:25:48.347324733Z niconiconii 10444
+
🗎sigplace1.article.html 2022-08-20T17:25:48.32732498Z niconiconii 90753
+
🗎curabitur vel tempus ex.article 2022-08-20T17:25:48.259325819Z niconiconii 730
+
📁test articles 2022-08-20T17:25:48.343324783Z niconiconii 4096
+
🗎curabitur vel tempus ex.article.html 2022-08-20T17:25:48.33132493Z niconiconii 10653
+
🗎Love Live! Custom Arcade Controller.article 2022-08-20T17:25:48.263325769Z niconiconii 497
+ + +
+
+ +
+ +
+ diff --git a/out/articles/Love Live! Custom Arcade Controller.article b/out/articles/Love Live! Custom Arcade Controller.article new file mode 100644 index 0000000..80fb2c3 --- /dev/null +++ b/out/articles/Love Live! Custom Arcade Controller.article @@ -0,0 +1,7 @@ +

My Love Live! Custom Arcade Controller

+
+

+For over a year since I first got into Love Live! School Idol Festival ~after school ACTIVITY~ Wai-Wai!Home Meeting!! Try saying that one 10 times fast!Subscript +

+
+
15 July 2022 1:53PM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/Love Live! Custom Arcade Controller.article.html b/out/articles/Love Live! Custom Arcade Controller.article.html new file mode 100644 index 0000000..1185938 --- /dev/null +++ b/out/articles/Love Live! Custom Arcade Controller.article.html @@ -0,0 +1,194 @@ + + + + + + + + + + + +
+

My Love Live! Custom Arcade Controller

+
+

+For over a year since I first got into Love Live! School Idol Festival ~after school ACTIVITY~ Wai-Wai!Home Meeting!! Try saying that one 10 times fast!Subscript +

+
+
15 July 2022 1:53PM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/articles/curabitur vel tempus ex.article b/out/articles/curabitur vel tempus ex.article new file mode 100644 index 0000000..0603cb4 --- /dev/null +++ b/out/articles/curabitur vel tempus ex.article @@ -0,0 +1,11 @@ +

Curabitur vel tempus ex

+

+Curabitur vel tempus ex. Duis cursus sapien nisl, ut pulvinar dui porttitor ut. Nullam odio purus, tristique non turpis sit amet, malesuada ultricies purus. Mauris ut nulla nisl. Aenean sit amet est egestas justo volutpat consequat. Suspendisse in sagittis augue, et mattis tortor. Nullam viverra metus et nibh fringilla iaculis. +

+
+

+

+<><Test>"</test></test2><test3>"
+            
+

+
29 Apr 2022 7:37PM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/curabitur vel tempus ex.article.html b/out/articles/curabitur vel tempus ex.article.html new file mode 100644 index 0000000..28a3920 --- /dev/null +++ b/out/articles/curabitur vel tempus ex.article.html @@ -0,0 +1,198 @@ + + + + + + + + + + + +
+

Curabitur vel tempus ex

+

+Curabitur vel tempus ex. Duis cursus sapien nisl, ut pulvinar dui porttitor ut. Nullam odio purus, tristique non turpis sit amet, malesuada ultricies purus. Mauris ut nulla nisl. Aenean sit amet est egestas justo volutpat consequat. Suspendisse in sagittis augue, et mattis tortor. Nullam viverra metus et nibh fringilla iaculis. +

+
+

+

+<><Test>"</test></test2><test3>"
+            
+

+
29 Apr 2022 7:37PM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/articles/sigplace1.article b/out/articles/sigplace1.article new file mode 100644 index 0000000..46333eb --- /dev/null +++ b/out/articles/sigplace1.article @@ -0,0 +1,486 @@ +

Welcome to SigPlace!

+

+ This is a SigPlace article! It will contain information that is important (probably) and will be layed out as such. +

+

+ Paragraphs are automatically split up for readability and generated correctly via the parser. There's quite a bit of flexibility with the system and makes it easy to post updates should they be required. +

+

+ A lot of content management systems would do this by having a web interface and submitting content and managing it that way, but by coding my own management system and using the built-in OS' filesystem to handle the work, I save myself a lot of pains and headaches. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat, urna ut sollicitudin luctus, nulla magna faucibus mauris, at semper nisl nisi ut mauris. Vestibulum cursus tortor velit, ut congue ex porta in. Nullam hendrerit risus sit amet neque euismod faucibus. Sed ac diam non lectus euismod pulvinar eu non mauris. Donec accumsan nisl efficitur, sodales lectus et, finibus quam. Sed vel consectetur leo. Cras ut condimentum quam. Aliquam molestie viverra congue. Donec scelerisque nibh ac nulla dictum semper. Aliquam id massa a massa bibendum finibus id ac sapien. Integer vitae ullamcorper enim, non semper massa. +

+
+

+Proin cursus sodales elit, vitae volutpat mi fermentum a. In vitae magna quis leo cursus accumsan id facilisis purus. Vestibulum accumsan iaculis turpis eu sollicitudin. Sed ultricies felis non elit suscipit interdum. Maecenas sollicitudin turpis justo, vel pretium sapien scelerisque eget. Nullam sagittis finibus risus ut aliquam. Praesent quam orci, dapibus ut ex ac, sodales dapibus nunc. +

+
+

+Fusce magna risus, iaculis non justo sit amet, semper sodales urna. Morbi eu eros lectus. Integer euismod venenatis eros a hendrerit. Nulla ultricies lectus nec quam condimentum fermentum. Quisque a turpis vitae orci pharetra ullamcorper. Nunc fringilla vitae nunc a aliquam. In aliquam gravida massa. Sed imperdiet dignissim sapien, ullamcorper rutrum lacus convallis ut. +

+
+

+Nunc tortor sem, dapibus mattis varius id, varius eu leo. Phasellus efficitur nulla a diam faucibus, id facilisis lacus malesuada. Nulla condimentum egestas erat a fermentum. Ut interdum dui id est condimentum, vel fermentum nisi ornare. Sed eu rhoncus magna, sit amet finibus eros. In a nibh tincidunt, suscipit tellus eleifend, faucibus mauris. Vestibulum sagittis nisi et efficitur ullamcorper. Donec sodales efficitur ligula id congue. Etiam egestas tristique interdum. Mauris at massa eget metus pellentesque fermentum nec non lacus. Nulla turpis nunc, feugiat vel euismod ac, maximus id est. Praesent cursus elit ac dolor hendrerit lacinia. +

+
+

+Vestibulum laoreet lorem consequat, mollis augue finibus, luctus libero. Praesent convallis sed velit vitae molestie. Vestibulum nec fringilla tellus, non dictum nulla. Donec tempor ac diam sit amet porta. Quisque mi ex, vulputate ac tincidunt vel, vestibulum vitae orci. Duis gravida mauris eget mauris pulvinar, lobortis tincidunt neque efficitur. Nunc blandit metus vitae faucibus vulputate. Curabitur rhoncus volutpat lorem, sit amet pulvinar ipsum. Fusce ultricies enim odio, a viverra quam tincidunt quis. Aliquam sollicitudin a sapien id efficitur. Proin at finibus elit, id gravida elit. Nulla facilisi. Ut tincidunt, ligula eu pulvinar dapibus, lorem nisl facilisis tellus, in ornare quam dolor quis libero. Pellentesque ut convallis orci. Donec volutpat nunc velit, tristique convallis purus lacinia sit amet. Maecenas porttitor cursus nisl sed porta. +

+
+
Hello there! You can see this is the Love Live logo indeed! It is quite smol right now but that's okay. Let's keep on going with the text. If the caption is really long and with commas, they will now be combined,,,,,see how that works? Amazing!
+

+Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on. +

+
+

+

+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+public class sigPlace {
+    /* Test giant multi-line comment ""
+    final static String ROOTDIR = "sitefiles";
+    final static String REFDIR = "ref";
+    final static String OUTDIR = "out";
+    final static String ARTICLESDIR = "articles";
+    final static String UPLOADSDIR = "uploads";
+    final static String COMMENTSDIR = "comments";
+    final static String DIRECTORYLISTING_FILENAME = "DIRECTORY_LISTING";
+    static int PORT = 8080;
+    */
+    static double COLOR_ROTATION = 0;
+    static boolean inCodeBlock = false;
+    static String storedCodeBlock = "";
+    final static HashMap<String,String> map = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>("$SITENAME", "SigPlace"),
+        new AbstractMap.SimpleEntry<>("$SITE_BACKCOL", "#111"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_START", "<div class=\"contentWrapper\"><h1>"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_END", "</h1><div class=\"content\" %ID%>"),
+        new AbstractMap.SimpleEntry<>("$CONTENT_END", "</div>"),
+        new AbstractMap.SimpleEntry<>("$DATE_CONTENT_START", "<div class=\"datebar\"></div><div class=\"date\">")
+    ));
+    final static HashMap<String,Path> ops = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>(
+            "%DEFAULT", Paths.get(REFDIR,"DEFAULT.html")),
+        new AbstractMap.SimpleEntry<>(
+            "%FOOTER", Paths.get(REFDIR,"FOOTER.html"))
+    ));
+    public static void main(String[] args) {
+        if (args.length>0&&args.length%2==0) {
+            int i=0;
+            while (i<args.length) {
+                String arg1=args[i];
+                String arg2=args[i+1];
+                i+=2;
+                if (arg1.equals("-p")) {
+                    PORT=Integer.parseInt(arg2);
+                    System.out.println("Port set to "+PORT+".");
+                } else {
+                    System.err.println("Invalid argument \""+arg1+"\".");
+                    return;
+                }
+            }
+        }
+        System.out.println("Copying files over to output directory...");
+        try {
+            copyDirectory("sitefiles","out");
+            Iterator<Path> items = Files.walk(Paths.get("out")).filter((p)->!p.toAbsolutePath().toString().contains("images/")).iterator();
+            ParseArticleFiles(items);
+            items = Files.walk(Paths.get("out")).iterator();
+            ConvertArticleReferences(items);
+            items = Files.walk(Paths.get("out","articles")).iterator();
+            GenerateArticleFiles(items);
+        }catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Copying files over failed!");
+            return;
+        }
+        System.out.println("Building directory listings...");
+        try {
+            buildDirectoryListings();
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Failed to build directory listings!");
+            return;
+        }
+        System.out.println("Site has been built into the "+OUTDIR+" directory.");
+        ExportCodeFile();
+        System.out.println("\nStarting web server...");
+        new sigServer();
+    }
+    private static void ParseArticleFiles(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Found "+f.getFileName());
+            if (Files.isRegularFile(f)) {
+                try {
+                    System.out.println("  Preparing "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    if (isHTMLFile(f)) {
+                        content.addAll(0,Files.readAllLines(ops.get("%DEFAULT")));
+                        content.addAll(Files.readAllLines(ops.get("%FOOTER")));
+                    }
+                    System.out.println("  Parsing "+f.getFileName());
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        //System.out.println(s);
+                        if (s.length()>0&&(isHTMLFile(f)||isArticleFile(f))) {
+                            if (!inCodeBlock) {
+                                if (s.contains("<pre>")) {
+                                    //System.out.println("Inside <pre>");
+                                    inCodeBlock=true;
+                                    storedCodeBlock="";
+                                    s=s.substring(0,s.indexOf("<pre>"));
+                                }
+                            }
+                            if (inCodeBlock&&s.contains("</pre>")) {
+                                inCodeBlock=false;
+                                boolean keyword=false;
+                                boolean inString=false;
+                                boolean inChar=false;
+                                boolean canBeNumericalConstant=false;
+                                int lengthOfConstant=0;
+                                storedCodeBlock+=s.substring(0,s.indexOf("</pre>"));
+                                storedCodeBlock=storedCodeBlock.replaceAll(Pattern.quote("<"),"<");
+                                s+="</pre>";
+                                storedCodeBlock="<pre>"+storedCodeBlock;
+                                int startPos=0;
+                                String endText=s.substring(s.indexOf("</pre>")+"</pre>".length(),s.length());
+                                s="";
+                                for (int j=0;j<storedCodeBlock.length();j++) {
+                                    if (storedCodeBlock.charAt(j)=='"') {
+                                        inString=!inString;
+                                        if (inString) {
+                                            s+=SPAN("string")+"\"";
+                                        } else {
+                                            s+="\"</span>";
+                                            startPos=j+1;
+                                        }
+                                    } else
+                                    if (!inString&&!inChar) {
+                                        if (canBeNumericalConstant&&validNumericalConstantCharacters(lengthOfConstant, j)) {
+                                            lengthOfConstant++;
+                                            System.out.println("Length of Constant now "+lengthOfConstant);
+                                        }
+                                        if (canBeNumericalConstant&&lengthOfConstant>0&&!(validNumericalConstantCharacters(lengthOfConstant, j))) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            //System.out.println("Setting "+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j));
+                                            lengthOfConstant=0;
+                                            canBeNumericalConstant=false;
+                                            startPos=j+1;
+                                        } else
+                                        if (!canBeNumericalConstant&&storedCodeBlock.charAt(j)=='.') {
+                                            //Previous section was a member.
+                                            s+=SPAN("class")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>3&&storedCodeBlock.substring(j-3,j+1).equals("true")&&!isAlphanumeric(j-4)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>4&&storedCodeBlock.substring(j-4,j+1).equals("false")&&!isAlphanumeric(j-5)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (storedCodeBlock.charAt(j)=='(') {
+                                            s+=SPAN("function")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && storedCodeBlock.charAt(j)==' '&&storedCodeBlock.charAt(j-1)!=' ') {
+                                            //Previous section was a keyword.
+                                            keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && (storedCodeBlock.charAt(j)==';'||storedCodeBlock.charAt(j)==':')) {
+                                            //Previous section was a keyword.
+                                            //keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (keyword&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z'||storedCodeBlock.charAt(j)==' ')) {
+                                            keyword=false;
+                                            s+=SPAN("variable")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else
+                                        if (!isAlphanumeric(j)){
+                                            if (startPos<j) {
+                                                s+=storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j);
+                                            } else {
+                                                s+=storedCodeBlock.charAt(j);
+                                            }
+                                            startPos=j+1;
+                                        }
+                                    } else {
+                                        s+=storedCodeBlock.charAt(j);
+                                        startPos=j+1;
+                                    }
+                                    if (canBeNumericalConstant&&lengthOfConstant==0&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9')) {
+                                        canBeNumericalConstant=false;
+                                    }
+                                    if (!canBeNumericalConstant&&!isAlphanumeric(j)) {
+                                        canBeNumericalConstant=true;
+                                        lengthOfConstant=0;
+                                        System.out.println("Found "+storedCodeBlock.charAt(j)+", can be numeric...");
+                                    }
+                                }
+                                s+=endText;
+                                //System.out.println("Stored code block: "+storedCodeBlock);
+                            } else 
+                            if (inCodeBlock) {
+                                storedCodeBlock+=s+"\n";
+                                s=" ";
+                            }
+                        }
+                        if (s.length()>0&&isArticleFile(f)) {
+                            //Check for markdown pieces.
+                            if (s.charAt(0)=='-') {
+                                //Start of a title piece.
+                                s=s.replace("-",map.get("$TITLE_CONTENT_START"));
+                                s=s+map.get("$TITLE_CONTENT_END").replace("%ID%","id=\"content_"+f+"\"");
+                                //Use ⤈ if there's more text to be shown than can fit.
+                            } else
+                            if (s.contains("===")) {
+                                s=map.get("$CONTENT_END")+map.get("$DATE_CONTENT_START")+s.replace("===","")+map.get("$CONTENT_END")+"%CONDITIONAL_EXPAND%"+map.get("$CONTENT_END");
+                            } else 
+                            if (s.charAt(0)==':') {
+                                //Image with caption.
+                                //Format:
+                                //:<url>,<left|right|center>,<width>,<caption>
+                                String[] splitter = s.split(Pattern.quote(","));
+                                StringBuilder captionText = new StringBuilder(splitter[3]);
+                                for (int j=4;j<splitter.length;j++) {
+                                    captionText.append(",").append(splitter[j]);
+                                }
+                                s="<div><figure style=\"text-align:center;"+((splitter[1].equals("left")||splitter[1].equals("right"))?"width:"+splitter[2]+"%;float:"+splitter[1]+";":"")+"\"><img src=\"/"+splitter[0].substring(1)+"\" style=\"margin:auto;width:100%;\"><figcaption>"+captionText.toString()+"</figcaption></figure></div>";
+                            } else {
+                                //It's regular content, so add paragraphs.
+                                s="<p class=\"color"+(((int)(COLOR_ROTATION=(COLOR_ROTATION+0.4)%6))+1)+"\">"+s+"</p>";
+                            }
+                        } else 
+                        if (s.length()==0&&isArticleFile(f)) {
+                            s="<br/>"; //Setup a line break here.
+                        }
+                        for (String key : map.keySet()) {
+                            s=s.replaceAll(Pattern.quote(key),map.get(key));
+                        }
+                        content.set(i,s);
+                    }
+                    System.out.println("  Writing to "+f.toAbsolutePath());
+                    Files.write(f, content, Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+                    
+                    System.out.println(" "+f.getFileName() + " conversion complete!");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    private static boolean validNumericalConstantCharacters(int lengthOfConstant, int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='.'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='A'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='F'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='a'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='f'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='x'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='X';
+    }
+    private static boolean isAlphanumeric(int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z';
+    }
+    /**
+     * Writes a span tag with the included class.
+     * **/
+    private static String SPAN(String className) {
+        return "<span class=\""+className+"\">";
+    }
+    private static void GenerateArticleFiles(Iterator<Path> items){
+        System.out.println(" Generating article files...");
+        while (items.hasNext()) {
+            Path f = items.next();
+            try {
+                if (Files.isRegularFile(f)&&isArticleFile(f)) {
+                    System.out.println("  Creating article for "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    List<String> preContent = Files.readAllLines(ops.get("%DEFAULT"));
+                    List<String> postContent = Files.readAllLines(ops.get("%FOOTER"));
+                    StringBuilder sb = new StringBuilder();
+                    for (String d : preContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : content) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        d=d.replaceFirst("div class=\"content\"","div class=\"expandedContent\"");
+                        d=d.replaceFirst("%CONDITIONAL_EXPAND%","");
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : postContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    Files.write(Paths.get(f.getParent().toString(),f.getFileName()+".html"),sb.toString().getBytes());
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    private static void ConvertArticleReferences(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Looking for Article References..."+f.getFileName());
+            boolean articleJavascriptIncluded=false;
+            if (Files.isRegularFile(f)&&isHTMLFile(f)) {
+                System.out.println("  Searching "+f.getFileName());
+                try {
+                    List<String> content = Files.readAllLines(f);
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        if (s.length()>0&&s.contains("$ARTICLE_PREVIEW")) {
+                            String article = ARTICLESDIR+"/"+s.replace("$ARTICLE_PREVIEW ","")+".article";
+                            System.out.println("   Found article preview request in "+f.getFileName()+" for article "+article+".");
+                            Path file = Paths.get(OUTDIR,article);
+                            List<String> newData = Files.readAllLines(file);
+                            if (newData.size()>0) {
+                                content.set(i,newData.get(0));
+                                for (int j=1;j<newData.size();j++) {
+                                    content.add(i+j, newData.get(j));
+                                }
+                                String lastline=content.get(i+newData.size()-1);
+                                lastline=lastline.replace("%CONDITIONAL_EXPAND%","<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand(this,'"+Paths.get(OUTDIR,article.toString())+"')\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                                content.set(i+newData.size()-1,lastline);//<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand("+i+")\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                            } else {
+                                content.set(i,"");
+                            }
+                            if (!articleJavascriptIncluded) {
+                                List<String> articlejs = Files.readAllLines(Paths.get(REFDIR,"article.js"));
+                                for (int j=articlejs.size()-1;j>=0;j--) {
+                                    content.add(i,articlejs.get(j));
+                                }
+                                articleJavascriptIncluded=true;
+                            }
+                        }
+                    }
+                    Files.write(f,content);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    static void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) 
+    throws IOException {
+        Files.walk(Paths.get(sourceDirectoryLocation))
+        .forEach(source -> {
+            Path destination = Paths.get(destinationDirectoryLocation, source.toString()
+                .substring(sourceDirectoryLocation.length()));
+            try {
+                if (Files.isDirectory(destination)) {
+                    Files.createDirectories(destination);
+                } else {
+                    Files.copy(source, destination, new CopyOption[]{StandardCopyOption.COPY_ATTRIBUTES,StandardCopyOption.REPLACE_EXISTING});
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+    static void buildDirectoryListings() 
+    throws IOException {
+        String startingPath=Paths.get(sigPlace.OUTDIR).toAbsolutePath().toString();
+        HashMap<String,List<Path>> map = new HashMap<>();
+        Iterator<Path> it = Files.walk(Paths.get(sigPlace.OUTDIR)).iterator();
+        map.put("/",new ArrayList<Path>());
+        while (it.hasNext()) {
+            Path f = it.next();
+            if (!f.getFileName().toString().equals(OUTDIR)) {
+                String myKey = f.toAbsolutePath().toString().replace(startingPath,"").replace(f.getFileName().toString(),"");
+                //System.out.println(myKey+","+f);
+                map.putIfAbsent(myKey,new ArrayList<Path>());
+                map.get(myKey).add(f);
+            }
+        }
+        System.out.println("Directory structure determined:");
+        System.out.println("    "+map);
+        for (String key : map.keySet()) {
+            System.out.println("Creating directory listing for "+key+"...");
+            StringBuilder sb = new StringBuilder("");
+            List<String> data = Files.readAllLines(ops.get("%DEFAULT"));
+            List<String> data2 = Files.readAllLines(ops.get("%FOOTER"));
+            for (String d : data) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            sb.append("<h2>Directory Listing for "+key+"</h2>");
+            sb.append("<div class=\"folderlisting\"><a href=\"")
+            .append(key)
+            .append("..\" class=\"icon\">📁</a><a href=\"")
+            .append(key)
+            .append("..\">.. </a><a href=\"")
+            .append(key)
+            .append("..\" class=\"nounderline\">(Previous Directory)</a></div>");
+            for (Path f : map.get(key)) {
+                sb.append("<div class=\"").append((Files.isDirectory(f)?"folderlisting":"filelisting")).append("\">")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\" class=\"icon\">")
+                .append((Files.isDirectory(f)?"📁":"🗎"))
+                .append("</a>")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\">")
+                .append(f.getFileName())
+                .append("</a>\t")
+                .append(Files.getLastModifiedTime(f))
+                .append("\t")
+                .append(Files.getOwner(f))
+                .append("\t")
+                .append(Files.size(f))
+                .append("</div>\n");
+            }
+            for (String d : data2) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            Path newf = Files.write(Paths.get(OUTDIR,key,DIRECTORYLISTING_FILENAME),sb.toString().getBytes());
+            System.out.println("  Added info for ("+map.size()+") files to "+newf.toAbsolutePath());
+        }
+    }
+    private static boolean isArticleFile(Path f) {
+        return f.getFileName().toString().contains(".article");
+    }
+    private static boolean isHTMLFile(Path f) {
+        return f.getFileName().toString().contains(".html");
+    }
+    private static void ExportCodeFile() {
+        try {
+            Path file = Paths.get("sigServer.java");
+            List<String> data = Files.readAllLines(file);
+            int i=0;
+            while (!data.get(i++).contains("sigServer()")&&i<data.size());
+            if (i<data.size()) {
+                Files.write(Paths.get(OUTDIR,"codeBackground"),data.subList(i, Math.min(i+40,data.size())),Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+    }
+}
+
+

+
3 May 2022 10:25AM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/sigplace1.article.html b/out/articles/sigplace1.article.html new file mode 100644 index 0000000..4709526 --- /dev/null +++ b/out/articles/sigplace1.article.html @@ -0,0 +1,673 @@ + + + + + + + + + + + +
+

Welcome to SigPlace!

+

+ This is a SigPlace article! It will contain information that is important (probably) and will be layed out as such. +

+

+ Paragraphs are automatically split up for readability and generated correctly via the parser. There's quite a bit of flexibility with the system and makes it easy to post updates should they be required. +

+

+ A lot of content management systems would do this by having a web interface and submitting content and managing it that way, but by coding my own management system and using the built-in OS' filesystem to handle the work, I save myself a lot of pains and headaches. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat, urna ut sollicitudin luctus, nulla magna faucibus mauris, at semper nisl nisi ut mauris. Vestibulum cursus tortor velit, ut congue ex porta in. Nullam hendrerit risus sit amet neque euismod faucibus. Sed ac diam non lectus euismod pulvinar eu non mauris. Donec accumsan nisl efficitur, sodales lectus et, finibus quam. Sed vel consectetur leo. Cras ut condimentum quam. Aliquam molestie viverra congue. Donec scelerisque nibh ac nulla dictum semper. Aliquam id massa a massa bibendum finibus id ac sapien. Integer vitae ullamcorper enim, non semper massa. +

+
+

+Proin cursus sodales elit, vitae volutpat mi fermentum a. In vitae magna quis leo cursus accumsan id facilisis purus. Vestibulum accumsan iaculis turpis eu sollicitudin. Sed ultricies felis non elit suscipit interdum. Maecenas sollicitudin turpis justo, vel pretium sapien scelerisque eget. Nullam sagittis finibus risus ut aliquam. Praesent quam orci, dapibus ut ex ac, sodales dapibus nunc. +

+
+

+Fusce magna risus, iaculis non justo sit amet, semper sodales urna. Morbi eu eros lectus. Integer euismod venenatis eros a hendrerit. Nulla ultricies lectus nec quam condimentum fermentum. Quisque a turpis vitae orci pharetra ullamcorper. Nunc fringilla vitae nunc a aliquam. In aliquam gravida massa. Sed imperdiet dignissim sapien, ullamcorper rutrum lacus convallis ut. +

+
+

+Nunc tortor sem, dapibus mattis varius id, varius eu leo. Phasellus efficitur nulla a diam faucibus, id facilisis lacus malesuada. Nulla condimentum egestas erat a fermentum. Ut interdum dui id est condimentum, vel fermentum nisi ornare. Sed eu rhoncus magna, sit amet finibus eros. In a nibh tincidunt, suscipit tellus eleifend, faucibus mauris. Vestibulum sagittis nisi et efficitur ullamcorper. Donec sodales efficitur ligula id congue. Etiam egestas tristique interdum. Mauris at massa eget metus pellentesque fermentum nec non lacus. Nulla turpis nunc, feugiat vel euismod ac, maximus id est. Praesent cursus elit ac dolor hendrerit lacinia. +

+
+

+Vestibulum laoreet lorem consequat, mollis augue finibus, luctus libero. Praesent convallis sed velit vitae molestie. Vestibulum nec fringilla tellus, non dictum nulla. Donec tempor ac diam sit amet porta. Quisque mi ex, vulputate ac tincidunt vel, vestibulum vitae orci. Duis gravida mauris eget mauris pulvinar, lobortis tincidunt neque efficitur. Nunc blandit metus vitae faucibus vulputate. Curabitur rhoncus volutpat lorem, sit amet pulvinar ipsum. Fusce ultricies enim odio, a viverra quam tincidunt quis. Aliquam sollicitudin a sapien id efficitur. Proin at finibus elit, id gravida elit. Nulla facilisi. Ut tincidunt, ligula eu pulvinar dapibus, lorem nisl facilisis tellus, in ornare quam dolor quis libero. Pellentesque ut convallis orci. Donec volutpat nunc velit, tristique convallis purus lacinia sit amet. Maecenas porttitor cursus nisl sed porta. +

+
+
Hello there! You can see this is the Love Live logo indeed! It is quite smol right now but that's okay. Let's keep on going with the text. If the caption is really long and with commas, they will now be combined,,,,,see how that works? Amazing!
+

+Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on. +

+
+

+

+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+public class sigPlace {
+    /* Test giant multi-line comment ""
+    final static String ROOTDIR = "sitefiles";
+    final static String REFDIR = "ref";
+    final static String OUTDIR = "out";
+    final static String ARTICLESDIR = "articles";
+    final static String UPLOADSDIR = "uploads";
+    final static String COMMENTSDIR = "comments";
+    final static String DIRECTORYLISTING_FILENAME = "DIRECTORY_LISTING";
+    static int PORT = 8080;
+    */
+    static double COLOR_ROTATION = 0;
+    static boolean inCodeBlock = false;
+    static String storedCodeBlock = "";
+    final static HashMap<String,String> map = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>("$SITENAME", "SigPlace"),
+        new AbstractMap.SimpleEntry<>("$SITE_BACKCOL", "#111"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_START", "<div class=\"contentWrapper\"><h1>"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_END", "</h1><div class=\"content\" %ID%>"),
+        new AbstractMap.SimpleEntry<>("$CONTENT_END", "</div>"),
+        new AbstractMap.SimpleEntry<>("$DATE_CONTENT_START", "<div class=\"datebar\"></div><div class=\"date\">")
+    ));
+    final static HashMap<String,Path> ops = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>(
+            "%DEFAULT", Paths.get(REFDIR,"DEFAULT.html")),
+        new AbstractMap.SimpleEntry<>(
+            "%FOOTER", Paths.get(REFDIR,"FOOTER.html"))
+    ));
+    public static void main(String[] args) {
+        if (args.length>0&&args.length%2==0) {
+            int i=0;
+            while (i<args.length) {
+                String arg1=args[i];
+                String arg2=args[i+1];
+                i+=2;
+                if (arg1.equals("-p")) {
+                    PORT=Integer.parseInt(arg2);
+                    System.out.println("Port set to "+PORT+".");
+                } else {
+                    System.err.println("Invalid argument \""+arg1+"\".");
+                    return;
+                }
+            }
+        }
+        System.out.println("Copying files over to output directory...");
+        try {
+            copyDirectory("sitefiles","out");
+            Iterator<Path> items = Files.walk(Paths.get("out")).filter((p)->!p.toAbsolutePath().toString().contains("images/")).iterator();
+            ParseArticleFiles(items);
+            items = Files.walk(Paths.get("out")).iterator();
+            ConvertArticleReferences(items);
+            items = Files.walk(Paths.get("out","articles")).iterator();
+            GenerateArticleFiles(items);
+        }catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Copying files over failed!");
+            return;
+        }
+        System.out.println("Building directory listings...");
+        try {
+            buildDirectoryListings();
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Failed to build directory listings!");
+            return;
+        }
+        System.out.println("Site has been built into the "+OUTDIR+" directory.");
+        ExportCodeFile();
+        System.out.println("\nStarting web server...");
+        new sigServer();
+    }
+    private static void ParseArticleFiles(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Found "+f.getFileName());
+            if (Files.isRegularFile(f)) {
+                try {
+                    System.out.println("  Preparing "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    if (isHTMLFile(f)) {
+                        content.addAll(0,Files.readAllLines(ops.get("%DEFAULT")));
+                        content.addAll(Files.readAllLines(ops.get("%FOOTER")));
+                    }
+                    System.out.println("  Parsing "+f.getFileName());
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        //System.out.println(s);
+                        if (s.length()>0&&(isHTMLFile(f)||isArticleFile(f))) {
+                            if (!inCodeBlock) {
+                                if (s.contains("<pre>")) {
+                                    //System.out.println("Inside <pre>");
+                                    inCodeBlock=true;
+                                    storedCodeBlock="";
+                                    s=s.substring(0,s.indexOf("<pre>"));
+                                }
+                            }
+                            if (inCodeBlock&&s.contains("</pre>")) {
+                                inCodeBlock=false;
+                                boolean keyword=false;
+                                boolean inString=false;
+                                boolean inChar=false;
+                                boolean canBeNumericalConstant=false;
+                                int lengthOfConstant=0;
+                                storedCodeBlock+=s.substring(0,s.indexOf("</pre>"));
+                                storedCodeBlock=storedCodeBlock.replaceAll(Pattern.quote("<"),"<");
+                                s+="</pre>";
+                                storedCodeBlock="<pre>"+storedCodeBlock;
+                                int startPos=0;
+                                String endText=s.substring(s.indexOf("</pre>")+"</pre>".length(),s.length());
+                                s="";
+                                for (int j=0;j<storedCodeBlock.length();j++) {
+                                    if (storedCodeBlock.charAt(j)=='"') {
+                                        inString=!inString;
+                                        if (inString) {
+                                            s+=SPAN("string")+"\"";
+                                        } else {
+                                            s+="\"</span>";
+                                            startPos=j+1;
+                                        }
+                                    } else
+                                    if (!inString&&!inChar) {
+                                        if (canBeNumericalConstant&&validNumericalConstantCharacters(lengthOfConstant, j)) {
+                                            lengthOfConstant++;
+                                            System.out.println("Length of Constant now "+lengthOfConstant);
+                                        }
+                                        if (canBeNumericalConstant&&lengthOfConstant>0&&!(validNumericalConstantCharacters(lengthOfConstant, j))) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            //System.out.println("Setting "+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j));
+                                            lengthOfConstant=0;
+                                            canBeNumericalConstant=false;
+                                            startPos=j+1;
+                                        } else
+                                        if (!canBeNumericalConstant&&storedCodeBlock.charAt(j)=='.') {
+                                            //Previous section was a member.
+                                            s+=SPAN("class")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>3&&storedCodeBlock.substring(j-3,j+1).equals("true")&&!isAlphanumeric(j-4)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>4&&storedCodeBlock.substring(j-4,j+1).equals("false")&&!isAlphanumeric(j-5)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (storedCodeBlock.charAt(j)=='(') {
+                                            s+=SPAN("function")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && storedCodeBlock.charAt(j)==' '&&storedCodeBlock.charAt(j-1)!=' ') {
+                                            //Previous section was a keyword.
+                                            keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && (storedCodeBlock.charAt(j)==';'||storedCodeBlock.charAt(j)==':')) {
+                                            //Previous section was a keyword.
+                                            //keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (keyword&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z'||storedCodeBlock.charAt(j)==' ')) {
+                                            keyword=false;
+                                            s+=SPAN("variable")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else
+                                        if (!isAlphanumeric(j)){
+                                            if (startPos<j) {
+                                                s+=storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j);
+                                            } else {
+                                                s+=storedCodeBlock.charAt(j);
+                                            }
+                                            startPos=j+1;
+                                        }
+                                    } else {
+                                        s+=storedCodeBlock.charAt(j);
+                                        startPos=j+1;
+                                    }
+                                    if (canBeNumericalConstant&&lengthOfConstant==0&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9')) {
+                                        canBeNumericalConstant=false;
+                                    }
+                                    if (!canBeNumericalConstant&&!isAlphanumeric(j)) {
+                                        canBeNumericalConstant=true;
+                                        lengthOfConstant=0;
+                                        System.out.println("Found "+storedCodeBlock.charAt(j)+", can be numeric...");
+                                    }
+                                }
+                                s+=endText;
+                                //System.out.println("Stored code block: "+storedCodeBlock);
+                            } else 
+                            if (inCodeBlock) {
+                                storedCodeBlock+=s+"\n";
+                                s=" ";
+                            }
+                        }
+                        if (s.length()>0&&isArticleFile(f)) {
+                            //Check for markdown pieces.
+                            if (s.charAt(0)=='-') {
+                                //Start of a title piece.
+                                s=s.replace("-",map.get("$TITLE_CONTENT_START"));
+                                s=s+map.get("$TITLE_CONTENT_END").replace("%ID%","id=\"content_"+f+"\"");
+                                //Use ⤈ if there's more text to be shown than can fit.
+                            } else
+                            if (s.contains("===")) {
+                                s=map.get("$CONTENT_END")+map.get("$DATE_CONTENT_START")+s.replace("===","")+map.get("$CONTENT_END")+"%CONDITIONAL_EXPAND%"+map.get("$CONTENT_END");
+                            } else 
+                            if (s.charAt(0)==':') {
+                                //Image with caption.
+                                //Format:
+                                //:<url>,<left|right|center>,<width>,<caption>
+                                String[] splitter = s.split(Pattern.quote(","));
+                                StringBuilder captionText = new StringBuilder(splitter[3]);
+                                for (int j=4;j<splitter.length;j++) {
+                                    captionText.append(",").append(splitter[j]);
+                                }
+                                s="<div><figure style=\"text-align:center;"+((splitter[1].equals("left")||splitter[1].equals("right"))?"width:"+splitter[2]+"%;float:"+splitter[1]+";":"")+"\"><img src=\"/"+splitter[0].substring(1)+"\" style=\"margin:auto;width:100%;\"><figcaption>"+captionText.toString()+"</figcaption></figure></div>";
+                            } else {
+                                //It's regular content, so add paragraphs.
+                                s="<p class=\"color"+(((int)(COLOR_ROTATION=(COLOR_ROTATION+0.4)%6))+1)+"\">"+s+"</p>";
+                            }
+                        } else 
+                        if (s.length()==0&&isArticleFile(f)) {
+                            s="<br/>"; //Setup a line break here.
+                        }
+                        for (String key : map.keySet()) {
+                            s=s.replaceAll(Pattern.quote(key),map.get(key));
+                        }
+                        content.set(i,s);
+                    }
+                    System.out.println("  Writing to "+f.toAbsolutePath());
+                    Files.write(f, content, Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+                    
+                    System.out.println(" "+f.getFileName() + " conversion complete!");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    private static boolean validNumericalConstantCharacters(int lengthOfConstant, int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='.'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='A'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='F'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='a'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='f'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='x'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='X';
+    }
+    private static boolean isAlphanumeric(int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z';
+    }
+    /**
+     * Writes a span tag with the included class.
+     * **/
+    private static String SPAN(String className) {
+        return "<span class=\""+className+"\">";
+    }
+    private static void GenerateArticleFiles(Iterator<Path> items){
+        System.out.println(" Generating article files...");
+        while (items.hasNext()) {
+            Path f = items.next();
+            try {
+                if (Files.isRegularFile(f)&&isArticleFile(f)) {
+                    System.out.println("  Creating article for "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    List<String> preContent = Files.readAllLines(ops.get("%DEFAULT"));
+                    List<String> postContent = Files.readAllLines(ops.get("%FOOTER"));
+                    StringBuilder sb = new StringBuilder();
+                    for (String d : preContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : content) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        d=d.replaceFirst("div class=\"content\"","div class=\"expandedContent\"");
+                        d=d.replaceFirst("%CONDITIONAL_EXPAND%","");
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : postContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    Files.write(Paths.get(f.getParent().toString(),f.getFileName()+".html"),sb.toString().getBytes());
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    private static void ConvertArticleReferences(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Looking for Article References..."+f.getFileName());
+            boolean articleJavascriptIncluded=false;
+            if (Files.isRegularFile(f)&&isHTMLFile(f)) {
+                System.out.println("  Searching "+f.getFileName());
+                try {
+                    List<String> content = Files.readAllLines(f);
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        if (s.length()>0&&s.contains("$ARTICLE_PREVIEW")) {
+                            String article = ARTICLESDIR+"/"+s.replace("$ARTICLE_PREVIEW ","")+".article";
+                            System.out.println("   Found article preview request in "+f.getFileName()+" for article "+article+".");
+                            Path file = Paths.get(OUTDIR,article);
+                            List<String> newData = Files.readAllLines(file);
+                            if (newData.size()>0) {
+                                content.set(i,newData.get(0));
+                                for (int j=1;j<newData.size();j++) {
+                                    content.add(i+j, newData.get(j));
+                                }
+                                String lastline=content.get(i+newData.size()-1);
+                                lastline=lastline.replace("%CONDITIONAL_EXPAND%","<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand(this,'"+Paths.get(OUTDIR,article.toString())+"')\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                                content.set(i+newData.size()-1,lastline);//<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand("+i+")\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                            } else {
+                                content.set(i,"");
+                            }
+                            if (!articleJavascriptIncluded) {
+                                List<String> articlejs = Files.readAllLines(Paths.get(REFDIR,"article.js"));
+                                for (int j=articlejs.size()-1;j>=0;j--) {
+                                    content.add(i,articlejs.get(j));
+                                }
+                                articleJavascriptIncluded=true;
+                            }
+                        }
+                    }
+                    Files.write(f,content);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    static void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) 
+    throws IOException {
+        Files.walk(Paths.get(sourceDirectoryLocation))
+        .forEach(source -> {
+            Path destination = Paths.get(destinationDirectoryLocation, source.toString()
+                .substring(sourceDirectoryLocation.length()));
+            try {
+                if (Files.isDirectory(destination)) {
+                    Files.createDirectories(destination);
+                } else {
+                    Files.copy(source, destination, new CopyOption[]{StandardCopyOption.COPY_ATTRIBUTES,StandardCopyOption.REPLACE_EXISTING});
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+    static void buildDirectoryListings() 
+    throws IOException {
+        String startingPath=Paths.get(sigPlace.OUTDIR).toAbsolutePath().toString();
+        HashMap<String,List<Path>> map = new HashMap<>();
+        Iterator<Path> it = Files.walk(Paths.get(sigPlace.OUTDIR)).iterator();
+        map.put("/",new ArrayList<Path>());
+        while (it.hasNext()) {
+            Path f = it.next();
+            if (!f.getFileName().toString().equals(OUTDIR)) {
+                String myKey = f.toAbsolutePath().toString().replace(startingPath,"").replace(f.getFileName().toString(),"");
+                //System.out.println(myKey+","+f);
+                map.putIfAbsent(myKey,new ArrayList<Path>());
+                map.get(myKey).add(f);
+            }
+        }
+        System.out.println("Directory structure determined:");
+        System.out.println("    "+map);
+        for (String key : map.keySet()) {
+            System.out.println("Creating directory listing for "+key+"...");
+            StringBuilder sb = new StringBuilder("");
+            List<String> data = Files.readAllLines(ops.get("%DEFAULT"));
+            List<String> data2 = Files.readAllLines(ops.get("%FOOTER"));
+            for (String d : data) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            sb.append("<h2>Directory Listing for "+key+"</h2>");
+            sb.append("<div class=\"folderlisting\"><a href=\"")
+            .append(key)
+            .append("..\" class=\"icon\">📁</a><a href=\"")
+            .append(key)
+            .append("..\">.. </a><a href=\"")
+            .append(key)
+            .append("..\" class=\"nounderline\">(Previous Directory)</a></div>");
+            for (Path f : map.get(key)) {
+                sb.append("<div class=\"").append((Files.isDirectory(f)?"folderlisting":"filelisting")).append("\">")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\" class=\"icon\">")
+                .append((Files.isDirectory(f)?"📁":"🗎"))
+                .append("</a>")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\">")
+                .append(f.getFileName())
+                .append("</a>\t")
+                .append(Files.getLastModifiedTime(f))
+                .append("\t")
+                .append(Files.getOwner(f))
+                .append("\t")
+                .append(Files.size(f))
+                .append("</div>\n");
+            }
+            for (String d : data2) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            Path newf = Files.write(Paths.get(OUTDIR,key,DIRECTORYLISTING_FILENAME),sb.toString().getBytes());
+            System.out.println("  Added info for ("+map.size()+") files to "+newf.toAbsolutePath());
+        }
+    }
+    private static boolean isArticleFile(Path f) {
+        return f.getFileName().toString().contains(".article");
+    }
+    private static boolean isHTMLFile(Path f) {
+        return f.getFileName().toString().contains(".html");
+    }
+    private static void ExportCodeFile() {
+        try {
+            Path file = Paths.get("sigServer.java");
+            List<String> data = Files.readAllLines(file);
+            int i=0;
+            while (!data.get(i++).contains("sigServer()")&&i<data.size());
+            if (i<data.size()) {
+                Files.write(Paths.get(OUTDIR,"codeBackground"),data.subList(i, Math.min(i+40,data.size())),Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+    }
+}
+
+

+
3 May 2022 10:25AM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/articles/test articles/DIRECTORY_LISTING b/out/articles/test articles/DIRECTORY_LISTING new file mode 100644 index 0000000..f19772c --- /dev/null +++ b/out/articles/test articles/DIRECTORY_LISTING @@ -0,0 +1,33 @@ + + + + + + + + + +

Directory Listing for /articles/test articles/

🗎test3.article 2022-08-20T17:25:48.263325769Z niconiconii 994
+
🗎test2.article 2022-08-20T17:25:48.263325769Z niconiconii 781
+
🗎test2.article.html 2022-08-20T17:25:48.339324832Z niconiconii 10668
+
🗎test3.article.html 2022-08-20T17:25:48.335324882Z niconiconii 10881
+
🗎test1.article.html 2022-08-20T17:25:48.343324783Z niconiconii 10972
+
🗎test1.article 2022-08-20T17:25:48.263325769Z niconiconii 1085
+ + +
+
+ +
+ +
+ diff --git a/out/articles/test articles/test1.article b/out/articles/test articles/test1.article new file mode 100644 index 0000000..540970a --- /dev/null +++ b/out/articles/test articles/test1.article @@ -0,0 +1,5 @@ +

A Test Title

+

+ In dolor erat, malesuada at elit cursus, convallis imperdiet turpis. Ut aliquet magna tellus, at viverra mauris ullamcorper vehicula. Nam quis urna semper magna ornare elementum sed id mauris. Suspendisse faucibus nunc ante, ac rhoncus nisl tristique sed. Vestibulum pretium odio eget scelerisque vestibulum. Aliquam viverra ex ac vestibulum interdum. Donec ligula nunc, dignissim a purus vitae, fermentum laoreet diam. Quisque nec auctor urna. Vestibulum sit amet ligula ullamcorper, congue ipsum et, accumsan ante. Phasellus fermentum, sapien nec pulvinar blandit, elit purus pretium urna, et dapibus orci urna eu metus. Nunc molestie dictum pharetra. Suspendisse luctus felis et ante tristique, vitae commodo diam porttitor. Aliquam orci eros, placerat ac justo vitae, bibendum efficitur metus. Phasellus eget bibendum mauris. +

+
2 May 2022 10:16AM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/test articles/test1.article.html b/out/articles/test articles/test1.article.html new file mode 100644 index 0000000..391eced --- /dev/null +++ b/out/articles/test articles/test1.article.html @@ -0,0 +1,192 @@ + + + + + + + + + + + +
+

A Test Title

+

+ In dolor erat, malesuada at elit cursus, convallis imperdiet turpis. Ut aliquet magna tellus, at viverra mauris ullamcorper vehicula. Nam quis urna semper magna ornare elementum sed id mauris. Suspendisse faucibus nunc ante, ac rhoncus nisl tristique sed. Vestibulum pretium odio eget scelerisque vestibulum. Aliquam viverra ex ac vestibulum interdum. Donec ligula nunc, dignissim a purus vitae, fermentum laoreet diam. Quisque nec auctor urna. Vestibulum sit amet ligula ullamcorper, congue ipsum et, accumsan ante. Phasellus fermentum, sapien nec pulvinar blandit, elit purus pretium urna, et dapibus orci urna eu metus. Nunc molestie dictum pharetra. Suspendisse luctus felis et ante tristique, vitae commodo diam porttitor. Aliquam orci eros, placerat ac justo vitae, bibendum efficitur metus. Phasellus eget bibendum mauris. +

+
2 May 2022 10:16AM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/articles/test articles/test2.article b/out/articles/test articles/test2.article new file mode 100644 index 0000000..fc2d656 --- /dev/null +++ b/out/articles/test articles/test2.article @@ -0,0 +1,5 @@ +

Another test title

+

+ Sed lobortis nisi id nunc tincidunt volutpat. Mauris cursus felis quis condimentum posuere. Pellentesque vitae dolor et justo suscipit ultrices. Integer dapibus leo id felis varius, ut volutpat massa bibendum. Quisque sed nunc arcu. In sit amet faucibus magna, non venenatis massa. Cras sed placerat risus, id consectetur est. Pellentesque in nunc dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eget lorem ac urna posuere accumsan. Quisque sed imperdiet nisi. +

+
1 May 2022 05:13AM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/test articles/test2.article.html b/out/articles/test articles/test2.article.html new file mode 100644 index 0000000..b1e7f42 --- /dev/null +++ b/out/articles/test articles/test2.article.html @@ -0,0 +1,192 @@ + + + + + + + + + + + +
+

Another test title

+

+ Sed lobortis nisi id nunc tincidunt volutpat. Mauris cursus felis quis condimentum posuere. Pellentesque vitae dolor et justo suscipit ultrices. Integer dapibus leo id felis varius, ut volutpat massa bibendum. Quisque sed nunc arcu. In sit amet faucibus magna, non venenatis massa. Cras sed placerat risus, id consectetur est. Pellentesque in nunc dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eget lorem ac urna posuere accumsan. Quisque sed imperdiet nisi. +

+
1 May 2022 05:13AM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/articles/test articles/test3.article b/out/articles/test articles/test3.article new file mode 100644 index 0000000..964bb80 --- /dev/null +++ b/out/articles/test articles/test3.article @@ -0,0 +1,5 @@ +

And More

+

+ Curabitur suscipit quam tellus, non rhoncus diam vehicula in. Aliquam ut dapibus tortor. Cras accumsan arcu vel ante maximus ornare. Nam tempus fermentum leo maximus euismod. Donec vehicula pretium est a ultrices. Nunc blandit nibh lorem, nec blandit leo posuere quis. Sed mauris ligula, euismod eu aliquam vel, rhoncus eget magna. Proin eget tortor ut ligula suscipit mattis. Integer rutrum aliquet eleifend. Suspendisse leo libero, placerat nec mi id, sagittis malesuada felis. Quisque euismod ante cursus elit lobortis, eu tempus ligula condimentum. Mauris viverra metus et dignissim efficitur. Ut placerat nunc nunc, eu tempus neque ultrices nec. Suspendisse et magna risus. Phasellus in ullamcorper tortor. Sed lobortis ut mi in blandit. +

+
30 Apr 2022 6:14PM
%CONDITIONAL_EXPAND%
diff --git a/out/articles/test articles/test3.article.html b/out/articles/test articles/test3.article.html new file mode 100644 index 0000000..d48fa43 --- /dev/null +++ b/out/articles/test articles/test3.article.html @@ -0,0 +1,192 @@ + + + + + + + + + + + +
+

And More

+

+ Curabitur suscipit quam tellus, non rhoncus diam vehicula in. Aliquam ut dapibus tortor. Cras accumsan arcu vel ante maximus ornare. Nam tempus fermentum leo maximus euismod. Donec vehicula pretium est a ultrices. Nunc blandit nibh lorem, nec blandit leo posuere quis. Sed mauris ligula, euismod eu aliquam vel, rhoncus eget magna. Proin eget tortor ut ligula suscipit mattis. Integer rutrum aliquet eleifend. Suspendisse leo libero, placerat nec mi id, sagittis malesuada felis. Quisque euismod ante cursus elit lobortis, eu tempus ligula condimentum. Mauris viverra metus et dignissim efficitur. Ut placerat nunc nunc, eu tempus neque ultrices nec. Suspendisse et magna risus. Phasellus in ullamcorper tortor. Sed lobortis ut mi in blandit. +

+
30 Apr 2022 6:14PM
+
+ +
+ Leave a comment!

+

+

+ +
+
+  B  +  I  +  U  +  <code>  +  <http://>  +  😊  +  😔  +  👍  +  ❤️  +  😡  +
+ +


+ +


+ + + +
+
+
+ +
+ +
+ diff --git a/out/codeBackground b/out/codeBackground new file mode 100644 index 0000000..b01356b --- /dev/null +++ b/out/codeBackground @@ -0,0 +1,40 @@ + try { + socket = new ServerSocket(sigPlace.PORT); + System.out.println("Listening on port "+sigPlace.PORT+"."); + while (true) { + try (Socket client = socket.accept()) { + System.out.println("New client connection detected: "+client.toString()); + InputStreamReader reader = new InputStreamReader(client.getInputStream(),"ISO-8859-1"); + BufferedReader in = new BufferedReader(reader); + String requestLine,line; + ZonedDateTime modifiedDate = null; + String boundary=null; + boolean truncateUntilBoundary=false; + String filename=null; + OutputStream stream = null; + int expectedDataLength=0; + requestLine=in.readLine(); //Read the first line, this should be our request. + //System.out.println(requestLine); + if (requestLine!=null) { + String[] splitter = requestLine.split(Pattern.quote(" ")); + boolean ISPOST = splitter[0].equals("POST"); + boolean isApplication=false; + if (splitter.length==3) { + while (in.ready()) { + line=in.readLine(); + //System.out.println(line); + if (ISPOST) { + if (isApplication) { + if (line.length()==0) { //Now expecting the body since the header is done. + for (int i=0;i0) { + if (line.equals(boundary)) { diff --git a/out/error.html b/out/error.html new file mode 100644 index 0000000..e2a8e36 --- /dev/null +++ b/out/error.html @@ -0,0 +1,50 @@ + + + + + + + + + + + +
+We're Sorry! Your webpage is in another castle! +=== +

+

Go Back

+
+
+
+ +
+
+ diff --git a/out/images/DIRECTORY_LISTING b/out/images/DIRECTORY_LISTING new file mode 100644 index 0000000..dfe09d9 --- /dev/null +++ b/out/images/DIRECTORY_LISTING @@ -0,0 +1,29 @@ + + + + + + + + + +

Directory Listing for /images/

🗎github.webp 2022-08-05T22:59:52.026818Z niconiconii 7270
+
🗎Love_Live!_Logo.png 2022-08-05T22:59:52.026818Z niconiconii 12167
+ + +
+
+ +
+ +
+ diff --git a/out/images/Love_Live!_Logo.png b/out/images/Love_Live!_Logo.png new file mode 100644 index 0000000000000000000000000000000000000000..4cd1d5caf139c42c479625fc9f1da780bccdb4f5 GIT binary patch literal 12167 zcmZvCWmsInvh57+9$bREyC*mVg2O;?f)DQQ7J?+W6C^kc5?lt?K!897A3V6bJ#xR9@Vq=hF0001NWhFT+0005>lKzB-^78h=6_|Pv=q^eI z?f?K6{l5q3QzGpJ0AQ%u$;xVI*gAVSyW2XuyjGT#eeL4rY;6a&0swp#a<#od$=AeE ztJhYzdNQz+x^!?TfR4TjZ5Yp>5brC%JOYp4%|K)fh91!?{2V3S{;*jLrQDeH0+tq= zx1VAR<8+Ngj%b!je+2p+A0FQSx$oG?*?E}oox}~nCt&)rU1$#w)ryo5gV7|aEA@|b zh9JCBf+M}g+aBw+K^_1AP7r;4f;=G755QVy00O{emWzR4Xze+?O@m1v@cIh?PDikV z2~5%g40GuW69I-v0TAtmj~IXy008V8AVUYJzy=&#C`%y&VCBh6Bmh_;WjPuk9tg-} zQDi`P(+)7x4b|d6fc63ks@~9XAwg?^AqGu+iU=W{$N;YdP!jGNGeAhD497U&wFm-0 zmYVP<;%imJ0-ot^c)6)dWQ!6I03A#Hnf`8?pQt7E7rFP@34EP)y%$_3V@|?~XN|r| zmy@1NPpGtms5*fK0Fd8K^*o74C+%!+u5DZIfR8T*3ZEQKoav-!PgkEhJ|iFj@ZL`z zFPLs^%^|uB0U@5<4&@&J3wi+C)mvl!Mf3tgj9-4YalRrCZ>aOWX$(tHQDR_X9x_^d z>*U#plX~V~bB4zSUA=sLTJ$>sxMsb{tcDhaKf0PbdDUno?2IAF@H$=Z&_4}D20tdS zPOS^n8F9S&bP9@X(V$Zs@@>`nB1b!tx=yeg%y&wY_K2SBjSZ-ZQir~8Lj5rYh6Wu0 z5#n$_(_Vl#LFb&G$uYkG@N5M5e6In3s^9-=~L99g4guq4k=GzY#p&w3gA3e;O=s zpYjmEH4aHDbeJMT)=f@I4W59k{S+R*gT!y|Zmndy?t z)EgQ72yXj*EX3-PKnhh%N3_(md5k8^IE1FjN(?w7UpL=l&@v|RDPt--C@m^+7Hbzv zP2<_+s50#*IgYGsqSc2~y-xqqoP?XC{`G#OZ?l<5Y#?S`6}^x_t2l)~MbJum3#lZZ zPbRaVLi1;N-fy&u7_odqWyb<94Q}n|azX*mEXJSN#Ij?>oJF(0vg~Z^u5Gz@J=)Nh z!>Q%df2B`5{6*c}*$uz&#=?%m4j)poU?FoL^Cv4MZ6@Q+RQ--Tlb$)O!}EuaBGV=V zH^W&M#CF9N@aoGbL8@4)UTRS4PKA!HyRP)CZw01Kr7muziC*A$1>FXXjdJwg#Few< zRJ!fuLNyaw-dc$olbWVQU8av=cb3@oQIQG-QA$NRmd%4?@wCK)d{(C*nK?H-#C;Bj z3^j`n^|uGAUdZYPDtaG)x{ z+ZIhJ7csXm9Yx!02>OsnSywqzT2u+FSS>k7m|NKKEf)6|4{Ua^{!DSmvTmDdobebR zALdx9f>n(iB#6%DIOLgk&37z5#7CCM=M1RC3B?ViEu;mEA*ZROT~}r3N$L6OUF!X* zQl2x~=h%0g(+6u%=x1YPi)D{Bl~rd~_j_eKt`e;iC9+PlUTQln@E$xIU>sx}pd5-` znO`wpIbKatjZ+d(&53)62e^57j(dS!I`)g#1p3PR%lmfqZ76KMx#yk>l6-%cG)9o_ zl}@7VSo*2dDc^4_b&LF{ZTiQ|Wl?r}_EPn{J$>X;dC)c2L z*YSe9-D|#Q#Ha6(&44|?EnsITd1wQo10oGlCQ=Ei zAaXo%I|?_J)GHY*bZi3}w`6B1$r;71CI6BQN7mGgm&|=_<;FuN~JF-lY+dv{#Hogk3JF_z~oVIXLb6d)3rL6BZAy%qjiMuVGFeXG<-jf(IrB0ExDzN;|4P_wSN zMMdK4cCKFPmB_MqpzNJ(l)8fFAV0dg7Q62kvahZ5=W2R#b1PMo^RDxpqA58kIYnC7 zc4>|5e|VZ%n$@k@*^{w1eYYJ)DUzc{uQ%y$-Om?afg@F?iW;?QG;oMjxy#snK9GL! zX;JD_GW^ZIYW=i#OOF{w9MG8r(P)7*z*>9^PT_Rj^6kX*aoQx_T)f6wZ6AH?PNoCL zY{%-;9yQiMTDoWUzDs8bTH(_rC9>>c`U0utDI;S}H5Z1hmaoiHKk6Rar_X-S3uYrp zHLY@~DyzAHD70*^>%TXh4Y>4mTv%99X&yb?SK2S$cdEKJ=&n`iw0}GME9wNhn&LEm zi^9}VWyRy0pZ#UR&&HplKM@7Z1rI-rH&rd3eG@9W^2-f29@BfQu59j_XIhx+UiS7s z#|fu;CBAZ;a?tUE-ACV{Q$Fz0Y5FK^Ig#9gqOE&7Xt_nvTYVre(Z9qW^-BJD-`>L+ zyj0uWU61alB@|DsB<8Y}9pb!@eVFC_!^Mydr}ynv5A*8x0RIh*zuzYMmim6KW(GH3 zqU|gBvQLY3dscB4ITlEM>pcGZxhR*)gi5ii`8nvAcf-(j*>7s?Da?Bj+nSiN+@#E*Esy7K@C{@2Vwh zBo%{P9@ms=KREAOU5_2=OVoH=sO^hS9nS>c*+XaD|J?lHGS2tyJRUrtXm(;+rfgws zyS(wbIwbMNI8t3Q_Dl4sedtlGjS>O9>}OgY=$#_uVUZRv*{z-%WxZU?-Tjag*IO zzUAj`$Cc%^Vng&pG#wMZlBeGvswWl$k6Vu0R);!iGFcwpJZYRy-B}Km{!+h|+6j1i z;J%JHzh|7z=YQF4zP41-QUd_|7y*EgZ~)-;`9Pmz@8ZZAeI3DkT`!e9Z&!O z7#fx3-s<=)9OQbpyqcYjUL7kbLiqH_LSGKQy#O|4`#YplzDPm-b6p&x7yTfq0|c+V zjzZHC(+i(M;WsIT5K$pZOlqN0`znn?{_%vQxAjDx_D;^Ze|~hdyUkUjp#S89^Oxqj4Y*18M=n0BJ^85OTrD;RZI` z8onR!zD!@6&+#`Nv8@imyO^(alrDl08`aEjP&H(5Fo8>?DrZEQj2Ef`;E`@l9e9Vx zPd9grVT4viSQo?ud3B;!j-1wp7Rf@hk3i@iLm#469YxmxmpnF;nJ2&YHqptTP#B1q}Py5V)0XGL!c#=B8rB9YNS zuLNc@vji*8t#*d~Bmf6%wQ{Mxv^YJD3Yu&<2!LNySvepE5>g(2%rrvNl*dxj@DezA zJ6GRF2!7@`348JOkDgQX(W8Aiy`-WSH8FUUUz+`00L{XtB(HzqnLNx6c^vgMf3Z9z z;R^aT&#LzO<#ImxTqt6WGJ>W zqtR@(3I}~7GXdbFwZ0S|^v&CfLg0?#xTc~E#yF{UGtGHXqr@^pF>@$1mu~KH#qxe9 z#L>$BWyVZVyz@qA$kY7$6u<{{b9qCM{VSK3@2cgio;ZoG94it!th-N zO;c_2Oe*ki-Zx>zs!2hweQmft^ftBa&CB?y^qpjQPFnI~ZcK~yM|zRsf>r8Iuw~G` z5R=E!nEHuAhhptrXk&xd62){c(L#IRX; zb9CDa(O51A_0<^!Yhv~Kq1R_d`BoL@MbNWzAjhBshCfBoFOL^8XD-h90C6ujif z?aCNY_9_kiL5c>%9NK~aqCL5%<5(Pk37C{gfMkgBmqThACvJ|$c+3poPMKP0nwA}* z*e>}YzO`S^D1{U*shShre$78VTYilv&&o1Pq|aV($*TzY7a8_)Eg>Og$5-}Z&e;qU zqv4D%(F1Mj>yJ7Y-0-DU$>gIqmXLp0v{|AQ`(2boATR&v+~NNgGv_CIR`4NCp!j;E zO3m>v?)(-nMIfZ_pWT376pM32qB?|#_W*}w_0U(4j*z6zIJ$w`C{!`>uSvGH6yapO z$(eUc?T1U94$RtVx!0loM%jcxjqaXJG!WjO4Gp6M9&kW6{ zDp@my*z`!&?qDH2v6UXbqHeI($3#yVT~n!}%+Pb(rxusRV=FIQLRIm`ouNZWtQjZrOHkTKh*vKTY47RCGgLx`B0!!uCM& zIsp#4z$M^=4)iJ>l$AT^_Tx|nd2WQ|w=DTB$(puGGm2h{uhxj5=p2p8t&LIa(gVda zS^H%#O-O@QKoI8AnAm5;x*8u%e;U5)WvnHoBLd|g*@!D> z6K1Tw>$s(={t8PDkuH6pJVw}-tD>m+kfCD2dLnDhY}OpHxP&lXnF1A~99U7NKSorK z$hlGOJFNzn5 zAj`3BJLL?c{+rC?2J>2-`mKnepk0rV;dD^jgs&3z%EZH*AB{ZN{*+6#2 zrR`Vi8%k+9X4QyQHTQX9T?`VYS`-2<{M8bO0r(9;f@ZRrte)e8S`KKW3XS?Kj&f>e zyP=-+u@|ndc$$%}B@znzo5u9b1o!ev6KEhB&zQ1vf@VGP@^_@=O?sZ=Lrk9^ShP<* zob3mdBNfF^H&#Kgc1x0K+9se~=*_p}*(`dzp_fA2GK9Nu(eX+VR*Od&xZ6vYs?6T+ z8xxh%gw;~g(BGKCrTLKk38`?H9CKnlEfr45PKurE_DJJA_qWH;egEcsi1R$VMIkqi zVMLR{d?&JqKNie9DoX+O>SMUpIPnGM0|i6{R}s(c1xHelr;t22;j&v8lWy%6+N-Dt z#=qy-rst%F5I(K2Cj*2|Ej)mWlSLlXP$3wsg}aXHh5|CYEcM5OS7;F&`-Xxfa;iGS z5tGU`PyMKOKhAS)K=q2FB6>hW@5UmglIi;72AlX%l=Yo?=6Ylq)79(Sf{j*a5omHq zgc)RGvmz@m)s4ao!N7Nk+ZQ6)BFprhz(!3_Yk9;4bqxo|A6+p_)}MU3Pr_!jtKVs= zK=d2|XBOCw1E0b!FPSqBuM7H9%VbcPiS%hK5aGu_Yn>_2iRo&tz58vEYx7{+utTSB zJh&E8;fspI=e@5Yjbql61UBvj`7+D+ni%GNpbeo?Fb)VApXu_sS?^h-oYOH1mU7Ea zBY2mE3FKeEjTR(K$xR?YirXucp8K)WM*;l;b>PcJOJdM`%!Z;OQ?lnnJ#XHzGk^*C2m^7)}_GjePe-=Xv0g=(hjv`RO7rN zCJw47MA%OUnY9|*<_)rqj#0wjb9|4R_9zZ7I=x1bRu9;`!unu&D-~_VZzp$qONKe- zf|XWNwDLE605WJV}pCo9L#@pk^6m1E=#BGJ^^MMQGQ4p}gNO!lwL)5+ngLGbM9 zMT{Bcmw0QCUtCf&JUPJm=^ZNkwV9pSj#&GZZm51P_Id^~R#FQAuLo0R^m9Ez;*a27 zM{BLZkX9*#%6JD`in6@oPm&+QbRdYoW*QE>H}gu)kRV0lS!`atQSt$%%zxVHPQ-#b ziNZC6D`IwDKWO83Dw!J);PfKoGp{MA5M9ibe%Nq}t<)*x9`s0J&^kF3oy+HRO;xeh z0@cskTX=#)+SHpbXmarg=@RG(Q#b_zejcB}w(qozeYiqrBOk&%W2etER5e`NfZc4< zeMP``(e%?pgr0PeG%sqTe00^BkaHbDIh;EHg zMf+A6rZN%PP=(2QbqmevA{Zux^y}%NR8N<93X8hvfcEx8ogaAA45ug0RN0`f+&0^F zKZmtU0&0vRjx91bZuSAZR||cpVJb{&RQU`oL$kvKFot*rySy&B zZ?bYu3+A+u0q0^h0M(!8pk)Yejq(ltSn}V)TrO*_-piK-VC<6b?ZCW1Puz7V<+?p% zY~^n^V{8*`R5L0#nwhEDNW|i5p*^hxj6Srbtp(tUe0$jx|GnS%*%e{myMm_tqf{ia zIpIK0bKFOqR>GW$cE--7JxyzGu$zpakEfXBa;PK*Y$(2hxEIkB`;^ti5IAH9z?raY z|BBlXO8}xUpP`b!yNULWx{8jD_q(AGv$NiOgKknX&OgN0*2Pp=VVi&$;#MSu_-aCs2ZMh$J@I>=RWoKQ{)h7hD*C61VUzBg`!#kT?GSV?XgCbk_-^0&qu-UfE!6_l#}_jLY)9Wm4hPM`(~3eayQdRX-eY7V|L_nMJQi z3_9(WfnVq>cBDWNJJP~1nFritY5-B$oX*~YnE}O zt_zVo1>$x?!<-UE>hiE%e@0TRt*KZQLkO46@Z z==TkW>yowM(ZoLnfIGrXR#L6#!BwMD24l7TC~f;s#rY^;gtxyNjtIam2c(ICxmuBb zf|=47;mdfnVchyfFn_unT2TFFwd~%q^(9Bm8|o?*-UJu@y)lsRK(JNeCwE|Va&%WX zBX=sKf;z9q`jyo=4cykOV<$)mFjrN$9|X)sr@rFY{p|ZIa0=}9MNRSgo3Gs5*-qU! z5e9RF1Sl1+afA0dK!^n4gOZVMPFIG5_y?oq&p$U)S}Ld&2&ozU7`AgM^UX|W`P$uq zE;Z*Ya+2?^)J|L_sc-TtzM>_a##qNy#?_Iv5a@@Jbg|$fhIG$}MNNy0vlkkKrCOoG z<=`DvTQfYh>(W+*73Nf6h~IP779j*}!txxp;{)F(!mJ(vB}{8VcSJ|2v(38oE5*=< zFhDF>VDrnD6~Y`GIZ@d@!xy)-8V`Cs)0!%jfuy&4*v?6;bS7-Dzuii5$C6oI2u_Hv zyW_0h=v+q2iCD!F(DZE@3_HcaHt^26@0~~&J)*aZ5Px6N`MlafvZx4x59$-dsIQU+ zH2i{J`ITZrs36ipBlP|jbNL|+Y%V61B18R0P&Z)cEPUb?6(00J`2J5L)NrzMsX|oc zLY@shRUW zWaG#gLOmk8)j|gIjEgd@hizU#2g3wguS~rWDlv)Et!UP@6Mqvlg!2C?m;%oY4oYAT z7CP&HMK$VsXp1^n{JXI5bY%IR8WiH2J)wVY|CS)sCwDxRys59v%bT^XK{|F`<}y)5je(9YiQ z8#o5}=cPF<@$D0HW_2MJRAx};YbNYh*pQZ4qBG>QsB3&EDu<|=npy42=qQsXd|%Ee zFgBi(g3a~SNZl)`r-qE^QoVuM@1AruU47O#M_jJ2#=fABO1*YX#bC=7g*$PyIFa|y z!Xwr(I2zx}@4L3Pqb1gcE4UKQnM!?_j0TxYSIG?J?es5S3Oa2N?iWxmV^b;~dL9yI zd|W>wC-{CRgy#Pa4a8-TQcx9iNBl)0Kd0V{k3MQ2_C}1w zJ7ioGRNGryM>cD>9wE`BJODm%^TNle?ol|A+ExkFn?!Wh19)+4oSO8~J#`r<3Q_BY z|G8kDQ#&ck(pay3R+Aj#0vx4|uuZ%_>Pn4M%qe(hiT3S^;hk#U+O|MWK&u2u+~SM5 zL+p9o5mRjCM@qdx%iK`;s9I*%ALzuPt!bpYCL#p-Bg*TXT^Ki-OqC*A7-KvnV-0QW zyYZ7P+#})Y&xm7#ny#Z;J$oNyQ=diu09Iz)Uvmqw_wh2BEz@0+vbb)Lx22&UA)jPr zsjXn0a0nycgpcbAJNjS|uRR2_Hp@RpY}sh`3?I&?jD=tNVe8!CLTbLhCD2DcRYkvk z623%4^`UPMc^_7O+v$*P#PWm-vbC!Yel&4f#QEj@>DG?qjF#2CXVMtces3;cS zK4`raMT|EI!4{|?4(k8Po7h7)DP81cDxeuGEtCw=AZ|%NZ2(zpD}FSA(ovf#Sy|I= z^%?z{%X547povpdY|uy6*W{R zOVEi4+ zig6tAx6puNHG15{1I@Isd-)uU2sH5M)Eh?I{aN0TWcMQ`SPRcrik|bms;X~dC>>R0?EL7sHHpA-BPKG$Pd<8GmZOiiTe_h3rq2yq4z zVLiFVg9{6~Ny@4`)|GO}(Ap;whU`ncIJ*sce#B^?f`Sx;Tj6?t9cLg6i5M~#dS?W@ z;GC-SLVs8(?iE^=QS15$&bz!867-OKd>6>$`+~u8>J8szJtN!*R})G#BQ~M7wRCg4 z2B&{A2wj!_eIp6O7a;^KJ$Aaii3l+5-I%~N(5sMJouNN+EQcYB(3{Q7hGH)rJO4g- zr{LvnCYx%i&U1RH`hpG05riGxlPr%tmB!QuhFmWnABHfh-2AfpNAtKU3}nDfKJyhF{8D?Q{W1PX+At=!$;p}Y%#=RO&PhuMt`b|9+da(ZQ3`WD@FFg*{l4>3gN#dUNdXLue*EOChbfd24CNBD*vYN2qd2q0WQ)x-RV}6teH1QFi%WLzPO1ip*JS>xh=T~t zatD>nCpP2S5)|34zNrl(&Y_-0kB$gTh?4-}O_6SDs3uILae#jBsTqcp=0IR_Uk@FC zE*#|v0;xjCpppHPDvoh#_4DJiLy$Xu%nbO#rn>0FmI#>X0OLr47#Ycnep}O@um$^k zIC^Twl@dA6AXv^p@3(rXCS>c@+h2Aex zQ%L`wXn0tJ&e2jQ%q;hbqH|kV_VuDTU%PVSt{ycDFNNO?C3%h^asw-Uj`n52+Y5j4 zws3(@M?v|Ck&`UMxuK%G`^gcJpqY7(`G_4nug_b{U3%9`L+M9PH(n0Z8*&)X%lAaY z$=!fbrloCBebWZhigb(RCgm4PoMD~DB>Qdqc?D`t=>=U09=%MTW924Q57(sX{rstI zKD7_3%g%Yy-X3fRhTO}fQr6Rdb6G$40oeYK;Hw8JZG${@H2bPK)T14?ARF|wk5 z!X@4{Z1Tv9=gDK5hkcKyi%?M92?R0rbj|f!7?*_l_M@tTk6ZH<;IR_@xIad9Vu#LZrAKD-W(zzi4^ zZG)b|oRa|}*st+J+ZRH@Z1HFMX&LS{B+=;z$^1HG^P|-mk%qXzXgQd9J1@b*Gniuh z{337YhxFcrF#Wn;TVhfa>DmvbpS<69}q(9gdD79YqKTyeg+*K zuN03ZBMSxX&1YQNh`nvE@Gq?)qnoxtT7db7HeHH?$8kf`pLztm`!2@_K%EU89M?OL zLm+T%W=PvCG+z9kt=I{lK8tTj);-(S7es|o?$A|CXznkEn>YSp2zHw>E(KBcA=L=a&_;{DDEHK&sL7e|Pz*c5 zN-^YoIKbRGW5?BGbua~YLLocT#q?0i@0o=Cm*si2;%&piMgK0aIMb3odH63cRgftO6U;kljYj3+ z5D~Nay6XPGv4a2Ux7qb%y4Mds`hNtaDRocVnO=VzTNsq`*3Ds}DSXPoewR+tD zIK(?9{%xx-s{_A3ZV)wzxq>5Nk~gp8ZBDkUjjT#ObaP! zfHe%emrgZbf87BKC*V@K_Dp+R(W*V-j|jWPhgDQxQ4^mY%NswY==2<&)q}WCI$}fi7wDtJBPRabeuW?R)d|p3<>eablVSDMM5>?7Y&+h>RN0n@!$L zoRmeOLQb0&Buv$|@|V$~%VtFERv*{AVgaMjLcROdV^^j(V7TUXZW9C6tZAR%vd!I! zx7d~@wr_zvzbs9A_)LBCoFPlzR%M9%=ORM|!cOdoXAVPEnD0|gMhsd^`hELPJ!Rg4 z(6Vi@avXn8f9@bn+L_y=$$^d zM`zyMAqcTZRjJjeH<0)PPYozAwgxytpTyE8Ygsp!{4C5V`2uo&)W*Jta31X~e1L(f zBMt5iBTCK}SRn_8lsmUPKiBMVTzh@k(q_)nL)~gg`dC!1IOGmbk)|}8`g~Gt({DBm zaH(k$5NduJUfE>XC>R5CQY>j`W^%@ya1D2aKfhC=80dMQW95!B_aiGJc{$ykG=JuR z?BW~tt+%^pZ!HC5-$z4*Q5-jU_*Qa+xj?D%s0)URYwx3xj7Qkk2&j$FR7?YQ(1;Hz zSSdb`8EfQ5iugm0yzsj32ZOp(pgv$iJr*F0bi93k{UN!jN4t6Si^(kf|@~I`k&yD8YV}Rz<>9BF*R-K3&nEWvEV~; z*4028+G1o!2YH<<;UuB-Yo8eLMBcoiB~%~&=nxR{e$&3(KH5V3d!u;7u2YefGnh~I z1pa+ixMzdvxx_WZ9pmWOW}N@pJ@mRYuEDXL)O;$&Q$K+#jLOyCEk2jRQ$xMbeTn;dA150t`6>u;;-yP6&Rk=q=r&OtM< zC*b{u+wF>mqWP^BZrV#2kwL@fgapNRlQb{bhR6T>(EHd)T5ZGZv`4@{Lg_dCIB6!+o)r(_EINnX0~emN&Zw(7d!a3Jj)A--pIg@zk$l3qs)1Z zCNvzVrJ9Lb=fb+7EBNpQ_1#O?wj&^pO{g$zywz~$7zV$>hGYiyP?liU@etxx7&6d% z{6`Dgh+!H}e2jmr{J&$x|0mF1R=AhU|401av#2KelQUp0g#TxwZBVA-WZS~?Yw?(XhhN*a+=x}`z7q`Mn|^M60U zdw(v@{ARA^Zl245D?%V2X#oIjc^Q}%Ohg9<000pEmlxpwv-AfTRGbh-^;qqxp&=#(ycm_L>8$i~iQeo!+98<3nx8Xoiq)uRq;u zeSvD49mLj_-cFJ#(@y2%wTpq!fq>Y_Ma|((^xl;s)m-80xK`A{b}6c?Xc@MF+<%fb zV8ggViVjGR7OhVxQc|qdREMdfFrH+zzfvN_-<&O5Ppm{Yf)V%jY>-J2)Q4nB_Ubm&slq%8dsHjLZ6d< z=nPn#$qV>XVzxQO+%{-i5gDmm?xe$&5tHDOcU*m3e;V~CjP)9|H%_Kl)yb%JimjuvmpaT46$#Hdr3=j<0g2d4y;YX&up#A zYC=BCRxw#M$IWa6PZ$abtT!4K7_4_N(%^gE;P?@MBrji6-?{Tg(MU{BXj`2b;R{l= ze%nm|j%y1#I9zfK2BzLSU{v*)nfDBEMeD4;Gw(ADfczHN;^Ny}Vqldecf+8%_>k`G z@+3r~%lD|S9Ypp_v~Xe4Onk8#TG=wXbS4lfyAy3|Zb#cu$LOWk;Vi&o!Oa-;k<(V^ z0ZE@!a>dJ<+ZM0x?m->@pcb#0HzQ2F1AWU^Avk3RQp%GJmC#-UUwwe2s+?GpWed|U zIXDTSN$(~&kE2ujFRCTD=FP&}>8J*O?yt;@2~gh8-NY#V759~=Sk*RI7+#fSZ8wBW zX0}TU`L5^;LAL3c^h3+jrajGf{=`OZ`(Z5HH^;$K{-IJmIMm9dJYwoTs8d;ddzLak z*foi~8qzmEoO4Ys)1~ISY3s+CVaL@KD~h?e`p)=S-xD-uMN{v70xQml;G`?yQH~$l zEsyNMFu(l6%ED_e4S7*jOl7K2U>~$Izp)3f@SfBL96wvAH%f==0D z-^JL;1xjL+i)~pY{os2_onE6PeKnhAlN)UB<2)SbOazEqm zrFSkm0rKf@krRtr$tJd30i9ow{LfddHH;LMYhD{SG_p4*y|bE^r7=`Irq|_iqCArE z?Xu7v%2n9J1*(vEEmhf3h3!LFMt(j^V?sdKAWf9{vss|bV`G+I4^bbN?H)=Ibb#oyX(dry`uzKs0El<$Bc4r zmh2>Nc%wXYX#CArLB`Slo$`o>1r}%9VbHsv%HZ`=xoa6EwnNm;mO1%tuWMJVy=xwp z`6%YRuW+S9bije#D7*#tS2nogNipKKzzP*kjoW&YccU>`-#802#9RP%;iC!GC)Dd1 z0d~eL$vEA;tS271;C3;C&h2qXw<#KcKpRr8V-E1d&5C|1hTtbv{NafWm^dj>GPK2E z6e>lxBtb|fr7F{xlrN!bdd~Eq$+Ui&O4Q9wHG>`+NCRjeB((~Hc~$8Ti1p51vHK*< ztAzlaXm2!Jr`pc}&TPa%KG^48Dj!ROu9Eurc-piu50Vpav`pu#@*_F7FO29 zD%aebIIS=4^rBWxmpESYhUQ~85X~J#Ea~=iZ!R(ae2BimP0uzP61o6&5JUkStj;oD zU+hG1DWjCL=&LS!zt>Fix(?{h-CDOJQ9>q}IkN(3OFzxC+}_*_+5b-Ww?bqzCN-^% z{ZQWdz(&s-oqI)uGt1QC9xxmiOU}A`vEjB#FMaA3#l1_mBZp2um90on%|t(@kxT9z(6;o8X=^)=c6=U;M2%qnd>1zxE#p`o}jnm(Klsu@amSLZ?K)D(IR zf#5xer&FF2e*Ai4GN2(_Zw;IIM8nTUncfvoT1Tznk}PD(R3Hof1yZXDb>=i5;ooSJ-oJJ^ zA}lcBIQ|{P?Q&(DD%1zhvKJOsb#+eT!Tzb8r!=0jDk`7$qL$TYM(*Of_cagp{+l66 zrv08t&t~p`9Pc^=%A6~VlI1R#I~NM5ux--9c-2kL0P5M!Y++R{z|_8q@3v*D@+=@L zYGKsFnb)m&_1?VsGT1AW_Qv+gq?)!?SnUe(eh1B#AD6|$pN#;D!X&^eks8vM#^lXa z|21EcGvmUA{!>~FIe3{Kxz&opN7FfdSI&+h@YggXIIu<+4^u8e| zEsnQp94H0#^pbSu7bjWx#~jyvz%dMve}tMuNIWNY2^mklu{fI`FadS3I8E1%4kxI?9^R#ox|n=r89c-sTgv3thAV+HP3Kcl2xBpii#r+S7&ywT4|3 z@pEA&#ylRlIBuz}X{xlFnc$TLl=qf!VN#tN+XKEFTsUFG_|2|CSbZ7 zziSfC1;49ia|yMp6eV*&b5Um_Z!Zg3J}t>wtm7hS*!JpNM01m>_vTe#Fp93$IB zxPixjU`XTay^s8ogYoK0gHOsDWYN<_O>I$V$337CzKn=$#Jy)pxWSvhrLtDM52oLj zx)_f`nm}_)8e(?y&Km?r`7;|^{~^*ECp~84Q}=tNR5OrOL!T2HzIS$7DvD*W#WsKl zA{n{fsR>ydij?76F96oVklMTX)X0K2VDd$Ak-?-!4!|hX3!gI^s>ko&jx^jUI7D8f zhtnTp(k&|Mp>^_2?OaZnPNf2mSnaV0W0>uQI~Aw8J<9N{*?^{sxZ4FhQ>MT~#kXU! z?MRj&8n^@hc|5N59)*$~29Gm=b-}fw*Qopu^3SQvqLjf^V8gp2s8^@FU!sr=hP8If z9)>l4JIk>EWe&^nQXlg5M&X*G{?EvUUj_|n4VpBO4?;)u#{kOL^!5XEQ?Z{Xou_V& z*p9_1bJ*1IYD-de4Jw-jerIV_L0zym=rem5p677s24$>wYD(6uVPmy_XCDc5N5G3v8J!Yv{o_8>JsVKXo(eJgC0@MOqi%4CK4rugx1h9!UcI1}_a__EbiW6d zd;Wcb68HWjwG%IwD)#Dhj9UhU@as+k8si0S8en!K9WI0&yt~U3#6rtY#j=<5Mm(YO zGiGQDO90#1Y96zH)m^cu(pl;4XnYs3?*d~G)u}BLYUMB&!vdexWxFxE-A3v?sAv7Q zOPR_X{X*%yiSH{mx;Q=RzfA4^d^|$3EgE*_W|zqOI)&aRV8>x7o}MfN>}yt0&eL&BqXJA&Dh zqB5J=i6QQTv|{SpSG|gi6?kE2B~V5JoEBA*JJhgBS;gwNA1rl^C7#PZrS$EFoR1{* z$z$GxODpbtrN9^)L}6++BO1QIBl8RusJA_b^a)sh;5K+|y^bn8=F}cARcR=K2oyN$ z$gaaHrgG$Fu^@;CyB-6TN0iL}xBip0H^m?l^W#RthsdO&LW{u1l0a!!(J zBMK28(c8w7uw&Q5ok7zrH`dJLwqCw_7D-C7k0R|!*d=q@p{W$f*7Zd`#(5e%f0;g( zWrf05aNX!wDgXV>Bjxxd-9k{OZ9TNEDJ2P_3`^v);QmTa+U-AArY1ywwN8mcvWx3qt#OQLDyCjCYI$4l5aMw z>;koR@|Twmy56fhgcEk~P*LWg?}P4N-X8#G2MNyIFoQNE`KgLK$iC=m`-Z1=msn6TzfaH$^z|NJvIB!V`sEGKwWNIAg9C~mNLvzDSn zhKU#|F?uI;H3$K2Tn?@F=O66YY4nB>cm_;9=xY<>=zA_o;1D6Slhr#ubrgvbps%#D z?Aa5~|Jd2sMWfgAJ3T3MVJYb?lxcUFBpjJq(64Qhon8?-C*pN>eJ%g_#B(B2={@?F zqpWW=AKHMOY})MLUNKUXnTpwA;j;A8pI2zVuR{I^0>Zk^nd$Y$g0V!r>;NB)Fc>#_RK875M z+#zZC6)e#jyJ>AbDtmyWpA2L*o5uE0TcAA5HYj4!xvaK@{2HU<0GH4fJ=Y5~B)or? zJ==Z&Yac(TpwL+M$$#_|?Qtcb21Yj#C7t#h7aiOyj~SF`ZWRcZb-&EM$)2P-ah}CF zkYWO@xz82t5<0-Am}%0K><6mEuS(H1@5!*{wH#ks^3)Xg1I|nq^Es*~727vqkSSg?c%Tk#jFncgP5K;LF@hzLvDFByXmR2SX(2ebZG& zJ){2K#hviDOY_EbT625Mx`CfzS&>hhAPl^@Hycp_1dIOn3I`YgXqZc6b|P3d?Qa1a z$DxbN} zj#FQ#k)E)E#DBek*oEsa-)w+_oMhV?Ny_(ju9<*9u_qRs_J3g9yUapz`UUjitF$Dm z3B^}G)j!~tE?xZ_M+o)hRlwPZUV?d=$C1F9y2NQp%X63RR?f!k#F6FYC7G8Tk=l9irUL^E5Mff|gd_fc$UP(n8V9%SuLwXuGx*C`3t z3QSI8pTMJ^5>%z7E$_o*Po7CdEEsG@d@e?5Cj$K{#NdgHZ=>H28oor2w{8Uyd~}`x z6z-=pR|I_fJSm5%F+_s7Yo-2=j(pZw7k%fOiWYhPmwNE5pDkcJFI9WCDepueS@tMV}aK;O?QRo)L`$J{Ae!lbq;oND6$UKkp#_ zL>q4_%0f^*hcY6DJ^$|e@qx>*9AR)tWD-Iem*-Sa98u=;BXP<9`D!c z!i)yP%n6BbpF{<3pTb=)jpbj%x}{Qz_$NAK$c}0V0pseou0$QSotXKN0~%)N(24VC zknlAMKxKCM`vUhiisi|GB{V|_xO0CVPubN)A5@9)b7Asa?F{Y8 z&wl%7L!M}`?qehU+98Ku+(g{rTqSI3j+{(LiM{?XfU|?Fm!wjPCAWyoC{Vm9G9V$; zJX6UIJ)-p^#qT3w2L4d`eJwbgAD;nfg zJa@7QHFT~)ExZBVUsTF*#6N^7ZYtmT%Ygh4$VZ?|4Aei@PqtTYMPS1yFXOuVKQgma%C9SAzyX(O74CSC2`1vos;~R%M1#MM-U4~H`BgnNDa?(S zbO9qLeF{T@;O7{Abnp_{yJ0&#j`=PQzy>uYMZFt9kQRh?a=V)!kRO>8(s?(2Z^>7- zNy0$n{=hR%0)tL#@t#@e&o0=&v7MH=F*dsNyuYsz&rBUx(pyDU_X=39fCYb@Vg*{Q zJP;2opJQC(-RqOdEuBmDHE*91!6sd}L!^7%4-e~xqg?V!EZ*P-hjSMV%zQCU94N^D z#&8=voaJq`>K`gCdhud+6#9U1FT%1-AiKdwgN?FAi7Q&eEh}UHFi9x6u z!S<^cF7_qP_gnm(lU1B#L#sLI@)n04{^ppKFl*VX@EBtbEgPZ#+cA0M}QW{94) z2y7fO&62vDP?N=a(1ut4=KKdb4>_BELH?5Oi2U24PcXB(X?X#m%8@w9e<;al>5btP zYC&{iH7XX`XBT)Zkwlxcv>{`J`P_#C)j8=@7UWPb&767S5ia|g<~o(c#++GfiR304 zBw0a|oS#F#v14q1q2kFU*yOj$w1M*VXLQDEHG`+VFuAmgztX(i;tc#m9XFy#U~K%> zsMs>~Z?ge*bk*huT*2@7kXa4>SF6-b;TdL})tW%2qbn5x_BCqk-<%3OgRUp)eB#;wHK5iFe!T(qE% zhs@}2@j4T}8Lx{yv#)Y&dreSB|C(-=o16u$9wx*Z-}$8K_Ucu9S%~`OkN*3Z)Fx;6 zmyh(KTX_Nn~)vOj~*r(WDT!@dp6I{>29 z_a5q>b8u}H{FbMr<VE9MsA2189ZOIspE3COa2*>yFkXQTy_KeAHpTu174PO0Yj){)V> zI$FR63Ef#KJ1>;k*wzpI379C4{@D*4I4(8&n~MIp`}8Mv&F$T*1qQ(LxYB>G68%3Q z000vO + + + + + + + + + + +
+This is a different webpage.
+ +

Welcome to SigPlace!

🔗
+

+ This is a SigPlace article! It will contain information that is important (probably) and will be layed out as such. +

+

+ Paragraphs are automatically split up for readability and generated correctly via the parser. There's quite a bit of flexibility with the system and makes it easy to post updates should they be required. +

+

+ A lot of content management systems would do this by having a web interface and submitting content and managing it that way, but by coding my own management system and using the built-in OS' filesystem to handle the work, I save myself a lot of pains and headaches. +

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. In feugiat, urna ut sollicitudin luctus, nulla magna faucibus mauris, at semper nisl nisi ut mauris. Vestibulum cursus tortor velit, ut congue ex porta in. Nullam hendrerit risus sit amet neque euismod faucibus. Sed ac diam non lectus euismod pulvinar eu non mauris. Donec accumsan nisl efficitur, sodales lectus et, finibus quam. Sed vel consectetur leo. Cras ut condimentum quam. Aliquam molestie viverra congue. Donec scelerisque nibh ac nulla dictum semper. Aliquam id massa a massa bibendum finibus id ac sapien. Integer vitae ullamcorper enim, non semper massa. +

+
+

+Proin cursus sodales elit, vitae volutpat mi fermentum a. In vitae magna quis leo cursus accumsan id facilisis purus. Vestibulum accumsan iaculis turpis eu sollicitudin. Sed ultricies felis non elit suscipit interdum. Maecenas sollicitudin turpis justo, vel pretium sapien scelerisque eget. Nullam sagittis finibus risus ut aliquam. Praesent quam orci, dapibus ut ex ac, sodales dapibus nunc. +

+
+

+Fusce magna risus, iaculis non justo sit amet, semper sodales urna. Morbi eu eros lectus. Integer euismod venenatis eros a hendrerit. Nulla ultricies lectus nec quam condimentum fermentum. Quisque a turpis vitae orci pharetra ullamcorper. Nunc fringilla vitae nunc a aliquam. In aliquam gravida massa. Sed imperdiet dignissim sapien, ullamcorper rutrum lacus convallis ut. +

+
+

+Nunc tortor sem, dapibus mattis varius id, varius eu leo. Phasellus efficitur nulla a diam faucibus, id facilisis lacus malesuada. Nulla condimentum egestas erat a fermentum. Ut interdum dui id est condimentum, vel fermentum nisi ornare. Sed eu rhoncus magna, sit amet finibus eros. In a nibh tincidunt, suscipit tellus eleifend, faucibus mauris. Vestibulum sagittis nisi et efficitur ullamcorper. Donec sodales efficitur ligula id congue. Etiam egestas tristique interdum. Mauris at massa eget metus pellentesque fermentum nec non lacus. Nulla turpis nunc, feugiat vel euismod ac, maximus id est. Praesent cursus elit ac dolor hendrerit lacinia. +

+
+

+Vestibulum laoreet lorem consequat, mollis augue finibus, luctus libero. Praesent convallis sed velit vitae molestie. Vestibulum nec fringilla tellus, non dictum nulla. Donec tempor ac diam sit amet porta. Quisque mi ex, vulputate ac tincidunt vel, vestibulum vitae orci. Duis gravida mauris eget mauris pulvinar, lobortis tincidunt neque efficitur. Nunc blandit metus vitae faucibus vulputate. Curabitur rhoncus volutpat lorem, sit amet pulvinar ipsum. Fusce ultricies enim odio, a viverra quam tincidunt quis. Aliquam sollicitudin a sapien id efficitur. Proin at finibus elit, id gravida elit. Nulla facilisi. Ut tincidunt, ligula eu pulvinar dapibus, lorem nisl facilisis tellus, in ornare quam dolor quis libero. Pellentesque ut convallis orci. Donec volutpat nunc velit, tristique convallis purus lacinia sit amet. Maecenas porttitor cursus nisl sed porta. +

+
+
Hello there! You can see this is the Love Live logo indeed! It is quite smol right now but that's okay. Let's keep on going with the text. If the caption is really long and with commas, they will now be combined,,,,,see how that works? Amazing!
+

+Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on.Here we demonstrate the love live logo. But wait, it's literally like in the middle wtf is going on. +

+
+

+

+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.CopyOption;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.StandardOpenOption;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+public class sigPlace {
+    /* Test giant multi-line comment ""
+    final static String ROOTDIR = "sitefiles";
+    final static String REFDIR = "ref";
+    final static String OUTDIR = "out";
+    final static String ARTICLESDIR = "articles";
+    final static String UPLOADSDIR = "uploads";
+    final static String COMMENTSDIR = "comments";
+    final static String DIRECTORYLISTING_FILENAME = "DIRECTORY_LISTING";
+    static int PORT = 8080;
+    */
+    static double COLOR_ROTATION = 0;
+    static boolean inCodeBlock = false;
+    static String storedCodeBlock = "";
+    final static HashMap<String,String> map = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>("$SITENAME", "SigPlace"),
+        new AbstractMap.SimpleEntry<>("$SITE_BACKCOL", "#111"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_START", "<div class=\"contentWrapper\"><h1>"),
+        new AbstractMap.SimpleEntry<>("$TITLE_CONTENT_END", "</h1><div class=\"content\" %ID%>"),
+        new AbstractMap.SimpleEntry<>("$CONTENT_END", "</div>"),
+        new AbstractMap.SimpleEntry<>("$DATE_CONTENT_START", "<div class=\"datebar\"></div><div class=\"date\">")
+    ));
+    final static HashMap<String,Path> ops = new HashMap<>(Map.ofEntries(
+        new AbstractMap.SimpleEntry<>(
+            "%DEFAULT", Paths.get(REFDIR,"DEFAULT.html")),
+        new AbstractMap.SimpleEntry<>(
+            "%FOOTER", Paths.get(REFDIR,"FOOTER.html"))
+    ));
+    public static void main(String[] args) {
+        if (args.length>0&&args.length%2==0) {
+            int i=0;
+            while (i<args.length) {
+                String arg1=args[i];
+                String arg2=args[i+1];
+                i+=2;
+                if (arg1.equals("-p")) {
+                    PORT=Integer.parseInt(arg2);
+                    System.out.println("Port set to "+PORT+".");
+                } else {
+                    System.err.println("Invalid argument \""+arg1+"\".");
+                    return;
+                }
+            }
+        }
+        System.out.println("Copying files over to output directory...");
+        try {
+            copyDirectory("sitefiles","out");
+            Iterator<Path> items = Files.walk(Paths.get("out")).filter((p)->!p.toAbsolutePath().toString().contains("images/")).iterator();
+            ParseArticleFiles(items);
+            items = Files.walk(Paths.get("out")).iterator();
+            ConvertArticleReferences(items);
+            items = Files.walk(Paths.get("out","articles")).iterator();
+            GenerateArticleFiles(items);
+        }catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Copying files over failed!");
+            return;
+        }
+        System.out.println("Building directory listings...");
+        try {
+            buildDirectoryListings();
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.err.println("Failed to build directory listings!");
+            return;
+        }
+        System.out.println("Site has been built into the "+OUTDIR+" directory.");
+        ExportCodeFile();
+        System.out.println("\nStarting web server...");
+        new sigServer();
+    }
+    private static void ParseArticleFiles(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Found "+f.getFileName());
+            if (Files.isRegularFile(f)) {
+                try {
+                    System.out.println("  Preparing "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    if (isHTMLFile(f)) {
+                        content.addAll(0,Files.readAllLines(ops.get("%DEFAULT")));
+                        content.addAll(Files.readAllLines(ops.get("%FOOTER")));
+                    }
+                    System.out.println("  Parsing "+f.getFileName());
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        //System.out.println(s);
+                        if (s.length()>0&&(isHTMLFile(f)||isArticleFile(f))) {
+                            if (!inCodeBlock) {
+                                if (s.contains("<pre>")) {
+                                    //System.out.println("Inside <pre>");
+                                    inCodeBlock=true;
+                                    storedCodeBlock="";
+                                    s=s.substring(0,s.indexOf("<pre>"));
+                                }
+                            }
+                            if (inCodeBlock&&s.contains("</pre>")) {
+                                inCodeBlock=false;
+                                boolean keyword=false;
+                                boolean inString=false;
+                                boolean inChar=false;
+                                boolean canBeNumericalConstant=false;
+                                int lengthOfConstant=0;
+                                storedCodeBlock+=s.substring(0,s.indexOf("</pre>"));
+                                storedCodeBlock=storedCodeBlock.replaceAll(Pattern.quote("<"),"<");
+                                s+="</pre>";
+                                storedCodeBlock="<pre>"+storedCodeBlock;
+                                int startPos=0;
+                                String endText=s.substring(s.indexOf("</pre>")+"</pre>".length(),s.length());
+                                s="";
+                                for (int j=0;j<storedCodeBlock.length();j++) {
+                                    if (storedCodeBlock.charAt(j)=='"') {
+                                        inString=!inString;
+                                        if (inString) {
+                                            s+=SPAN("string")+"\"";
+                                        } else {
+                                            s+="\"</span>";
+                                            startPos=j+1;
+                                        }
+                                    } else
+                                    if (!inString&&!inChar) {
+                                        if (canBeNumericalConstant&&validNumericalConstantCharacters(lengthOfConstant, j)) {
+                                            lengthOfConstant++;
+                                            System.out.println("Length of Constant now "+lengthOfConstant);
+                                        }
+                                        if (canBeNumericalConstant&&lengthOfConstant>0&&!(validNumericalConstantCharacters(lengthOfConstant, j))) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            //System.out.println("Setting "+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j));
+                                            lengthOfConstant=0;
+                                            canBeNumericalConstant=false;
+                                            startPos=j+1;
+                                        } else
+                                        if (!canBeNumericalConstant&&storedCodeBlock.charAt(j)=='.') {
+                                            //Previous section was a member.
+                                            s+=SPAN("class")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>3&&storedCodeBlock.substring(j-3,j+1).equals("true")&&!isAlphanumeric(j-4)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>4&&storedCodeBlock.substring(j-4,j+1).equals("false")&&!isAlphanumeric(j-5)&&!isAlphanumeric(j+1)) {
+                                            s+=SPAN("number")+storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j)+"</span>";
+                                            startPos=j+1;
+                                        } else 
+                                        if (storedCodeBlock.charAt(j)=='(') {
+                                            s+=SPAN("function")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && storedCodeBlock.charAt(j)==' '&&storedCodeBlock.charAt(j-1)!=' ') {
+                                            //Previous section was a keyword.
+                                            keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (j>0&&isAlphanumeric(j-1) && (storedCodeBlock.charAt(j)==';'||storedCodeBlock.charAt(j)==':')) {
+                                            //Previous section was a keyword.
+                                            //keyword=true;
+                                            s+=SPAN("keyword")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else 
+                                        if (keyword&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z'||storedCodeBlock.charAt(j)==' ')) {
+                                            keyword=false;
+                                            s+=SPAN("variable")+storedCodeBlock.substring(startPos,j)+"</span>"+storedCodeBlock.charAt(j);
+                                            startPos=j+1;
+                                        } else
+                                        if (!isAlphanumeric(j)){
+                                            if (startPos<j) {
+                                                s+=storedCodeBlock.substring(startPos,j)+storedCodeBlock.charAt(j);
+                                            } else {
+                                                s+=storedCodeBlock.charAt(j);
+                                            }
+                                            startPos=j+1;
+                                        }
+                                    } else {
+                                        s+=storedCodeBlock.charAt(j);
+                                        startPos=j+1;
+                                    }
+                                    if (canBeNumericalConstant&&lengthOfConstant==0&&!(storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9')) {
+                                        canBeNumericalConstant=false;
+                                    }
+                                    if (!canBeNumericalConstant&&!isAlphanumeric(j)) {
+                                        canBeNumericalConstant=true;
+                                        lengthOfConstant=0;
+                                        System.out.println("Found "+storedCodeBlock.charAt(j)+", can be numeric...");
+                                    }
+                                }
+                                s+=endText;
+                                //System.out.println("Stored code block: "+storedCodeBlock);
+                            } else 
+                            if (inCodeBlock) {
+                                storedCodeBlock+=s+"\n";
+                                s=" ";
+                            }
+                        }
+                        if (s.length()>0&&isArticleFile(f)) {
+                            //Check for markdown pieces.
+                            if (s.charAt(0)=='-') {
+                                //Start of a title piece.
+                                s=s.replace("-",map.get("$TITLE_CONTENT_START"));
+                                s=s+map.get("$TITLE_CONTENT_END").replace("%ID%","id=\"content_"+f+"\"");
+                                //Use ⤈ if there's more text to be shown than can fit.
+                            } else
+                            if (s.contains("===")) {
+                                s=map.get("$CONTENT_END")+map.get("$DATE_CONTENT_START")+s.replace("===","")+map.get("$CONTENT_END")+"%CONDITIONAL_EXPAND%"+map.get("$CONTENT_END");
+                            } else 
+                            if (s.charAt(0)==':') {
+                                //Image with caption.
+                                //Format:
+                                //:<url>,<left|right|center>,<width>,<caption>
+                                String[] splitter = s.split(Pattern.quote(","));
+                                StringBuilder captionText = new StringBuilder(splitter[3]);
+                                for (int j=4;j<splitter.length;j++) {
+                                    captionText.append(",").append(splitter[j]);
+                                }
+                                s="<div><figure style=\"text-align:center;"+((splitter[1].equals("left")||splitter[1].equals("right"))?"width:"+splitter[2]+"%;float:"+splitter[1]+";":"")+"\"><img src=\"/"+splitter[0].substring(1)+"\" style=\"margin:auto;width:100%;\"><figcaption>"+captionText.toString()+"</figcaption></figure></div>";
+                            } else {
+                                //It's regular content, so add paragraphs.
+                                s="<p class=\"color"+(((int)(COLOR_ROTATION=(COLOR_ROTATION+0.4)%6))+1)+"\">"+s+"</p>";
+                            }
+                        } else 
+                        if (s.length()==0&&isArticleFile(f)) {
+                            s="<br/>"; //Setup a line break here.
+                        }
+                        for (String key : map.keySet()) {
+                            s=s.replaceAll(Pattern.quote(key),map.get(key));
+                        }
+                        content.set(i,s);
+                    }
+                    System.out.println("  Writing to "+f.toAbsolutePath());
+                    Files.write(f, content, Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+                    
+                    System.out.println(" "+f.getFileName() + " conversion complete!");
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    private static boolean validNumericalConstantCharacters(int lengthOfConstant, int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='.'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='A'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='F'||lengthOfConstant>0&&storedCodeBlock.charAt(j)>='a'&&lengthOfConstant>0&&storedCodeBlock.charAt(j)<='f'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='x'||lengthOfConstant>0&&storedCodeBlock.charAt(j)=='X';
+    }
+    private static boolean isAlphanumeric(int j) {
+        return storedCodeBlock.charAt(j)>='0'&&storedCodeBlock.charAt(j)<='9'||storedCodeBlock.charAt(j)>='A'&&storedCodeBlock.charAt(j)<='Z'||storedCodeBlock.charAt(j)>='a'&&storedCodeBlock.charAt(j)<='z';
+    }
+    /**
+     * Writes a span tag with the included class.
+     * **/
+    private static String SPAN(String className) {
+        return "<span class=\""+className+"\">";
+    }
+    private static void GenerateArticleFiles(Iterator<Path> items){
+        System.out.println(" Generating article files...");
+        while (items.hasNext()) {
+            Path f = items.next();
+            try {
+                if (Files.isRegularFile(f)&&isArticleFile(f)) {
+                    System.out.println("  Creating article for "+f.getFileName());
+                    List<String> content = Files.readAllLines(f);
+                    List<String> preContent = Files.readAllLines(ops.get("%DEFAULT"));
+                    List<String> postContent = Files.readAllLines(ops.get("%FOOTER"));
+                    StringBuilder sb = new StringBuilder();
+                    for (String d : preContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : content) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        d=d.replaceFirst("div class=\"content\"","div class=\"expandedContent\"");
+                        d=d.replaceFirst("%CONDITIONAL_EXPAND%","");
+                        sb.append(d).append("\n");
+                    }
+                    for (String d : postContent) {
+                        for (String k : sigPlace.map.keySet()) {
+                            d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                        }
+                        sb.append(d).append("\n");
+                    }
+                    Files.write(Paths.get(f.getParent().toString(),f.getFileName()+".html"),sb.toString().getBytes());
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    private static void ConvertArticleReferences(Iterator<Path> items) {
+        while (items.hasNext()) {
+            Path f = items.next();
+            System.out.println(" Looking for Article References..."+f.getFileName());
+            boolean articleJavascriptIncluded=false;
+            if (Files.isRegularFile(f)&&isHTMLFile(f)) {
+                System.out.println("  Searching "+f.getFileName());
+                try {
+                    List<String> content = Files.readAllLines(f);
+                    for (int i=0;i<content.size();i++) {
+                        String s = content.get(i);
+                        if (s.length()>0&&s.contains("$ARTICLE_PREVIEW")) {
+                            String article = ARTICLESDIR+"/"+s.replace("$ARTICLE_PREVIEW ","")+".article";
+                            System.out.println("   Found article preview request in "+f.getFileName()+" for article "+article+".");
+                            Path file = Paths.get(OUTDIR,article);
+                            List<String> newData = Files.readAllLines(file);
+                            if (newData.size()>0) {
+                                content.set(i,newData.get(0));
+                                for (int j=1;j<newData.size();j++) {
+                                    content.add(i+j, newData.get(j));
+                                }
+                                String lastline=content.get(i+newData.size()-1);
+                                lastline=lastline.replace("%CONDITIONAL_EXPAND%","<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand(this,'"+Paths.get(OUTDIR,article.toString())+"')\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                                content.set(i+newData.size()-1,lastline);//<div class=\"unexpanded\" id=\"expand_"+i+"\" onClick=\"expand("+i+")\"><br/><br/><br/><br/>⤈ Click to expand.</div>");
+                            } else {
+                                content.set(i,"");
+                            }
+                            if (!articleJavascriptIncluded) {
+                                List<String> articlejs = Files.readAllLines(Paths.get(REFDIR,"article.js"));
+                                for (int j=articlejs.size()-1;j>=0;j--) {
+                                    content.add(i,articlejs.get(j));
+                                }
+                                articleJavascriptIncluded=true;
+                            }
+                        }
+                    }
+                    Files.write(f,content);
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+    static void copyDirectory(String sourceDirectoryLocation, String destinationDirectoryLocation) 
+    throws IOException {
+        Files.walk(Paths.get(sourceDirectoryLocation))
+        .forEach(source -> {
+            Path destination = Paths.get(destinationDirectoryLocation, source.toString()
+                .substring(sourceDirectoryLocation.length()));
+            try {
+                if (Files.isDirectory(destination)) {
+                    Files.createDirectories(destination);
+                } else {
+                    Files.copy(source, destination, new CopyOption[]{StandardCopyOption.COPY_ATTRIBUTES,StandardCopyOption.REPLACE_EXISTING});
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        });
+    }
+    static void buildDirectoryListings() 
+    throws IOException {
+        String startingPath=Paths.get(sigPlace.OUTDIR).toAbsolutePath().toString();
+        HashMap<String,List<Path>> map = new HashMap<>();
+        Iterator<Path> it = Files.walk(Paths.get(sigPlace.OUTDIR)).iterator();
+        map.put("/",new ArrayList<Path>());
+        while (it.hasNext()) {
+            Path f = it.next();
+            if (!f.getFileName().toString().equals(OUTDIR)) {
+                String myKey = f.toAbsolutePath().toString().replace(startingPath,"").replace(f.getFileName().toString(),"");
+                //System.out.println(myKey+","+f);
+                map.putIfAbsent(myKey,new ArrayList<Path>());
+                map.get(myKey).add(f);
+            }
+        }
+        System.out.println("Directory structure determined:");
+        System.out.println("    "+map);
+        for (String key : map.keySet()) {
+            System.out.println("Creating directory listing for "+key+"...");
+            StringBuilder sb = new StringBuilder("");
+            List<String> data = Files.readAllLines(ops.get("%DEFAULT"));
+            List<String> data2 = Files.readAllLines(ops.get("%FOOTER"));
+            for (String d : data) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            sb.append("<h2>Directory Listing for "+key+"</h2>");
+            sb.append("<div class=\"folderlisting\"><a href=\"")
+            .append(key)
+            .append("..\" class=\"icon\">📁</a><a href=\"")
+            .append(key)
+            .append("..\">.. </a><a href=\"")
+            .append(key)
+            .append("..\" class=\"nounderline\">(Previous Directory)</a></div>");
+            for (Path f : map.get(key)) {
+                sb.append("<div class=\"").append((Files.isDirectory(f)?"folderlisting":"filelisting")).append("\">")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\" class=\"icon\">")
+                .append((Files.isDirectory(f)?"📁":"🗎"))
+                .append("</a>")
+                .append("<a href=\""+(f.toAbsolutePath().toString().replace(Paths.get(OUTDIR).toAbsolutePath().toString(),""))+"\">")
+                .append(f.getFileName())
+                .append("</a>\t")
+                .append(Files.getLastModifiedTime(f))
+                .append("\t")
+                .append(Files.getOwner(f))
+                .append("\t")
+                .append(Files.size(f))
+                .append("</div>\n");
+            }
+            for (String d : data2) {
+                for (String k : sigPlace.map.keySet()) {
+                    d=d.replaceAll(Pattern.quote(k),sigPlace.map.get(k));
+                }
+                sb.append(d).append("\n");
+            }
+            Path newf = Files.write(Paths.get(OUTDIR,key,DIRECTORYLISTING_FILENAME),sb.toString().getBytes());
+            System.out.println("  Added info for ("+map.size()+") files to "+newf.toAbsolutePath());
+        }
+    }
+    private static boolean isArticleFile(Path f) {
+        return f.getFileName().toString().contains(".article");
+    }
+    private static boolean isHTMLFile(Path f) {
+        return f.getFileName().toString().contains(".html");
+    }
+    private static void ExportCodeFile() {
+        try {
+            Path file = Paths.get("sigServer.java");
+            List<String> data = Files.readAllLines(file);
+            int i=0;
+            while (!data.get(i++).contains("sigServer()")&&i<data.size());
+            if (i<data.size()) {
+                Files.write(Paths.get(OUTDIR,"codeBackground"),data.subList(i, Math.min(i+40,data.size())),Charset.defaultCharset(),StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE);
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+    }
+}
+
+

+
3 May 2022 10:25AM




⤈ Click to expand.
+

A Test Title

🔗
+

+ In dolor erat, malesuada at elit cursus, convallis imperdiet turpis. Ut aliquet magna tellus, at viverra mauris ullamcorper vehicula. Nam quis urna semper magna ornare elementum sed id mauris. Suspendisse faucibus nunc ante, ac rhoncus nisl tristique sed. Vestibulum pretium odio eget scelerisque vestibulum. Aliquam viverra ex ac vestibulum interdum. Donec ligula nunc, dignissim a purus vitae, fermentum laoreet diam. Quisque nec auctor urna. Vestibulum sit amet ligula ullamcorper, congue ipsum et, accumsan ante. Phasellus fermentum, sapien nec pulvinar blandit, elit purus pretium urna, et dapibus orci urna eu metus. Nunc molestie dictum pharetra. Suspendisse luctus felis et ante tristique, vitae commodo diam porttitor. Aliquam orci eros, placerat ac justo vitae, bibendum efficitur metus. Phasellus eget bibendum mauris. +

+
2 May 2022 10:16AM




⤈ Click to expand.
+

Another test title

🔗
+

+ Sed lobortis nisi id nunc tincidunt volutpat. Mauris cursus felis quis condimentum posuere. Pellentesque vitae dolor et justo suscipit ultrices. Integer dapibus leo id felis varius, ut volutpat massa bibendum. Quisque sed nunc arcu. In sit amet faucibus magna, non venenatis massa. Cras sed placerat risus, id consectetur est. Pellentesque in nunc dolor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque eget lorem ac urna posuere accumsan. Quisque sed imperdiet nisi. +

+
1 May 2022 05:13AM




⤈ Click to expand.
+

And More

🔗
+

+ Curabitur suscipit quam tellus, non rhoncus diam vehicula in. Aliquam ut dapibus tortor. Cras accumsan arcu vel ante maximus ornare. Nam tempus fermentum leo maximus euismod. Donec vehicula pretium est a ultrices. Nunc blandit nibh lorem, nec blandit leo posuere quis. Sed mauris ligula, euismod eu aliquam vel, rhoncus eget magna. Proin eget tortor ut ligula suscipit mattis. Integer rutrum aliquet eleifend. Suspendisse leo libero, placerat nec mi id, sagittis malesuada felis. Quisque euismod ante cursus elit lobortis, eu tempus ligula condimentum. Mauris viverra metus et dignissim efficitur. Ut placerat nunc nunc, eu tempus neque ultrices nec. Suspendisse et magna risus. Phasellus in ullamcorper tortor. Sed lobortis ut mi in blandit. +

+
30 Apr 2022 6:14PM




⤈ Click to expand.
+

Curabitur vel tempus ex

🔗
+

+Curabitur vel tempus ex. Duis cursus sapien nisl, ut pulvinar dui porttitor ut. Nullam odio purus, tristique non turpis sit amet, malesuada ultricies purus. Mauris ut nulla nisl. Aenean sit amet est egestas justo volutpat consequat. Suspendisse in sagittis augue, et mattis tortor. Nullam viverra metus et nibh fringilla iaculis. +

+
+

+

+<><Test>"</test></test2><test3>"
+            
+

+
29 Apr 2022 7:37PM




⤈ Click to expand.
+
+
+
+ +
+
+ diff --git a/out/reset.css b/out/reset.css new file mode 100644 index 0000000..73614e1 --- /dev/null +++ b/out/reset.css @@ -0,0 +1,47 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/out/sig.css b/out/sig.css new file mode 100644 index 0000000..c0f6dcc --- /dev/null +++ b/out/sig.css @@ -0,0 +1,479 @@ +a:link{ + color:#D7F; + font-size:0.8em; +} +a:visited{ + color:#D7F; + font-size:0.8em; +} +a:hover{ + color:white; + font-size:0.8em; +} +a.nounderline:link{ + text-decoration:none; +} +a.nounderline:visited{ + text-decoration:none; +} +a.nounderline:hover{ + text-decoration:none; +} +h2{ + font-size:3em; +} +.generateTime{ + font-size:10px; + color:blue; +} +.codeForeground{ + font-family:'Courier New', Courier, monospace; + position:fixed; + left:-12px; + top:-8px; + z-index:-4999; + color:rgba(0,0,0,0); + background: linear-gradient(90deg, rgba(17,17,17,1) 0%, rgba(17,17,17,1) 42%, rgba(17,17,17,0.6825105042016807) 44%, rgba(17,17,17,1) 46%, rgba(17,17,17,1) 100%); + background-size:300% 100%; + user-select:none; + animation-name:backgroundMove; + animation-duration:15s; + animation-iteration-count: infinite; + font-size:32px; + overflow:hidden; + max-width:98vw; + max-height:90vh; +} +.codeBackground{ + font-family:'Courier New', Courier, monospace; + position:fixed; + left:-12px; + top:-8px; + color:#44FF44; + z-index:-5000; + user-select:none; + font-size:32px; + overflow:hidden; + max-width:98vw; + max-height:90vh; +} +@keyframes backgroundMove{ + 0%{ + background-position: 0% 50%; + } + 100%{ + background-position: 100% 50%; + } +} +body{ + font-family: 'Trebuchet MS', Garamond, serif, 'Tahoma', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + background-color:#111; +} +sub{ + font-size:0.65em; + position:relative; + bottom:-4px; +} +sup{ + font-size:0.65em; + position:relative; + top:-8px; +} +.contentBody{ + backdrop-filter: blur(4px); + color: #a985e4; + font-weight:900; + text-shadow: 0.3px 0.3px 3px #666666; + z-index:-1; + padding-top:4px; +} + .contentBody .color1{ + color: #a985e4; + } + .contentBody .color2{ + color: #85abe4; + } + .contentBody .color3{ + color: #85e4ad; + } + .contentBody .color4{ + color: #d3e485; + } + .contentBody .color5{ + color: #e4a385; + } + .contentBody .color6{ + color: #e485b1; + } + .contentBody .contentWrapper{ + position:relative; + border-style: none none outset none; + border-radius: 0px 0px 12px 0px; + border-color: rgb(17, 153, 17, .3); + border-width: 3px; + margin: 0px 4px 8px 4px; + min-width:98vw; + z-index:0; + } + .contentBody .contentWrapper:hover{ + border-color: rgb(17, 153, 17, .8); + } + .contentBody .contentWrapper h1{ + display: inline-block; + font-size:2.1em; + margin: 12px 4px 0px 4px; + padding: 12px 32px 12px 32px; + border-bottom-style: outset; + border-radius:32px 32px 0px 0px; + color: #AA77FF; + background-color:rgba(255, 255, 255, .06); + z-index:0; + } + .contentBody .contentWrapper .content{ + display: inline-block; + min-width:97vw; + font-size:1.15em; + line-height:1.4; + padding: 4px; + margin: 0px 4px 0px 4px; + background-color: rgba(255, 255, 255, .06); + z-index:0; + max-height:120px; + overflow:hidden; + } + .contentBody .contentWrapper .expandedContent{ + display: inline-block; + min-width:97vw; + font-size:1.15em; + line-height:1.4; + padding: 4px; + margin: 0px 4px 0px 4px; + background-color: rgba(255, 255, 255, .06); + z-index:0; + } + .contentBody .contentWrapper figure{ + border: 2px ridge rgb(88, 35, 86); + border-radius:4px; + margin:12px 20px 12px 20px; + } + .contentBody .contentWrapper figcaption{ + font-size: 0.85em; + font-style: italic; + color:rgb(221, 105, 217); + } + .contentBody .contentWrapper .datebar{ + font-size:0.75em; + margin: 0px 4px 0px 4px; + min-width:98vw; + min-height:1px; + z-index:0; + background: linear-gradient(90deg,rgba(255, 255, 255, .06) 0%, rgba(255, 255, 255, .3) 20%,rgba(255, 255, 255, .06) 45%,rgba(255, 255, 255, .06) 0%); + } + .contentBody .contentWrapper .date{ + font-size:0.75em; + margin: 0px 4px 0px 4px; + padding: 2px 0px 0px 2px; + min-width:98vw; + z-index:0; + background-color: rgba(255, 255, 255, .06); + } + .contentBody .contentWrapper .unexpanded{ + position:absolute; + bottom:0px; + min-width:98vw; + text-align:center; + font-size:1.75em; + background: linear-gradient(180deg,rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 5%, rgba(32,32,32,1.0) 100%); + user-select:none; + } + .contentBody .contentWrapper .unexpanded:hover{ + bottom:-8px; + background: linear-gradient(180deg,rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 5%, rgba(64,64,64,1.0) 100%); + cursor:pointer; + } + .contentBody .filelisting{ + padding:12px 4px 2px 4px; + font-size:1.75em; + } + .contentBody .folderlisting{ + padding:12px 4px 2px 4px; + font-size:1.75em; + } + .contentBody .icon:link{ + text-decoration:none; + } + .contentBody .icon:visited{ + text-decoration:none; + } + .contentBody .icon:hover{ + text-decoration:none; + } +pre{ + font-family:'Courier New', Courier, monospace; + display:inline-block; + padding:3px; + margin-left:20px; + font-size:0.85em; + position:relative; + width:85vw; + max-height:480px; + overflow:scroll; + inline-size: 85vw; + color:darkseagreen; + background:radial-gradient(farthest-side at 90% 90%,rgba(0, 255, 0, .06) 0%, rgba(255, 255, 255, .06) 100%); +} +/* width */ +::-webkit-scrollbar { + width:8px; + height:8px; + float:right; + } + ::-webkit-scrollbar:hover{ + width: 16px; + height: 16px; + } + /* Track */ + ::-webkit-scrollbar-track { + background:rgba(0,0,0,0); + } + /* Handle */ + ::-webkit-scrollbar-thumb { + background: rgb(161, 46, 161); + } + /* Handle on hover */ + ::-webkit-scrollbar-thumb:hover { + background: rgb(197, 34, 189); + } + ::-webkit-scrollbar-corner{ + background:rgba(0,0,0,0); + } + /* width */ + pre::-webkit-scrollbar { + width:16px; + height:16px; + } +pre .keyword{ + color:cornflowerblue; +} +pre .variable{ + color:#AA77FF; +} +pre .class{ + color:rgb(216, 107, 74); +} +pre .function{ + color:darkgoldenrod; +} +pre .string{ + color:forestgreen; +} +pre .number{ + color:#d8f070; +} +pre .comment{ + color:#6b235e; +} +textarea{ + font-family:'Courier New', Courier, monospace; + display:inline-block; + padding:3px; + margin-left:20px; + font-size:0.85em; + position:relative; + inline-size: 85vw; + color:darkseagreen; + background:radial-gradient(farthest-side at 90% 90%,rgba(0, 255, 0, .06) 0%, rgba(255, 255, 255, .06) 100%); + border-radius:8px; + font-size:1.4em; +} +textarea:focus{ + outline: none !important; +} +h1 { + font-size:3.25em; +} +.commentForm{ + padding:16px; + line-height:2.2; + vertical-align: text-top; +} +.commentInfo{ + padding-left:24px; +} +.commentDisplayer{ + font-family:'Courier New', Courier, monospace; + border: 1px solid rgb(36, 163, 36); + border-radius:8px; + margin:16px; + padding:8px; + line-height:1.4; +} +input{ + font-family:'Courier New', Courier, monospace; + width:240px; + background-color:rgba(0,0,0,0); + border: 1px solid rgb(4, 80, 4); + color:lime; + font-size:1.4em; +} +input:focus{ + outline: none !important; + background-color:rgb(24, 24, 24); + border: 1px solid rgb(10, 136, 10); +} +option{ + font-family:'Courier New', Courier, monospace; + width:240px; + background-color:rgba(0,0,0,0); + border: 1px solid rgb(4, 80, 4); + color:lime; + font-size:1.4em; +} +option:focus{ + outline: none !important; + background-color:rgb(24, 24, 24); + border: 1px solid rgb(10, 136, 10); +} +select{ + font-family:'Courier New', Courier, monospace; + width:240px; + background-color:rgba(0,0,0,0); + border: 1px solid rgb(4, 80, 4); + color:lime; + font-size:1.4em; +} +select:focus{ + outline: none !important; + background-color:rgb(24, 24, 24); + border: 1px solid rgb(10, 136, 10); +} +button{ + background-color:rgba(0,0,0,0); + border: 1px solid rgb(4, 80, 4); + font-size:2em; + margin-left:24px; + margin-top:8px; + color:lime; +} +button:hover{ + background-color:rgb(0, 53, 3); + border: 1px solid rgb(10, 136, 10); +} +button:disabled{ + background-color:rgb(0, 81, 95); +} +select:disabled{ + background-color:rgb(0, 81, 95); +} +input:disabled{ + background-color:rgb(0, 81, 95); +} +textarea:disabled{ + background-color:rgb(0, 81, 95); +} +.toolbar{ + background-color:#666666; + color:#000000; + font-size:0.75em; + width:fit-content; + margin-left:36px; + margin-top:24px; +} +.toolbarItem:hover{ + background-color:#a1a1a1; + cursor:pointer; +} +.contentWrapper .reallink{ + font-size:1.7em; + text-decoration: none; + color:white; +} +.navbar{ + font-size:1.0em; + color:lime; + padding-top:8px; + padding-bottom:8px; + border-bottom: 1px solid darkgreen; + position: -webkit-sticky; /* Safari */ + position: sticky; + top:0px; + z-index:2; + width:100%; + background:radial-gradient(farthest-side at 90% 90%,rgba(0, 64, 0, .5) 0%, rgba(64, 0, 64, .5) 100%); +} +.navbar:hover{ + background:radial-gradient(farthest-side at 90% 90%,rgba(0, 64, 0, .95) 0%, rgba(64, 0, 64, .95) 100%); +} +.navbaritem{ + padding-left:16px; + padding-right:16px; + display:inline-flex; + text-decoration:underline; + color:rgb(255, 200, 253); +} +.navbaritem a:link{ + color:rgb(255, 200, 253); +} +.navbaritem a:hover{ + color:white; +} +.navbaritem a:visited{ + color:rgb(255, 200, 253); +} +#liveindicator a:link{ + color:red; + text-decoration: none; +} +#liveindicator a:hover{ + color:red; +} +#liveindicator a:visited{ + color:rgb(255, 200, 253); +} +.navbaritem:first-of-type{ + padding-left:32px; +} +.navbaritem:hover{ + color:white; + cursor:pointer; +} +@keyframes blink{ + 0%{color:rgba(255,0,0,0);} + 100%{color:rgba(255,0,0,0.8);} +} +#liveindicator{ + display:inline-flex; +} +#liveindicator a{ + animation-name: blink; + animation-duration: 3s; + animation-iteration-count: infinite; + animation-direction:alternate; + text-decoration: none; + padding-left:8px; + font-weight:900; +} +.socials{ + display:inline; + float:right; +} +.socials img{ + width:16px; + padding-right:16px; + filter: invert(100%); +} +.socials img:hover{ + cursor:pointer; +} +.socials img:first-of-type{ + padding-right:32px; +} +.socials a:link{ + color:rgb(255, 200, 253); +} +.socials a:hover{ + color:white; +} +.socials a:visited{ + color:rgb(255, 200, 253); +} diff --git a/out/testfile.html b/out/testfile.html new file mode 100644 index 0000000..59adf19 --- /dev/null +++ b/out/testfile.html @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+SigPlace +-SigPlace +=== +

+Other Page! +
+
+
+ +
+
+ diff --git a/out/uploadform.html b/out/uploadform.html new file mode 100644 index 0000000..275c159 --- /dev/null +++ b/out/uploadform.html @@ -0,0 +1,51 @@ + + + + + + + + + + + +
+SigPlace +
+ + +
+
+
+
+ +
+
+ diff --git a/sigPlace.jar b/sigPlace.jar index e19c70bdc82ed90fc4980b514eb2f11c1618dd76..626c351d5944b12aedb3f5fda3a92a53358e02db 100644 GIT binary patch delta 13033 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 delta 9333 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 d;NTX;;NY