Page MenuHomedesp's stash

No OneTemporary

diff --git a/.gitignore b/.gitignore
index 03c88fd..6e83ad8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
.htaccess
+ctf-diary-generator/ctf-diary/
+ctf/
+/ctf.html
\ No newline at end of file
diff --git a/canvas.png b/canvas.png
new file mode 100644
index 0000000..6be62f8
Binary files /dev/null and b/canvas.png differ
diff --git a/ctf-diary-generator/generator.py b/ctf-diary-generator/generator.py
new file mode 100644
index 0000000..b386f47
--- /dev/null
+++ b/ctf-diary-generator/generator.py
@@ -0,0 +1,206 @@
+import yaml, os, re
+from datetime import datetime
+from markdown import markdown
+from bs4 import BeautifulSoup, Comment
+#also requires pymdown-extensions
+
+#note to self: to convert existing ctf diaries, check whether `\n([0-9a-zA-Z]+)` (or `^((?:[a-zA-Z0-9] ?)+)\n- ` for some messier writeups) looks like a chall name, then replace with `\n### $1`
+#remove all first level -s that i use for paragraph into 2 \ns
+#push all ```s to the left without spaces
+
+#TODO aggregate stats (total ctfs, total solves, solve and co-solve amt, category solves breakdown, avg chall per ctf?, avg points?, avg solve count??)
+#exclude organized events
+
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+
+alphanum = re.compile(r'[^A-Za-z0-9\- ]+')
+merge_space = re.compile(r'\s+')
+remove_formatting = lambda str: merge_space.sub('-', alphanum.sub('', str).strip()).lower() #for name formats
+
+objects = {}
+
+comments = {}
+
+#read special events
+with open(f'{CWD}/ctf-diary/special.yml', encoding='utf-8') as s:
+ objects.update(yaml.load(s, Loader=yaml.Loader))
+
+#read all ctfs in record
+skipped_cmts = []
+for file in os.listdir(f'{CWD}/ctf-diary/ctfs'):
+ if file.endswith('.yml'):
+ name = file[:-4]
+ #read metadata into objects
+ with open(f'{CWD}/ctf-diary/ctfs/{file}', encoding='utf-8') as s:
+ objects.update({name: yaml.load(s, Loader=yaml.Loader)})
+
+ #read comments; split according to headers ('### ') which should only be used by chall names, where the - is the start of comments
+ #the 3 ### should be good enough to differentiate headers from code comments, we will do sanity check when we actually map the comments anyway
+ try:
+ with open(f'{CWD}/ctf-diary/ctfs/comments/{name}.md', encoding='utf-8') as c:
+ assert c.read(4) == '### ' #the first line should already have a challenge, also discard the header
+ comments.update({name: {remove_formatting((sp:=v.split('\n', 1))[0]): sp[1] for v in c.read().split('\n### ')}})
+ except Exception as e:
+ skipped_cmts.append(name)
+ if 'challenges' in objects[name] and not all('writeup-url' in chall and chall['writeup-url'] for chall in objects[name]['challenges']): #only print if ctf should have comments
+ print(f'Cannot read comments for {file} ({type(e).__name__}), skipping...')
+
+#date is already datetime.date (thanks pyyaml)
+objects = dict(sorted(objects.items(), key=lambda item: item[1]['date']))
+
+#add year objects
+year = None
+templist = []
+for k, v in objects.items():
+ if year != v['date'].year:
+ year = v['date'].year
+ if templist: #ensure templist is not empty before inserting a year (since that always happen)
+ #no need to str(year) since .format nudge it into string anyway
+ templist.append((year, {'style': 'timeline-year', 'content': year, 'date': datetime.fromisoformat(f'{year}-01-01')}))
+
+ templist.append((k,v))
+
+#apparently printing dicts autosorts it for you but iterating is fine
+templist.reverse()
+objects = dict(templist)
+
+
+with open(f'{CWD}/templates/ctf.html', encoding='utf-8') as cf:
+ ctf = cf.read()
+with open(f'{CWD}/templates/special.html', encoding='utf-8') as sf:
+ special = sf.read()
+with open(f'{CWD}/templates/diary.html', encoding='utf-8') as df:
+ diary = df.read()
+
+
+#generation helpers
+
+added = []
+def get_comment(chall, ctf):
+ name = remove_formatting(next(iter(chall.values())))
+ if 'writeup-url' in chall and chall['writeup-url']:
+ return f'href="{chall["writeup-url"]}"'
+ elif ctf in comments and name in comments[ctf]:
+ added.append(f'{ctf}-{name}')
+ return f'data-comment="{ctf}-{name}"'
+ else:
+ if ctf not in skipped_cmts: #only print if the file is read, otherwise its just redundant
+ print(f"{ctf}-{name} has no comments, name mismatch?")
+ return ''
+
+
+ranks = {1: 'first', 2: 'second', 3: 'third'}
+def get_ordinal(n):
+ if n < 0:
+ return '<div>N/A</div>'
+ else:
+ formatted = f"{n}<sup>{'th' if 11 <= (n % 100) <= 13 else ['th', 'st', 'nd', 'rd', 'th'][min(n % 10, 4)]}</sup>"
+ if n <= 3:
+ return '<div class="text-' + ranks[n] + '">' + formatted + '</div>'
+ else:
+ return '<div>' + formatted + '</div>'
+
+
+special_field_names = {
+ 'name': '<th scope="col">Challenge <a class="text-light" data-toggle="modal" data-target="#help" href="#help" role="button"><i class="fa fa-question-circle"></i></a></th>',
+ 'writeup-url': '<th scope="col">Full writeup</th>',
+ #special fields that are not actually fields
+ 'first-blood': '',
+ 'writeup-prize': '',
+}
+
+chall_decor = {'first-blood': '๐Ÿฉธ', 'writeup-prize': '๐Ÿ‘‘'}
+
+special_fields = {
+ #for now instead of bolding first item in row, just bold these 2 since i dont think ill need another name for the challenges anyway
+ #we are still assuming the name is in the first column though - commenting breaks if not
+ 'name': lambda v,c: f'<th scope="row">{v} {" ".join([v for k, v in chall_decor.items() if k in c])}</th>',
+ 'challenge-written': lambda v,_: f'<th scope="row">{v}</th>',
+ 'writeup-url': lambda v,_: '<td>' + ('โœ”๏ธ' if v else 'โŒ') + '</td>',
+ 'solve-status': lambda v,_: '<td>' + {'solved': 'โœ”๏ธ', 'co-solved': '๐Ÿค', 'sniped': '๐Ÿ’ค', 'unsolved': '๐Ÿ‘€'}[v] + '</td>',
+ #special fields that are not actually fields
+ 'first-blood': lambda v,_: '',
+ 'writeup-prize': lambda v,_: '',
+}
+
+
+
+#generate the page following the template formats
+html = diary.format(
+ ctfs="".join([
+ #special
+ special.format(style=v['style'], content=v['content'])
+ if 'content' in v else
+ #actual ctfs
+ ctf.format(
+ style='timeline-organized' if v['organizer'] else '',
+ #class="headings" to have same style but not clickable if url is null, otherwise link
+ #also link is non w3c compliant hack around interactive elements inside buttons; who complies anyway :)
+ url=f'class="nav-link" onclick="window.location=\'{v["url"]}\'; event.stopPropagation()"' if v['url'] else 'class="headings"',
+ name=v['name'],
+ #isoformat is the one we want for datetime, but we only need date not time; actual format should be <month-abbr>. <day>
+ date=f'<time datetime="{v["date"].isoformat().split("T")[0]}">{v["date"].strftime("%b. %d")}</time>',
+ duration=f'{v["duration"]}h', #currently we are hardcoding hours, but we can always parse
+ type=v['type'],
+ team=v['team'],
+ rank='<div class="text-success">Organizer</div>'
+ if v['organizer'] else
+ (('<div>' + v['rank'] + '</div>' if isinstance(v['rank'], str) else get_ordinal(v['rank'])) +
+ ('<span data-toggle="tooltip" title="All challenges cleared">โœจ</span>' if v['full-clear'] else '')),
+ #use the first challenge as header definition
+ challengeheader='<thead><tr>'
+ + ''.join([
+ #normal fields that are named as expected so we can just use it as the headers
+ '<th scope="col">' + name.replace('-', ' ').capitalize() + '</th>'
+ if name not in special_field_names else
+ #special fields that needs renaming
+ special_field_names[name]
+ for name in v['challenges'][0].keys()])
+ + '</tr></thead>'
+ if 'challenges' in v else "<div class='text-center'>No specific challenges have been logged; It's all a team effort!</div>", #allow no challenge specified (e.g. A/D ctfs where its basically fully team effort so no specific challs that i wouldve fully solved)
+ challenges=''.join(['<tbody><tr ' + get_comment(chall, k) + '>'
+ #assume every chall object follows the same format as the first, or else header mismatches
+ + ''.join([
+ f'<td>{field}</td>'
+ if name not in special_fields else
+ special_fields[name](field, chall)
+ for name, field in chall.items()])
+ + '</tr><tbody>'
+ for chall in v['challenges']])
+ if 'challenges' in v else '',
+ )
+ for k, v in objects.items()])
+)
+
+
+#lint output
+soup = BeautifulSoup(html, 'html.parser')
+
+for comment in soup.findAll(text=lambda text:isinstance(text, Comment)):
+ comment.extract()
+
+with open('ctf.html', 'w', encoding="utf-8") as out:
+ out.write(str(soup)) #minify
+
+
+#write comments into their respective files
+if not os.path.exists('ctf'):
+ os.mkdir('ctf')
+
+for ctf, challs in comments.items():
+ for name, cmt in challs.items():
+ with open(f'ctf/{ctf}-{name}.html', 'w', encoding="utf-8") as out:
+ #out.write(markdown(cmt, extensions=['fenced_code', 'codehilite'], extension_configs={'codehilite': {'noclasses': True}}))
+ out.write(markdown(cmt,
+ extensions=['pymdownx.highlight', 'pymdownx.superfences', 'pymdownx.tilde', 'pymdownx.inlinehilite', 'pymdownx.emoji', 'pymdownx.magiclink'],
+ extension_configs={
+ 'pymdownx.highlight': {
+ 'guess_lang': 'block',
+ 'pygments_lang_class': True,
+ },
+ }))
+
+ #sanity check if we missed any challs in the yml by comparing against added comments
+ if f'{ctf}-{name}' not in added:
+ print(f"{ctf}-{name} has a comment but doesn't exist in {ctf}.yml - missed definition?")
\ No newline at end of file
diff --git a/ctf-diary-generator/templates/ctf.html b/ctf-diary-generator/templates/ctf.html
new file mode 100644
index 0000000..ea017fc
--- /dev/null
+++ b/ctf-diary-generator/templates/ctf.html
@@ -0,0 +1,32 @@
+<!--row needed to correctly align ctf-table-->
+<div class="text-right info-subsegment ctf-info row">
+ <div class="btn-group timeline-anchor {style}">
+ <!--dropdown-toggle solely for the arrow-->
+ <button type="button" class="btn text-white text-left dropdown-toggle" data-toggle="collapse" aria-expanded="false">
+ <div class="ctf-title">
+ <div {url}>
+ {name}
+ </div>
+ </div>
+ <div class="ctf-metadata">
+ <i>{date} <div class='big-sep'></div> {duration} <div class='big-sep'></div> {type}</i>
+ </div>
+ </button>
+
+ <div class="ctf-details">
+ {rank}
+ <div class='big-sep'></div>
+ <div>{team}</div>
+ </div>
+ </div>
+
+ <div class="collapse ctf-table">
+ <div class="table-responsive">
+ <table class="table table-hover text-left table-dark">
+ <col style="width:40%"> <!--widen challenge name-->
+ {challengeheader}
+ {challenges}
+ </table>
+ </div>
+ </div>
+</div>
\ No newline at end of file
diff --git a/ctf-diary-generator/templates/diary.html b/ctf-diary-generator/templates/diary.html
new file mode 100644
index 0000000..c297c26
--- /dev/null
+++ b/ctf-diary-generator/templates/diary.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+ <link rel="preload" href="canvas.png" as="image">
+
+ <link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
+ <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
+ <link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
+ <script src="https://kit.fontawesome.com/c2944013c3.js" crossorigin="anonymous"></script>
+ <link rel="stylesheet" href="main.css">
+ <link rel="stylesheet" href="pygments-native.css">
+
+ <title>desp's CTF diary</title>
+ </head>
+
+ <body class="text-center text-white">
+ <div class="d-flex w-100 h-auto p-3 flex-column">
+ <header>
+ <nav class="nav nav-mast head justify-content-center float-md-right">
+ <a class="nav-link" href="/">Home</a>
+ <a class="nav-link" href="/projects.html">Projects</a>
+ <a class="nav-link" href="https://stash.despawningbone.me">Codestash</a>
+ <a class="nav-link active" aria-current="page" href="#">CTF diary</a>
+ </nav>
+ </header>
+ <div class="headings pt-5 my-auto mx-auto w-75">
+ <div id="mainline">CTF diary<br></div>
+ <div style="font-size:0.8em">
+ A timeline on the CTFs I've played in, challenges I've solved, and comments on the challenges.
+ </div>
+ </div>
+ </div>
+
+
+ <div class="info-segment timeline-content">
+
+ <div class="timeline col"></div>
+
+ <div class="col pr-5">
+
+ <div class="w-100 mx-auto p-5-flex divider"></div>
+
+ {ctfs}
+
+ <div class="w-100 mx-auto p-5-flex divider"></div>
+
+ </div>
+ </div>
+
+ <!--help popup-->
+ <div class="modal fade" id="help" aria-hidden="true" aria-labelledby="helpTitle" tabindex="-1">
+ <div class="modal-dialog modal-dialog-centered modal-lg">
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="helpTitle">Glossary</h5>
+ <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body text-left">
+ Icons next to challenge names: <br>
+ ๐Ÿฉธ - First blood <br>
+ ๐Ÿ‘‘ - Writeup prize won <br>
+ <br>
+ Solve status: <br>
+ โœ”๏ธ - solved during the ctf <br>
+ ๐Ÿค - co-solved <br>
+ ๐Ÿ’ค - got sniped (solved after teammates solved during the ctf) <br>
+ ๐Ÿ‘€ - didn't solve during the ctf, but worth mentioning (e.g. solved afterwards) <br>
+ <br>
+ Most of these challenges are ordered chronologically by when it's solved.<br>
+ Click on the row to see my comments<sup>*</sup> / solve scripts (if any) for the challenge!<br>
+ <hr>
+ <div style="font-size:0.7em">* - The comments are usually in the form of unedited draft writeups - they might contain anything from unverified information to straight up incoherent babbles that can only be understood by me; be warned!</div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!--comments popup; requires some nudging from js to display content on demand-->
+ <div class="modal fade" id="comment" aria-hidden="true" aria-labelledby="commentTitle" tabindex="-1">
+ <div class="modal-dialog modal-dialog-centered modal-xl"> <!--xl since there's gonna be a *lot* of code-->
+ <div class="modal-content">
+ <div class="modal-header">
+ <h5 class="modal-title" id="commentTitle"> <!--dynamically generated--> </h5>
+ <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
+ <span aria-hidden="true">&times;</span>
+ </button>
+ </div>
+ <div class="modal-body text-left ctf-comment">
+ <!--dynamically loaded-->
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <footer class="d-flex flex-column w-100 mt-5">
+ <p class="large-content mx-auto p-2 pt-3">Made from scratch by despawningbone with Bootstrap and AOS - view in <a href="https://stash.despawningbone.me/diffusion/WEB/" class="nav-link inline">codestash</a></p>
+ </footer>
+
+ <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
+ <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
+ <script src="https://unpkg.com/aos@next/dist/aos.js"></script>
+ <script src="main.js"></script>
+ </body>
+</html>
+
diff --git a/ctf-diary-generator/templates/special.html b/ctf-diary-generator/templates/special.html
new file mode 100644
index 0000000..b362d3d
--- /dev/null
+++ b/ctf-diary-generator/templates/special.html
@@ -0,0 +1,5 @@
+<div class="w-100 mx-auto text-left align-middle divider timeline-anchor {style}">
+ <div class="text-muted">
+ {content}
+ </div>
+</div>
\ No newline at end of file
diff --git a/main.css b/main.css
index 874217b..a46282e 100644
--- a/main.css
+++ b/main.css
@@ -1,123 +1,375 @@
html, body {
- height: 145%;
- font-family: 'Source Code Pro', monospace;
+ font-family: 'Varela Round', monospace;
+ background: url('canvas.png'), #121212;
+ background-size: cover;
+ /*animation: delaybg 1s;*/
+}
+
+/* @keyframes delaybg {
+ 0%, 99% { background: #121212; height: 100%; overflow: hidden;}
+ 100% { background: url('canvas5.5.png'), #121212; height: auto; overflow: auto; }
+}
+
+#cover {
+ animation: fadein ease 1.5s;
+ animation-iteration-count: 1;
+ animation-fill-mode: forwards;
+}
+
+@keyframes fadein {
+ from { opacity: 0; }
+ to { : 1; }
+} */
+
+/*needed for background image since theres a margin-right: -15px for some reason*/
+.row {
+ margin: auto !important;
}
.nav-link {
- color: #dd7;
+ color: #dd7;
}
.nav-link:hover {
- color: #aa4;
+ color: #aa4;
}
#cover {
- top: -10%;
- background-size: cover;
- box-shadow: 100px;
+ top: -10%;
+ mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 94%, rgba(0, 0, 0, 0));
+ -webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 94%, rgba(0, 0, 0, 0));
+ background: #121212; /*to be overriden*/
+ background-size: cover;
+ background-position: center;
+ box-shadow: 100px;
+ height: 110vh !important;
}
.tooltip {
- left: 0px;
+ left: 0px;
}
.tooltip-inner {
- background-color: #343a40;
+ background-color: #121212;
+ font-family: 'Varela Round', monospace;
}
.arrow::before {
- border-bottom-color:#343a40 !important;
- border-top-color:#343a40 !important;
+ border-bottom-color:#121212 !important;
+ border-top-color:#121212 !important;
}
.col {
- padding-left: 0.25em;
- padding-right: 0.25em;
+ padding-left: 0.25em;
+ padding-right: 0.25em;
+}
+
+#cover #mainline {
+ margin-top: -2.5em;
}
#mainline {
- font-weight: bold;
- font-size: 1.25em;
+ font-weight: bold;
+ font-size: 1.25em;
+}
+
+#links {
+ padding-top: 2.5vh;
}
#links img {
- max-width: 50px;
- width:100%;
+ max-width: 50px;
+ width:100%;
}
.skills .card, #mainskill{
- background-color: rgba(20, 20, 20, 0.5);
- box-shadow: 4px 4px 15px rgba(10, 10, 10, 0.8);
- border-radius: 8px;
+ background-color: rgba(40, 40, 40, 0.7);
+ box-shadow: 4px 4px 15px rgba(30, 30, 30, 0.8);
+ border-radius: 8px;
}
.skills .card-body, #mainskill .card-body {
- font-size: 0.8rem;
+ font-size: 0.8rem;
}
#mainskill {
- min-width:25%;
- max-width:50%;
+ min-width:25%;
+ max-width:50%;
}
footer {
- background-color: rgba(20, 20, 20, 0.4);
+ background-color: rgba(10, 10, 10, 0.6);
}
.nav-link.inline { /*reset for footer*/
- display: inline;
- padding: 0;
+ display: inline;
+ padding: 0;
}
footer, .smaller {
- font-size: 0.75em;
+ font-size: 0.75em;
}
.project {
- font-weight: bold;
+ font-weight: bold;
}
.info-segment .large-content span {
- margin-left: 2em;
+ margin-left: 2em;
}
.splitview {
- margin-right: 0px !important;
- margin-left: 0px !important;
+ margin-right: 0px !important;
+ margin-left: 0px !important;
+}
+
+.info-segment .headings {
+ color: #dd7;
+ padding: .5rem 1rem;
+}
+
+.modal-content {
+ background: rgba(30, 30, 30, 0.8);
+}
+
+/*
+ * timeline styling
+ */
+
+/*assumes timeline-content has 2 columns, 1 .timeline and 1 content column thats it*/
+/*anchor also needs to be flex or else the anchor node gets misaligned*/
+.timeline-content, .timeline-anchor {
+ display: flex;
+}
+
+.timeline {
+ display: inline-block;
+ max-width: 1em;
+ height: auto;
+ background: rgba(80, 80, 80, 0.5);
+ margin: 3em;
+ border-radius: 1em;
+ /*patch for terminating the timeline at the nodes; assume p-5 divider exists at topmost and bottommost, and 2em of margin on both sides of the last element*/
+ margin-top: 15em;
+ margin-bottom: 15em;
+}
+
+/*all elements in the non timeline column that specifies it is an anchor*/
+.timeline-content:not(.timeline) .timeline-anchor::before {
+ /*set up .fa for this pseudo element*/
+ font-size: 2em;
+ font-family: var(--fa-style-family-classic);
+ font-weight: 900;
+
+ /*node style on timeline*/
+ content: "\f192";
+ color: rgba(200, 200, 200, 0.8);
+
+ /*apparently flexbox centers content in pseudo elements*/
+ display:flex;
+ flex-direction:row;
+ align-items: center;
+
+ /*move the pseudoelement onto the timeline*/
+ position: relative;
+ left: -1.375em; /*.timeline margin (3em) + .col margin on timeline (0.25em) - half of this width (0.5em), scaled by 2em*/
+ margin-left: -1em; /*remove the size of this element in parent*/
+ width: 1em;
+}
+
+/*special types with ctf-info still in it*/
+.timeline-organized::before {
+ content: "\f005" !important;
+ left: -1.475em !important; /*seems like certain fonts have a different width than the normal node*/
+}
+
+/*big special types*/
+.timeline-year::before {
+ content: "\f79f" !important;
+ left: -1.475em !important;
+}
+
+.timeline-year > * {
+ font-size: 2.5em !important;
+ padding: 1.5em !important;
+ padding-left: 0.5em !important;
+}
+
+/*smaller special types*/
+.timeline-join > *, .timeline-announce > *, .timeline-hiatus > * {
+ font-size: 1.5em !important;
+ padding: 0.5em !important;
+}
+
+.timeline-join::before {
+ content: "\f2f6" !important;
+}
+
+.timeline-announce::before {
+ content: "\f0a1" !important;
+}
+
+.timeline-hiatus::before {
+ content: "\f186" !important;
+ left: -1.275em !important;
+}
+
+/*
+ * collapsable table styling
+ */
+
+.ctf-info {
+ position: relative;
+ width: 100%;
+ background: rgba(30, 30, 30, 0.4);
+ border-radius: 1em;
+ margin-top: 2em !important;
+ margin-bottom: 2em !important;
+}
+
+.ctf-info > .btn-group { /*header*/
+ width: 100%;
+ height: 100%;
+ background: rgba(60, 60, 60, 0.4);
+ border-radius: 1em;
+}
+
+.ctf-info .ctf-table {
+ width: 100%;
+ /*if we set height here the collapse animation dies, and padding makes the animation choppy*/
+}
+
+.ctf-info .table-responsive {
+ padding: 0.7em;
+ padding-bottom: 0em;
+}
+
+.ctf-info .table {
+ background: none;
+ width: 100%;
+}
+
+.ctf-table th, .ctf-table td, .ctf-table .table-dark tbody+tbody {
+ border-top: none;
+}
+
+.ctf-title {
+ font-size: 2em;
+ display: inline-block;
+ padding-top: 1.3em;
+ padding-left: 1.3em;
+}
+
+.ctf-metadata {
+ position: absolute;
+ top: 0;
+ padding: 0.7em;
+}
+
+.ctf-details {
+ position: absolute;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ right: 0;
+ height: 100%;
+ padding-right: 3em;
+ font-size: 1.5em;
+}
+
+.ctf-details > *:not(sup) {
+ padding: 0.2em;
+}
+
+/*android webview still uses webkit prefix for transform even though not for keyframes*/
+.ctf-info.show .btn::after {
+ -webkit-transform: rotate(-180deg);
+ transform:rotate(-180deg);
+}
+
+/*both ways should have a transition*/
+.ctf-info .btn::after {
+ transition: transform 500ms ease;
+ scale: 1.5;
+}
+
+/*for modelling a less obvious separator*/
+.big-sep {
+ display: inline-block;
+ vertical-align: middle;
+}
+
+.big-sep::before {
+ content: '/';
+ font-size: 180%;
+ color: rgba(80, 80, 80, 0.5);
+ text-align: center;
+}
+
+
+.emojione {
+ width: 1em;
+ height: 1em;
+}
+
+.text-first {
+ color: #FFD700;
+ text-shadow: 0 0 0.4em #FFD700;
+}
+
+.text-second {
+ color: #C0C0C0;
+ text-shadow: 0 0 0.4em #FFF;
+}
+
+.text-third {
+ color: #CD7F32;
+ text-shadow: 0 0 0.4em #CD7F32;
}
@media (max-width: 767px) {
- .skills {
- width: 100%;
- font-size: 0.75rem;
- }
- .skills .card-body {
- display:none;
- }
+ /*fixes stretching in safari*/
+ .splitview img {
+ width: 100% !important;
+ height: 100% !important;
+ }
+
+ .skills {
+ width: 100%;
+ font-size: 0.75rem;
+ }
- .headings { font-size: 1.25rem; }
- .large-content { font-size: 0.75em; width: 100%; }
+ .skills .card-body {
+ display: none;
+ }
- .splitview { width: 100%; text-align: center !important; padding: 2rem !important;}
+ .headings { font-size: 1.25rem; }
+ .large-content { font-size: 0.75em; width: 100%; }
- .p-5-flex { padding: 2rem !important; } /*patch back padding since p-5 is too much*/
+ .splitview { width: 100%; text-align: center !important; padding: 2rem !important;}
+
+ .p-5-flex { padding: 2rem !important; } /*patch back padding since p-5 is too much*/
}
@media (min-width: 768px) {
- .headings { font-size: 1.5rem; }
- .large-content { font-size: 0.75em; width: 75%; }
- .skills { width: 65%; }
+ .headings { font-size: 1.5rem; }
+ .large-content { font-size: 0.75em; width: 75%; }
+ .skills { width: 90%; }
+
+ .splitview { width: 50%; }
+ .info-subsegment { display: flex; }
- .splitview { width: 50%; }
- .info-subsegment { display: flex; }
+ .p-5-flex { padding: 5rem !important; }
- .p-5-flex { padding: 5rem !important; }
+ .info-segment { padding-left: 2%; padding-right: 2%; }
}
@media (min-width: 992px) {
- .headings { font-size: 1.75rem; }
- .large-content { font-size: 1em; }
+ .headings { font-size: 1.75rem; }
+ .large-content { font-size: 1em; }
}
@media (min-width: 1200px) {
- .headings { font-size: 2rem; }
- .large-content { font-size: 1.25em; }
+ .headings { font-size: 2rem; }
+ .large-content { font-size: 1.25em; }
+ .info-segment { padding-left: 5%; padding-right: 5%; }
+ .skills { width: 70%; }
}
\ No newline at end of file
diff --git a/main.html b/main.html
index 4fe82cd..1b2d8db 100644
--- a/main.html
+++ b/main.html
@@ -1,97 +1,107 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<script type="text/javascript">
//randomize background and preload
const bgCount = 7;
- var bg = new Image();
- bg.src = 'images/' + Math.ceil(Math.random() * bgCount) + '.png';
+ var bg = document.createElement("link");
+ bg.rel = "preload";
+ bg.as = "image";
+ bg.href = 'images/' + Math.ceil(Math.random() * bgCount) + '.png';;
+ document.head.appendChild(bg);
+
+ var preloadstyle = document.createElement("style");
+ preloadstyle.innerText = 'body { background-position-y: 100vh !important; } #cover { background-image: url(' + bg.href + ') !important; }';
+ document.head.appendChild(preloadstyle);
</script>
+ <link rel="preload" href="canvas.png" as="image">
+
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
<link rel="stylesheet" href="main.css">
- <title>Hi! - despawningbone's portfolio</title>
+ <title>Hi! - desp's portfolio</title>
</head>
- <body class="bg-dark text-center text-white">
+ <body class="text-center text-white">
<div id="cover" class="d-flex w-100 h-50 p-3 mx-auto flex-column">
<header>
<nav class="nav nav-mast head justify-content-center float-md-right">
<a class="nav-link active" aria-current="page" href="#">Home</a>
<a class="nav-link" href="/projects.html">Projects</a>
<a class="nav-link" href="https://stash.despawningbone.me">Codestash</a>
+ <a class="nav-link" href="/ctf.html">CTF diary</a>
</nav>
</header>
<div class="headings justify-content-center my-auto container-fluid w-75">
<div id="mainline">despawningbone<br></div>
<div>Just a weeb who loves tech.</div>
<div id="links" class="mx-auto row mt-4 w-75">
<a href="mailto://[email protected]" class="col"><img alt="email" class="img-fluid" data-toggle="tooltip" data-placement="bottom" title="contact me!" src="images/mail.png"></img></a>
<a href="https://github.com/despawningbone" class="col"><img alt="github" class="img-fluid" data-toggle="tooltip" data-placement="bottom" title="public projects only; check codestash for more!" src="images/github.png"></img></a>
<a href="#" class="col"><img id="discord" alt="discord" class="img-fluid" data-toggle="tooltip" data-placement="bottom" title="despawningbone#4078" src="images/discord.png"></img></a>
<a href="https://myanimelist.net/profile/despawningbone" class="col"><img alt="MAL" class="img-fluid" data-toggle="tooltip" data-placement="bottom" title="my anime list! (literally)" src="images/mal.png"></img></a>
<a href="https://osu.ppy.sh/users/despawningbone" class="col"><img alt="osu!" class="img-fluid" data-toggle="tooltip" data-placement="bottom" title="click the circles!" src="images/osu.png"></img></a>
</div>
</div>
</div>
<div id="info" class="d-flex flex-column container-fluid">
<div class="info-segment" data-aos="fade-up">
<p class="headings row pt-5 p-3">About me</p>
<p class="large-content pb-4 mx-auto">Heyo! I am an aspiring computer science major from Hong Kong who has been coding for fun since 2016.
<br>As one of my major hobbies, I try to explore a variety of different technical fields, from hardware development to UI design.
<br>However, my main focus has always been programming and system administration, with most of my time spent on doing projects such as despbot and vortex.
<br>Recently though, I've been spending more time on cybersecurity, and I hope to be able to work on this field in the future.
</p>
</div>
<div class="info-segment" data-aos="fade-up">
<p class="headings row pt-5 p-3">Technical Skills</p>
<div id="mainskill" class="card mb-4 mx-auto"><div class="card-header">Java</div><div class="card-body">Preferred language</div></div>
<div id="techskills" class="skills row h-50 mx-auto container-fluid justify-content-center">
<div class="card m-2"><div class="card-header">C#</div><div class="card-body">Alternative to java</div></div>
<div class="card m-2"><div class="card-header">Python</div><div class="card-body">Prototyping/automation</div></div>
<div class="card m-2"><div class="card-header">git</div><div class="card-body">Adept at common workflows</div></div>
<div class="card m-2"><div class="card-header">SQL</div><div class="card-body">SQLite/MySQL integrations</div></div>
<div class="card m-2"><div class="card-header">Linux</div><div class="card-body">Sysadmin on debian-based</div></div>
<div class="card m-2"><div class="card-header">IDA</div><div class="card-body">Reversing Win32 PEs</div></div>
<div class="card m-2"><div class="card-header">Pentesting</div><div class="card-body">Metasploit; Known-CVE scripts</div></div>
<div class="card m-2"><div class="card-header">Win32API</div><div class="card-body">Formats and functions</div></div>
<div class="card m-2"><div class="card-header">C/C++</div><div class="card-body">Novice knowledge for low level interactions</div></div>
<div class="card m-2"><div class="card-header">Arduino/Pi</div><div class="card-body">Small projects e.g. cap. keypad</div></div>
<div class="card m-2"><div class="card-header">CSS</div><div class="card-body">Theming web apps</div></div>
<div class="card m-2"><div class="card-header">JavaScript</div><div class="card-body">Basic knowledge</div></div>
<div class="card m-2"><div class="card-header">HTML</div><div class="card-body">Basic knowledge</div></div>
</div>
</div>
<div class="info-segment" data-aos="fade-up">
<p class="headings row pt-5 p-3">Other Skills and Hobbies</p>
<div id="otherskills" class="skills row h-50 mx-auto container-fluid justify-content-center">
<div class="card m-2"><div class="card-header">Cantonese</div><div class="card-body">Mother tongue</div></div>
<div class="card m-2"><div class="card-header">English</div><div class="card-body">Most fluent second language</div></div>
<div class="card m-2"><div class="card-header">Mandarin</div><div class="card-body">Can carry out daily conversations</div></div>
<div class="card m-2"><div class="card-header">Japanese</div><div class="card-body">(Work in progress)</div></div>
<div class="card m-2"><div class="card-header">Amateur Photography</div><div class="card-body">The backgrounds here are taken by me!</div></div>
</div>
</div>
</div>
<footer class="d-flex flex-column w-100 mt-5">
<p class="large-content mx-auto p-2 pt-3">Made from scratch by despawningbone with Bootstrap and AOS - view in <a href="https://stash.despawningbone.me/diffusion/WEB/" class="nav-link inline">codestash</a></p>
</footer>
- <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script src="main.js"></script>
</body>
</html>
diff --git a/main.js b/main.js
index 8934c1d..7e00a9d 100644
--- a/main.js
+++ b/main.js
@@ -1,26 +1,48 @@
AOS.init();
-if(typeof bg !== 'undefined') document.getElementById('cover').style.backgroundImage = 'linear-gradient(to bottom, rgba(52, 58, 64, 0) 94%, rgba(52, 58, 64, 1)), url(' + bg.src + ')';
-
//initialize tooltips
$('[data-toggle="tooltip"]').tooltip({
- offset: '0, 20%'
+ offset: '0, 20%'
});
+$('#discord').bind('click touchend', function() {
+ if (navigator.clipboard.writeText("despawningbone#4078")) {
+ $(this).tooltip('hide');
+ $('#discord').attr('data-original-title', "(copied!)");
+ setTimeout(() => $('#discord').attr('data-original-title', "despawningbone#4078"), 400);
+ $(this).tooltip('show');
+ }
+});
-/*$('[data-toggle="tooltip"]').mouseenter(function(){ //tooltip patch for browsers since its shifted somehow
- if(!/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
- document.styleSheets[2].cssRules[4].style.setProperty('left', (($(this).parent().index() + 1) * 2.5) + 'px', "important");
- }
-});*/ //fixed by changing discord id from a to img wtf
+//relative data-target patch for accordions, and also to add .show back into the button
+$('body').on('click', '[data-toggle=collapse]', function (e) {
+ var $parent = $(this).parents('.ctf-info');
+ $parent.find('.ctf-table').collapse('toggle');
+ $parent.toggleClass('show')
+});
-$('#discord').bind('click touchend', function() {
- console.log(this);
- if (navigator.clipboard.writeText("despawningbone#4078")) {
- $(this).tooltip('hide');
- $('#discord').attr('data-original-title', "(copied!)");
- setTimeout(() => $('#discord').attr('data-original-title', "despawningbone#4078"), 400);
- $(this).tooltip('show');
+//ctf diary comment popup dynamically load content
+//TODO allow use of url#data-comment to load modal
+$('.ctf-table tbody tr').on('click',function(){
+ href = $(this).attr('href');
+ //if full writeup is available, redirect
+ if(href) {
+ window.location=href;
+ } else {
+ //else open comment popup
+ href = $(this).attr('data-comment');
+
+ //set comment title to chall name
+ $('#commentTitle').text('Comments - ' + this.firstElementChild.textContent)
+
+ //only load if attr is found, which means a comment should be found
+ if(href) {
+ console.log('ctf/' + href + '.html')
+ $('.ctf-comment').load('ctf/' + href + '.html', function(res, status, xhr){
+ if(status !== "error") //only show if we can load it, otherwise treat as no comment
+ $('#comment').modal({show:true});
+ });
}
+ }
});
\ No newline at end of file
diff --git a/projects.html b/projects.html
index 3c6be78..6209de2 100644
--- a/projects.html
+++ b/projects.html
@@ -1,95 +1,98 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+ <link rel="preload" href="canvas.png" as="image">
+
<link href="https://fonts.googleapis.com/css2?family=Source+Code+Pro&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/aos@next/dist/aos.css" />
<link rel="stylesheet" href="main.css">
- <title>Hi! - despawningbone's portfolio</title>
+ <title>Hi! - desp's portfolio</title>
</head>
- <body class="bg-dark text-center text-white">
+ <body class="text-center text-white">
<div class="d-flex w-100 h-auto p-3 flex-column">
<header>
<nav class="nav nav-mast head justify-content-center float-md-right">
<a class="nav-link" href="/">Home</a>
<a class="nav-link active" aria-current="page" href="#">Projects</a>
<a class="nav-link" href="https://stash.despawningbone.me">Codestash</a>
+ <a class="nav-link" href="/ctf.html">CTF diary</a>
</nav>
</header>
- <div class="headings pt-5 my-auto mx-auto w-75">
+ <div class="headings pt-5 my-auto mx-auto w-75" data-aos="fade-up">
<div id="mainline">Project Highlights<br></div>
<div><i>More projects can be found on the codestash!</i></div>
</div>
</div>
<div class="info-segment row">
<div class="w-100 mx-auto p-5-flex divider"></div>
<div class="text-right info-subsegment" data-aos="fade-up">
<div class="splitview my-auto row"><img class="img-fluid mx-auto" src="images/vortex.jpg"></img></div>
<div class="m-auto pr-5 splitview">
<p class="project headings"><a href="https://www.vortexnetwork.me" class="nav-link">Vortex Network</a></p>
<p class="large-content ml-auto"><span>Originally invited to be a plugin developer from the start of the server, I officially joined the development team not long after,
migrating it to a network. I have since maintained the Ubuntu-based infrastructure backend, the 3 websites and a discord bot along with plugin development.<br></span>
<span>From intrusion detection and prevention to general sysadmin work, I've gained a lot of real world insights into how actual system administration on a cloud might feel like,
and it taught me how to code as a team, use CD/CI technologies, and a lot more that I wouldn't have expected from developing a minecraft server.</span>
</p>
<p class="smaller">Project since July 2017</p>
</div>
</div>
<div class="w-100 mx-auto m-5 p-5-flex divider"></div>
<div class="text-left info-subsegment" data-aos="fade-up">
<div class="m-auto pl-5 splitview">
<p class="project headings"><a href="https://discordapp.com/oauth2/authorize?&client_id=311086271642599424&scope=bot&permissions=0" class="nav-link">despbot</a></p>
<p class="large-content mr-auto"><span>Ever since I started using Discord back in 2016, it has been my favorite communication platform; Everything just felt intuitive and simple yet customizable.
With this newfound favorite, I started digging into everything it has to offer, and I eventually stumbled upon the officially supported bots and their API.<br></span>
<span>Having only started programming by then, it proved to be a great opportunity for me to learn and test my skills while making helpful utilities for my daily use.
Throughout the years, it has evolved from a single 8ball to 50+ different commands, hardcoded values to per-guild configs, and from one giant class filled with if-elses to a multithreaded framework supporting nested subcommands.<br></span>
<span>It is currently semi-public as there are still a lot left to do; However, feel free to add it to any servers if you find it useful too ๐Ÿ˜Š</span>
</p>
<p class="smaller">View in <a href="https://stash.despawningbone.me/diffusion/DESB/" class="nav-link inline">codestash</a> ยท Project since Jan 2017</p>
</div>
<div class="splitview my-auto row"><img class="img-fluid mx-auto" src="images/despbot.png"></img></div>
</div>
<div class="w-100 mx-auto m-5 p-5-flex divider"></div>
<div class="text-right info-subsegment" data-aos="fade-up">
<div class="splitview my-auto row"><img class="img-fluid p-5-flex mx-auto" src="images/spigot.jpg"></img></div>
<div class="m-auto pr-5 splitview">
<p class="project headings"><a href="https://www.spigotmc.org/resources/authors/despawningbone.256767/" class="nav-link">Spigot Plugins</a></p>
<p class="large-content ml-auto"><span>As one of the most fasinating games I've ever played, I've spent countless hours on the technical side of Minecraft, whether it was redstone or command blocks.
Eventually, with a private feature being heavily requested on a server I played frequently back then, I decided: why not try programming it myself and give it to the server instead?<br></span>
<span>With only basic C knowledge and having only created simple utilities, it proved to be a challenge, but it also was what really sparked my interest in computer science.
I created and published several more plugins in the coming years, before moving on to creating custom plugins for vortex network.</span>
</p>
<p class="smaller">Project since Dec 2016 ยท on hiatus</p>
</div>
</div>
<div class="w-100 mx-auto mt-5 p-5-flex divider"></div>
</div>
</div>
<footer class="d-flex flex-column w-100 mt-5">
<p class="large-content mx-auto p-2 pt-3">Made from scratch by despawningbone with Bootstrap and AOS - view in <a href="https://stash.despawningbone.me/diffusion/WEB/" class="nav-link inline">codestash</a></p>
</footer>
- <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
+ <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="https://unpkg.com/aos@next/dist/aos.js"></script>
<script src="main.js"></script>
</body>
</html>
diff --git a/pygments-native.css b/pygments-native.css
new file mode 100644
index 0000000..525604a
--- /dev/null
+++ b/pygments-native.css
@@ -0,0 +1,80 @@
+.highlight .hll { background-color: #404040 }
+.highlight { background: #202020; color: #d0d0d0 }
+.highlight .c { color: #999999; font-style: italic } /* Comment */
+.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
+.highlight .esc { color: #d0d0d0 } /* Escape */
+.highlight .g { color: #d0d0d0 } /* Generic */
+.highlight .k { color: #6ab825; font-weight: bold } /* Keyword */
+.highlight .l { color: #d0d0d0 } /* Literal */
+.highlight .n { color: #d0d0d0 } /* Name */
+.highlight .o { color: #d0d0d0 } /* Operator */
+.highlight .x { color: #d0d0d0 } /* Other */
+.highlight .p { color: #d0d0d0 } /* Punctuation */
+.highlight .ch { color: #999999; font-style: italic } /* Comment.Hashbang */
+.highlight .cm { color: #999999; font-style: italic } /* Comment.Multiline */
+.highlight .cp { color: #cd2828; font-weight: bold } /* Comment.Preproc */
+.highlight .cpf { color: #999999; font-style: italic } /* Comment.PreprocFile */
+.highlight .c1 { color: #999999; font-style: italic } /* Comment.Single */
+.highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */
+.highlight .gd { color: #d22323 } /* Generic.Deleted */
+.highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */
+.highlight .gr { color: #d22323 } /* Generic.Error */
+.highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */
+.highlight .gi { color: #589819 } /* Generic.Inserted */
+.highlight .go { color: #cccccc } /* Generic.Output */
+.highlight .gp { color: #aaaaaa } /* Generic.Prompt */
+.highlight .gs { color: #d0d0d0; font-weight: bold } /* Generic.Strong */
+.highlight .gu { color: #ffffff; text-decoration: underline } /* Generic.Subheading */
+.highlight .gt { color: #d22323 } /* Generic.Traceback */
+.highlight .kc { color: #6ab825; font-weight: bold } /* Keyword.Constant */
+.highlight .kd { color: #6ab825; font-weight: bold } /* Keyword.Declaration */
+.highlight .kn { color: #6ab825; font-weight: bold } /* Keyword.Namespace */
+.highlight .kp { color: #6ab825 } /* Keyword.Pseudo */
+.highlight .kr { color: #6ab825; font-weight: bold } /* Keyword.Reserved */
+.highlight .kt { color: #6ab825; font-weight: bold } /* Keyword.Type */
+.highlight .ld { color: #d0d0d0 } /* Literal.Date */
+.highlight .m { color: #3677a9 } /* Literal.Number */
+.highlight .s { color: #ed9d13 } /* Literal.String */
+.highlight .na { color: #bbbbbb } /* Name.Attribute */
+.highlight .nb { color: #24909d } /* Name.Builtin */
+.highlight .nc { color: #447fcf; text-decoration: underline } /* Name.Class */
+.highlight .no { color: #40ffff } /* Name.Constant */
+.highlight .nd { color: #ffa500 } /* Name.Decorator */
+.highlight .ni { color: #d0d0d0 } /* Name.Entity */
+.highlight .ne { color: #bbbbbb } /* Name.Exception */
+.highlight .nf { color: #447fcf } /* Name.Function */
+.highlight .nl { color: #d0d0d0 } /* Name.Label */
+.highlight .nn { color: #447fcf; text-decoration: underline } /* Name.Namespace */
+.highlight .nx { color: #d0d0d0 } /* Name.Other */
+.highlight .py { color: #d0d0d0 } /* Name.Property */
+.highlight .nt { color: #6ab825; font-weight: bold } /* Name.Tag */
+.highlight .nv { color: #40ffff } /* Name.Variable */
+.highlight .ow { color: #6ab825; font-weight: bold } /* Operator.Word */
+.highlight .w { color: #666666 } /* Text.Whitespace */
+.highlight .mb { color: #3677a9 } /* Literal.Number.Bin */
+.highlight .mf { color: #3677a9 } /* Literal.Number.Float */
+.highlight .mh { color: #3677a9 } /* Literal.Number.Hex */
+.highlight .mi { color: #3677a9 } /* Literal.Number.Integer */
+.highlight .mo { color: #3677a9 } /* Literal.Number.Oct */
+.highlight .sa { color: #ed9d13 } /* Literal.String.Affix */
+.highlight .sb { color: #ed9d13 } /* Literal.String.Backtick */
+.highlight .sc { color: #ed9d13 } /* Literal.String.Char */
+.highlight .dl { color: #ed9d13 } /* Literal.String.Delimiter */
+.highlight .sd { color: #ed9d13 } /* Literal.String.Doc */
+.highlight .s2 { color: #ed9d13 } /* Literal.String.Double */
+.highlight .se { color: #ed9d13 } /* Literal.String.Escape */
+.highlight .sh { color: #ed9d13 } /* Literal.String.Heredoc */
+.highlight .si { color: #ed9d13 } /* Literal.String.Interpol */
+.highlight .sx { color: #ffa500 } /* Literal.String.Other */
+.highlight .sr { color: #ed9d13 } /* Literal.String.Regex */
+.highlight .s1 { color: #ed9d13 } /* Literal.String.Single */
+.highlight .ss { color: #ed9d13 } /* Literal.String.Symbol */
+.highlight .bp { color: #24909d } /* Name.Builtin.Pseudo */
+.highlight .fm { color: #447fcf } /* Name.Function.Magic */
+.highlight .vc { color: #40ffff } /* Name.Variable.Class */
+.highlight .vg { color: #40ffff } /* Name.Variable.Global */
+.highlight .vi { color: #40ffff } /* Name.Variable.Instance */
+.highlight .vm { color: #40ffff } /* Name.Variable.Magic */
+.highlight .il { color: #3677a9 } /* Literal.Number.Integer.Long */
+
+pre code, .highlight.language-text { color: #e83e8c !important }
\ No newline at end of file
diff --git a/robots.txt b/robots.txt
new file mode 100644
index 0000000..7b669f4
--- /dev/null
+++ b/robots.txt
@@ -0,0 +1,3 @@
+User-agent: *
+Disallow: /ctf.html
+Disallow: /ctf/
\ No newline at end of file

File Metadata

Mime Type
text/x-diff
Expires
Sat, Sep 21, 6:34 PM (1 d, 18 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d5/8f/98c590c249d1e456b0d8ceda603d

Event Timeline