Compare commits
239 Commits
Author | SHA1 | Date |
---|---|---|
Matt Mascarenhas | 14dafa4abe | |
Matt Mascarenhas | 213bb2f882 | |
Matt Mascarenhas | 77aec74483 | |
Matt Mascarenhas | 6852d06e04 | |
Matt Mascarenhas | 52d6d989f8 | |
Matt Mascarenhas | df93674bf7 | |
Matt Mascarenhas | 026585e50b | |
Matt Mascarenhas | 9d5f0f9146 | |
Matt Mascarenhas | a7694d4c3b | |
Matt Mascarenhas | c9bf96c7aa | |
Matt Mascarenhas | 44a5008aa7 | |
Matt Mascarenhas | 6576a91d11 | |
Matt Mascarenhas | 1280142d45 | |
Matt Mascarenhas | 6b09247cd2 | |
Matt Mascarenhas | 554f7393ff | |
Matt Mascarenhas | e8ed2f0143 | |
Matt Mascarenhas | ac4b155e73 | |
Matt Mascarenhas | 0f15957cb5 | |
Matt Mascarenhas | 68d1469212 | |
Matt Mascarenhas | f321a6b6bf | |
Matt Mascarenhas | 6ea5cb6d22 | |
Matt Mascarenhas | 0825cbb5ff | |
Matt Mascarenhas | 6e9c7edd1d | |
Matt Mascarenhas | b8f143e350 | |
Matt Mascarenhas | f60cf3087f | |
Matt Mascarenhas | 1cf703e346 | |
Matt Mascarenhas | 26e304f62c | |
Matt Mascarenhas | 8dffa513cc | |
Matt Mascarenhas | e17c3aa78c | |
Matt Mascarenhas | 84a35b9ece | |
Matt Mascarenhas | ef9937e95b | |
Matt Mascarenhas | 652d8f186f | |
Matt Mascarenhas | 91c33c580b | |
Matt Mascarenhas | f7a6df994f | |
Matt Mascarenhas | b6fb755d29 | |
Matt Mascarenhas | d036145b7f | |
Matt Mascarenhas | 60615322dd | |
Matt Mascarenhas | 2deb244cce | |
Matt Mascarenhas | 4dc034ecc3 | |
Matt Mascarenhas | ee788b0c30 | |
Matt Mascarenhas | c839e2ed85 | |
Matt Mascarenhas | 012d1608a0 | |
Matt Mascarenhas | 97806c2c9c | |
Matt Mascarenhas | dd33bb49b3 | |
Matt Mascarenhas | e39a09c0ad | |
Matt Mascarenhas | 744515dac4 | |
Matt Mascarenhas | 209979f63a | |
Matt Mascarenhas | 12b06812bf | |
Matt Mascarenhas | 373195069a | |
Matt Mascarenhas | 07795b7cbd | |
Matt Mascarenhas | b0501d20ac | |
Matt Mascarenhas | af1bff4218 | |
Matt Mascarenhas | 63ab9d5bc2 | |
Matt Mascarenhas | 9cdb3b96d9 | |
Matt Mascarenhas | 61fa4e4808 | |
Matt Mascarenhas | cf51ba24e3 | |
Matt Mascarenhas | a6a9653306 | |
Matt Mascarenhas | c104500020 | |
Matt Mascarenhas | 0d88c24db6 | |
Matt Mascarenhas | 65fe93fb57 | |
Matt Mascarenhas | b20192e445 | |
Matt Mascarenhas | 9a31a1b10c | |
Matt Mascarenhas | d1440a7ac6 | |
Matt Mascarenhas | 0f67d4e658 | |
Alex Baines | 00fc6c0ae5 | |
Alex Baines | c0c3558473 | |
Alex Baines | 3f47e62a7e | |
Alex Baines | c911e393d5 | |
Matt Mascarenhas | 05b7883033 | |
Alex Baines | e4c2ae4ffa | |
Alex Baines | 1d916415c1 | |
Alex Baines | 678be54e51 | |
Alex Baines | 1993e9f1dd | |
Alex Baines | 968437d263 | |
Alex Baines | 67c4942b60 | |
Matt Mascarenhas | 828fff7a7a | |
Matt Mascarenhas | 8283e2a9e5 | |
Matt Mascarenhas | 22633794b5 | |
Matt Mascarenhas | 0cfa87ba84 | |
Matt Mascarenhas | 806c9feba8 | |
Matt Mascarenhas | b6fff3cc24 | |
Matt Mascarenhas | 20d7e82a66 | |
Matt Mascarenhas | 33f6186aa1 | |
Matt Mascarenhas | 2d26562301 | |
Matt Mascarenhas | 4ba03f9338 | |
Matt Mascarenhas | 7e80017434 | |
Matt Mascarenhas | 29df4df8a4 | |
Matt Mascarenhas | 5857a30eaf | |
Matt Mascarenhas | 0a9d51b0d7 | |
Matt Mascarenhas | 50dbc7b5c3 | |
Matt Mascarenhas | e7d70ccb3a | |
Matt Mascarenhas | f519a0977f | |
Matt Mascarenhas | 545938d766 | |
Matt Mascarenhas | 2cf8739a60 | |
Matt Mascarenhas | eccd02cc71 | |
Matt Mascarenhas | 3945ac883c | |
Matt Mascarenhas | 6eeb588adf | |
Matt Mascarenhas | b3470e0f48 | |
Matt Mascarenhas | 2748687839 | |
Matt Mascarenhas | 6da970d48c | |
Matt Mascarenhas | 0959fa2774 | |
Matt Mascarenhas | 7edcecfd40 | |
Matt Mascarenhas | bc6f21f71d | |
Matt Mascarenhas | 8aa67a386a | |
Matt Mascarenhas | ce9a0e7635 | |
Matt Mascarenhas | 877dbab5bd | |
Matt Mascarenhas | 9dfdc117be | |
Matt Mascarenhas | e2ea8fdaf3 | |
Matt Mascarenhas | 33e590c6da | |
Matt Mascarenhas | 3e0ba0b77b | |
Matt Mascarenhas | 18b39b9f72 | |
Matt Mascarenhas | f20a35e0de | |
Matt Mascarenhas | 3728c8aaee | |
Matt Mascarenhas | bd8c6b805d | |
Matt Mascarenhas | c883bbb971 | |
Matt Mascarenhas | 05518781c4 | |
Matt Mascarenhas | 9051caa94e | |
Matt Mascarenhas | 35b6b803e3 | |
Matt Mascarenhas | 9278390a38 | |
Matt Mascarenhas | f5a767ff94 | |
Matt Mascarenhas | d6e633cf3e | |
Alex Baines | 21814d1e48 | |
Matt Mascarenhas | 9b26d109be | |
Matt Mascarenhas | d37a39af32 | |
Matt Mascarenhas | c4ef54c742 | |
Matt Mascarenhas | 9d0cdfb488 | |
Matt Mascarenhas | 2eddd7a7c2 | |
Matt Mascarenhas | 3da53413ce | |
Alex Baines | 07db5d0397 | |
Alex Baines | 82a49f57e9 | |
Matt Mascarenhas | f3b728ee6f | |
Matt Mascarenhas | 8607ca87ea | |
Matt Mascarenhas | aa0a8ba327 | |
Matt Mascarenhas | 92909a9ee9 | |
Matt Mascarenhas | 8a4a383705 | |
Matt Mascarenhas | 6ca1446450 | |
Asaf Gartner | 6136a45886 | |
Matt Mascarenhas | 8c17194180 | |
Matt Mascarenhas | a1e8efe431 | |
Matt Mascarenhas | 966d616b48 | |
Matt Mascarenhas | 0eeadd560b | |
Matt Mascarenhas | 4d495543f5 | |
Matt Mascarenhas | 45cf7772d9 | |
Matt Mascarenhas | 238427331f | |
Matt Mascarenhas | fc7c28c047 | |
Matt Mascarenhas | 8ec5475456 | |
Matt Mascarenhas | c788fd464e | |
Matt Mascarenhas | ce367b00aa | |
Matt Mascarenhas | 426cbfccba | |
Matt Mascarenhas | 845a824d62 | |
Matt Mascarenhas | 525590fa36 | |
Matt Mascarenhas | d420513e20 | |
Matt Mascarenhas | e77d208645 | |
Matt Mascarenhas | be37ea234a | |
Matt Mascarenhas | 4a0630beb0 | |
Matt Mascarenhas | 8d75865cf3 | |
Matt Mascarenhas | 4b9e1a2fa0 | |
Matt Mascarenhas | 1efd808783 | |
Matt Mascarenhas | 14afdc044d | |
Matt Mascarenhas | 33cbb5b05f | |
Matt Mascarenhas | a27e603e6e | |
Alex Baines | 7034ce096b | |
Matt Mascarenhas | de2c632806 | |
Matt Mascarenhas | ab598e37e6 | |
Matt Mascarenhas | 2053be1969 | |
Matt Mascarenhas | 23e31df4e2 | |
Matt Mascarenhas | 6f99a50f50 | |
Matt Mascarenhas | e7aefbada0 | |
Matt Mascarenhas | 2cac3ed03b | |
Matt Mascarenhas | c5bc487313 | |
Alex Baines | bbd1d657a7 | |
Matt Mascarenhas | c7762a0f7d | |
Matt Mascarenhas | 87e63a54e7 | |
Matt Mascarenhas | 9d9d8a6332 | |
Matt Mascarenhas | 1603245fad | |
Matt Mascarenhas | bd590d4c07 | |
Matt Mascarenhas | e5d592dc11 | |
Matt Mascarenhas | 0f27c96b29 | |
Matt Mascarenhas | 3d7add5b66 | |
Matt Mascarenhas | d7d27f59b7 | |
Matt Mascarenhas | b8013133b9 | |
Matt Mascarenhas | f270ee2afa | |
Matt Mascarenhas | 5e7029d2b0 | |
Matt Mascarenhas | 78861a1c78 | |
Matt Mascarenhas | 93fa77b055 | |
Matt Mascarenhas | 6b1156292c | |
Matt Mascarenhas | acbe38b01f | |
Matt Mascarenhas | b55f20dcb1 | |
Matt Mascarenhas | 7d88e3c17d | |
Matt Mascarenhas | c1d6c87746 | |
Matt Mascarenhas | 8f37ce0b76 | |
Alex Baines | 6fe3ed8dad | |
Matt Mascarenhas | f1e39e0513 | |
Matt Mascarenhas | f6b85b5958 | |
Matt Mascarenhas | e4c1446256 | |
Matt Mascarenhas | 120290b398 | |
Matt Mascarenhas | 4a954b6ac6 | |
Matt Mascarenhas | 1bbdf5aea4 | |
Matt Mascarenhas | 153d14a810 | |
Matt Mascarenhas | 0aa585a15d | |
Matt Mascarenhas | 7312de5691 | |
Matt Mascarenhas | f7b3e6ffe2 | |
Matt Mascarenhas | fda3ee819b | |
Matt Mascarenhas | f07cc87629 | |
Matt Mascarenhas | 9ce24be33a | |
Matt Mascarenhas | 6f751dd2b2 | |
Matt Mascarenhas | f454e01e28 | |
Matt Mascarenhas | 24f02aec93 | |
Matt Mascarenhas | 75f65e561d | |
Matt Mascarenhas | 0f38660b2e | |
Matt Mascarenhas | 50e2880d1b | |
Matt Mascarenhas | 1636c5fa14 | |
Matt Mascarenhas | 5539af0210 | |
Matt Mascarenhas | 1b241ddcfe | |
Matt Mascarenhas | 1bb5cb034b | |
Matt Mascarenhas | 59d03c91bb | |
Matt Mascarenhas | 4572817837 | |
Alex Baines | c7d764c0a6 | |
Matt Mascarenhas | df5fe8de03 | |
Matt Mascarenhas | b133f15a11 | |
Matt Mascarenhas | d82e665310 | |
Matt Mascarenhas | f9bebe2924 | |
Matt Mascarenhas | 445969aee2 | |
Matt Mascarenhas | d8b21171a1 | |
Matt Mascarenhas | 67f6ff4db2 | |
Matt Mascarenhas | 928d639c41 | |
Matt Mascarenhas | f3899c2f35 | |
Matt Mascarenhas | 6e1f6a4faa | |
Matt Mascarenhas | bcaa6d63db | |
Matt Mascarenhas | ec556a8e3b | |
Matt Mascarenhas | 5f21a9544d | |
Matt Mascarenhas | ad8fb22211 | |
Matt Mascarenhas | 53aea540ab | |
Matt Mascarenhas | 2059b9367a | |
Alex Baines | a389423b73 | |
Alex Baines | 58c3de0aa2 | |
Matt Mascarenhas | c59a4fcc5a | |
Matt Mascarenhas | b3d1399237 | |
Matt Mascarenhas | 048d522657 |
170
README.md
|
@ -1,77 +1,145 @@
|
|||
Fair warning: This is all under development and not yet packaged up for easy
|
||||
deployment
|
||||
|
||||
## hmml_to_html
|
||||
## Cinera
|
||||
|
||||
### Install the dependencies
|
||||
|
||||
1. curl
|
||||
|
||||
### Download, and copy the parser into place
|
||||
|
||||
1. `git clone https://git.handmade.network/Annotation-Pushers/Annotation-System.git`
|
||||
2. `cd Annotation-System/cinera`
|
||||
3. `cp ../hmmlib2/hmmlib.h .`
|
||||
|
||||
Note: For each parser update, remember to copy it into place.
|
||||
|
||||
### Build
|
||||
|
||||
Clone the repo, `cd hmml_to_html` and run:
|
||||
1. `$SHELL cinera.c`
|
||||
|
||||
zsh hmml_to_html.c
|
||||
### Configure
|
||||
|
||||
(replacing zsh with your shell as appropriate)
|
||||
cinera -h
|
||||
|
||||
This outputs a binary `hmml_to_html`
|
||||
This documents the configuration file format and default settings.
|
||||
|
||||
### Configure the server
|
||||
|
||||
If you enforce a strict Content Security Policy and X-Frame-Options in your
|
||||
server configuration as recommended by [Security
|
||||
Headers](https://securityheaders.com/), you may enable _Cinera_ to function by
|
||||
making two small tweaks:
|
||||
|
||||
add_header Content-Security-Policy "default-src … https://www.youtube.com https://s.ytimg.com";
|
||||
add_header X-Frame-Options "ALLOW-FROM https://www.youtube.com";
|
||||
|
||||
Note: For more information about these and other security headers, see Scott
|
||||
Helme's articles [Content Security Policy - An Introduction](https://scotthelme.co.uk/content-security-policy-an-introduction/)
|
||||
and [Hardening your HTTP response headers](https://scotthelme.co.uk/hardening-your-http-response-headers/#x-frame-options).
|
||||
|
||||
### Run
|
||||
|
||||
#### Ordinary operation
|
||||
cinera -c /path/to/config.conf
|
||||
|
||||
./hmml_to_html test.hmml
|
||||
#### Templates
|
||||
|
||||
This simply generates an HTML file (and updates `cinera_topics.css` if needed)
|
||||
from `test.hmml` and outputs to `out.html`
|
||||
*(Global) Search Template*
|
||||
- `<!-- __CINERA_INCLUDES__ -->` _to put inside your own `<head></head>`_
|
||||
- `<!-- __CINERA_SEARCH__ -->` _the table of contents and search functionality_
|
||||
|
||||
Note that if the `.hmml` file contains quotes (as `test.hmml` does), it would be
|
||||
easiest for now just to remove the quote from `test.hmml`. If you want quotes
|
||||
to work, run:
|
||||
*Player Template*
|
||||
- `<!-- __CINERA_INCLUDES__ -->` _to put inside your own `<head></head>`_
|
||||
- `<!-- __CINERA_PLAYER__ -->`
|
||||
|
||||
mkdir /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
|
||||
git clone https://gist.github.com/insofaras/25fc16d58a297a486334 /home/matt/git/GitHub/insofaras/25fc16d58a297a486334
|
||||
*Optional tags available for use in your Player Template*
|
||||
- `<!-- __CINERA_TITLE__ -->`
|
||||
- `<!-- __CINERA_VIDEO_ID__ -->`
|
||||
- `<!-- __CINERA_VOD_PLATFORM__ -->`
|
||||
|
||||
(Seriously, the path is hardcoded for now)
|
||||
*Other tags available for use in any template*
|
||||
- Asset tags:
|
||||
- `<!-- __CINERA_ASSET__ path.ext -->`
|
||||
General purpose tag that outputs the URL of the specified asset
|
||||
relative to the Asset Root URL (-R)
|
||||
- `<!-- __CINERA_IMAGE__ path.ext -->`
|
||||
General purpose tag that outputs the URL of the specified asset
|
||||
relative to the Images Directory (-i)
|
||||
- `<!-- __CINERA_CSS__ path.ext -->`
|
||||
Convenience tag that outputs a `<link rel="stylesheet"...>` node
|
||||
for the specified asset relative to the CSS Directory (-c), for
|
||||
use inside your `<head>` block
|
||||
- `<!-- __CINERA_JS__ path.ext -->`
|
||||
Convenience tag that outputs a `<script type="text/javascript"...>`
|
||||
node for the specified asset relative to the JS Directory (-j),
|
||||
for use wherever a `<script>` node is valid
|
||||
The path.ext in these tags supports parent directories to locate the
|
||||
asset file relative to its specified type directory (generic, CSS, image
|
||||
or JS), including the "../" directory, and paths containing spaces must
|
||||
be surrounded with double-quotes (\-escapable if the quoted path itself
|
||||
contains double-quotes).
|
||||
|
||||
Note also that `cinera.css` contains a `body {}` block at the bottom which you
|
||||
may want to remove / comment out
|
||||
All these asset tags additionally perform versioning, appending a query string
|
||||
(-Q) and the file's checksum to the URL. Changes to a file trigger a rehash and
|
||||
edit of all HTML pages citing this asset.
|
||||
|
||||
#### Integration
|
||||
- Navigation / Menu tags:
|
||||
- `<!-- __CINERA_NAV__ -->`
|
||||
This menu will contain only the current project, its siblings and
|
||||
subprojects of both the aforementioned
|
||||
- `<!-- __CINERA_GLOBAL_NAV__ -->`
|
||||
This menu will contain every project in the configuration
|
||||
|
||||
CINERA_MODE=INTEGRATE ./hmml_to_html test.hmml
|
||||
These navigation tags additionally take one parameter, e.g.
|
||||
`<!-- __CINERA_NAV__ horizontal -->`:
|
||||
- `dropdown`
|
||||
A dropdown menu, that opens on hover
|
||||
- `horizontal`
|
||||
More-or-less the same as `dropdown`, but always open
|
||||
- `plain`
|
||||
A straightforward `<ul>` for you to style how you like
|
||||
|
||||
This will integrate into `template.html` (currently hardcoded) the player and
|
||||
related elements generated from `test.hmml` and output to `out.html`
|
||||
- `<!-- __CINERA_PROJECT__ -->`
|
||||
The project's `html_title` if configured, otherwise its `title`
|
||||
- `<!-- __CINERA_PROJECT_PLAIN__ -->`
|
||||
The project's `title`
|
||||
- `<!-- __CINERA_PROJECT_ID__ -->`
|
||||
- `<!-- __CINERA_PROJECT_LINEAGE__ -->`
|
||||
The IDs of all projects from the root to the current project, separated
|
||||
by a spaced-slash
|
||||
- `<!-- __CINERA_SEARCH_URL__ -->`
|
||||
- `<!-- __CINERA_THEME__ -->`
|
||||
- `<!-- __CINERA_URL__ -->`
|
||||
- `<!-- __CINERA_CUSTOM0__ -->`
|
||||
- `<!-- __CINERA_CUSTOM1__ -->`
|
||||
- `<!-- __CINERA_CUSTOM2__ -->`
|
||||
⋮
|
||||
- `<!-- __CINERA_CUSTOM15__ -->`
|
||||
Freeform buffers for small snippets of localised information, e.g. a
|
||||
single `<a>` element or perhaps a `<!-- comment -->`
|
||||
They correspond to the custom0 to custom15 attributes in the [video]
|
||||
node in your .hmml files
|
||||
0 to 11 may hold up to 255 characters
|
||||
12 to 15 may hold up to 1023 characters
|
||||
|
||||
Feel free to play with `template.html` to your heart's content. If you do
|
||||
anything invalid, `hmml_to_html` will tell you what's wrong
|
||||
|
||||
Valid tags:
|
||||
|
||||
- `<!-- __CINERA_TITLE__ -->` _the day / episode name, intended to be used
|
||||
inside your own `<title>` element, but may be used wherever and as many times
|
||||
as you want on your page_
|
||||
- `<!-- __CINERA_INCLUDES__ -->` _the necessary `.css` and `.js` files, and charset setting_
|
||||
- `<!-- __CINERA_MENUS__ -->` _ _the menu bar that typically appears above the
|
||||
player in my samples_
|
||||
- `<!-- __CINERA_PLAYER__ -->` _the player_
|
||||
- `<!-- __CINERA_SCRIPT__ -->` _the listeners that enable interaction with the player_
|
||||
Feel free to play with templates to your heart's content. If you do anything
|
||||
invalid, _Cinera_ will tell you what's wrong.
|
||||
|
||||
#### Arguments
|
||||
|
||||
Usage: ./hmml_to_html [option(s)] filename(s)
|
||||
Usage: ./cinera [option(s)]
|
||||
|
||||
Options:
|
||||
-c <CSS directory path>
|
||||
Override default CSS directory (".")
|
||||
-i <images directory path>
|
||||
Override default images directory (".")
|
||||
-j <JS directory path>
|
||||
Override default JS directory (".")
|
||||
-o <output location>
|
||||
Override default output location ("out.html")
|
||||
-q <quotes directory path>
|
||||
Override default quotes directory ("/home/matt/git/GitHub/insofaras/25fc16d58a297a486334")
|
||||
-t <template location>
|
||||
Override default template location ("template.html")
|
||||
and automatically enable integration
|
||||
-h
|
||||
display this help
|
||||
Options:
|
||||
-c <config file path>
|
||||
Set the main config file path
|
||||
Defaults to: $XDG_CONFIG_HOME/cinera/cinera.conf
|
||||
-0
|
||||
Dry-run mode. Parse and print the config, but do not modify the
|
||||
filesystem
|
||||
-e
|
||||
Display (examine) database and exit
|
||||
-v
|
||||
Display version and exit
|
||||
-h
|
||||
Display this help
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// NOTE(matt): To use, source this file inside the element you wish to be obscured while processing occurs.
|
||||
// After processing is complete, call FlipClear()
|
||||
|
||||
var ThisScriptElement = document.currentScript;
|
||||
var NodeToHide = ThisScriptElement.parentNode;
|
||||
|
||||
var CineraClearElement = document.createElement("DIV");
|
||||
CineraClearElement.style.position = "fixed";
|
||||
CineraClearElement.style.height = "100%";
|
||||
CineraClearElement.style.width = "100%";
|
||||
CineraClearElement.style.zIndex = 64;
|
||||
|
||||
var CineraPlacedClear = NodeToHide.appendChild(CineraClearElement);
|
||||
var Colour = getBackgroundColourRGB(CineraPlacedClear);
|
||||
CineraPlacedClear.style.background = "rgb(" + Colour.R + ", " + Colour.G + ", " + Colour.B + ")"
|
||||
document.body.style.overflowY = "hidden";
|
||||
|
||||
function
|
||||
FlipClear(BodyOverflowY)
|
||||
{
|
||||
document.body.style.overflowY = BodyOverflowY ? BodyOverflowY : null;
|
||||
CineraPlacedClear.parentNode.removeChild(CineraPlacedClear);
|
||||
}
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1,76 @@
|
|||
var baseURL = location.hash ? (location.toString().substr(0, location.toString().length - location.hash.length)) : location;
|
||||
|
||||
var CineraProps = {
|
||||
C: null,
|
||||
V: views.REGULAR,
|
||||
Z: null,
|
||||
X: null,
|
||||
Y: null,
|
||||
W: null,
|
||||
mW: null,
|
||||
H: null,
|
||||
mH: null,
|
||||
P: null,
|
||||
Display: null,
|
||||
FlexDirection: null,
|
||||
JustifyContent: null,
|
||||
O: null,
|
||||
IsMobile: IsMobile(),
|
||||
ScrollX: null,
|
||||
ScrollY: null,
|
||||
VODPlatform: null,
|
||||
};
|
||||
CineraProps.O = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
|
||||
var MobileCineraContentRuleSelector = ".cinera.mobile .cineraPlayerContainer .markers_container > .markers .marker .cineraContent";
|
||||
var MobileCineraContentRule = GetOrSetRule(MobileCineraContentRuleSelector);
|
||||
|
||||
var MenuContainerRuleSelector = ".cineraMenus > .menu .quotes_container, .cineraMenus > .menu .references_container, .cineraMenus > .menu .filter_container, .cineraMenus > .menu .views_container, .cineraMenus > .menu .link_container, .cineraMenus > .menu .credits_container";
|
||||
var MenuContainerRule = GetOrSetRule(MenuContainerRuleSelector);
|
||||
|
||||
var cinera = document.querySelector(".cinera");
|
||||
var player = new Player(cinera, onRefChanged);
|
||||
|
||||
window.addEventListener("resize", function() {
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
setTimeout(DelayedUpdateSize, 512, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.updateSize();
|
||||
}
|
||||
});
|
||||
|
||||
screen.orientation.onchange = function() {
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
setTimeout(DelayedUpdateSize, 512, player);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.updateSize();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener("keydown", function(ev) {
|
||||
var key = ev.key;
|
||||
if(ev.getModifierState("Shift") && key == " ")
|
||||
{
|
||||
key = "capitalSpace";
|
||||
}
|
||||
|
||||
if(!ev.getModifierState("Control") && player.handleKey(key) == true && player.MenusFocused.Item)
|
||||
{
|
||||
ev.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
document.addEventListener("fullscreenchange", function() {
|
||||
if(!document.fullscreenElement && CineraProps.V == views.SUPERTHEATRE)
|
||||
{
|
||||
CineraProps.V = views.THEATRE;
|
||||
localStorage.setItem(player.cineraViewStorageItem, views.THEATRE);
|
||||
player.updateSize();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,86 @@
|
|||
var cineraDropdownNavigation = document.getElementsByClassName("cineraNavDropdown");
|
||||
for(var i = 0; i < cineraDropdownNavigation.length; ++i)
|
||||
{
|
||||
var cineraFamily = cineraDropdownNavigation[i].getElementsByClassName("cineraNavHorizontal")[0];
|
||||
cineraDropdownNavigation[i].addEventListener("click", function() {
|
||||
if(cineraFamily.classList.contains("visible"))
|
||||
{
|
||||
cineraFamily.classList.remove("visible");
|
||||
}
|
||||
else
|
||||
{
|
||||
cineraFamily.classList.add("visible");
|
||||
}
|
||||
});
|
||||
|
||||
cineraDropdownNavigation[i].addEventListener("mouseenter", function() {
|
||||
cineraFamily.classList.add("visible");
|
||||
});
|
||||
|
||||
cineraDropdownNavigation[i].addEventListener("mouseleave", function() {
|
||||
cineraFamily.classList.remove("visible");
|
||||
});
|
||||
}
|
||||
|
||||
var Sprites = document.getElementsByClassName("cineraSprite");
|
||||
|
||||
for(var i = 0; i < Sprites.length; ++i)
|
||||
{
|
||||
var This = Sprites[i];
|
||||
|
||||
var TileX = This.getAttribute("data-tile-width");
|
||||
var TileY = This.getAttribute("data-tile-height");
|
||||
var AspectRatio = TileX / TileY;
|
||||
|
||||
// TODO(matt): Nail down the desiredness situation. Perhaps respond to:
|
||||
// width / min-width / height / min-height set in a CSS file
|
||||
// flexbox layout, if possible
|
||||
|
||||
// NOTE(matt): These values are "decoupled" here, to facilitate handling of sizes other than the original
|
||||
// We'll probably need some way of checking the desired and original of both the X and Y, and pick which one on
|
||||
// which to base the computation of the other
|
||||
var DesiredX = TileX;
|
||||
var DesiredY = DesiredX / AspectRatio;
|
||||
var Proportion = DesiredX / TileX;
|
||||
//
|
||||
////
|
||||
|
||||
// NOTE(matt): Size the container and its background image
|
||||
//
|
||||
This.style.width = DesiredX + "px";
|
||||
This.style.height = DesiredY + "px";
|
||||
|
||||
var SpriteWidth = This.getAttribute("data-sprite-width");
|
||||
var SpriteHeight = This.getAttribute("data-sprite-height");
|
||||
This.style.backgroundSize = SpriteWidth * Proportion + "px " + SpriteHeight * Proportion + "px";
|
||||
//
|
||||
////
|
||||
|
||||
// NOTE(matt): Pick the tile
|
||||
//
|
||||
setSpriteLightness(This);
|
||||
if(This.classList.contains("dark"))
|
||||
{
|
||||
This.style.backgroundPositionX = This.getAttribute("data-x-dark") + "px";
|
||||
}
|
||||
|
||||
if(elementIsFocused(This))
|
||||
{
|
||||
This.style.backgroundPositionY = This.getAttribute("data-y-focused") + "px";
|
||||
}
|
||||
|
||||
if(This.classList.contains("off"))
|
||||
{
|
||||
This.style.backgroundPositionY = This.getAttribute("data-y-disabled") + "px";
|
||||
}
|
||||
else
|
||||
{
|
||||
This.style.backgroundPositionY = This.getAttribute("data-y-normal") + "px";
|
||||
}
|
||||
//
|
||||
////
|
||||
|
||||
// NOTE(matt): Finally apply the background image
|
||||
var URL = This.getAttribute("data-src");
|
||||
This.style.backgroundImage = "url('" + URL + "')";
|
||||
}
|
|
@ -0,0 +1,614 @@
|
|||
var orientations = {
|
||||
PORTRAIT: 0,
|
||||
LANDSCAPE_LEFT: 90,
|
||||
LANDSCAPE_RIGHT: -90,
|
||||
};
|
||||
|
||||
function
|
||||
DeriveReliableWindowDimensions()
|
||||
{
|
||||
// https://www.howtocreate.co.uk/tutorials/javascript/browserwindow
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
|
||||
var ScrollPosX = window.scrollX;
|
||||
var ScrollPosY = window.scrollY;
|
||||
|
||||
var DisplaySettings = [];
|
||||
for(var i = 0; i < document.body.children.length; ++i)
|
||||
{
|
||||
var Child = document.body.children[i];
|
||||
DisplaySettings.push(Child.style.display);
|
||||
Child.style.display = "none";
|
||||
}
|
||||
|
||||
var Element = document.createElement("div");
|
||||
Element.style.position = "fixed";
|
||||
Element.style.top = 0;
|
||||
Element.style.right = 0;
|
||||
Element.style.bottom = 0;
|
||||
Element.style.left = 0;
|
||||
Element.style.zOffset = -1;
|
||||
Element.style.opacity = 0;
|
||||
var ElementInPlace = document.body.appendChild(Element);
|
||||
Result.X = ElementInPlace.offsetWidth;
|
||||
Result.Y = ElementInPlace.offsetHeight;
|
||||
ElementInPlace.remove();
|
||||
|
||||
for(var i = 0; i < document.body.children.length; ++i)
|
||||
{
|
||||
var Child = document.body.children[i];
|
||||
Child.style.display = DisplaySettings.shift();
|
||||
}
|
||||
|
||||
ScrollTriggeredInternally = true;
|
||||
window.scroll(ScrollPosX, ScrollPosY);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GetWindowDim(IsMobile)
|
||||
{
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
|
||||
if(IsMobile)
|
||||
{
|
||||
Result = DeriveReliableWindowDimensions();
|
||||
}
|
||||
else
|
||||
{
|
||||
Result.X = document.documentElement.clientWidth;
|
||||
Result.Y = document.documentElement.clientHeight;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function IsVisible(Element, WindowDim) {
|
||||
var BoundingRect = Element.getBoundingClientRect();
|
||||
return ((BoundingRect.top >= 0 && BoundingRect.top <= WindowDim.Y) ||
|
||||
(BoundingRect.bottom >= 0 && BoundingRect.bottom <= WindowDim.Y) ||
|
||||
(BoundingRect.top < 0 && BoundingRect.bottom > WindowDim.Y))
|
||||
&& ((BoundingRect.left >= 0 && BoundingRect.left <= WindowDim.X) ||
|
||||
(BoundingRect.right >= 0 && BoundingRect.right <= WindowDim.X) ||
|
||||
(BoundingRect.left < 0 && BoundingRect.right > WindowDim.X));
|
||||
}
|
||||
|
||||
function
|
||||
GetRealOrientation(PreferredLandscape, IsMobile)
|
||||
{
|
||||
var Result = screen.orientation.angle;
|
||||
var WindowDim = GetWindowDim(IsMobile);
|
||||
if(WindowDim.Y > WindowDim.X)
|
||||
{
|
||||
Result = orientations.PORTRAIT;
|
||||
}
|
||||
else if(Result == undefined || Result == orientations.PORTRAIT)
|
||||
{
|
||||
Result = PreferredLandscape;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
var DebugConsoleMessageCount = 0;
|
||||
function Say(Message)
|
||||
{
|
||||
var DebugConsole = document.getElementById("debug-console");
|
||||
if(DebugConsole)
|
||||
{
|
||||
DebugConsole.textContent += DebugConsoleMessageCount++ + ": " + Message + "\n";
|
||||
DebugConsole.scrollTo(
|
||||
{
|
||||
top: DebugConsole.scrollHeight,
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getBackgroundBrightness(element) {
|
||||
var colour = getComputedStyle(element).getPropertyValue("background-color");
|
||||
var depth = 0;
|
||||
while((colour == "transparent" || colour == "rgba(0, 0, 0, 0)") && depth <= 4)
|
||||
{
|
||||
element = element.parentNode;
|
||||
colour = getComputedStyle(element).getPropertyValue("background-color");
|
||||
++depth;
|
||||
}
|
||||
var rgb = colour.slice(4, -1).split(", ");
|
||||
var result = Math.sqrt(rgb[0] * rgb[0] * .241 +
|
||||
rgb[1] * rgb[1] * .691 +
|
||||
rgb[2] * rgb[2] * .068);
|
||||
return result;
|
||||
}
|
||||
|
||||
function setSpriteLightness(spriteElement)
|
||||
{
|
||||
if(getBackgroundBrightness(spriteElement) < 127)
|
||||
{
|
||||
spriteElement.classList.add("dark");
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteElement.classList.remove("dark");
|
||||
}
|
||||
}
|
||||
|
||||
function elementIsFocused(Element)
|
||||
{
|
||||
var Result = false;
|
||||
if(Element.classList.contains("focused"))
|
||||
{
|
||||
Result = true;
|
||||
}
|
||||
while(Element.parent)
|
||||
{
|
||||
Element = Element.parent;
|
||||
if(Element.classList.contains("focused"))
|
||||
{
|
||||
Result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function focusSprite(Element)
|
||||
{
|
||||
if(Element.classList.contains("cineraSprite"))
|
||||
{
|
||||
setSpriteLightness(Element);
|
||||
Element.style.backgroundPositionY = Element.getAttribute("data-y-focused") + "px";
|
||||
}
|
||||
for(var i = 0; i < Element.childElementCount; ++i)
|
||||
{
|
||||
focusSprite(Element.children[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function enableSprite(Element)
|
||||
{
|
||||
if(Element.classList.contains("focused"))
|
||||
{
|
||||
focusSprite(Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Element.classList.contains("cineraSprite"))
|
||||
{
|
||||
setSpriteLightness(Element);
|
||||
Element.style.backgroundPositionY = Element.getAttribute("data-y-normal") + "px";
|
||||
}
|
||||
for(var i = 0; i < Element.childElementCount; ++i)
|
||||
{
|
||||
enableSprite(Element.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function disableSprite(Element)
|
||||
{
|
||||
if(Element.classList.contains("focused"))
|
||||
{
|
||||
focusSprite(Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Element.classList.contains("cineraSprite"))
|
||||
{
|
||||
setSpriteLightness(Element);
|
||||
Element.style.backgroundPositionY = Element.getAttribute("data-y-disabled") + "px";
|
||||
}
|
||||
for(var i = 0; i < Element.childElementCount; ++i)
|
||||
{
|
||||
disableSprite(Element.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function unfocusSprite(Element)
|
||||
{
|
||||
if(Element.classList.contains("off"))
|
||||
{
|
||||
disableSprite(Element);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Element.classList.contains("cineraSprite"))
|
||||
{
|
||||
setSpriteLightness(Element);
|
||||
Element.style.backgroundPositionY = Element.getAttribute("data-y-normal") + "px";
|
||||
}
|
||||
for(var i = 0; i < Element.childElementCount; ++i)
|
||||
{
|
||||
unfocusSprite(Element.children[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function IsMobile() {
|
||||
// NOTE(matt): From https://medium.com/simplejs/detect-the-users-device-type-with-a-simple-javascript-check-4fc656b735e1
|
||||
var Identifier = navigator.userAgent||navigator.vendor||window.opera;
|
||||
var Result = (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(Identifier)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(Identifier.substr(0,4)));
|
||||
return Result;
|
||||
};
|
||||
|
||||
function GetRule(SelectorText)
|
||||
{
|
||||
// NOTE(matt): Modifying CSS style
|
||||
// From https://stackoverflow.com/a/566445
|
||||
// https://usefulangle.com/post/39/adding-css-to-stylesheet-with-javascript
|
||||
var Result = undefined;
|
||||
|
||||
var StyleSheets = document.styleSheets;
|
||||
var cssRuleCode = document.all ? 'rules' : 'cssRules'; // account for IE and FF
|
||||
for(var StyleSheetIndex = StyleSheets.length - 1; StyleSheetIndex >= 0; --StyleSheetIndex)
|
||||
{
|
||||
var ThisSheet = StyleSheets[StyleSheetIndex];
|
||||
if(ThisSheet.href !== null && ThisSheet.href.includes(location.hostname))
|
||||
{
|
||||
var Rules = ThisSheet[cssRuleCode];
|
||||
for(var RuleIndex = Rules.length - 1; RuleIndex >= 0; --RuleIndex)
|
||||
{
|
||||
var ThisRule = Rules[RuleIndex];
|
||||
if(SelectorText === ThisRule.selectorText)
|
||||
{
|
||||
Result = ThisRule;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(Result !== undefined) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GetRulesOfStyleSheetIndex(Index)
|
||||
{
|
||||
var Result = undefined;
|
||||
var StyleSheets = document.styleSheets;
|
||||
var cssRuleCode = document.all ? 'rules' : 'cssRules'; // account for IE and FF
|
||||
var StyleSheet = StyleSheets[Index];
|
||||
if(StyleSheet)
|
||||
{
|
||||
Result = StyleSheet[cssRuleCode];
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GetLocalStyleSheet()
|
||||
{
|
||||
var Result;
|
||||
var StyleSheets = document.styleSheets;
|
||||
for(var StyleSheetIndex = StyleSheets.length - 1; StyleSheetIndex >= 0; --StyleSheetIndex)
|
||||
{
|
||||
var This = StyleSheets[StyleSheetIndex];
|
||||
if(This.href !== null && This.href.includes(location.hostname) && !This.disabled)
|
||||
{
|
||||
Result = This;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
GetOrSetRule(SelectorText)
|
||||
{
|
||||
var Result = GetRule(SelectorText);
|
||||
if(Result === undefined)
|
||||
{
|
||||
var StyleSheet = GetLocalStyleSheet();
|
||||
if(StyleSheet)
|
||||
{
|
||||
var cssRuleCode = document.all ? 'rules' : 'cssRules'; // account for IE and FF
|
||||
var Rules = StyleSheet[cssRuleCode];
|
||||
var RuleIndex = StyleSheet.insertRule(SelectorText + "{}", Rules.length - 1);
|
||||
Result = Rules[RuleIndex];
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
function IsInRangeEx(Min, N, Max)
|
||||
{
|
||||
return N > Min && N < Max;
|
||||
}
|
||||
|
||||
/* Auto-scrolling */
|
||||
var ScrollTriggeredInternally = false;
|
||||
var LastScrollYPos = 0;
|
||||
var ScrollTicking = false;
|
||||
var ScrollerFunction;
|
||||
var ScrollCondition;
|
||||
|
||||
function ScrollTo(Element, ScrollPos, IsMobile, StickyObscuringElement) {
|
||||
if(Element.offsetWidth && Element.offsetHeight)
|
||||
{
|
||||
var ScrolledToTop = ScrollPos == 0;
|
||||
var ScrolledToBottom = (window.innerHeight + Math.ceil(window.pageYOffset)) >= document.body.scrollHeight;
|
||||
if(!ScrolledToTop || !ScrolledToBottom)
|
||||
{
|
||||
var Ceiling = StickyObscuringElement ? StickyObscuringElement.offsetHeight : 0;
|
||||
var VisibleArea = GetWindowDim(IsMobile);
|
||||
VisibleArea.Y -= Ceiling;
|
||||
|
||||
var PercentageOfVisibleHeightToGather = 5;
|
||||
var GatherableHeight = VisibleArea.Y * PercentageOfVisibleHeightToGather / 100;
|
||||
|
||||
var BoundingRect = Element.getBoundingClientRect();
|
||||
|
||||
var ElementTop = BoundingRect.top - Ceiling;
|
||||
var ElementBottom = ElementTop + BoundingRect.height;
|
||||
|
||||
var UpperProtrusion = -ElementTop;
|
||||
var LowerProtrusion = ElementBottom - VisibleArea.Y;
|
||||
|
||||
var DesiredScroll = null;
|
||||
var YOffsetFromPage = getElementYOffsetFromPage(Element);
|
||||
if(IsInRangeEx(0, UpperProtrusion, GatherableHeight))
|
||||
{
|
||||
if(!ScrolledToBottom)
|
||||
{
|
||||
DesiredScroll = YOffsetFromPage - Ceiling;
|
||||
}
|
||||
}
|
||||
else if(IsInRangeEx(0, LowerProtrusion, GatherableHeight))
|
||||
{
|
||||
if(!ScrolledToTop)
|
||||
{
|
||||
if(IsInRangeEx(0, UpperProtrusion + LowerProtrusion, GatherableHeight))
|
||||
{
|
||||
DesiredScroll = YOffsetFromPage - Ceiling;
|
||||
}
|
||||
else
|
||||
{
|
||||
DesiredScroll = ScrollPos + LowerProtrusion;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(DesiredScroll !== null && DesiredScroll != ScrollPos)
|
||||
{
|
||||
window.scrollTo({
|
||||
top: DesiredScroll,
|
||||
behavior: "smooth"
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function
|
||||
InitScrollEventListener(Element, IsMobile, StickyObscuringElement)
|
||||
{
|
||||
window.addEventListener('scroll', function() {
|
||||
if(ScrollTriggeredInternally)
|
||||
{
|
||||
ScrollTriggeredInternally = false;
|
||||
}
|
||||
else if(ScrollCondition == undefined || ScrollCondition == true)
|
||||
{
|
||||
LastScrollYPos = window.scrollY;
|
||||
|
||||
if (!ScrollTicking) {
|
||||
window.requestAnimationFrame(function() {
|
||||
clearTimeout(ScrollerFunction);
|
||||
ScrollerFunction = setTimeout(ScrollTo, 2000, Element, LastScrollYPos, IsMobile, StickyObscuringElement);
|
||||
ScrollTicking = false;
|
||||
});
|
||||
|
||||
ScrollTicking = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/* /Auto-scrolling */
|
||||
|
||||
function getElementXOffsetFromPage(el) {
|
||||
var left = 0;
|
||||
do {
|
||||
left += el.offsetLeft;
|
||||
} while (el = el.offsetParent);
|
||||
return left;
|
||||
}
|
||||
|
||||
function getElementYOffsetFromPage(el) {
|
||||
var top = 0;
|
||||
do {
|
||||
top += el.offsetTop;
|
||||
} while (el = el.offsetParent);
|
||||
return top;
|
||||
}
|
||||
|
||||
function
|
||||
MaxWidthOfElement(Element, WindowDim)
|
||||
{
|
||||
// NOTE(matt): This works fine for Elements whose natural max width fills the whole line, i.e. block elements and children
|
||||
// thereof. To support inline elements, we'll need to mirror MaxHeightOfElement() and may as well roll the two
|
||||
// functions into one.
|
||||
var Result = 0;
|
||||
|
||||
var OriginalWidth = Element.style.width;
|
||||
Element.style.width = "100%";
|
||||
var NaturalMax = Element.offsetWidth;
|
||||
Element.style.width = OriginalWidth;
|
||||
|
||||
var InnerWidth = WindowDim ? WindowDim.X : document.documentElement.clientWidth;
|
||||
Result = Math.min(NaturalMax, InnerWidth);
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
MaxHeightOfElement(Element, WindowDim)
|
||||
{
|
||||
var Result = 0;
|
||||
|
||||
var DisplaySettings = [];
|
||||
for(var i = 0; i < Element.children.length; ++i)
|
||||
{
|
||||
var Child = Element.children[i];
|
||||
DisplaySettings.push(Child.style.display);
|
||||
Child.style.display = "none";
|
||||
}
|
||||
|
||||
var OriginalHeight = Element.style.height;
|
||||
Element.style.height = "100%";
|
||||
var NaturalMax = Element.offsetHeight;
|
||||
Element.style.height = OriginalHeight;
|
||||
|
||||
var InnerHeight = WindowDim ? WindowDim.Y : document.documentElement.clientHeight;
|
||||
if(NaturalMax > 0)
|
||||
{
|
||||
Result = Math.min(NaturalMax, InnerHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
Result = InnerHeight;
|
||||
}
|
||||
|
||||
for(var i = 0; i < Element.children.length; ++i)
|
||||
{
|
||||
var Child = Element.children[i];
|
||||
Child.style.display = DisplaySettings.shift();
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
MaxDimensionsOfElement(Element, WindowDim)
|
||||
{
|
||||
var Result = {
|
||||
X: null,
|
||||
Y: null,
|
||||
};
|
||||
Result.X = MaxWidthOfElement(Element, WindowDim);
|
||||
Result.Y = MaxHeightOfElement(Element, WindowDim);
|
||||
return Result;
|
||||
}
|
||||
|
||||
function
|
||||
Clamp(EndA, N, EndB)
|
||||
{
|
||||
var Min = EndA < EndB ? EndA : EndB;
|
||||
var Max = EndA > EndB ? EndA : EndB;
|
||||
return N < Min ? Min : N > Max ? Max : N;
|
||||
}
|
||||
|
||||
function
|
||||
Clamp01(N)
|
||||
{
|
||||
return N < 0 ? 0 : N > 1 ? 1 : N;
|
||||
}
|
||||
|
||||
function
|
||||
Lerp(A, t, B)
|
||||
{
|
||||
return (1-t)*A + t*B;
|
||||
}
|
||||
|
||||
function
|
||||
IsOverflowed(Element)
|
||||
{
|
||||
return Element.scrollHeight > Element.clientHeight || Element.scrollWidth > Element.clientWidth;
|
||||
}
|
||||
|
||||
function
|
||||
SetHelpUnfocused(Button)
|
||||
{
|
||||
Button.firstElementChild.innerText = "¿";
|
||||
Button.firstElementChild.title = "Keypresses will not pass through to Cinera because focus is currently elsewhere.\n\nTo regain focus, please press Tab / Shift-Tab (multiple times) or click somewhere related to Cinera other than the video, e.g. this button";
|
||||
}
|
||||
|
||||
function
|
||||
SetHelpFocused(Button)
|
||||
{
|
||||
Button.firstElementChild.innerText = "?";
|
||||
Button.firstElementChild.title = ""
|
||||
}
|
||||
|
||||
function
|
||||
BindHelp(Button, DocumentationContainer)
|
||||
{
|
||||
window.addEventListener("blur", function(){
|
||||
SetHelpUnfocused(Button);
|
||||
});
|
||||
|
||||
window.addEventListener("focus", function(){
|
||||
SetHelpFocused(Button);
|
||||
});
|
||||
|
||||
Button.addEventListener("click", function() {
|
||||
DocumentationContainer.classList.toggle("visible");
|
||||
})
|
||||
}
|
||||
|
||||
function getBackgroundColourRGB(element) {
|
||||
var Colour = getComputedStyle(element).getPropertyValue("background-color");
|
||||
var depth = 0;
|
||||
while((Colour == "transparent" || Colour == "rgba(0, 0, 0, 0)") && element.parentElement && depth <= 4)
|
||||
{
|
||||
element = element.parentElement;
|
||||
Colour = getComputedStyle(element).getPropertyValue("background-color");
|
||||
++depth;
|
||||
}
|
||||
var Staging = Colour.slice(Colour.indexOf("(") + 1, -1).split(", ");
|
||||
var Result = {
|
||||
R: parseInt(Staging[0]),
|
||||
G: parseInt(Staging[1]),
|
||||
B: parseInt(Staging[2]),
|
||||
};
|
||||
return Result;
|
||||
}
|
||||
|
||||
function getBackgroundBrightness(element) {
|
||||
var Colour = getBackgroundColourRGB(element);
|
||||
var Result = Math.sqrt(Colour.R * Colour.R * .241 +
|
||||
Colour.G * Colour.G * .691 +
|
||||
Colour.B * Colour.B * .068);
|
||||
return Result;
|
||||
}
|
||||
|
||||
function setTextLightness(textElement)
|
||||
{
|
||||
var textHue = textElement.getAttribute("data-hue");
|
||||
var textSaturation = textElement.getAttribute("data-saturation");
|
||||
if(textHue && textSaturation)
|
||||
{
|
||||
if(getBackgroundBrightness(textElement.parentNode) < 127)
|
||||
{
|
||||
textElement.style.color = ("hsl(" + textHue + ", " + textSaturation + ", 76%)");
|
||||
}
|
||||
else
|
||||
{
|
||||
textElement.style.color = ("hsl(" + textHue + ", " + textSaturation + ", 24%)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setDotLightness(topicDot)
|
||||
{
|
||||
var dotHue = topicDot.getAttribute("data-hue");
|
||||
var dotSaturation = topicDot.getAttribute("data-saturation");
|
||||
if(dotHue && dotSaturation)
|
||||
{
|
||||
if(getBackgroundBrightness(topicDot.parentNode) < 127)
|
||||
{
|
||||
topicDot.style.backgroundColor = ("hsl(" + dotHue + ", " + dotSaturation + ", 76%)");
|
||||
topicDot.style.borderColor = ("hsl(" + dotHue + ", " + dotSaturation + ", 76%)");
|
||||
}
|
||||
else
|
||||
{
|
||||
topicDot.style.backgroundColor = ("hsl(" + dotHue + ", " + dotSaturation + ", 47%)");
|
||||
topicDot.style.borderColor = ("hsl(" + dotHue + ", " + dotSaturation + ", 47%)");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
document.body.style.overflowY = "scroll";
|
||||
CineraProps.Orientation = GetRealOrientation(orientations.LANDSCAPE_LEFT, CineraProps.IsMobile);
|
||||
|
||||
// Element Selection
|
||||
//
|
||||
Nav.Nexus = document.getElementById("cineraIndex");
|
||||
Nav.Controls.Header = document.getElementById("cineraIndexControl");
|
||||
Nav.Controls.Sort = Nav.Controls.Header.querySelector(".cineraMenuItem.sort");
|
||||
Nav.Controls.View = Nav.Controls.Header.querySelector(".cineraMenuItem.view");
|
||||
Nav.Controls.Anim = Nav.Controls.Header.querySelector(".cineraMenuItem.anim");
|
||||
Nav.Controls.Save = Nav.Controls.Header.querySelector(".cineraMenuItem.save");
|
||||
Nav.Controls.Help = Nav.Nexus.querySelector(".cineraHelp");
|
||||
Nav.Controls.HelpDocumentation = Nav.Controls.Help.querySelector(".help_container");
|
||||
Nav.GridContainer = Nav.Nexus.querySelector(".cineraIndexGridContainer");
|
||||
Nav.Controls.GridTraversal.Container = Nav.GridContainer.querySelector(".cineraTraversalContainer");
|
||||
Nav.Controls.GridTraversal.Header = Nav.GridContainer.querySelector(".cineraTraversal");
|
||||
Nav.Controls.GridTraversal.Ascend = Nav.Controls.GridTraversal.Header.querySelector(".cineraButton.ascension");
|
||||
Nav.Controls.GridTraversal.Prev = Nav.Controls.GridTraversal.Header.querySelector(".cineraButton.prev");
|
||||
Nav.Controls.GridTraversal.Next = Nav.Controls.GridTraversal.Header.querySelector(".cineraButton.next");
|
||||
|
||||
Search.QueryElement = document.getElementById("query");
|
||||
Search.ResultsSummary = document.getElementById("cineraResultsSummary");
|
||||
Search.ResultsContainer = document.getElementById("cineraResults");
|
||||
Search.IndexContainer = document.getElementById("cineraIndexList");
|
||||
Search.ProjectsContainer = Search.IndexContainer.querySelectorAll(".cineraIndexProject");
|
||||
//
|
||||
///
|
||||
|
||||
// NOTE(matt): Initialisation
|
||||
//
|
||||
if(CineraProps.IsMobile)
|
||||
{
|
||||
Nav.Nexus.classList.add("mobile");
|
||||
}
|
||||
InitTraversalStack();
|
||||
InitNexus();
|
||||
InitHelpKeys(Nav.Controls.HelpDocumentation);
|
||||
Nav.GridSize = ComputeOptimalGridSize();
|
||||
SetHelpKeyAvailability(Nav.GridSize);
|
||||
InitButtons(); // NOTE(matt): Also does "keydown" listeners, needed before UpdateButtons()
|
||||
UpdateButtons();
|
||||
|
||||
InitQuery(Search.QueryElement);
|
||||
InitPrototypes(Search.ResultsContainer);
|
||||
prepareProjects();
|
||||
|
||||
SyncNavState();
|
||||
FlipClear("scroll");
|
||||
//
|
||||
////
|
||||
|
||||
// NOTE(matt): Listeners
|
||||
//
|
||||
BindControlKeys();
|
||||
BindGridKeys(Nav.GridSize);
|
||||
BindControls();
|
||||
InitResizeEventListener();
|
||||
InitOrientationChangeListener();
|
||||
InitScrollEventListener(Nav.GridContainer, CineraProps.IsMobile, Nav.Controls.Header);
|
||||
//
|
||||
////
|
||||
|
||||
// NOTE(matt): On-load Execution
|
||||
//
|
||||
runSearch();
|
||||
//
|
||||
////
|
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 893 B |
After Width: | Height: | Size: 801 B |
|
@ -0,0 +1,12 @@
|
|||
<!-- Index template -->
|
||||
<html>
|
||||
<head>
|
||||
<title><!-- __CINERA_PROJECT__ --> Episode Guide</title>
|
||||
<!-- __CINERA_INCLUDES__ -->
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="background-color: #3399FF; text-align:center; width: 100%; margin: 0 auto"><!-- __CINERA_PROJECT__ --> Episode Guide</h1>
|
||||
<div>This should just be the table of contents, heroes and heroines</div>
|
||||
<!-- __CINERA_INDEX__ -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,19 @@
|
|||
<!-- Player template -->
|
||||
<html>
|
||||
<head>
|
||||
<title><!-- __CINERA_TITLE__ --> - <!-- __CINERA_PROJECT__ --></title>
|
||||
<!-- __CINERA_INCLUDES__ -->
|
||||
</head>
|
||||
<!-- 1. This is a random comment. How does this affect it, if at all? -->
|
||||
<body>
|
||||
<a href="../">Awesome Contents</a>
|
||||
<h1 style="background-color: #3399FF; text-align:center; width: 100%; margin: 0 auto"><!-- __CINERA_TITLE__ --></h1>
|
||||
<div>
|
||||
<!-- __CINERA_MENUS__ -->
|
||||
<!-- __CINERA_PLAYER__ -->
|
||||
</div>
|
||||
<!-- 2. This is a random comment. How does this affect it, if at all? -->
|
||||
<!-- __CINERA_SCRIPT__ -->
|
||||
<!-- 3. This is a random comment. How does this affect it, if at all? -->
|
||||
</body>
|
||||
</html>
|
|
@ -1,425 +0,0 @@
|
|||
/* Structure */
|
||||
|
||||
.title,
|
||||
.title > .menu > .refs .ref,
|
||||
.title > .menu > .credits_container .credit {
|
||||
border-bottom: 1px solid;
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title > *,
|
||||
.title > .menu > .refs .ref,
|
||||
.title > .menu > .credits_container .credit .person {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.title .episode_name {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.title > #focus-warn {
|
||||
color: #F00;
|
||||
flex: 1;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.title > .menu {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.title > .menu .mouse_catcher {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.title > .menu.filter.responsible,
|
||||
.title .filter_content.responsible,
|
||||
.title .filter_content.responsible .text,
|
||||
.title > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-duration: 8s;
|
||||
animation-timing-function: ease-out;
|
||||
animation-iteration-count: 1;
|
||||
}
|
||||
|
||||
.help_key {
|
||||
font-family: Inconsolata;
|
||||
font-size: 16px;
|
||||
border: 1px solid;
|
||||
display: inline-block;
|
||||
background-color: #111; /* Per project */
|
||||
border-radius: 4px;
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
padding: 4px;
|
||||
line-height: 16px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.help_key.unavailable,
|
||||
.help_text.unavailable,
|
||||
.help_container h2 .unavailable {
|
||||
opacity: 0.32;
|
||||
}
|
||||
|
||||
.key_block {
|
||||
display: inline-flex;
|
||||
align-items: flex-end;
|
||||
flex-direction: row;
|
||||
margin: 8px;
|
||||
}
|
||||
|
||||
.help_text {
|
||||
margin: 0 8px 0 2px;
|
||||
}
|
||||
|
||||
|
||||
.help_container h1 {
|
||||
display: inline;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.help_container h1:after {
|
||||
content: "\a";
|
||||
}
|
||||
|
||||
|
||||
.help_container h2 {
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.help_paragraph {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title > .help {
|
||||
cursor: default;
|
||||
border: 1px solid;
|
||||
border-radius: 4px;
|
||||
height: 6px;
|
||||
padding: 4px;
|
||||
width: 6px;
|
||||
margin: 2px;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.help_grid {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.help_container {
|
||||
background-color: black; /* Per project */
|
||||
color: #EEE; /* Per project */
|
||||
display: none;
|
||||
font-weight: normal;
|
||||
line-height: 12px;
|
||||
opacity: 0.9;
|
||||
padding: 8px;
|
||||
position: fixed;
|
||||
right: 612px;
|
||||
top: 42px;
|
||||
}
|
||||
|
||||
.help_container.visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.title > .menu .refs,
|
||||
.title > .menu .filter_container,
|
||||
.title > .menu .credits_container{
|
||||
border: 1px solid;
|
||||
border-top: none;
|
||||
display: none;
|
||||
/* TODO(matt): Set the height to the player's height */
|
||||
max-height: 512px;
|
||||
overflow-y: auto;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.title > .menu .refs,
|
||||
.title > .menu .filter_container {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.title > .menu .credits_container {
|
||||
min-width: 240px;
|
||||
}
|
||||
|
||||
/*.title > .menu:hover .refs,*/
|
||||
.title > .menu.quotes .refs.visible,
|
||||
.title > .menu.references .refs.visible,
|
||||
/*.title > .menu:hover .filter_container,*/
|
||||
.title > .menu.filter .filter_container.visible,
|
||||
.title > .menu.credits .credits_container.visible {
|
||||
/*.title > .menu:hover .credits_container {*/
|
||||
display: block;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title > .menu > .credits_container .credit .person {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.title > .menu > .credits_container .credit .support {
|
||||
flex-grow: 1;
|
||||
text-align: right;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref:last-child,
|
||||
.title > .menu > .credits_container .credit:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .timecode,
|
||||
.title > .menu > .filter_container .filter_mode {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .timecode {
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .timecode:hover {
|
||||
/* TODO(matt): background-image "play" symbol, right aligned */
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .ref_content,
|
||||
.title > .menu > .filter_content {
|
||||
margin-bottom: 8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .source,
|
||||
.title > .menu > .refs .ref .quote_byline,
|
||||
.title > .menu > .filter_container .filter_title,
|
||||
.title > .menu > .credits_container .credit .role {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .source,
|
||||
.title > .menu > .refs .ref .quote_byline,
|
||||
.title > .menu > .credits_container .credit .role {
|
||||
line-height: 8px;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .quote_byline,
|
||||
.title > .menu > .refs .ref .ref_indices {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .quote_byline {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .ref_indices {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .ref_indices .timecode:first-child::before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .ref_indices .timecode::before {
|
||||
content: "•";
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .timecode .ref_index {
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_mode {
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_mode.exclusive:after {
|
||||
content: "exclusive";
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_mode.inclusive:after {
|
||||
content: "inclusive";
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filters {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filters > * {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content .icon {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content.off .icon {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content.rant .icon {
|
||||
color: #F00;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_media .filter_content.off .icon {
|
||||
opacity: 0.32;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content.rant .text,
|
||||
.markers_container > .marker.rant .content,
|
||||
.markers_container > .marker.off_rant .content {
|
||||
font-variant: small-caps;
|
||||
}
|
||||
|
||||
.player_container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.video_container {
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.markers_container {
|
||||
overflow-y: scroll;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.markers_container > .marker {
|
||||
border-bottom: 1px solid;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
max-height: 320px;
|
||||
transition: max-height .32s;
|
||||
}
|
||||
|
||||
.markers_container > .marker.skip {
|
||||
max-height: 0;
|
||||
transition: max-height .32s;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.markers_container > .marker .content {
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
padding: 5px;
|
||||
width: 320px;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.markers_container > .marker.authored .content .author,
|
||||
.markers_container > .marker.off_authored .content .author {
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.title > .menu > .refs .ref .ref_title,
|
||||
.title .filter_content.authored .text,
|
||||
.markers_container > .marker.authored,
|
||||
.markers_container > .marker.off_authored {
|
||||
font-style: oblique;
|
||||
}
|
||||
|
||||
.markers_container > .marker.off_authored,
|
||||
.markers_container > .marker.off_rant {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.markers_container > .marker .content sup {
|
||||
font-style: normal;
|
||||
font-variant: normal;
|
||||
}
|
||||
|
||||
.markers_container > .marker .progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 0px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.markers_container > .marker .timecode {
|
||||
font-size: 9px;
|
||||
font-style: normal;
|
||||
padding-right: 8px;
|
||||
position: relative;
|
||||
top: -2px;
|
||||
}
|
||||
|
||||
.markers_container > .marker .content .categories {
|
||||
display: inline-flex;
|
||||
margin: 4px;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content .category,
|
||||
.markers_container > .marker .content .categories .category {
|
||||
border-radius: 50%;
|
||||
height: 5px;
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content .category.off,
|
||||
.markers_container > .marker .content .categories .category.off {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.markers_container > .marker .content .categories .category {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.title > .menu > .filter_container .filter_content .icon {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* CUSTOM PAGE STYLE */
|
||||
|
||||
body {
|
||||
background-color: #000;
|
||||
font-family: sans-serif;
|
||||
color: white;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Open menu: ▾ ▾
|
||||
Open link in new tab: ⤻ or &10559; or &8599; or ⭷
|
||||
Play from timecode: ⏵ (or, if ↓ ▸)
|
||||
Playable from timecode: ▹
|
||||
*/
|
|
@ -1,80 +0,0 @@
|
|||
.title {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
.title > a {
|
||||
color: rgba(38, 139, 210, 1);
|
||||
}
|
||||
|
||||
.title > a:visited {
|
||||
color: rgba(38, 139, 210, 1);
|
||||
}
|
||||
|
||||
.title .refs_container {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #B57714;
|
||||
}
|
||||
|
||||
.title .refs_container:hover {
|
||||
background-color: #666;
|
||||
}
|
||||
|
||||
.title .refs_container.current {
|
||||
box-shadow: inset 0px 0px 30px #B57714;
|
||||
}
|
||||
|
||||
.title .refs_container .refs {
|
||||
background-color: black;
|
||||
border: 3px solid #444;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.title .refs_container > .refs .ref {
|
||||
border-bottom: 1px solid rgb(51, 51, 51);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.title .refs_container > .refs .ref.current {
|
||||
background-color: #8B3D23;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.title .refs_container > .refs .ref:hover {
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.title .refs_container > .refs .ref.current:hover {
|
||||
background-color: rgba(139, 61, 35, 0.7);
|
||||
}
|
||||
|
||||
.title .refs_container > .refs .ref .source {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.markers_container > .marker {
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.05);
|
||||
}
|
||||
|
||||
.markers_container > .marker:hover > .content {
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.markers_container > .marker:hover .faded .content {
|
||||
background-color: rgba(139, 61, 35, 0.7);
|
||||
color: black;
|
||||
}
|
||||
|
||||
.markers_container > .marker > .content {
|
||||
background-color: #161616;
|
||||
color: #8A877D;
|
||||
}
|
||||
|
||||
.markers_container > .marker.current > .content {
|
||||
color: #B57714;
|
||||
}
|
||||
|
||||
.markers_container > .marker .progress .content {
|
||||
background-color: #8B3D23;
|
||||
color: black;
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
.title.hero,
|
||||
.title.hero .menu .refs,
|
||||
.title.hero .menu > .refs .ref,
|
||||
.markers_container.hero,
|
||||
.markers_container.hero > .marker {
|
||||
background-color: #161616;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.title.hero,
|
||||
.title.hero .menu > .refs .ref,
|
||||
.markers_container.hero > .marker > .content {
|
||||
color: #8A877D;
|
||||
}
|
||||
|
||||
.title.hero .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #B57714;
|
||||
}
|
||||
|
||||
.title.hero .menu:hover,
|
||||
.title.hero .menu > .refs .ref:hover,
|
||||
.markers_container.hero > .marker:hover > .content {
|
||||
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
.title.hero .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #B57714;
|
||||
}
|
||||
|
||||
.title.hero .menu > .refs .ref.current,
|
||||
.markers_container.hero > .marker .progress .content {
|
||||
background-color: #8B3D23;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.hero .menu > .refs .ref .source,
|
||||
.title.hero .menu > .refs .ref .quote_byline {
|
||||
color: #6B3E0B;
|
||||
}
|
||||
|
||||
.title.hero .menu > .refs .ref.current .source,
|
||||
.title.hero .menu > .refs .ref.current .quote_byline {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.title.hero .menu > .refs .ref.current:hover,
|
||||
.markers_container.hero > .marker:hover .faded .content {
|
||||
background-color: rgba(139, 61, 35, 0.7);
|
||||
}
|
||||
|
||||
.title.hero .menu > .refs .ref .timecode:hover {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
/* Regular */
|
||||
.markers_container.hero > .marker.current > .content {
|
||||
color: #B57714;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.markers_container.hero > .marker.blackboard {
|
||||
background: #000;
|
||||
border-color: #161616;
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker.blackboard > .content {
|
||||
color: #D7BA82;
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker:hover.blackboard > .content {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
/* Run */
|
||||
.markers_container.hero > .marker.run > .content,
|
||||
.markers_container.hero > .marker.run > .progress .content,
|
||||
.markers_container.hero > .marker:hover.run > .faded .content {
|
||||
background: hsla(128, 16%, 64%, .2);
|
||||
background-image: linear-gradient(to right, blue 4%, black 4%, black 96%, red 4%),
|
||||
linear-gradient(to bottom, blue 4%, black 4%, black 96%, red 4%),
|
||||
/*#236a58*/
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker.run > .content {
|
||||
color: #D7BA82;
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker:hover.run > .content {
|
||||
background: #111;
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker.run > .progress .content {
|
||||
color: #D7BA82;
|
||||
}
|
||||
|
||||
.markers_container.hero > .marker:hover.run > .faded .content {
|
||||
background: #111;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
.title.hmdshow,
|
||||
.title.hmdshow > .menu .refs,
|
||||
.title.hmdshow > .menu .filter_container,
|
||||
.title.hmdshow > .menu > .refs .ref,
|
||||
.title.hmdshow > .menu > .filter_container .filter_mode,
|
||||
.title.hmdshow > .menu > .credits_container,
|
||||
.title.hmdshow > .menu > .credits_container .credit,
|
||||
.markers_container.hmdshow,
|
||||
.markers_container.hmdshow > .marker {
|
||||
background-color: #EEE;
|
||||
border-color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.hmdshow,
|
||||
.title.hmdshow > .menu > .refs .ref,
|
||||
.title.hmdshow > .menu > .refs .ref .timecode.focused:before,
|
||||
.title.hmdshow > .menu > .credits_container .credit .name,
|
||||
.markers_container.hmdshow > .marker > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #CB957A;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #CB957A;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref .ref_indices .timecode.focused,
|
||||
.markers_container.hmdshow > .marker.current > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref.current .ref_indices .timecode.focused {
|
||||
color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu.visible,
|
||||
|
||||
.title.hmdshow > .menu > .quotes_container .ref.focused,
|
||||
.title.hmdshow > .menu > .references_container .ref.focused,
|
||||
|
||||
.title.hmdshow > .menu > .filter_container .filter_mode:hover,
|
||||
.title.hmdshow > .menu > .filter_container .filter_content.focused,
|
||||
|
||||
.title.hmdshow > .menu > .credits_container .credit *.focused,
|
||||
|
||||
.markers_container.hmdshow > .marker:hover > .content {
|
||||
background-color: #CB957A;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref.current .source,
|
||||
.title.hmdshow > .menu > .refs .ref.current .quote_byline,
|
||||
.title.hmdshow > .menu > .refs .ref.current .ref_indices .timecode.focused:before {
|
||||
color: #C4C4C4;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref.current,
|
||||
.markers_container.hmdshow > .marker > .progress .content {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref.current,
|
||||
.markers_container.hmdshow > .marker > .progress .content {
|
||||
background-color: rgb(203, 149, 122);
|
||||
}
|
||||
|
||||
.markers_container.hmdshow > .marker:hover > .faded .content {
|
||||
background-color: rgba(203, 149, 122, 0.7);
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu > .refs .ref .source,
|
||||
.title.hmdshow > .menu > .refs .ref .quote_byline,
|
||||
.title.hmdshow > .menu > .filter_container .filter_content.off .text,
|
||||
.title.hmdshow > .menu > .credits_container .credit .role {
|
||||
color: #3D3D3D;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.title.hmdshow .filter_content.blackboard,
|
||||
.markers_container.hmdshow .blackboard > .content,
|
||||
.markers_container.hmdshow .off_blackboard > .content,
|
||||
.markers_container.hmdshow > .marker.blackboard > .progress .content,
|
||||
.markers_container.hmdshow > .marker:hover.blackboard > .faded .content {
|
||||
background-size: 12px 12px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.title.hmdshow .filter_content.blackboard,
|
||||
.markers_container.hmdshow .blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.hmdshow .off_blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .08) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .08) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.hmdshow > .marker.blackboard > .progress .content {
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.hmdshow > .marker:hover.blackboard > .faded .content {
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* TODO(matt):
|
||||
*
|
||||
* .markers_container.hmdshow > marker.run
|
||||
*/
|
||||
|
||||
@keyframes hmdshow_fade_mode {
|
||||
0% { color: #FFF; }
|
||||
100% { color: #000; }
|
||||
}
|
||||
|
||||
@keyframes hmdshow_fade_text {
|
||||
0% { color: #000; }
|
||||
100% { color: #888; }
|
||||
}
|
||||
|
||||
@keyframes hmdshow_fade_background {
|
||||
0% { background-color: rgba(246, 178, 26, 0.8);}
|
||||
100% { background-color: #EEE; }
|
||||
}
|
||||
|
||||
/* TODO(matt): Get this to work! */
|
||||
.title.hmdshow > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: hmdshow_fade_mode;
|
||||
}
|
||||
|
||||
.title.hmdshow .filter_content.responsible .text {
|
||||
animation-name: hmdshow_fade_text;
|
||||
}
|
||||
|
||||
.title.hmdshow > .menu.filter.responsible,
|
||||
.title.hmdshow .filter_content.responsible,
|
||||
.title.hmdshow > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: hmdshow_fade_background;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
.title.lecture,
|
||||
.title.lecture > .menu .refs,
|
||||
.title.lecture > .menu .filter_container,
|
||||
.title.lecture > .menu > .refs .ref,
|
||||
.title.lecture > .menu > .filter_container .filter_mode,
|
||||
.title.lecture > .menu > .credits_container,
|
||||
.title.lecture > .menu > .credits_container .credit,
|
||||
.markers_container.lecture,
|
||||
.markers_container.lecture > .marker {
|
||||
background-color: #EEE;
|
||||
border-color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.lecture,
|
||||
.title.lecture > .menu > .refs .ref,
|
||||
.title.lecture > .menu > .refs .ref .timecode.focused:before,
|
||||
.title.lecture > .menu > .credits_container .credit .name,
|
||||
.markers_container.lecture > .marker > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.lecture > .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #CB957A;
|
||||
}
|
||||
|
||||
.title.lecture > .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #CB957A;
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref .ref_indices .timecode.focused,
|
||||
.markers_container.lecture > .marker.current > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref.current .ref_indices .timecode.focused {
|
||||
color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.lecture > .menu.visible,
|
||||
|
||||
.title.lecture > .menu > .quotes_container .ref.focused,
|
||||
.title.lecture > .menu > .references_container .ref.focused,
|
||||
|
||||
.title.lecture > .menu > .filter_container .filter_mode:hover,
|
||||
.title.lecture > .menu > .filter_container .filter_content.focused,
|
||||
|
||||
.title.lecture > .menu > .credits_container .credit *.focused,
|
||||
|
||||
.markers_container.lecture > .marker:hover > .content {
|
||||
background-color: #CB957A;
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref.current .source,
|
||||
.title.lecture > .menu > .refs .ref.current .quote_byline,
|
||||
.title.lecture > .menu > .refs .ref.current .ref_indices .timecode.focused:before {
|
||||
color: #C4C4C4;
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref.current,
|
||||
.markers_container.lecture > .marker > .progress .content {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref.current,
|
||||
.markers_container.lecture > .marker > .progress .content {
|
||||
background-color: rgb(203, 149, 122);
|
||||
}
|
||||
|
||||
.markers_container.lecture > .marker:hover > .faded .content {
|
||||
background-color: rgba(203, 149, 122, 0.7);
|
||||
}
|
||||
|
||||
.title.lecture > .menu > .refs .ref .source,
|
||||
.title.lecture > .menu > .refs .ref .quote_byline,
|
||||
.title.lecture > .menu > .filter_container .filter_content.off .text,
|
||||
.title.lecture > .menu > .credits_container .credit .role {
|
||||
color: #3D3D3D;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.title.lecture .filter_content.blackboard,
|
||||
.markers_container.lecture .blackboard > .content,
|
||||
.markers_container.lecture .off_blackboard > .content,
|
||||
.markers_container.lecture > .marker.blackboard > .progress .content,
|
||||
.markers_container.lecture > .marker:hover.blackboard > .faded .content {
|
||||
background-size: 12px 12px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.title.lecture .filter_content.blackboard,
|
||||
.markers_container.lecture .blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.lecture .off_blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .08) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .08) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.lecture > .marker.blackboard > .progress .content {
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.lecture > .marker:hover.blackboard > .faded .content {
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* TODO(matt):
|
||||
*
|
||||
* .markers_container.lecture > marker.run
|
||||
*/
|
||||
|
||||
@keyframes lecture_fade_mode {
|
||||
0% { color: #FFF; }
|
||||
100% { color: #000; }
|
||||
}
|
||||
|
||||
@keyframes lecture_fade_text {
|
||||
0% { color: #000; }
|
||||
100% { color: #888; }
|
||||
}
|
||||
|
||||
@keyframes lecture_fade_background {
|
||||
0% { background-color: rgba(246, 178, 26, 0.8);}
|
||||
100% { background-color: #EEE; }
|
||||
}
|
||||
|
||||
/* TODO(matt): Get this to work! */
|
||||
.title.lecture > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: lecture_fade_mode;
|
||||
}
|
||||
|
||||
.title.lecture .filter_content.responsible .text {
|
||||
animation-name: lecture_fade_text;
|
||||
}
|
||||
|
||||
.title.lecture > .menu.filter.responsible,
|
||||
.title.lecture .filter_content.responsible,
|
||||
.title.lecture > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: lecture_fade_background;
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
* Colours:
|
||||
* Main Purple: #372F46 or rgba(55, 47, 70, 1);
|
||||
* Highlight Green: #3A4A3F or rbga(58, 74, 63, 1);
|
||||
*/
|
||||
|
||||
.title.obbg {
|
||||
background-color: #EEE;
|
||||
color: #000;
|
||||
border-color: #372F46;
|
||||
}
|
||||
|
||||
.title.obbg .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #372F46;
|
||||
}
|
||||
|
||||
.title.obbg .menu:hover {
|
||||
background-color: #FFF8E7;
|
||||
}
|
||||
|
||||
.title.obbg > .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #372F46;
|
||||
}
|
||||
|
||||
.title.obbg .menu .refs {
|
||||
background-color: #EEE;
|
||||
border-color: #372F46;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref {
|
||||
border-color: #372F46;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref.current {
|
||||
background-color: #372F46;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref:hover {
|
||||
background-color: #DDD;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref.current:hover {
|
||||
background-color: #68557E;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref .source {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref .quote_byline {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.title.obbg .menu > .refs .ref.current .source {
|
||||
color: #FFF8E7;
|
||||
}
|
||||
|
||||
/* Regular */
|
||||
.markers_container.obbg {
|
||||
background-color: #EEE;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker {
|
||||
border-color: #888;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker:hover > .content {
|
||||
background-color: #DDD;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker:hover > .faded .content {
|
||||
background-color: #68557E;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker > .content {
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.current > .content {
|
||||
color: #102369;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker > .progress .content {
|
||||
background-color: #372C44;
|
||||
color: #EEE;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.markers_container.obbg > .marker:hover.blackboard > .content {
|
||||
background-color: #FFF8E7;
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker:hover.blackboard > .faded .content {
|
||||
background-color: rgba(42, 49, 114, 0.7);
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.blackboard > .content {
|
||||
background-color: #FFFFFF;
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.blackboard.current > .content {
|
||||
color: #2A3172;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.blackboard > .progress .content {
|
||||
background-color: #2A3172;
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
/* TODO(matt):
|
||||
*
|
||||
* .markers_container.obbg > marker.run
|
||||
*/
|
||||
|
||||
/* Run */
|
||||
.markers_container.obbg > .marker.run > .content {
|
||||
background: rgb(114,171,206); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(114,171,206,.5) 0%, rgba(82,178,82,.5) 18%, rgba(82,178,82,.5) 22%, rgba(198,194,110,.5) 38%, rgba(198,194,110,.5) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(top, rgba(114,171,206,.5) 0%,rgba(82,178,82,.5) 18%,rgba(82,178,82,.5) 22%,rgba(198,194,110,.5) 38%,rgba(198,194,110,.5) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to bottom, rgba(114,171,206,.5) 0%,rgba(82,178,82,.5) 18%,rgba(82,178,82,.5) 22%,rgba(198,194,110,.5) 38%,rgba(198,194,110,.5) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72abce', endColorstr='#c6c26e',GradientType=0 ); /* IE6-9 */
|
||||
color: #000000;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker:hover.run > .content {
|
||||
background: rgb(114,171,206); /* Old browsers */
|
||||
background: -moz-linear-gradient(top, rgba(114,171,206,.5) 0%, rgba(82,178,82,.5) 18%, rgba(82,178,82,.5) 22%, rgba(198,194,110,.5) 38%, rgba(198,194,110,.5) 100%); /* FF3.6-15 */
|
||||
background: -webkit-linear-gradient(top, rgba(114,171,206,.5) 0%,rgba(82,178,82,.5) 18%,rgba(82,178,82,.5) 22%,rgba(198,194,110,.5) 38%,rgba(198,194,110,.5) 100%); /* Chrome10-25,Safari5.1-6 */
|
||||
background: linear-gradient(to bottom, rgba(114,171,206,.6) 0%,rgba(82,178,82,.6) 18%,rgba(82,178,82,.6) 22%,rgba(198,194,110,.6) 38%,rgba(198,194,110,.6) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72abce', endColorstr='#c6c26e',GradientType=0 ); /* IE6-9 */
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker:hover.run > .faded .content {
|
||||
background-color: rgba(42, 49, 114, 0.7);
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.run.current > .content {
|
||||
color: #2A3172;
|
||||
}
|
||||
|
||||
.markers_container.obbg > .marker.run > .progress .content {
|
||||
background-color: #2A3172;
|
||||
background-size: 12px 12px;
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
background-position: center;
|
||||
color: #FFFFFF;
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
.title.riscy,
|
||||
.title.riscy > .menu .refs,
|
||||
.title.riscy > .menu .filter_container,
|
||||
.title.riscy > .menu > .refs .ref,
|
||||
.title.riscy > .menu > .filter_container .filter_mode,
|
||||
.title.riscy > .menu > .credits_container,
|
||||
.title.riscy > .menu > .credits_container .credit,
|
||||
.markers_container.riscy,
|
||||
.markers_container.riscy > .marker {
|
||||
background-color: #EEE;
|
||||
border-color: rgba(246, 178, 26, 0.8);
|
||||
}
|
||||
|
||||
.title.riscy,
|
||||
.title.riscy > .menu > .refs .ref,
|
||||
/*.title.riscy > .menu > .refs .ref .timecode:hover:before,*/
|
||||
.title.riscy > .menu > .refs .ref .timecode.focused:before,
|
||||
.title.riscy > .menu > .credits_container .credit .name,
|
||||
.markers_container.riscy > .marker > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.riscy > .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #2A3172;
|
||||
}
|
||||
|
||||
.title.riscy > .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #2A3172;
|
||||
}
|
||||
|
||||
/*.title.riscy > .menu > .refs .ref .ref_indices .timecode:hover,*/
|
||||
.title.riscy > .menu > .refs .ref .ref_indices .timecode.focused,
|
||||
.markers_container.riscy > .marker.current > .content {
|
||||
color: #2A3172;
|
||||
}
|
||||
|
||||
.title.riscy > .menu > .refs .ref.current .ref_indices .timecode.focused {
|
||||
color: rgb(246, 178, 26);
|
||||
}
|
||||
|
||||
/*.title.riscy > .menu:hover,*/
|
||||
.title.riscy > .menu.visible,
|
||||
|
||||
/*.title.riscy > .menu > .refs .ref:hover,*/
|
||||
.title.riscy > .menu > .quotes_container .ref.focused,
|
||||
.title.riscy > .menu > .references_container .ref.focused,
|
||||
|
||||
.title.riscy > .menu > .filter_container .filter_mode:hover,
|
||||
/*.title.riscy > .menu > .filter_container .filter_content:hover,*/
|
||||
.title.riscy > .menu > .filter_container .filter_content.focused,
|
||||
|
||||
/*.title.riscy > .menu > .credits_container .credit *:hover,*/
|
||||
.title.riscy > .menu > .credits_container .credit *.focused,
|
||||
|
||||
.markers_container.riscy > .marker:hover > .content {
|
||||
background-color: #FFF8E7;
|
||||
}
|
||||
|
||||
.title.riscy > .menu > .refs .ref.current .source,
|
||||
.title.riscy > .menu > .refs .ref.current .quote_byline,
|
||||
.title.riscy > .menu > .refs .ref.current .ref_indices .timecode.focused:before {
|
||||
color: #FFF8E7;
|
||||
}
|
||||
|
||||
.title.riscy > .menu > .refs .ref.current,
|
||||
/*.title.riscy > .menu > .refs .ref.current .timecode:hover:before,*/
|
||||
.markers_container.riscy > .marker > .progress .content {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.title.riscy > .menu > .refs .ref.current,
|
||||
.markers_container.riscy > .marker > .progress .content {
|
||||
background-color: rgb(42, 49, 114);
|
||||
}
|
||||
|
||||
/*.title.riscy > .menu > .refs .ref.current:hover,*/
|
||||
.markers_container.riscy > .marker:hover > .faded .content {
|
||||
background-color: rgba(42, 49, 114, 0.7);
|
||||
}
|
||||
|
||||
.title.riscy > .menu > .refs .ref .source,
|
||||
.title.riscy > .menu > .refs .ref .quote_byline,
|
||||
.title.riscy > .menu > .filter_container .filter_content.off .text,
|
||||
.title.riscy > .menu > .credits_container .credit .role {
|
||||
color: #888;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.title.riscy .filter_content.blackboard,
|
||||
.markers_container.riscy .blackboard > .content,
|
||||
.markers_container.riscy .off_blackboard > .content,
|
||||
.markers_container.riscy > .marker.blackboard > .progress .content,
|
||||
.markers_container.riscy > .marker:hover.blackboard > .faded .content {
|
||||
background-size: 12px 12px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.title.riscy .filter_content.blackboard,
|
||||
.markers_container.riscy .blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.riscy .off_blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .08) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .08) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.riscy > .marker.blackboard > .progress .content {
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.riscy > .marker:hover.blackboard > .faded .content {
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* TODO(matt):
|
||||
*
|
||||
* .markers_container.riscy > marker.run
|
||||
*/
|
||||
|
||||
@keyframes riscy_fade_mode {
|
||||
0% { color: #FFF; }
|
||||
100% { color: #000; }
|
||||
}
|
||||
|
||||
@keyframes riscy_fade_text {
|
||||
0% { color: #000; }
|
||||
100% { color: #888; }
|
||||
}
|
||||
|
||||
@keyframes riscy_fade_background {
|
||||
0% { background-color: rgba(246, 178, 26, 0.8);}
|
||||
100% { background-color: #EEE; }
|
||||
}
|
||||
|
||||
/* TODO(matt): Get this to work! */
|
||||
.title.riscy > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: riscy_fade_mode;
|
||||
}
|
||||
|
||||
.title.riscy .filter_content.responsible .text {
|
||||
animation-name: riscy_fade_text;
|
||||
}
|
||||
|
||||
.title.riscy > .menu.filter.responsible,
|
||||
.title.riscy .filter_content.responsible,
|
||||
.title.riscy > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: riscy_fade_background;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
.title.special,
|
||||
.title.special > .menu .refs,
|
||||
.title.special > .menu .filter_container,
|
||||
.title.special > .menu > .refs .ref,
|
||||
.title.special > .menu > .filter_container .filter_mode,
|
||||
.title.special > .menu > .credits_container,
|
||||
.title.special > .menu > .credits_container .credit,
|
||||
.markers_container.special,
|
||||
.markers_container.special > .marker {
|
||||
background-color: #EEE;
|
||||
border-color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.special,
|
||||
.title.special > .menu > .refs .ref,
|
||||
.title.special > .menu > .refs .ref .timecode.focused:before,
|
||||
.title.special > .menu > .credits_container .credit .name,
|
||||
.markers_container.special > .marker > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.special > .menu {
|
||||
transition: box-shadow 800ms cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
box-shadow: inset 0 0 0 #CB957A;
|
||||
}
|
||||
|
||||
.title.special > .menu.current {
|
||||
box-shadow: inset 0px 0px 30px #CB957A;
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref .ref_indices .timecode.focused,
|
||||
.markers_container.special > .marker.current > .content {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref.current .ref_indices .timecode.focused {
|
||||
color: rgba(120, 4, 4, 0.8);
|
||||
}
|
||||
|
||||
.title.special > .menu.visible,
|
||||
|
||||
.title.special > .menu > .quotes_container .ref.focused,
|
||||
.title.special > .menu > .references_container .ref.focused,
|
||||
|
||||
.title.special > .menu > .filter_container .filter_mode:hover,
|
||||
.title.special > .menu > .filter_container .filter_content.focused,
|
||||
|
||||
.title.special > .menu > .credits_container .credit *.focused,
|
||||
|
||||
.markers_container.special > .marker:hover > .content {
|
||||
background-color: #CB957A;
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref.current .source,
|
||||
.title.special > .menu > .refs .ref.current .quote_byline,
|
||||
.title.special > .menu > .refs .ref.current .ref_indices .timecode.focused:before {
|
||||
color: #C4C4C4;
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref.current,
|
||||
.markers_container.special > .marker > .progress .content {
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref.current,
|
||||
.markers_container.special > .marker > .progress .content {
|
||||
background-color: rgb(203, 149, 122);
|
||||
}
|
||||
|
||||
.markers_container.special > .marker:hover > .faded .content {
|
||||
background-color: rgba(203, 149, 122, 0.7);
|
||||
}
|
||||
|
||||
.title.special > .menu > .refs .ref .source,
|
||||
.title.special > .menu > .refs .ref .quote_byline,
|
||||
.title.special > .menu > .filter_container .filter_content.off .text,
|
||||
.title.special > .menu > .credits_container .credit .role {
|
||||
color: #3D3D3D;
|
||||
}
|
||||
|
||||
/* Blackboard */
|
||||
.title.special .filter_content.blackboard,
|
||||
.markers_container.special .blackboard > .content,
|
||||
.markers_container.special .off_blackboard > .content,
|
||||
.markers_container.special > .marker.blackboard > .progress .content,
|
||||
.markers_container.special > .marker:hover.blackboard > .faded .content {
|
||||
background-size: 12px 12px;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.title.special .filter_content.blackboard,
|
||||
.markers_container.special .blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.special .off_blackboard > .content {
|
||||
background-image: linear-gradient(to right , rgba(51, 153, 255, .08) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(51, 153, 255, .08) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.special > .marker.blackboard > .progress .content {
|
||||
background-image: linear-gradient(to right , rgba(255, 255, 255, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(255, 255, 255, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
.markers_container.special > .marker:hover.blackboard > .faded .content {
|
||||
background-image: linear-gradient(to right , rgba(0, 0, 0, .16) 1px, transparent 1px),
|
||||
linear-gradient(to bottom, rgba(0, 0, 0, .16) 1px, transparent 1px);
|
||||
}
|
||||
|
||||
/* TODO(matt):
|
||||
*
|
||||
* .markers_container.special > marker.run
|
||||
*/
|
||||
|
||||
@keyframes special_fade_mode {
|
||||
0% { color: #FFF; }
|
||||
100% { color: #000; }
|
||||
}
|
||||
|
||||
@keyframes special_fade_text {
|
||||
0% { color: #000; }
|
||||
100% { color: #888; }
|
||||
}
|
||||
|
||||
@keyframes special_fade_background {
|
||||
0% { background-color: rgba(246, 178, 26, 0.8);}
|
||||
100% { background-color: #EEE; }
|
||||
}
|
||||
|
||||
/* TODO(matt): Get this to work! */
|
||||
.title.special > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: special_fade_mode;
|
||||
}
|
||||
|
||||
.title.special .filter_content.responsible .text {
|
||||
animation-name: special_fade_text;
|
||||
}
|
||||
|
||||
.title.special > .menu.filter.responsible,
|
||||
.title.special .filter_content.responsible,
|
||||
.title.special > .menu > .filter_container .filter_mode.responsible {
|
||||
animation-name: special_fade_background;
|
||||
}
|
Before Width: | Height: | Size: 987 B |
|
@ -1,60 +0,0 @@
|
|||
.category.platform-layer { border: 1px solid hsl(160, 81%, 26%); background: hsl(160, 81%, 26%); }
|
||||
.category.font { border: 1px solid hsl(13, 87%, 26%); background: hsl(13, 87%, 26%); }
|
||||
.category.input-handling { border: 1px solid hsl(335, 94%, 26%); background: hsl(335, 94%, 26%); }
|
||||
.category.inventory { border: 1px solid hsl(111, 79%, 26%); background: hsl(111, 79%, 26%); }
|
||||
.category.hardware { border: 1px solid hsl(284, 94%, 26%); background: hsl(284, 94%, 26%); }
|
||||
.category.math { border: 1px solid hsl(185, 74%, 26%); background: hsl(185, 74%, 26%); }
|
||||
.category.demo { border: 1px solid hsl(113, 95%, 26%); background: hsl(113, 95%, 26%); }
|
||||
.category.memory { border: 1px solid hsl(111, 89%, 26%); background: hsl(111, 89%, 26%); }
|
||||
.category.mesh-building { border: 1px solid hsl(334, 99%, 26%); background: hsl(334, 99%, 26%); }
|
||||
.category.rendering { border: 1px solid hsl(140, 79%, 26%); background: hsl(140, 79%, 26%); }
|
||||
.category.procedural-generation { border: 1px solid hsl(186, 87%, 26%); background: hsl(186, 87%, 26%); }
|
||||
.category.asset-loading { border: 1px solid hsl(18, 76%, 26%); background: hsl(18, 76%, 26%); }
|
||||
.category.game-development { border: 1px solid hsl(58, 96%, 26%); background: hsl(58, 96%, 26%); }
|
||||
.category.level-of-detail { border: 1px solid hsl(211, 97%, 26%); background: hsl(211, 97%, 26%); }
|
||||
.category.lighting { border: 1px solid hsl(40, 76%, 26%); background: hsl(40, 76%, 26%); }
|
||||
.category.game { border: 1px solid hsl(315, 84%, 26%); background: hsl(315, 84%, 26%); }
|
||||
.category.optimisation { border: 1px solid hsl(327, 86%, 26%); background: hsl(327, 86%, 26%); }
|
||||
.category.threading { border: 1px solid hsl(25, 97%, 26%); background: hsl(25, 97%, 26%); }
|
||||
.category.maths { border: 1px solid hsl(84, 88%, 26%); background: hsl(84, 88%, 26%); }
|
||||
.category.camera { border: 1px solid hsl(141, 89%, 26%); background: hsl(141, 89%, 26%); }
|
||||
.category.collision { border: 1px solid hsl(342, 93%, 26%); background: hsl(342, 93%, 26%); }
|
||||
.category.physics { border: 1px solid hsl(242, 94%, 26%); background: hsl(242, 94%, 26%); }
|
||||
.category.movement { border: 1px solid hsl(341, 97%, 26%); background: hsl(341, 97%, 26%); }
|
||||
.category.debug-visualisation { border: 1px solid hsl(60, 86%, 26%); background: hsl(60, 86%, 26%); }
|
||||
.category.programming { border: 1px solid hsl(283, 84%, 26%); background: hsl(283, 84%, 26%); }
|
||||
.category.networking { border: 1px solid hsl(10, 94%, 26%); background: hsl(10, 94%, 26%); }
|
||||
.category.network { border: 1px solid hsl(342, 75%, 26%); background: hsl(342, 75%, 26%); }
|
||||
.category.object-system { border: 1px solid hsl(87, 80%, 26%); background: hsl(87, 80%, 26%); }
|
||||
.category.language { border: 1px solid hsl(142, 84%, 26%); background: hsl(142, 84%, 26%); }
|
||||
.category.asm { border: 1px solid hsl(71, 92%, 26%); background: hsl(71, 92%, 26%); }
|
||||
.category.game-design { border: 1px solid hsl(162, 92%, 26%); background: hsl(162, 92%, 26%); }
|
||||
.category.art { border: 1px solid hsl(157, 76%, 26%); background: hsl(157, 76%, 26%); }
|
||||
.category.entity-system { border: 1px solid hsl(275, 92%, 26%); background: hsl(275, 92%, 26%); }
|
||||
.category.animation { border: 1px solid hsl(170, 81%, 26%); background: hsl(170, 81%, 26%); }
|
||||
.category.sorting { border: 1px solid hsl(285, 97%, 26%); background: hsl(285, 97%, 26%); }
|
||||
.category.particle-system { border: 1px solid hsl(116, 99%, 26%); background: hsl(116, 99%, 26%); }
|
||||
.category.simulation { border: 1px solid hsl(328, 91%, 26%); background: hsl(328, 91%, 26%); }
|
||||
.category.save---load { border: 1px solid hsl(120, 93%, 26%); background: hsl(120, 93%, 26%); }
|
||||
.category.logistics { border: 1px solid hsl(54, 76%, 26%); background: hsl(54, 76%, 26%); }
|
||||
.category.parsing { border: 1px solid hsl(27, 79%, 26%); background: hsl(27, 79%, 26%); }
|
||||
.category.profiling { border: 1px solid hsl(314, 91%, 26%); background: hsl(314, 91%, 26%); }
|
||||
.category.prng { border: 1px solid hsl(13, 87%, 26%); background: hsl(13, 87%, 26%); }
|
||||
.category.ui { border: 1px solid hsl(43, 94%, 26%); background: hsl(43, 94%, 26%); }
|
||||
.category.audio { border: 1px solid hsl(287, 77%, 26%); background: hsl(287, 77%, 26%); }
|
||||
.category.pathfinding { border: 1px solid hsl(314, 87%, 26%); background: hsl(314, 87%, 26%); }
|
||||
.category.simd { border: 1px solid hsl(229, 77%, 26%); background: hsl(229, 77%, 26%); }
|
||||
.category.mesh-chunk { border: 1px solid hsl(75, 89%, 26%); background: hsl(75, 89%, 26%); }
|
||||
.category.ai { border: 1px solid hsl(115, 74%, 26%); background: hsl(115, 74%, 26%); }
|
||||
.category.driver { border: 1px solid hsl(285, 76%, 26%); background: hsl(285, 76%, 26%); }
|
||||
.category.fabrication { border: 1px solid hsl(169, 77%, 26%); background: hsl(169, 77%, 26%); }
|
||||
.category.peripheral { border: 1px solid hsl(327, 92%, 26%); background: hsl(327, 92%, 26%); }
|
||||
.category.biology { border: 1px solid hsl(40, 80%, 26%); background: hsl(40, 80%, 26%); }
|
||||
.category.mathematics { border: 1px solid hsl(9, 91%, 26%); background: hsl(9, 91%, 26%); }
|
||||
.category.platform { border: 1px solid hsl(256, 91%, 26%); background: hsl(256, 91%, 26%); }
|
||||
.category.string-manipulation { border: 1px solid hsl(16, 82%, 26%); background: hsl(16, 82%, 26%); }
|
||||
.category.timing { border: 1px solid hsl(228, 94%, 26%); background: hsl(228, 94%, 26%); }
|
||||
.category.performance { border: 1px solid hsl(38, 93%, 26%); background: hsl(38, 93%, 26%); }
|
||||
.category.number-systems { border: 1px solid hsl(246, 86%, 26%); background: hsl(246, 86%, 26%); }
|
||||
.category.formula { border: 1px solid hsl(55, 81%, 26%); background: hsl(55, 81%, 26%); }
|
||||
.category.linear-algebra { border: 1px solid hsl(60, 76%, 26%); background: hsl(60, 76%, 26%); }
|
|
@ -1,85 +0,0 @@
|
|||
edition Project;
|
||||
|
||||
paths
|
||||
{
|
||||
# In HMN, root would be the directory that serves up https://hero.handmade.network/episodes where the searcher will reside
|
||||
root "/usr/local/www/test";
|
||||
# All *.hmml files below the repo_remote location are to be pulled in to the system with the directories being compared with
|
||||
# the member and project settings from the [video] node
|
||||
repo_remote "https://git.handmade.network/Annotation-Pushers/Annotation-Game";
|
||||
repo_local "/usr/local/www/repo";
|
||||
# The automatic stub creator will use the stub_base as its base directory
|
||||
stub_base "${repo_local}/projects";
|
||||
|
||||
quotes_remote "";
|
||||
quotes_local "";
|
||||
}
|
||||
|
||||
authentication
|
||||
{
|
||||
# NOTE(matt): Do we need any more auth stuff? Surely we will
|
||||
repo_token "";
|
||||
quotes_token "";
|
||||
}
|
||||
|
||||
project_info
|
||||
{
|
||||
riscy # Note that settings that open blocks do not end in a ; thus distinguishing them from variables set at the same scope
|
||||
{
|
||||
# We need to set member and platform in the config file so the stub generator can do its thing. Maybe consider further,
|
||||
# though, whether the [video] node in our .hmml files still needs to take them
|
||||
member = "miotatsu";
|
||||
platform = "youtube";
|
||||
|
||||
feed = "https://www.youtube.com/feeds/videos.xml?user=BathtubBlogger";
|
||||
project_name "RISCY BUSINESS";
|
||||
project_unit "Day";
|
||||
title_pattern "${project_name} - ${project_unit} ${number} - ${title}";
|
||||
# TODO(matt): Work out this title_pattern with some actual stuff
|
||||
}
|
||||
}
|
||||
|
||||
# Comment to end of line
|
||||
credentials
|
||||
{
|
||||
funding_platform patreon; # This determines the logo and URL-generation, and we'll need to specify the platforms we support.
|
||||
# A more flexible, if verbose, alternative would be to make each config specify a funding_icon and
|
||||
# the full funding_url
|
||||
#
|
||||
# Note that this setting cascades down to the child scopes, i.e. Miblo{}, miotatsu{}, etc
|
||||
|
||||
Miblo # The single-word name we use in the .hmml files, which also matches the username of project owners
|
||||
{
|
||||
display_name "Matt Mascarenhas"; # Optional, and may optionally be surrounded by quotes
|
||||
homepage "http://miblodelcarpio.co.uk/"; # May optionally be quoted, as the admin prefers, but must be quoted if
|
||||
# containing a ; (which is a valid character according to:
|
||||
# https://url.spec.whatwg.org/#userinfo-percent-encode-set)
|
||||
#
|
||||
# For a Network Edition instance, it may be nice, although not mandatory, if
|
||||
# the homepage is set to the member's profile page in the Network
|
||||
avatar "some_location.png"; # TODO(matt): Mock up the Credits Menu to determine whether or not we want this
|
||||
funding_username miblo;
|
||||
}
|
||||
|
||||
miotatsu
|
||||
{
|
||||
display_name "Mio Iwakura";
|
||||
homepage "http://riscy.tv/";
|
||||
funding_username miotatsu;
|
||||
}
|
||||
|
||||
_yunsup_lee # Prefixing with _ could be the convention for guests who are not in the member base of the (associated) network
|
||||
# If so, maybe throw a warning for the annotator when a _-prefixed member is not present in the config
|
||||
{
|
||||
display_name "Yunsup Lee";
|
||||
homepage "https://www.linkedin.com/in/yunsup-lee-385b692b";
|
||||
}
|
||||
|
||||
_andrew_waterman
|
||||
{
|
||||
display_name "Andrew Waterman";
|
||||
homepage "https://www.linkedin.com/in/andrew-waterman-76805788";
|
||||
}
|
||||
}
|
||||
|
||||
# NOTE(matt): Semantic characters, which may require \-escaping: ; # { " $
|
|
@ -1,98 +0,0 @@
|
|||
#ifndef HMML_H_
|
||||
#define HMML_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Data structures
|
||||
|
||||
typedef struct {
|
||||
char* member;
|
||||
char* stream_platform;
|
||||
char* stream_username;
|
||||
char* project;
|
||||
char* title;
|
||||
char* vod_platform;
|
||||
char* id;
|
||||
|
||||
char** co_hosts;
|
||||
size_t co_host_count;
|
||||
|
||||
char** guests;
|
||||
size_t guest_count;
|
||||
|
||||
char** annotators;
|
||||
size_t annotator_count;
|
||||
} HMML_VideoMetaData;
|
||||
|
||||
typedef struct {
|
||||
char* site;
|
||||
char* page;
|
||||
char* url;
|
||||
char* title;
|
||||
char* article;
|
||||
char* author;
|
||||
char* editor;
|
||||
char* publisher;
|
||||
char* isbn;
|
||||
int offset;
|
||||
} HMML_Reference;
|
||||
|
||||
typedef enum {
|
||||
HMML_CATEGORY,
|
||||
HMML_MEMBER,
|
||||
HMML_PROJECT,
|
||||
|
||||
HMML_MARKER_COUNT,
|
||||
} HMML_MarkerType;
|
||||
|
||||
typedef struct {
|
||||
HMML_MarkerType type;
|
||||
char* marker;
|
||||
char* parameter;
|
||||
char* episode;
|
||||
int offset;
|
||||
} HMML_Marker;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
char* author;
|
||||
} HMML_Quote;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
char* time;
|
||||
char* text;
|
||||
char* author;
|
||||
|
||||
HMML_Reference* references;
|
||||
size_t reference_count;
|
||||
|
||||
HMML_Marker* markers;
|
||||
size_t marker_count;
|
||||
|
||||
HMML_Quote quote;
|
||||
bool is_quote;
|
||||
} HMML_Annotation;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
char* message;
|
||||
} HMML_Error;
|
||||
|
||||
typedef struct {
|
||||
bool well_formed;
|
||||
HMML_VideoMetaData metadata;
|
||||
HMML_Annotation* annotations;
|
||||
size_t annotation_count;
|
||||
HMML_Error error;
|
||||
} HMML_Output;
|
||||
|
||||
// Functions
|
||||
|
||||
HMML_Output hmml_parse_file (FILE* file);
|
||||
void hmml_dump (HMML_Output* output);
|
||||
void hmml_free (HMML_Output* output);
|
||||
|
||||
#endif
|
|
@ -1,477 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<!-- Load the player -->
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<link rel="stylesheet" type="text/css" href="riscy.css">
|
||||
<link rel="stylesheet" type="text/css" href="topics.css">
|
||||
<script type="text/javascript" src="player.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
Player.initializeYoutube(function() {});
|
||||
</script>
|
||||
<div class="title riscy">
|
||||
<span class="episode_name">Coloured Nicks</span>
|
||||
<div class="menu">
|
||||
<span>Quotes ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<span data-id="α" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Quote 1</div>
|
||||
<div class="ref_title">Stay RISCY, everyone</div>
|
||||
<div class="quote_byline">—miotatsu, Wed Nov 16 21:03:26 2016</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="176" class="timecode"><span class="ref_index">[α]</span><span class="time">2:56</span></span>
|
||||
</div>
|
||||
</span>
|
||||
<span data-id="β" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Quote 2</div>
|
||||
<div class="ref_title">I dream of nice things</div>
|
||||
<div class="quote_byline">—miotatsu, Fri Dec 2 21:00:05 2016</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="312" class="timecode"><span class="ref_index">[β]</span><span class="time">5:12</span></span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu">
|
||||
<span>References ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<a data-id="https://en.wikipedia.org/wiki/Logic_gate" href="https://en.wikipedia.org/wiki/Logic_gate" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Wikipedia</div>
|
||||
<div class="ref_title">Logic gate</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[1]</span><span class="time">1:00</span></span><span data-timestamp="624" class="timecode"><span class="ref_index">[3]</span><span class="time">10:24</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="0-7356-0505-X" href="http://www.charlespetzold.com/code/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Charles Petzold (Microsoft Press)</div>
|
||||
<div class="ref_title">Code: The Hidden Language of Computer Hardware and Software</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[2]</span><span class="time">1:00</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="https://handmade.network/" href="https://handmade.network/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="ref_title">Handmade Network</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="754" class="timecode"><span class="ref_index">[4]</span><span class="time">12:34</span></span><span data-timestamp="992" class="timecode"><span class="ref_index">[5]</span><span class="time">16:32</span></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu filter">
|
||||
<span><img src="hues_HCL.png"></span>
|
||||
<div class="filter">
|
||||
<div class="filter_mode inclusive">Filter mode: </div>
|
||||
<div class="filters">
|
||||
<div class="filter_topics">
|
||||
<div class="filter_title">Topics</div>
|
||||
<div class="filter_content rendering">
|
||||
<span class="icon category rendering"></span><span class="text">rendering</span>
|
||||
</div>
|
||||
<div class="filter_content hardware">
|
||||
<span class="icon category hardware"></span><span class="text">hardware</span>
|
||||
</div>
|
||||
<div class="filter_content mathematics">
|
||||
<span class="icon category mathematics"></span><span class="text">mathematics</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter_media">
|
||||
<div class="filter_title">Media</div>
|
||||
<div class="filter_content authored">
|
||||
<span class="icon">🗪</span><span class="text">authored</span>
|
||||
</div>
|
||||
<div class="filter_content blackboard">
|
||||
<span class="icon">🖌</span><span class="text">blackboard</span>
|
||||
</div>
|
||||
<div class="filter_content programming">
|
||||
<span class="icon">🖮</span><span class="text">programming</span>
|
||||
</div>
|
||||
<div class="filter_content rant">
|
||||
<span class="icon">💢</span><span class="text">rant</span>
|
||||
</div>
|
||||
<div class="filter_content research">
|
||||
<span class="icon">📖</span><span class="text">research</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="annotator_container">Annotator: <span class="annotator">Miblo</span></span>
|
||||
</div>
|
||||
<div class="player_container">
|
||||
<div class="video_container" data-videoId="ug5WkCROkOk"></div>
|
||||
<div class="markers_container riscy">
|
||||
<div data-timestamp="12" class="marker programming cat_rendering cat_hardware">
|
||||
<div class="content"><span class="timecode">0:12</span>Basic test with a little longer text<span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">0:12</span>Basic test with a little longer text<span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">0:12</span>Basic test with a little longer text<span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="60" class="marker authored cat_rendering cat_hardware research" data-ref="https://en.wikipedia.org/wiki/Logic_gate,0-7356-0505-X">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><span class="categories"><div class="category rendering"></div><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="176" class="marker programming" data-ref="α">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="312" class="marker blackboard rant cat_mathematics" data-ref="β">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="624" class="marker programming" data-ref="https://en.wikipedia.org/wiki/Logic_gate">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="630" class="marker rant">
|
||||
<div class="content"><span class="timecode">10:30</span>1. Some text. Simples!</div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:30</span>1. Some text. Simples!</div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:30</span>1. Some text. Simples!</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="642" class="marker rant">
|
||||
<div class="content"><span class="timecode">10:42</span>2. Some text. Simples!</div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:42</span>2. Some text. Simples!</div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:42</span>2. Some text. Simples!</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="754" class="marker programming" data-ref="https://handmade.network/">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>4</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>4</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>4</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="992" class="marker programming" data-ref="https://handmade.network/">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>5</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>5</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>5</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var player = new Player(document.querySelector(".player_container"), onRefChanged);
|
||||
window.addEventListener("resize", function() { player.updateSize(); });
|
||||
document.addEventListener("keypress", function(ev) {
|
||||
switch (ev.key) {
|
||||
case 'n':
|
||||
case 'd':
|
||||
case 's': {
|
||||
player.jumpToNextMarker();
|
||||
} break;
|
||||
|
||||
case 'p':
|
||||
case 'a':
|
||||
case 'w': {
|
||||
player.jumpToPrevMarker();
|
||||
} break;
|
||||
}
|
||||
});
|
||||
|
||||
var refTimecodes = document.querySelectorAll(".refs .ref .timecode");
|
||||
for (var i = 0; i < refTimecodes.length; ++i) {
|
||||
refTimecodes[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
var time = ev.currentTarget.getAttribute("data-timestamp");
|
||||
player.setTime(parseInt(time, 10));
|
||||
player.play();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var filter = document.querySelector(".filter");
|
||||
var filterModeElement = filter.querySelector(".filter_mode");
|
||||
var filterMode = filterModeElement.classList[1];
|
||||
|
||||
var filterState = { "rendering": { "type": "topic", "off": false },
|
||||
"hardware": { "type": "topic", "off": false },
|
||||
"mathematics": { "type": "topic", "off": false },
|
||||
"authored": { "type": "medium", "off": false },
|
||||
"blackboard": { "type": "medium", "off": false },
|
||||
"programming": { "type": "medium", "off": false },
|
||||
"rant": { "type": "medium", "off": false },
|
||||
"research": { "type": "medium", "off": false }};
|
||||
|
||||
// Filter Mode Toggle
|
||||
var testMarkers = document.querySelectorAll(".marker");
|
||||
filterModeElement.addEventListener("click", function(ev) {
|
||||
if(filterMode == "inclusive")
|
||||
{
|
||||
filterModeElement.classList.remove("inclusive");
|
||||
filterModeElement.classList.add("exclusive");
|
||||
filterMode = "exclusive";
|
||||
|
||||
for(var i = 0; i < testMarkers.length; ++i)
|
||||
{
|
||||
var testCategories = testMarkers[i].classList;
|
||||
for(var j = 0; j < testCategories.length; ++j)
|
||||
{
|
||||
if((testCategories[j].startsWith("off_")) && !testMarkers[i].classList.contains("skip"))
|
||||
{
|
||||
testMarkers[i].classList.add("skip");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
filterModeElement.classList.remove("exclusive");
|
||||
filterModeElement.classList.add("inclusive");
|
||||
filterMode = "inclusive";
|
||||
|
||||
for(var i = 0; i < testMarkers.length; ++i)
|
||||
{
|
||||
var testCategories = testMarkers[i].classList;
|
||||
for(var j = 0; j < testCategories.length; ++j)
|
||||
{
|
||||
if((testCategories[j] in filterState || testCategories[j].startsWith("cat_")) && testMarkers[i].classList.contains("skip"))
|
||||
{
|
||||
testMarkers[i].classList.remove("skip");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Filter Toggle
|
||||
var filterCategories = filter.querySelectorAll(".filter_topics .filter_content,.filter_media .filter_content");
|
||||
for(var i = 0; i < filterCategories.length; ++i)
|
||||
{
|
||||
filterCategories[i].addEventListener("click", function(ev) {
|
||||
var selectedCategory = this.classList[1];
|
||||
filterState[selectedCategory].off = !filterState[selectedCategory].off;
|
||||
|
||||
if(filterState[selectedCategory].off)
|
||||
{
|
||||
this.classList.add("off");
|
||||
var testMarkers = document.querySelectorAll(".marker." + selectedCategory + ", .marker.cat_" + selectedCategory);
|
||||
for(var j = 0; j < testMarkers.length; ++j)
|
||||
{
|
||||
if(filterState[selectedCategory].type == "topic")
|
||||
{
|
||||
testMarkers[j].classList.remove("cat_" + selectedCategory);
|
||||
testMarkers[j].classList.add("off_" + selectedCategory);
|
||||
var markerCategories = testMarkers[j].querySelectorAll(".category." + selectedCategory);
|
||||
for(var k = 0; k < markerCategories.length; ++k)
|
||||
{
|
||||
if(markerCategories[k].classList.contains(selectedCategory))
|
||||
{
|
||||
markerCategories[k].classList.add("off");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
testMarkers[j].classList.remove(selectedCategory);
|
||||
testMarkers[j].classList.add("off_" + selectedCategory);
|
||||
}
|
||||
|
||||
Skipping = 1;
|
||||
if(filterMode == "exclusive")
|
||||
{
|
||||
testMarkers[j].classList.add("skip");
|
||||
}
|
||||
else
|
||||
{
|
||||
var markerClasses = testMarkers[j].classList;
|
||||
for(var k = 0; k < markerClasses.length; ++k)
|
||||
{
|
||||
if(markerClasses[k] in filterState || markerClasses[k].replace(/^cat_/, "") in filterState)
|
||||
{
|
||||
Skipping = 0;
|
||||
}
|
||||
}
|
||||
if(Skipping)
|
||||
{
|
||||
testMarkers[j].classList.add("skip");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.classList.remove("off");
|
||||
var testMarkers = document.querySelectorAll(".marker.off_" + selectedCategory);
|
||||
for(var j = 0; j < testMarkers.length; ++j)
|
||||
{
|
||||
if(filterState[selectedCategory].type == "topic")
|
||||
{
|
||||
testMarkers[j].classList.remove("off_" + selectedCategory);
|
||||
testMarkers[j].classList.add("cat_" + selectedCategory);
|
||||
var markerCategories = testMarkers[j].querySelectorAll(".category." + selectedCategory);
|
||||
for(var k = 0; k < markerCategories.length; ++k)
|
||||
{
|
||||
if(markerCategories[k].classList.contains(selectedCategory))
|
||||
{
|
||||
markerCategories[k].classList.remove("off");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
testMarkers[j].classList.remove("off_" + selectedCategory);
|
||||
testMarkers[j].classList.add(selectedCategory);
|
||||
}
|
||||
|
||||
Skipping = 0;
|
||||
if(filterMode == "inclusive")
|
||||
{
|
||||
testMarkers[j].classList.remove("skip");
|
||||
}
|
||||
else
|
||||
{
|
||||
var markerClasses = testMarkers[j].classList;
|
||||
for(var k = 0; k < markerClasses.length; ++k)
|
||||
{
|
||||
if(markerClasses[k].startsWith("off_"))
|
||||
{
|
||||
Skipping = 1;
|
||||
}
|
||||
}
|
||||
if(!Skipping)
|
||||
{
|
||||
testMarkers[j].classList.remove("skip");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var refSources = document.querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refSources.length; ++i) {
|
||||
refSources[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
player.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function resetFade()
|
||||
{
|
||||
filter.classList.remove("responsible");
|
||||
filter.querySelector(".filter_mode").classList.remove("responsible");
|
||||
var responsibleCategories = filter.querySelectorAll(".filter_content.responsible");
|
||||
for(var i = 0; i < responsibleCategories.length; ++i)
|
||||
{
|
||||
responsibleCategories[i].classList.remove("responsible");
|
||||
}
|
||||
}
|
||||
|
||||
var sourceMenus = document.querySelectorAll(".menu");
|
||||
function onRefChanged(ref, element) {
|
||||
if(element.classList.contains("skip"))
|
||||
{
|
||||
if(!filter.classList.contains("responsible"))
|
||||
{
|
||||
filter.classList.add("responsible");
|
||||
}
|
||||
|
||||
for(var selector = 0; selector < element.classList.length; ++selector)
|
||||
{
|
||||
if(element.classList[selector].startsWith("off_"))
|
||||
{
|
||||
if(!filter.querySelector(".filter_content." + element.classList[selector].replace(/^off_/, "")).classList.contains("responsible"))
|
||||
{
|
||||
filter.querySelector(".filter_content." + element.classList[selector].replace(/^off_/, "")).classList.add("responsible");
|
||||
}
|
||||
}
|
||||
if((element.classList[selector].startsWith("cat_") || element.classList[selector] in filterState))
|
||||
{
|
||||
if(!filter.querySelector(".filter_mode").classList.add("responsible"))
|
||||
{
|
||||
filter.querySelector(".filter_mode").classList.add("responsible");
|
||||
}
|
||||
}
|
||||
setTimeout(resetFade, 8000);
|
||||
}
|
||||
player.jumpToNextMarker();
|
||||
return;
|
||||
}
|
||||
|
||||
for (var MenuIndex = 0; MenuIndex < sourceMenus.length; ++MenuIndex)
|
||||
{
|
||||
var SetMenu = 0;
|
||||
if (ref !== undefined && ref !== null) {
|
||||
var refElements = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
var refs = ref.split(",");
|
||||
|
||||
for (var i = 0; i < refElements.length; ++i) {
|
||||
if (refs.includes(refElements[i].getAttribute("data-id"))) {
|
||||
refElements[i].classList.add("current");
|
||||
SetMenu = 1;
|
||||
} else {
|
||||
refElements[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
if(SetMenu) {
|
||||
sourceMenus[MenuIndex].classList.add("current");
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
}
|
||||
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
var refs = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refs.length; ++i) {
|
||||
refs[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,421 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Coloured Nicks</title>
|
||||
|
||||
<!-- Load the player -->
|
||||
<script type="text/javascript" src="player.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<link rel="stylesheet" type="text/css" href="riscy.css">
|
||||
<link rel="stylesheet" type="text/css" href="topics.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="title riscy">
|
||||
<span class="episode_name">Coloured Nicks</span>
|
||||
<div class="menu quotes">
|
||||
<span>Quotes ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs quotes_container">
|
||||
<span data-id="α" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Quote 1</div>
|
||||
<div class="ref_title">Stay RISCY, everyone</div>
|
||||
<div class="quote_byline">—miotatsu, Wed Nov 16 21:03:26 2016</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="176" class="timecode"><span class="ref_index">[α]</span><span class="time">2:56</span></span>
|
||||
</div>
|
||||
</span>
|
||||
<span data-id="β" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Quote 2</div>
|
||||
<div class="ref_title">I dream of nice things</div>
|
||||
<div class="quote_byline">—miotatsu, Fri Dec 2 21:00:05 2016</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="312" class="timecode"><span class="ref_index">[β]</span><span class="time">5:12</span></span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu references">
|
||||
<span>References ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs references_container">
|
||||
<a data-id="https://en.wikipedia.org/wiki/Logic_gate" href="https://en.wikipedia.org/wiki/Logic_gate" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Wikipedia</div>
|
||||
<div class="ref_title">Logic gate</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[1]</span><span class="time">1:00</span></span><span data-timestamp="624" class="timecode"><span class="ref_index">[4]</span><span class="time">10:24</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="0-7356-0505-X" href="http://www.charlespetzold.com/code/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Charles Petzold (Microsoft Press)</div>
|
||||
<div class="ref_title">Code: The Hidden Language of Computer Hardware and Software</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[2]</span><span class="time">1:00</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="0-7356-0505-Y" href="http://www.charlespetzold.com/code/again" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Charles Petzold (Microsoft Press)</div>
|
||||
<div class="ref_title">Code Again: The Hidden Language of Computer Hardware and Software</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[3]</span><span class="time">1:00</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="https://handmade.network/" href="https://handmade.network/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="ref_title">Handmade Network</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="754" class="timecode"><span class="ref_index">[5]</span><span class="time">12:34</span></span><span data-timestamp="992" class="timecode"><span class="ref_index">[6]</span><span class="time">16:32</span></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu filter">
|
||||
<span><img src="hues_HCL.png"></span>
|
||||
<div class="filter_container">
|
||||
<div class="filter_mode inclusive">Filter mode: </div>
|
||||
<div class="filters">
|
||||
<div class="filter_topics">
|
||||
<div class="filter_title">Topics</div>
|
||||
<div class="filter_content hardware">
|
||||
<span class="icon category hardware"></span><span class="text">hardware</span>
|
||||
</div>
|
||||
<div class="filter_content mathematics">
|
||||
<span class="icon category mathematics"></span><span class="text">mathematics</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter_media">
|
||||
<div class="filter_title">Media</div>
|
||||
<div class="filter_content blackboard">
|
||||
<span class="icon">🖌</span><span class="text">Blackboard</span>
|
||||
</div>
|
||||
<div class="filter_content authored">
|
||||
<span class="icon">🗪</span><span class="text">Chat Comment</span>
|
||||
</div>
|
||||
<div class="filter_content default">
|
||||
<span class="icon">🖮</span><span class="text">Programming</span>
|
||||
</div>
|
||||
<div class="filter_content rant">
|
||||
<span class="icon">💢</span><span class="text">Rant</span>
|
||||
</div>
|
||||
<div class="filter_content research">
|
||||
<span class="icon">📖</span><span class="text">Research</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu credits">
|
||||
<div class="mouse_catcher"></div>
|
||||
<span>Credits</span>
|
||||
<div class="credits_container">
|
||||
<span class="credit">
|
||||
<a class="person" href="http://riscy.tv/" target="_blank">
|
||||
<div class="role">Host</div>
|
||||
<div class="name">Mio Iwakura</div>
|
||||
</a>
|
||||
<a class="support" href="http://patreon.com/miotatsu" target="_blank"><img src="patreon_logo.png"></a>
|
||||
</span>
|
||||
<span class="credit">
|
||||
<a class="person" href="http://miblodelcarpio.co.uk" target="_blank">
|
||||
<div class="role">Annotator</div>
|
||||
<div class="name">Matt Mascarenhas</div>
|
||||
</a>
|
||||
<a class="support" href="http://patreon.com/miblo" target="_blank"><img src="patreon_logo.png"></a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="help">
|
||||
<span>?</span>
|
||||
<div class="help_container">
|
||||
<span class="help_key">?</span><h1>Keyboard Navigation</h1>
|
||||
|
||||
<h2>Global Keys</h2>
|
||||
<span class="help_key">W</span>, <span class="help_key">A</span>, <span class="help_key">P</span> / <span class="help_key">S</span>, <span class="help_key">D</span>, <span class="help_key">N</span> <span class="help_text">Jump to previous / next marker</span><br>
|
||||
<span class="help_key">V</span> <span class="help_text">Reset filter</span> <span class="help_key">z</span> <span class="help_text">Toggle filter mode between "inclusive" and "exclusive"</span>
|
||||
|
||||
<h2>Menu toggling</h2>
|
||||
<span class="help_key">q</span> <span class="help_text">Quotes</span>
|
||||
<span class="help_key">r</span> <span class="help_text">References</span>
|
||||
<span class="help_key">f</span> <span class="help_text">Filter</span>
|
||||
<span class="help_key">c</span> <span class="help_text">Credits</span>
|
||||
|
||||
<h2>Movement</h2>
|
||||
<div class="help_paragraph">
|
||||
<div class="key_block">
|
||||
<div class="key_column" style="flex-grow: 1">
|
||||
<span class="help_key">a</span>
|
||||
</div>
|
||||
<div class="key_column" style="flex-grow: 2">
|
||||
<span class="help_key">w</span><br>
|
||||
<span class="help_key">s</span>
|
||||
</div>
|
||||
<div class="key_column" style="flex-grow: 1">
|
||||
<span class="help_key">d</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help_text">/</span>
|
||||
<div class="key_block">
|
||||
<div style="flex-grow: 1">
|
||||
<span class="help_key">←</span>
|
||||
</div>
|
||||
<div style="flex-grow: 2">
|
||||
<span class="help_key">↑</span><br>
|
||||
<span class="help_key">↓</span>
|
||||
</div>
|
||||
<div style="flex-grow: 1">
|
||||
<span class="help_key">→</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="help_text">/</span>
|
||||
<div class="key_block">
|
||||
<span class="help_key">h</span>
|
||||
<span class="help_key">j</span>
|
||||
<span class="help_key">k</span>
|
||||
<span class="help_key">l</span>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<h2>Quotes and References Menus</h2>
|
||||
<span style="width: auto" class="help_key">Enter</span><span class="help_text">Jump to timecode</span><br>
|
||||
<h2>References and Credits Menus</h2>
|
||||
<span class="help_key">o</span><span class="help_text">Open URL (in new tab)</span>
|
||||
|
||||
<h2>Filter Menu</h2>
|
||||
<span class="help_key">x</span>, <span style="width: auto" class="help_key">Space</span><span class="help_text">Toggle category and focus next</span><br>
|
||||
<span class="help_key">X</span>, <span style="width: auto; margin-right: 0px" class="help_key">Shift</span><span style="width: auto" class="help_key">Space</span><span class="help_text">Toggle category and focus previous</span><br>
|
||||
<span class="help_key">v</span><span class="help_text">Invert topics / media as per focus</span>
|
||||
<h2>Credits Menu</h2>
|
||||
<span style="width: auto" class="help_key">Enter</span>, <span class="help_key">o</span><span class="help_text">Open URL (in new tab)</span><br>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="player_container">
|
||||
<div class="video_container" data-videoId="ug5WkCROkOk"></div>
|
||||
<div class="markers_container riscy">
|
||||
<div data-timestamp="60" class="marker authored cat_hardware research" data-ref="https://en.wikipedia.org/wiki/Logic_gate,0-7356-0505-X,0-7356-0505-Y">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><sup>,3</sup><span class="categories"><div class="category hardware"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><sup>,3</sup><span class="categories"><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: hsl(257, 87%, 26%);">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: hsl(83, 75%, 26%); text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding circuit design he saw in Code<sup>2</sup><sup>,3</sup><span class="categories"><div class="category hardware"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="176" class="marker default" data-ref="α">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">2:56</span>“Stay RISCY, everyone”<sup>α</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="312" class="marker blackboard rant cat_mathematics" data-ref="β">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="624" class="marker default" data-ref="https://en.wikipedia.org/wiki/Logic_gate">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>4</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>4</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: hsl(26, 83%, 26%); text-decoration: none">milton</a> forum post<sup>4</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="642" class="marker rant">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="754" class="marker default" data-ref="https://handmade.network/">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>5</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>5</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">12:34</span>Something about the Handmade.Network<sup>5</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="992" class="marker default" data-ref="https://handmade.network/">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>6</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>6</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">16:32</span>Something else about the Handmade.Network<sup>6</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
var menuState = [];
|
||||
// TODO(matt): Do all this conditional stuff in hmml_to_html.c
|
||||
var quotesMenu = document.querySelector(".quotes_container");
|
||||
if(quotesMenu)
|
||||
{
|
||||
menuState.push(quotesMenu);
|
||||
var quoteItems = quotesMenu.querySelectorAll(".ref");
|
||||
for(var i = 0; i < quoteItems.length; ++i)
|
||||
{
|
||||
quoteItems[i].addEventListener("mouseenter", function(ev) {
|
||||
mouseOverQuotes(this);
|
||||
})
|
||||
};
|
||||
var lastFocusedQuote = null;
|
||||
}
|
||||
var referencesMenu = document.querySelector(".references_container");
|
||||
if(referencesMenu)
|
||||
{
|
||||
menuState.push(referencesMenu);
|
||||
var referenceItems = referencesMenu.querySelectorAll(".ref");
|
||||
for(var i = 0; i < referenceItems.length; ++i)
|
||||
{
|
||||
referenceItems[i].addEventListener("mouseenter", function(ev) {
|
||||
mouseOverReferences(this);
|
||||
})
|
||||
};
|
||||
var lastFocusedReference = null;
|
||||
var lastFocusedIdentifier = null;
|
||||
}
|
||||
var filterMenu = document.querySelector(".filter_container");
|
||||
if(filterMenu)
|
||||
{
|
||||
menuState.push(filterMenu);
|
||||
var lastFocusedCategory = null;
|
||||
var lastFocusedTopic = null;
|
||||
var lastFocusedMedium = null;
|
||||
|
||||
var filter = filterMenu.parentNode;
|
||||
|
||||
var filterModeElement = filter.querySelector(".filter_mode");
|
||||
filterModeElement.addEventListener("click", function(ev) {
|
||||
toggleFilterMode();
|
||||
});
|
||||
|
||||
var filterMode = filterModeElement.classList[1];
|
||||
var filterItems = filter.querySelectorAll(".filter_content");
|
||||
for(var i = 0; i < filterItems.length; ++i)
|
||||
{
|
||||
filterItems[i].addEventListener("mouseenter", function(ev) {
|
||||
navigateFilter(this);
|
||||
})
|
||||
|
||||
filterItems[i].addEventListener("click", function(ev) {
|
||||
filterItemToggle(this);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(matt): Generate this
|
||||
var filterState = {
|
||||
"hardware": { "type": "topic", "off": false },
|
||||
"mathematics": { "type": "topic", "off": false },
|
||||
"blackboard": { "type": "medium", "off": false },
|
||||
"authored": { "type": "medium", "off": false },
|
||||
"default": { "type": "medium", "off": false },
|
||||
"rant": { "type": "medium", "off": false },
|
||||
"research": { "type": "medium", "off": false },
|
||||
};
|
||||
}
|
||||
|
||||
var creditsMenu = document.querySelector(".credits_container");
|
||||
if(creditsMenu)
|
||||
{
|
||||
menuState.push(creditsMenu);
|
||||
var lastFocusedCreditItem = null;
|
||||
|
||||
var creditItems = creditsMenu.querySelectorAll(".person, .support");
|
||||
for(var i = 0; i < creditItems.length; ++i)
|
||||
{
|
||||
creditItems[i].addEventListener("mouseenter", function(ev) {
|
||||
if(this != lastFocusedCreditItem)
|
||||
{
|
||||
lastFocusedCreditItem.classList.remove("focused");
|
||||
lastFocusedCreditItem = this;
|
||||
focusedElement = lastFocusedCreditItem;
|
||||
focusedElement.classList.add("focused");
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
var sourceMenus = document.querySelectorAll(".menu");
|
||||
|
||||
var helpButton = document.querySelector(".help");
|
||||
var helpDocumentation = helpButton.querySelector(".help_container");
|
||||
helpButton.addEventListener("click", function(ev) {
|
||||
handleMouseOverMenu(this, ev.type);
|
||||
})
|
||||
|
||||
var focusedElement = null;
|
||||
var focusedIdentifier = null;
|
||||
|
||||
var player = new Player(document.querySelector(".player_container"), onRefChanged);
|
||||
window.addEventListener("resize", function() { player.updateSize(); });
|
||||
document.addEventListener("keydown", function(ev) {
|
||||
var key = ev.key;
|
||||
if(ev.getModifierState("Shift") && key == " ")
|
||||
{
|
||||
key = "capitalSpace";
|
||||
}
|
||||
|
||||
if(handleKey(key) == true && focusedElement)
|
||||
{
|
||||
ev.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
for(var i = 0; i < sourceMenus.length; ++i)
|
||||
{
|
||||
sourceMenus[i].addEventListener("mouseenter", function(ev) {
|
||||
handleMouseOverMenu(this, ev.type);
|
||||
})
|
||||
sourceMenus[i].addEventListener("mouseleave", function(ev) {
|
||||
handleMouseOverMenu(this, ev.type);
|
||||
})
|
||||
};
|
||||
|
||||
var refTimecodes = document.querySelectorAll(".refs .ref .timecode");
|
||||
for (var i = 0; i < refTimecodes.length; ++i) {
|
||||
refTimecodes[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
var time = ev.currentTarget.getAttribute("data-timestamp");
|
||||
mouseSkipToTimecode(player, time, ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var refSources = document.querySelectorAll(".refs .ref"); // This is for both quotes and refs
|
||||
for (var i = 0; i < refSources.length; ++i) {
|
||||
refSources[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
player.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var testMarkers = document.querySelectorAll(".marker");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,189 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<!-- Load the player -->
|
||||
<script type="text/javascript" src="player.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
<link rel="stylesheet" type="text/css" href="topics.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="title">
|
||||
<span class="episode_name">Coloured Nicks</span>
|
||||
<div class="refs_container">
|
||||
<span>Quotes ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<span data-id="α" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">#1 • Quote date</div>
|
||||
<div class="ref_title">Quote text</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="176" class="timecode"><span class="ref_index">[α]</span><span class="time">2:56</span></span>
|
||||
</div>
|
||||
</span>
|
||||
<span data-id="β" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">#2 • Quote date</div>
|
||||
<div class="ref_title">Quote text</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="312" class="timecode"><span class="ref_index">[β]</span><span class="time">5:12</span></span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="refs_container">
|
||||
<span>References ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<a data-id="serge_rgb" href="http://example.com/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Source</div>
|
||||
<div class="ref_title">Title</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[1]</span><span class="time">1:00</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="milton_forum" href="http://example.com/" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Source</div>
|
||||
<div class="ref_title">Title</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[2]</span><span class="time">1:00</span></span><span data-timestamp="624" class="timecode"><span class="ref_index">[3]</span><span class="time">10:24</span></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<span class="annotator_container">Annotator: <span class="annotator">Miblo</span></span>
|
||||
</div>
|
||||
<div class="player_container">
|
||||
<div class="video_container" data-videoId="ug5WkCROkOk"></div>
|
||||
<div class="markers_container">
|
||||
<div data-timestamp="60" class="marker authored cat_rendering research" data-ref="serge_rgb,milton_forum">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="176" class="marker" data-ref="α">
|
||||
<div class="content"><span class="timecode">2:56</span>“Quote text”<sup>α</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">2:56</span>“Quote text”<sup>α</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">2:56</span>“Quote text”<sup>α</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="312" class="marker blackboard cat_mathematics" data-ref="β">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>β</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="624" class="marker" data-ref="milton_forum">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div data-timestamp="642" class="marker">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var player = new Player(document.querySelector(".player_container"), onRefChanged);
|
||||
window.addEventListener("resize", function() { player.updateSize(); });
|
||||
document.addEventListener("keypress", function(ev) {
|
||||
switch (ev.key) {
|
||||
case 'n':
|
||||
case 'd':
|
||||
case 's': {
|
||||
player.jumpToNextMarker();
|
||||
} break;
|
||||
|
||||
case 'p':
|
||||
case 'a':
|
||||
case 'w': {
|
||||
player.jumpToPrevMarker();
|
||||
} break;
|
||||
}
|
||||
});
|
||||
|
||||
var refTimecodes = document.querySelectorAll(".refs .ref .timecode");
|
||||
for (var i = 0; i < refTimecodes.length; ++i) {
|
||||
refTimecodes[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
var time = ev.currentTarget.getAttribute("data-timestamp");
|
||||
player.setTime(parseInt(time, 10));
|
||||
player.play();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var refSources = document.querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refSources.length; ++i) {
|
||||
refSources[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
player.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onRefChanged(ref) {
|
||||
var sourceMenus = document.querySelectorAll(".refs_container");
|
||||
for (var MenuIndex = 0; MenuIndex < sourceMenus.length; ++MenuIndex)
|
||||
{
|
||||
var SetMenu = 0;
|
||||
if (ref !== undefined && ref !== null) {
|
||||
var refElements = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
var refs = ref.split(",");
|
||||
|
||||
for (var i = 0; i < refElements.length; ++i) {
|
||||
if (refs.includes(refElements[i].getAttribute("data-id"))) {
|
||||
refElements[i].classList.add("current");
|
||||
SetMenu = 1;
|
||||
} else {
|
||||
refElements[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
if(SetMenu) {
|
||||
sourceMenus[MenuIndex].classList.add("current");
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
}
|
||||
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
var refs = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refs.length; ++i) {
|
||||
refs[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,190 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
<!-- Load the player -->
|
||||
<script type="text/javascript" src="player.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="title">
|
||||
<span class="episode_name">Coloured Nicks</span>
|
||||
<div class="refs_container">
|
||||
<span>Quotes ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<span data-id="a" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">#1 • 2016-11-16</div>
|
||||
<div class="ref_title">Stay RISCY, everyone</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="176" class="timecode"><span class="ref_index">[a]</span><span class="time">2:56</span></span>
|
||||
</div>
|
||||
</span>
|
||||
<span data-id="b" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">#2 • 2016-12-02</div>
|
||||
<div class="ref_title">I dream of nice things</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="312" class="timecode"><span class="ref_index">[b]</span><span class="time">5:12</span></span>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="refs_container">
|
||||
<span>References ▼</span>
|
||||
<div class="mouse_catcher"></div>
|
||||
<div class="refs">
|
||||
<a data-id="0" href="https://milton.handmade.network/forums/t/1550-idea_:_ability_to_move_panels_outside_of_the_milton_window" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source">Milton Forums</div>
|
||||
<div class="ref_title">Idea : ability to move panels outside of the milton window?</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[1]</span><span class="time">1:00</span></span>
|
||||
</div>
|
||||
</a>
|
||||
<a data-id="1" href="https://milton.handmade.network/forums" target="_blank" class="ref">
|
||||
<span class="ref_content">
|
||||
<div class="source"></div>
|
||||
<div class="ref_title">Milton Forums</div>
|
||||
</span>
|
||||
<div class="ref_indices">
|
||||
<span data-timestamp="60" class="timecode"><span class="ref_index">[2]</span><span class="time">1:00</span></span>
|
||||
<span data-timestamp="624" class="timecode"><span class="ref_index">[3]</span><span class="time">10:24</span></span>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<span class="annotator_container">Annotator: <span class="annotator">Miblo</span></span>
|
||||
</div>
|
||||
<div class="player_container">
|
||||
<div class="video_container" data-videoId="ug5WkCROkOk"></div>
|
||||
<div class="markers_container">
|
||||
<div class="marker authored cat_rendering research" data-timestamp="60" data-ref="0,1">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/Zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/Zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">1:00</span><span class="author" style="color: #69D036;">insofaras</span> Some text referring to <a href="https://handmade.network/m/Zilarrezko" target="blank" style="color: #8624DC; text-decoration: none">Zilarrezko</a> about this thing<sup>1</sup> regarding triangle intersections he saw in the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forums<sup>2</sup><span class="categories"><div class="category rendering"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marker" data-timestamp="176" data-ref="a">
|
||||
<div class="content"><span class="timecode">2:56</span>"Stay RISCY, everyone"<sup>a</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">2:56</span>"Stay RISCY, everyone"<sup>a</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">2:56</span>"Stay RISCY, everyone"<sup>a</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marker blackboard" data-timestamp="312" data-ref="b">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>b</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>b</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">5:12</span>Matrix multiplication<sup>b</sup><span class="categories"><div class="category mathematics"></div></span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marker" data-timestamp="624" data-ref="1">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:24</span>More stuff referring to the <a href="https://milton.handmade.network/" target="blank" style="color: #8369CF; text-decoration: none">milton</a> forum post<sup>3</sup></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="marker" data-timestamp="642">
|
||||
<div class="content"><span class="timecode">10:42</span>Some text. Simples!</div>
|
||||
<div class="progress faded">
|
||||
<div class="content"><span class="timecode">10:24</span>Some text. Simples!</div>
|
||||
</div>
|
||||
<div class="progress main">
|
||||
<div class="content"><span class="timecode">10:24</span>Some text. Simples!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var player = new Player(document.querySelector(".player_container"), onRefChanged);
|
||||
window.addEventListener("resize", function() { player.updateSize(); });
|
||||
document.addEventListener("keypress", function(ev) {
|
||||
switch (ev.key) {
|
||||
case 'n':
|
||||
case 'd':
|
||||
case 's': {
|
||||
player.jumpToNextMarker();
|
||||
} break;
|
||||
|
||||
case 'p':
|
||||
case 'a':
|
||||
case 'w': {
|
||||
player.jumpToPrevMarker();
|
||||
} break;
|
||||
}
|
||||
});
|
||||
|
||||
var refTimecodes = document.querySelectorAll(".refs .ref .timecode");
|
||||
for (var i = 0; i < refTimecodes.length; ++i) {
|
||||
refTimecodes[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
var time = ev.currentTarget.getAttribute("data-timestamp");
|
||||
player.setTime(parseInt(time, 10));
|
||||
player.play();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var refSources = document.querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refSources.length; ++i) {
|
||||
refSources[i].addEventListener("click", function(ev) {
|
||||
if (player) {
|
||||
player.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function onRefChanged(ref) {
|
||||
var sourceMenus = document.querySelectorAll(".refs_container");
|
||||
for (var MenuIndex = 0; MenuIndex < sourceMenus.length; ++MenuIndex)
|
||||
{
|
||||
var SetMenu = 0;
|
||||
if (ref !== undefined && ref !== null) {
|
||||
var refElements = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
var refs = ref.split(",");
|
||||
|
||||
for (var i = 0; i < refElements.length; ++i) {
|
||||
if (refs.includes(refElements[i].getAttribute("data-id"))) {
|
||||
refElements[i].classList.add("current");
|
||||
SetMenu = 1;
|
||||
} else {
|
||||
refElements[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
if(SetMenu) {
|
||||
sourceMenus[MenuIndex].classList.add("current");
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
}
|
||||
|
||||
} else {
|
||||
sourceMenus[MenuIndex].classList.remove("current");
|
||||
var refs = sourceMenus[MenuIndex].querySelectorAll(".refs .ref");
|
||||
for (var i = 0; i < refs.length; ++i) {
|
||||
refs[i].classList.remove("current");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,11 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Preceding Text - <!-- __CINERA_TITLE__ --> - Following Text</title>
|
||||
<!-- __CINERA_INCLUDES__ -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- __CINERA_MENUS__ -->
|
||||
<!-- __CINERA_PLAYER__ -->
|
||||
<!-- __CINERA_SCRIPT__ -->
|
||||
</body>
|
||||
</html>
|
|
@ -1,28 +0,0 @@
|
|||
[video member=miotatsu project=test title="Coloured Nicks" vod_platform=youtube id=ug5WkCROkOk annotator=Miblo]
|
||||
[0:12][:inventory :inventory]
|
||||
[1:00][@insofaras][π² Some text < > referring to @Zilarrezko about this thing[ref
|
||||
site=Wikipedia
|
||||
page="Logic < gate"
|
||||
url=https://en.wikipedia.org/wiki/Logic_gate] regarding [:hardware circuit design] he saw in Code[ref
|
||||
title="Code: The Hidden Language of Computer Hardware and Software"
|
||||
author="Charles Petzold"
|
||||
publisher="Microsoft Press"
|
||||
isbn=0-7356-0505-X
|
||||
url=http://www.charlespetzold.com/code/][ref
|
||||
title="Code Again: The Hidden Language of Computer Hardware and Software"
|
||||
author="Charles Petzold"
|
||||
publisher="Microsoft Press"
|
||||
isbn=0-7356-0505-Y
|
||||
url=http://www.charlespetzold.com/code/again]][:research]
|
||||
[2:56][][quote 1]
|
||||
[5:12][Matrix multiplication][:blackboard :rant :math][quote 2]
|
||||
[10:24][More stuff referring to the ~milton forum post[ref
|
||||
site=Wikipedia
|
||||
page="Logic gate"
|
||||
url=https://en.wikipedia.org/wiki/Logic_gate]]
|
||||
[10:42][Some text. Simples!][:rant]
|
||||
[12:34][Something about the Handmade.Network[ref
|
||||
site="Handmade Network"
|
||||
url=https://handmade.network/]]
|
||||
[16:32][Something else about the Handmade.Network[ref site="Handmade Network" url=https://handmade.network/]]
|
||||
[/video]
|
|
@ -1,98 +0,0 @@
|
|||
#ifndef HMML_H_
|
||||
#define HMML_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Data structures
|
||||
|
||||
typedef struct {
|
||||
char* member;
|
||||
char* stream_platform;
|
||||
char* stream_username;
|
||||
char* project;
|
||||
char* title;
|
||||
char* vod_platform;
|
||||
char* id;
|
||||
|
||||
char** co_hosts;
|
||||
size_t co_host_count;
|
||||
|
||||
char** guests;
|
||||
size_t guest_count;
|
||||
|
||||
char** annotators;
|
||||
size_t annotator_count;
|
||||
} HMML_VideoMetaData;
|
||||
|
||||
typedef struct {
|
||||
char* site;
|
||||
char* page;
|
||||
char* url;
|
||||
char* title;
|
||||
char* article;
|
||||
char* author;
|
||||
char* editor;
|
||||
char* publisher;
|
||||
char* isbn;
|
||||
int offset;
|
||||
} HMML_Reference;
|
||||
|
||||
typedef enum {
|
||||
HMML_CATEGORY,
|
||||
HMML_MEMBER,
|
||||
HMML_PROJECT,
|
||||
|
||||
HMML_MARKER_COUNT,
|
||||
} HMML_MarkerType;
|
||||
|
||||
typedef struct {
|
||||
HMML_MarkerType type;
|
||||
char* marker;
|
||||
char* parameter;
|
||||
char* episode;
|
||||
int offset;
|
||||
} HMML_Marker;
|
||||
|
||||
typedef struct {
|
||||
int id;
|
||||
char* author;
|
||||
} HMML_Quote;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
char* time;
|
||||
char* text;
|
||||
char* author;
|
||||
|
||||
HMML_Reference* references;
|
||||
size_t reference_count;
|
||||
|
||||
HMML_Marker* markers;
|
||||
size_t marker_count;
|
||||
|
||||
HMML_Quote quote;
|
||||
bool is_quote;
|
||||
} HMML_Annotation;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
char* message;
|
||||
} HMML_Error;
|
||||
|
||||
typedef struct {
|
||||
bool well_formed;
|
||||
HMML_VideoMetaData metadata;
|
||||
HMML_Annotation* annotations;
|
||||
size_t annotation_count;
|
||||
HMML_Error error;
|
||||
} HMML_Output;
|
||||
|
||||
// Functions
|
||||
|
||||
HMML_Output hmml_parse_file (FILE* file);
|
||||
void hmml_dump (HMML_Output* output);
|
||||
void hmml_free (HMML_Output* output);
|
||||
|
||||
#endif
|
|
@ -1,12 +1,12 @@
|
|||
#ifndef HMML_H_
|
||||
#define HMML_H_
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Data structures
|
||||
|
||||
#define HMML_CUSTOM_ATTR_COUNT 16
|
||||
|
||||
typedef struct {
|
||||
char* member;
|
||||
char* stream_platform;
|
||||
|
@ -24,6 +24,15 @@ typedef struct {
|
|||
|
||||
char** annotators;
|
||||
size_t annotator_count;
|
||||
|
||||
char* template;
|
||||
char* medium;
|
||||
|
||||
char* custom[HMML_CUSTOM_ATTR_COUNT];
|
||||
|
||||
long publication_date;
|
||||
char* output;
|
||||
|
||||
} HMML_VideoMetaData;
|
||||
|
||||
typedef struct {
|
||||
|
@ -65,7 +74,7 @@ typedef struct {
|
|||
char* time;
|
||||
char* text;
|
||||
char* author;
|
||||
|
||||
|
||||
HMML_Reference* references;
|
||||
size_t reference_count;
|
||||
|
||||
|
@ -73,7 +82,7 @@ typedef struct {
|
|||
size_t marker_count;
|
||||
|
||||
HMML_Quote quote;
|
||||
bool is_quote;
|
||||
_Bool is_quote;
|
||||
} HMML_Annotation;
|
||||
|
||||
typedef struct {
|
||||
|
@ -82,7 +91,7 @@ typedef struct {
|
|||
} HMML_Error;
|
||||
|
||||
typedef struct {
|
||||
bool well_formed;
|
||||
_Bool well_formed;
|
||||
HMML_VideoMetaData metadata;
|
||||
HMML_Annotation* annotations;
|
||||
size_t annotation_count;
|
||||
|
@ -95,4 +104,10 @@ HMML_Output hmml_parse_file (FILE* file);
|
|||
void hmml_dump (HMML_Output* output);
|
||||
void hmml_free (HMML_Output* output);
|
||||
|
||||
// Version
|
||||
|
||||
extern const struct HMML_Version {
|
||||
int Major, Minor, Patch;
|
||||
} hmml_version;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#include "stb_sb.h"
|
||||
#include "hmmlib.h"
|
||||
|
||||
const struct HMML_Version hmml_version = { 0, 4, 0 };
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
HMML_Annotation* annos;
|
||||
|
@ -56,10 +58,10 @@
|
|||
yyextra->first = false;\
|
||||
} while(0)
|
||||
|
||||
#define UNQUOTE(_attr) ({ \
|
||||
#define UNQUOTE_LEN(_attr, _len) ({ \
|
||||
typeof(_attr) attr = (_attr); \
|
||||
size_t len = strlen(attr); \
|
||||
for(char* c = attr; *c; ++c){\
|
||||
typeof(_len) len = (_len); \
|
||||
for(char* c = attr; c < attr+len; ++c){\
|
||||
if(*c == '\\'){ \
|
||||
CHECKESCAPE(c[1]); \
|
||||
memmove(c, c+1, len-(c-attr)); \
|
||||
|
@ -69,6 +71,8 @@
|
|||
attr; \
|
||||
})
|
||||
|
||||
#define UNQUOTE(_attr) UNQUOTE_LEN(_attr, strlen(attr))
|
||||
|
||||
%}
|
||||
|
||||
%option reentrant
|
||||
|
@ -78,7 +82,7 @@
|
|||
S [\t \r]*
|
||||
ATTR_SIMPLE [^\" \]\t\r\n][^ \]\t\r\n]*
|
||||
ATTR_ALNUM [0-9a-zA-Z][0-9a-zA-Z_]*
|
||||
ATTR_QUOTED \"([^\n\"\\]|\\.)*\"
|
||||
ATTR_QUOTED \"([^\"\\]|\\.)*\"
|
||||
TAG_VIDEO_OPEN \[video
|
||||
TIMECODE \[[0-9]{1,2}(:[0-5][0-9]){1,2}\]
|
||||
BAD_TIMECODE \[[0-9]{1,2}(:[6-9][0-9]){1,2}\]
|
||||
|
@ -89,6 +93,7 @@ RB \]
|
|||
%s VIDEO
|
||||
%s V_ATTR
|
||||
%s V2_ATTR
|
||||
%s V3_ATTR
|
||||
%s ANNOTATION
|
||||
%s TEXT_START
|
||||
%s TEXT
|
||||
|
@ -117,11 +122,31 @@ RB \]
|
|||
<VIDEO>title{S}= { yyextra->attr = V_(title); BEGIN(V_ATTR); }
|
||||
<VIDEO>vod_platform{S}= { yyextra->attr = V_(vod_platform); BEGIN(V_ATTR); }
|
||||
<VIDEO>id{S}= { yyextra->attr = V_(id); BEGIN(V_ATTR); }
|
||||
<VIDEO>template{S}= { yyextra->attr = V_(template); BEGIN(V_ATTR); }
|
||||
<VIDEO>medium{S}= { yyextra->attr = V_(medium); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom0{S}= { yyextra->attr = V_(custom[0]); BEGIN(V_ATTR); } // probably smarter way to do this ¯\_(ツ)_/¯
|
||||
<VIDEO>custom1{S}= { yyextra->attr = V_(custom[1]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom2{S}= { yyextra->attr = V_(custom[2]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom3{S}= { yyextra->attr = V_(custom[3]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom4{S}= { yyextra->attr = V_(custom[4]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom5{S}= { yyextra->attr = V_(custom[5]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom6{S}= { yyextra->attr = V_(custom[6]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom7{S}= { yyextra->attr = V_(custom[7]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom8{S}= { yyextra->attr = V_(custom[8]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom9{S}= { yyextra->attr = V_(custom[9]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom10{S}= { yyextra->attr = V_(custom[10]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom11{S}= { yyextra->attr = V_(custom[11]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom12{S}= { yyextra->attr = V_(custom[12]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom13{S}= { yyextra->attr = V_(custom[13]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom14{S}= { yyextra->attr = V_(custom[14]); BEGIN(V_ATTR); }
|
||||
<VIDEO>custom15{S}= { yyextra->attr = V_(custom[15]); BEGIN(V_ATTR); }
|
||||
<VIDEO>co\-host{S}= { yyextra->attr = V_(co_hosts); BEGIN(V2_ATTR); }
|
||||
<VIDEO>guest{S}= { yyextra->attr = V_(guests); BEGIN(V2_ATTR); }
|
||||
<VIDEO>annotator{S}= { yyextra->attr = V_(annotators); BEGIN(V2_ATTR); }
|
||||
<VIDEO>publication_date{S}= { yyextra->attr = V_(publication_date); BEGIN(V3_ATTR); }
|
||||
<VIDEO>output{S}= { yyextra->attr = V_(output); BEGIN(V_ATTR); }
|
||||
<VIDEO>\] { BEGIN(ANNOTATION); };
|
||||
<VIDEO>. { HMML_ERR("Invalid char '%s' in video tag.", yytext); }
|
||||
<VIDEO>. { HMML_ERR("Unknown attribute in video tag, beginning with '%s'.", yytext); }
|
||||
|
||||
<V_ATTR>{S} { BEGIN(VIDEO); }
|
||||
<V_ATTR>{ATTR_SIMPLE} { *(char**)yyextra->attr = strndup(yytext , yyleng ); BEGIN(VIDEO); }
|
||||
|
@ -133,6 +158,11 @@ RB \]
|
|||
<V2_ATTR>{ATTR_QUOTED} { sb_push(*(char***)yyextra->attr, UNQUOTE(strndup(yytext+1, yyleng-2))); BEGIN(VIDEO); }
|
||||
<V2_ATTR>\] { yyless(0); BEGIN(VIDEO); }
|
||||
|
||||
<V3_ATTR>{S} { BEGIN(VIDEO); }
|
||||
<V3_ATTR>{ATTR_SIMPLE} { *(long*)yyextra->attr = atol(yytext); BEGIN(VIDEO); }
|
||||
<V3_ATTR>{ATTR_QUOTED} { *(long*)yyextra->attr = atol(UNQUOTE_LEN(yytext+1, yyleng-2)); BEGIN(VIDEO); }
|
||||
<V3_ATTR>\] { yyless(0); BEGIN(VIDEO); }
|
||||
|
||||
<ANNOTATION>{TIMECODE}{LB}@ { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-4); BEGIN(AUTHOR); }
|
||||
<ANNOTATION>{TIMECODE} { NEWANNO(); yyextra->an.time = strndup(yytext+1, yyleng-2); BEGIN(TEXT_START); }
|
||||
<ANNOTATION>{BAD_TIMECODE} { HMML_ERR("Timecode %s out of range.", yytext); }
|
||||
|
@ -142,7 +172,7 @@ RB \]
|
|||
<TEXT_START>{LB}: { M_(CATEGORY, TEXT); BEGIN(MARKER); }
|
||||
<TEXT_START>{LB}@ { M_(MEMBER , TEXT); BEGIN(MARKER); }
|
||||
<TEXT_START>{LB}~ { M_(PROJECT , TEXT); BEGIN(MARKER); }
|
||||
<TEXT_START>{LB} { yyless(0); BEGIN(TEXT); }
|
||||
<TEXT_START>{LB} { BEGIN(TEXT); }
|
||||
<TEXT_START>. { HMML_ERR("Unknown character '%s' after timecode.", yytext); }
|
||||
|
||||
<TEXT>{TEXT_BREAK}+ { memcpy(sb_add(yyextra->an.text, yyleng), yytext, yyleng); }
|
||||
|
@ -210,7 +240,7 @@ RB \]
|
|||
<CATEGORIES>{S}
|
||||
<CATEGORIES>:{ATTR_SIMPLE} { HMML_Marker m = { HMML_CATEGORY, strndup(yytext+1, yyleng-1), NULL, NULL, -1 }; sb_push(yyextra->an.markers, m); }
|
||||
<CATEGORIES>:{ATTR_QUOTED} { HMML_Marker m = { HMML_CATEGORY, UNQUOTE(strndup(yytext+2, yyleng-3)), NULL, NULL, -1 }; sb_push(yyextra->an.markers, m); }
|
||||
<CATEGORIES>\]{LB} { BEGIN(QUOTES); }
|
||||
<CATEGORIES>\]{LB}quote { BEGIN(QUOTES); }
|
||||
<CATEGORIES>\] { BEGIN(ANNOTATION); }
|
||||
<CATEGORIES>. { HMML_ERR("Unexpected character in category tag: '%s'\n", yytext); }
|
||||
|
||||
|
@ -318,6 +348,13 @@ void hmml_free(HMML_Output* hmml){
|
|||
free(hmml->metadata.title);
|
||||
free(hmml->metadata.vod_platform);
|
||||
free(hmml->metadata.id);
|
||||
free(hmml->metadata.template);
|
||||
free(hmml->metadata.medium);
|
||||
free(hmml->metadata.output);
|
||||
|
||||
for(size_t i = 0; i < HMML_CUSTOM_ATTR_COUNT; ++i){
|
||||
free(hmml->metadata.custom[i]);
|
||||
}
|
||||
|
||||
sb_each(i, hmml->metadata.co_hosts) free(*i);
|
||||
sb_each(i, hmml->metadata.guests) free(*i);
|
||||
|
@ -348,7 +385,7 @@ Index* index_find(Index* base, const char* text){
|
|||
void hmml_dump(HMML_Output* hmml){
|
||||
|
||||
if(!hmml){
|
||||
puts("(null");
|
||||
puts("(null)");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -357,7 +394,6 @@ void hmml_dump(HMML_Output* hmml){
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
puts("Annotations:");
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
|
|
|
@ -3,8 +3,16 @@ all: hmml.a example
|
|||
hmml.a: hmmlib.o
|
||||
ar rcs $@ $<
|
||||
|
||||
hmmlib.c: hmmlib.l
|
||||
lex -o $@ $<
|
||||
|
||||
hmmlib.o: hmmlib.c
|
||||
gcc -D_GNU_SOURCE -g -c $< -o $@
|
||||
gcc -std=gnu99 -D_GNU_SOURCE -g -c $< -o $@
|
||||
|
||||
example: example.c hmml.a
|
||||
gcc -g $^ -o $@
|
||||
gcc -std=gnu99 -g $^ -o $@
|
||||
|
||||
clean:
|
||||
$(RM) hmml.a hmmlib.o hmmlib.c example
|
||||
|
||||
.PHONY: all clean
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
/utils/hmmldump
|
||||
/utils/fuzz/fuzz.gcno
|
||||
/utils/fuzz/fuzz.gcda
|
||||
/utils/fuzz/output
|
||||
/utils/fuzz/fuzz
|
|
@ -0,0 +1,6 @@
|
|||
This is a single-header library for parsing the HMML Format.
|
||||
See https://git.handmade.network/Annotation-Pushers/Annotation-System/-/wikis/hmmlspec
|
||||
|
||||
To use:
|
||||
1. #include "hmmlib.h" in any files that use the functions / data structures.
|
||||
2. in **one** of your .c files, #define HMMLIB_IMPLEMENTATION before including it.
|
|
@ -0,0 +1,859 @@
|
|||
#ifndef HMMLIB_H_
|
||||
#define HMMLIB_H_
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// Data structures
|
||||
|
||||
typedef struct {
|
||||
char* name;
|
||||
char* role;
|
||||
} HMML_Credit;
|
||||
|
||||
typedef struct {
|
||||
char* key;
|
||||
char* value;
|
||||
} HMML_VideoCustomMetaData;
|
||||
|
||||
typedef struct {
|
||||
char* stream_platform;
|
||||
char* project;
|
||||
char* title;
|
||||
char* vod_platform;
|
||||
char* id;
|
||||
char* output;
|
||||
char* template;
|
||||
char* medium;
|
||||
char* number;
|
||||
char* cc_lang;
|
||||
|
||||
HMML_Credit* credits;
|
||||
size_t credit_count;
|
||||
|
||||
HMML_Credit* uncredits;
|
||||
size_t uncredit_count;
|
||||
|
||||
HMML_VideoCustomMetaData* custom;
|
||||
size_t custom_count;
|
||||
|
||||
} HMML_VideoMetaData;
|
||||
|
||||
typedef struct {
|
||||
char* site;
|
||||
char* page;
|
||||
char* url;
|
||||
char* title;
|
||||
char* article;
|
||||
char* author;
|
||||
char* editor;
|
||||
char* publisher;
|
||||
char* isbn;
|
||||
int offset;
|
||||
} HMML_Reference;
|
||||
|
||||
typedef enum {
|
||||
HMML_CATEGORY,
|
||||
HMML_MEMBER,
|
||||
HMML_PROJECT,
|
||||
|
||||
HMML_MARKER_COUNT,
|
||||
} HMML_MarkerType;
|
||||
|
||||
typedef struct {
|
||||
HMML_MarkerType type;
|
||||
char* marker;
|
||||
char* parameter;
|
||||
char* episode;
|
||||
int offset;
|
||||
} HMML_Marker;
|
||||
|
||||
typedef struct {
|
||||
_Bool present;
|
||||
int id;
|
||||
char* author;
|
||||
} HMML_Quote;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
|
||||
int h, m, s, ms;
|
||||
|
||||
char* text;
|
||||
char* author;
|
||||
|
||||
HMML_Reference* references;
|
||||
size_t reference_count;
|
||||
|
||||
HMML_Marker* markers;
|
||||
size_t marker_count;
|
||||
|
||||
HMML_Quote quote;
|
||||
} HMML_Timestamp;
|
||||
|
||||
typedef struct {
|
||||
int line;
|
||||
int col;
|
||||
char* message;
|
||||
} HMML_Error;
|
||||
|
||||
typedef struct {
|
||||
_Bool well_formed;
|
||||
HMML_VideoMetaData metadata;
|
||||
HMML_Timestamp* timestamps;
|
||||
size_t timestamp_count;
|
||||
HMML_Error error;
|
||||
void* free_list; // implementation detail
|
||||
} HMML_Output;
|
||||
|
||||
// Functions
|
||||
|
||||
HMML_Output hmml_parse (const char* string);
|
||||
void hmml_free (HMML_Output* output);
|
||||
|
||||
// Version
|
||||
|
||||
extern const struct HMML_Version {
|
||||
int Major, Minor, Patch;
|
||||
} hmml_version;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef HMMLIB_IMPLEMENTATION
|
||||
|
||||
#include <setjmp.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define HSTX(x) x, sizeof(x)-1
|
||||
#define HSTR(x) (const struct _hmml_str){ HSTX(x) }
|
||||
|
||||
#ifndef MALLOC
|
||||
#define MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef REALLOC
|
||||
#define REALLOC realloc
|
||||
#endif
|
||||
|
||||
#ifndef countof
|
||||
#define countof(x) (sizeof(x)/sizeof(*x))
|
||||
#endif
|
||||
|
||||
#define _hmml_debug(...)
|
||||
//#define _hmml_debug printf
|
||||
|
||||
struct _hmml_parser {
|
||||
HMML_Output out;
|
||||
const char* mem;
|
||||
const char* cursor;
|
||||
jmp_buf err_buf;
|
||||
uintptr_t* free_list;
|
||||
int line;
|
||||
};
|
||||
|
||||
struct _hmml_str {
|
||||
const char* ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
// memory management boilerplate stuff
|
||||
|
||||
static void* _hmml_store_ptr(struct _hmml_parser* p, void* input)
|
||||
{
|
||||
uintptr_t* ptr;
|
||||
if(p->free_list) {
|
||||
ptr = p->free_list;
|
||||
if(ptr[1] + 1 == ptr[0]) {
|
||||
size_t n = ptr[0] << 1;
|
||||
ptr = REALLOC(ptr, n * sizeof(uintptr_t));
|
||||
ptr[0] = n;
|
||||
}
|
||||
ptr[ptr[1]] = (uintptr_t)input;
|
||||
ptr[1]++;
|
||||
} else {
|
||||
ptr = MALLOC(8 * sizeof(uintptr_t));
|
||||
ptr[0] = 8;
|
||||
ptr[1] = 3;
|
||||
ptr[2] = (uintptr_t)input;
|
||||
}
|
||||
p->free_list = ptr;
|
||||
return input;
|
||||
}
|
||||
|
||||
static char* _hmml_persist_str(struct _hmml_parser* p, const struct _hmml_str str)
|
||||
{
|
||||
char* mem = MALLOC(str.len+1);
|
||||
memcpy(mem, str.ptr, str.len);
|
||||
mem[str.len] = '\0';
|
||||
return _hmml_store_ptr(p, mem);
|
||||
}
|
||||
|
||||
static void _hmml_persist_array_fn(struct _hmml_parser* p, void** out, size_t* out_count, void* in, size_t in_size)
|
||||
{
|
||||
void* base;
|
||||
if(!*out) {
|
||||
base = MALLOC(in_size + sizeof(size_t));
|
||||
_hmml_store_ptr(p, base);
|
||||
*(size_t*)base = p->free_list[1]-1;
|
||||
} else {
|
||||
base = (char*)(*out) - sizeof(size_t);
|
||||
base = REALLOC(base, (*out_count + 1) * in_size + sizeof(size_t));
|
||||
size_t free_list_off = *(size_t*)base;
|
||||
p->free_list[free_list_off] = (intptr_t)base;
|
||||
}
|
||||
|
||||
*out = (char*)base + sizeof(size_t);
|
||||
memcpy((char*)*out + (*out_count * in_size), in, in_size);
|
||||
++(*out_count);
|
||||
}
|
||||
|
||||
#define _hmml_persist_array(p, out, out_count, in) \
|
||||
_hmml_persist_array_fn((p), (void**)(out), (out_count), &(in), sizeof(in))
|
||||
|
||||
// error handling
|
||||
|
||||
#define _hmml_err(p, fmt, ...) \
|
||||
_hmml_err_fn((p), fmt "\n", ##__VA_ARGS__)
|
||||
|
||||
__attribute__((noreturn))
|
||||
static void _hmml_err_fn(struct _hmml_parser* p, const char* fmt, ...)
|
||||
{
|
||||
static char error_buf[4096];
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
int n = vsnprintf(error_buf, sizeof(error_buf), fmt, va);
|
||||
va_end(va);
|
||||
|
||||
int line = 1, col = 1;
|
||||
for(const char* ptr = p->mem; ptr != p->cursor; ++ptr) {
|
||||
if(*ptr == '\n') {
|
||||
++line;
|
||||
col = 1;
|
||||
} else {
|
||||
++col;
|
||||
}
|
||||
}
|
||||
|
||||
p->out.error.message = _hmml_persist_str(p, (struct _hmml_str){ error_buf, n });
|
||||
p->out.error.line = line;
|
||||
p->out.error.col = col;
|
||||
|
||||
longjmp(p->err_buf, 1);
|
||||
}
|
||||
|
||||
// actual parsing stuff
|
||||
|
||||
static void _hmml_skip_ws(struct _hmml_parser* p)
|
||||
{
|
||||
for(;;) {
|
||||
uint8_t c = *p->cursor;
|
||||
if(c && c <= ' ') {
|
||||
if(c == '\n') {
|
||||
++p->line;
|
||||
}
|
||||
++p->cursor;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static _Bool _hmml_str_eq(struct _hmml_str a, struct _hmml_str b)
|
||||
{
|
||||
return a.len == b.len && memcmp(a.ptr, b.ptr, a.len) == 0;
|
||||
}
|
||||
|
||||
static _Bool _hmml_unesc(char in, char* out)
|
||||
{
|
||||
if(strchr("[]:@~\\\"", in)) {
|
||||
*out = in;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static char* _hmml_read_attr(struct _hmml_parser* p, char* mem, size_t mem_size, _Bool break_on_punct)
|
||||
{
|
||||
const char* src = p->cursor;
|
||||
char* dst = mem;
|
||||
|
||||
if(*src == '"') {
|
||||
++src;
|
||||
while(*src && *src != '"' && (size_t)(src - p->cursor) < mem_size) {
|
||||
char converted;
|
||||
if(*src == '\\' && _hmml_unesc(src[1], &converted)) {
|
||||
*dst++ = converted;
|
||||
src += 2;
|
||||
} else {
|
||||
*dst++ = *src++;
|
||||
}
|
||||
}
|
||||
|
||||
if(*src != '"') {
|
||||
_hmml_err(p, "Partially quoted attribute");
|
||||
}
|
||||
|
||||
*dst = '\0';
|
||||
p->cursor = src+1;
|
||||
} else {
|
||||
const char* breaks = break_on_punct
|
||||
? " ]\r\n\t:,'-.#=[\\?!…()\"%"
|
||||
: " ]\r\n\t"
|
||||
;
|
||||
|
||||
size_t n = strcspn(src, breaks);
|
||||
if(n >= mem_size) {
|
||||
_hmml_err(p, "Attribute [%.10s...] too long", p->cursor);
|
||||
}
|
||||
memcpy(dst, src, n);
|
||||
dst += n;
|
||||
*dst = '\0';
|
||||
p->cursor += n;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void _hmml_read_kv(struct _hmml_parser* p, struct _hmml_str* key, struct _hmml_str* val)
|
||||
{
|
||||
static char key_memory[64];
|
||||
static char val_memory[1024];
|
||||
|
||||
size_t key_len = strcspn(p->cursor, " \r\n\t=");
|
||||
if(key_len >= sizeof(key_memory)) {
|
||||
_hmml_err(p, "Attribute key [%.10s...] too long", p->cursor);
|
||||
}
|
||||
|
||||
memcpy(key_memory, p->cursor, key_len);
|
||||
key_memory[key_len] = '\0';
|
||||
p->cursor += key_len;
|
||||
|
||||
_hmml_skip_ws(p);
|
||||
|
||||
if(*p->cursor != '=') {
|
||||
_hmml_err(p, "Expected '=', got [%.3s]", p->cursor);
|
||||
}
|
||||
|
||||
++p->cursor;
|
||||
|
||||
char* end = _hmml_read_attr(p, val_memory, sizeof(val_memory), 0);
|
||||
|
||||
_hmml_debug("read kv [%s] = [%s]\n", key_memory, val_memory);
|
||||
|
||||
key->ptr = key_memory;
|
||||
key->len = key_len;
|
||||
|
||||
val->ptr = val_memory;
|
||||
val->len = end - val_memory;
|
||||
}
|
||||
|
||||
static HMML_Marker _hmml_parse_marker(struct _hmml_parser* p)
|
||||
{
|
||||
static char marker_mem[4096];
|
||||
|
||||
// the extended markers are inside [ ] and can contain parameters
|
||||
_Bool extended = *p->cursor == '[';
|
||||
if(extended) {
|
||||
++p->cursor;
|
||||
}
|
||||
|
||||
HMML_Marker marker = {
|
||||
.offset = -1,
|
||||
};
|
||||
|
||||
char c = *p->cursor;
|
||||
if(c == '~') {
|
||||
marker.type = HMML_PROJECT;
|
||||
} else if(c == '@') {
|
||||
marker.type = HMML_MEMBER;
|
||||
} else if(c == ':') {
|
||||
marker.type = HMML_CATEGORY;
|
||||
} else {
|
||||
_hmml_err(p, "Unknown marker type");
|
||||
}
|
||||
|
||||
++p->cursor;
|
||||
|
||||
char* end = _hmml_read_attr(p, marker_mem, sizeof(marker_mem), !extended);
|
||||
marker.marker = _hmml_persist_str(p, (struct _hmml_str){ marker_mem, end - marker_mem });
|
||||
|
||||
if(extended) {
|
||||
_hmml_skip_ws(p);
|
||||
|
||||
if(*p->cursor == '#') {
|
||||
++p->cursor;
|
||||
size_t n = strcspn(p->cursor, " ");
|
||||
marker.episode = _hmml_persist_str(p, (struct _hmml_str){ p->cursor, n });
|
||||
p->cursor += n + 1;
|
||||
}
|
||||
|
||||
if(*p->cursor != ']') {
|
||||
const char* end = p->cursor;
|
||||
|
||||
for(;;) {
|
||||
if(!*end) {
|
||||
break;
|
||||
}
|
||||
|
||||
char converted;
|
||||
if(*end == '\\' && _hmml_unesc(end[1], &converted)) {
|
||||
end += 2;
|
||||
} else if(*end == ']'){
|
||||
break;
|
||||
} else {
|
||||
++end;
|
||||
}
|
||||
}
|
||||
|
||||
marker.parameter = _hmml_persist_str(p, (struct _hmml_str){ p->cursor, end - p->cursor });
|
||||
p->cursor = end;
|
||||
}
|
||||
|
||||
if(*p->cursor != ']') {
|
||||
_hmml_err(p, "Expected ']'");
|
||||
}
|
||||
++p->cursor;
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
static HMML_Reference _hmml_parse_ref(struct _hmml_parser* p)
|
||||
{
|
||||
HMML_Reference ref = {
|
||||
.offset = -1,
|
||||
};
|
||||
|
||||
struct str_attr {
|
||||
struct _hmml_str str;
|
||||
char** dest;
|
||||
} str_attrs[] = {
|
||||
{ HSTR("site") , &ref.site },
|
||||
{ HSTR("page") , &ref.page },
|
||||
{ HSTR("url") , &ref.url },
|
||||
{ HSTR("title") , &ref.title },
|
||||
{ HSTR("article") , &ref.article },
|
||||
{ HSTR("author") , &ref.author },
|
||||
{ HSTR("editor") , &ref.editor },
|
||||
{ HSTR("publisher"), &ref.publisher },
|
||||
{ HSTR("isbn") , &ref.isbn },
|
||||
};
|
||||
|
||||
for(;;) {
|
||||
next_attr:
|
||||
_hmml_skip_ws(p);
|
||||
|
||||
if(*p->cursor == ']') {
|
||||
++p->cursor;
|
||||
break;
|
||||
}
|
||||
|
||||
struct _hmml_str key, value;
|
||||
_hmml_read_kv(p, &key, &value);
|
||||
|
||||
for(size_t i = 0; i < countof(str_attrs); ++i) {
|
||||
struct str_attr* s = str_attrs + i;
|
||||
if(_hmml_str_eq(key, s->str)) {
|
||||
*s->dest = _hmml_persist_str(p, value);
|
||||
goto next_attr;
|
||||
}
|
||||
}
|
||||
|
||||
_hmml_err(p, "Unknown reference attribute");
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
static void _hmml_parse_timecode(struct _hmml_parser* p, HMML_Timestamp* ts)
|
||||
{
|
||||
unsigned int h = 0, m = 0, s = 0, ms = 0;
|
||||
int offset = 0;
|
||||
int count = sscanf(p->cursor, "[%u:%u%n", &m, &s, &offset);
|
||||
|
||||
if(count < 2) {
|
||||
_hmml_err(p, "Unable to parse timecode");
|
||||
}
|
||||
|
||||
p->cursor += offset;
|
||||
char c = *p->cursor;
|
||||
|
||||
if(c == ':') {
|
||||
unsigned int tmp;
|
||||
offset = 0;
|
||||
if(sscanf(p->cursor, ":%u%n", &tmp, &offset) != 1 || offset == 0) {
|
||||
_hmml_err(p, "Unable to parse 3-part timecode");
|
||||
}
|
||||
|
||||
h = m;
|
||||
m = s;
|
||||
s = tmp;
|
||||
|
||||
p->cursor += offset;
|
||||
c = *p->cursor;
|
||||
}
|
||||
|
||||
if(c == '.') {
|
||||
unsigned int tmp;
|
||||
offset = 0;
|
||||
|
||||
int non_number_chars = 2;
|
||||
int digits_in_100 = 3;
|
||||
int max_chars_to_parse = non_number_chars + digits_in_100;
|
||||
|
||||
if(sscanf(p->cursor, ".%u]%n", &tmp, &offset) != 1 || offset == 0 || offset > max_chars_to_parse) {
|
||||
_hmml_err(p, "Unable to parse %u.5-part timecode", h ? 3 : 2);
|
||||
}
|
||||
|
||||
for(int i = offset - non_number_chars; i < digits_in_100; ++i) {
|
||||
tmp *= 10;
|
||||
}
|
||||
ms = tmp;
|
||||
|
||||
p->cursor += offset;
|
||||
|
||||
} else if(c != ']') {
|
||||
_hmml_err(p, "Unable to parse timecode");
|
||||
} else {
|
||||
++p->cursor;
|
||||
}
|
||||
|
||||
if(ms >= 1000) {
|
||||
_hmml_err(p, "Milliseconds cannot exceed 999");
|
||||
}
|
||||
|
||||
if(s >= 60) {
|
||||
_hmml_err(p, "Seconds cannot exceed 59");
|
||||
}
|
||||
|
||||
if(m >= 60) {
|
||||
_hmml_err(p, "Minutes cannot exceed 59");
|
||||
}
|
||||
|
||||
ts->h = h;
|
||||
ts->m = m;
|
||||
ts->s = s;
|
||||
ts->ms = ms;
|
||||
}
|
||||
|
||||
static void _hmml_store_marker(struct _hmml_parser* p, HMML_Timestamp* ts, char** out, char* text_mem, size_t text_mem_size)
|
||||
{
|
||||
HMML_Marker m = _hmml_parse_marker(p);
|
||||
m.offset = (*out) - text_mem;
|
||||
_hmml_persist_array(p, &ts->markers, &ts->marker_count, m);
|
||||
|
||||
const char* marker_text = m.parameter
|
||||
? m.parameter
|
||||
: m.marker
|
||||
;
|
||||
|
||||
size_t text_len = strlen(marker_text);
|
||||
if((*out) + text_len > text_mem + text_mem_size) {\
|
||||
_hmml_err(p, "Not enough text memory");\
|
||||
}
|
||||
memcpy(*out, marker_text, text_len);
|
||||
*out += text_len;
|
||||
}
|
||||
|
||||
static size_t _hmml_parse_text(struct _hmml_parser* p, HMML_Timestamp* ts)
|
||||
{
|
||||
static char text_mem[4096];
|
||||
char* out = text_mem;
|
||||
|
||||
memset(text_mem, 0, sizeof(text_mem));
|
||||
|
||||
for(;;) {
|
||||
size_t n = strcspn(p->cursor, "\\\n\r[]:@~");
|
||||
char c = p->cursor[n];
|
||||
|
||||
if(out + n > text_mem + sizeof(text_mem)) {\
|
||||
_hmml_err(p, "Not enough text memory");\
|
||||
}
|
||||
memcpy(out, p->cursor, n);
|
||||
|
||||
p->cursor += n;
|
||||
out += n;
|
||||
|
||||
if(c == '\0') {
|
||||
_hmml_err(p, "Unexpected EOF");
|
||||
}
|
||||
|
||||
else if(c == ']') {
|
||||
++p->cursor;
|
||||
break;
|
||||
}
|
||||
|
||||
else if(c == '\\') {
|
||||
char converted;
|
||||
if(_hmml_unesc(p->cursor[1], &converted)) {
|
||||
*out++ = converted;
|
||||
p->cursor += 2;
|
||||
} else {
|
||||
*out++ = '\\';
|
||||
p->cursor++;
|
||||
}
|
||||
}
|
||||
|
||||
else if(c == '\n' || c == '\r') {
|
||||
++p->cursor;
|
||||
}
|
||||
|
||||
else if(c == '[') {
|
||||
if(strncmp(p->cursor + 1, "ref", 3) == 0) {
|
||||
p->cursor += 4;
|
||||
HMML_Reference ref = _hmml_parse_ref(p);
|
||||
ref.offset = out - text_mem;
|
||||
_hmml_persist_array(p, &ts->references, &ts->reference_count, ref);
|
||||
} else {
|
||||
_hmml_store_marker(p, ts, &out, text_mem, sizeof(text_mem));
|
||||
}
|
||||
}
|
||||
|
||||
// it is a @ ~ or : marker without parameters
|
||||
else {
|
||||
// if next char is a space, or prev char is not a space*, then it can't be a marker
|
||||
// * unless it's the first char
|
||||
if(strchr(" \t\r\n", p->cursor[1]) || !(out == text_mem || strchr(" \t\r\n", p->cursor[-1]))) {
|
||||
*out++ = c;
|
||||
++p->cursor;
|
||||
} else {
|
||||
_hmml_store_marker(p, ts, &out, text_mem, sizeof(text_mem));
|
||||
}
|
||||
}
|
||||
|
||||
if((size_t)(out - text_mem) >= sizeof(text_mem)) {
|
||||
_hmml_err(p, "Not enough text memory");
|
||||
}
|
||||
}
|
||||
|
||||
// trim trailing whitespace
|
||||
while(out > text_mem && (uint8_t)(out[-1]) <= ' ') {
|
||||
out[-1] = '\0';
|
||||
--out;
|
||||
}
|
||||
|
||||
size_t text_size = out - text_mem;
|
||||
ts->text = _hmml_persist_str(p, (struct _hmml_str){ text_mem, text_size });
|
||||
|
||||
return text_size;
|
||||
}
|
||||
|
||||
static void _hmml_parse_quote(struct _hmml_parser* p, HMML_Timestamp* ts)
|
||||
{
|
||||
char member[256];
|
||||
int id;
|
||||
int off = 0;
|
||||
|
||||
if(sscanf(p->cursor, "[quote %255s %d]%n", member, &id, &off) == 2 && off) {
|
||||
ts->quote.present = 1;
|
||||
ts->quote.id = id;
|
||||
ts->quote.author = _hmml_persist_str(p, (struct _hmml_str){ member, strlen(member) });
|
||||
} else if(sscanf(p->cursor, "[quote %d]%n", &id, &off) == 1 && off) {
|
||||
ts->quote.present = 1;
|
||||
ts->quote.id = id;
|
||||
} else {
|
||||
_hmml_err(p, "Unable to parse quote");
|
||||
}
|
||||
|
||||
p->cursor += off;
|
||||
}
|
||||
|
||||
static void _hmml_parse_timestamps(struct _hmml_parser* p)
|
||||
{
|
||||
for(;;) {
|
||||
_hmml_skip_ws(p);
|
||||
|
||||
if(*p->cursor == '\0') {
|
||||
_hmml_err(p, "Unexpected EOF");
|
||||
}
|
||||
|
||||
if(strncmp(p->cursor, "[/video]", 8) == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
HMML_Timestamp ts = {
|
||||
.line = p->line
|
||||
};
|
||||
|
||||
_hmml_parse_timecode(p, &ts);
|
||||
|
||||
if(*p->cursor != '[') {
|
||||
_hmml_err(p, "Expected '['");
|
||||
}
|
||||
|
||||
if(p->cursor[1] == '@') {
|
||||
HMML_Marker m = _hmml_parse_marker(p);
|
||||
ts.author = m.marker;
|
||||
}
|
||||
|
||||
++p->cursor;
|
||||
|
||||
int text_len = _hmml_parse_text(p, &ts);
|
||||
|
||||
if(p->cursor[0] == '[' && p->cursor[1] == ':') {
|
||||
++p->cursor;
|
||||
do {
|
||||
HMML_Marker m = _hmml_parse_marker(p);
|
||||
_hmml_persist_array(p, &ts.markers, &ts.marker_count, m);
|
||||
_hmml_skip_ws(p);
|
||||
if(*p->cursor != ':' && *p->cursor != ']') {
|
||||
_hmml_err(p, "Unterminated post-text category node");
|
||||
}
|
||||
} while(*p->cursor == ':');
|
||||
++p->cursor;
|
||||
}
|
||||
|
||||
if(p->cursor[0] == '[' && p->cursor[1] == 'q') {
|
||||
_hmml_parse_quote(p, &ts);
|
||||
}
|
||||
|
||||
// convert all markers to lowercase, fix any out of range offsets
|
||||
for(size_t i = 0; i < ts.marker_count; ++i) {
|
||||
HMML_Marker* m = ts.markers + i;
|
||||
for(char* c = m->marker; *c; ++c) {
|
||||
if(*c >= 'A' && *c <= 'Z') {
|
||||
*c = (*c - ('A' - 'a'));
|
||||
}
|
||||
}
|
||||
if(m->offset > text_len) {
|
||||
m->offset = text_len;
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < ts.reference_count; ++i) {
|
||||
HMML_Reference* ref = ts.references + i;
|
||||
if(ref->offset > text_len) {
|
||||
ref->offset = text_len;
|
||||
}
|
||||
}
|
||||
|
||||
_hmml_persist_array(p, &p->out.timestamps, &p->out.timestamp_count, ts);
|
||||
}
|
||||
}
|
||||
|
||||
static HMML_Credit _hmml_parse_credit(struct _hmml_parser* p, struct _hmml_str value)
|
||||
{
|
||||
HMML_Credit credit = {};
|
||||
char* colon = strchr(value.ptr, ':');
|
||||
if(colon) {
|
||||
*colon = '\0';
|
||||
credit.name = _hmml_persist_str(p, (struct _hmml_str){ value.ptr, colon - value.ptr });
|
||||
credit.role = _hmml_persist_str(p, (struct _hmml_str){ colon+1, value.len - ((colon+1) - value.ptr) });
|
||||
} else {
|
||||
credit.name = _hmml_persist_str(p, value);
|
||||
}
|
||||
return credit;
|
||||
}
|
||||
|
||||
static void _hmml_parse_video(struct _hmml_parser* p)
|
||||
{
|
||||
struct str_attr {
|
||||
struct _hmml_str str;
|
||||
char** dest;
|
||||
} str_attrs[] = {
|
||||
{ HSTR("stream_platform"), &p->out.metadata.stream_platform },
|
||||
{ HSTR("project") , &p->out.metadata.project },
|
||||
{ HSTR("title") , &p->out.metadata.title },
|
||||
{ HSTR("vod_platform") , &p->out.metadata.vod_platform },
|
||||
{ HSTR("id") , &p->out.metadata.id },
|
||||
{ HSTR("template") , &p->out.metadata.template },
|
||||
{ HSTR("medium") , &p->out.metadata.medium },
|
||||
{ HSTR("number") , &p->out.metadata.number },
|
||||
{ HSTR("output") , &p->out.metadata.output },
|
||||
{ HSTR("cc_lang") , &p->out.metadata.cc_lang },
|
||||
};
|
||||
|
||||
for(;;) {
|
||||
next_attr:
|
||||
_hmml_skip_ws(p);
|
||||
|
||||
if(*p->cursor == ']') {
|
||||
++p->cursor;
|
||||
_hmml_parse_timestamps(p);
|
||||
return;
|
||||
}
|
||||
|
||||
struct _hmml_str key, value;
|
||||
_hmml_read_kv(p, &key, &value);
|
||||
|
||||
for(size_t i = 0; i < countof(str_attrs); ++i) {
|
||||
struct str_attr* s = str_attrs + i;
|
||||
if(_hmml_str_eq(key, s->str)) {
|
||||
*s->dest = _hmml_persist_str(p, value);
|
||||
goto next_attr;
|
||||
}
|
||||
}
|
||||
|
||||
if(_hmml_str_eq(key, HSTR("credit"))) {
|
||||
HMML_Credit credit = _hmml_parse_credit(p, value);
|
||||
_hmml_persist_array(p, &p->out.metadata.credits, &p->out.metadata.credit_count, credit);
|
||||
goto next_attr;
|
||||
}
|
||||
|
||||
if(_hmml_str_eq(key, HSTR("uncredit"))) {
|
||||
HMML_Credit uncredit = _hmml_parse_credit(p, value);
|
||||
_hmml_persist_array(p, &p->out.metadata.uncredits, &p->out.metadata.uncredit_count, uncredit);
|
||||
goto next_attr;
|
||||
}
|
||||
|
||||
HMML_VideoCustomMetaData custom = {
|
||||
.key = _hmml_persist_str(p, key),
|
||||
.value = _hmml_persist_str(p, value),
|
||||
};
|
||||
|
||||
_hmml_persist_array(p, &p->out.metadata.custom, &p->out.metadata.custom_count, custom);
|
||||
}
|
||||
}
|
||||
|
||||
HMML_Output hmml_parse(const char* string)
|
||||
{
|
||||
struct _hmml_parser p = {
|
||||
.mem = string,
|
||||
.cursor = string,
|
||||
.line = 1,
|
||||
};
|
||||
|
||||
if(setjmp(p.err_buf) == 1) {
|
||||
// if it returns 1, an error happened
|
||||
p.out.free_list = p.free_list;
|
||||
return p.out;
|
||||
}
|
||||
|
||||
const struct _hmml_str prefix = HSTR("[video");
|
||||
if(strncmp(p.cursor, prefix.ptr, prefix.len)) {
|
||||
_hmml_err(&p, "Missing initial video tag.");
|
||||
} else {
|
||||
p.cursor += prefix.len;
|
||||
_hmml_parse_video(&p);
|
||||
}
|
||||
|
||||
p.out.free_list = p.free_list;
|
||||
p.out.well_formed = 1;
|
||||
return p.out;
|
||||
}
|
||||
|
||||
void hmml_free(HMML_Output* out)
|
||||
{
|
||||
if(!out->free_list) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(uintptr_t i = 2; i < ((uintptr_t*)out->free_list)[1]; ++i) {
|
||||
free(((void**)out->free_list)[i]);
|
||||
}
|
||||
|
||||
free(out->free_list);
|
||||
}
|
||||
|
||||
const struct HMML_Version hmml_version = {
|
||||
2, 0, 15
|
||||
};
|
||||
|
||||
#undef HSTX
|
||||
#undef HSTR
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
hmmldump: dump.c ../hmmlib.h stb_sb.h
|
||||
gcc -Wall -Wextra -I.. -g $< -o $@
|
|
@ -0,0 +1,241 @@
|
|||
#define HMMLIB_IMPLEMENTATION
|
||||
#include "hmmlib.h"
|
||||
#include "stb_sb.h"
|
||||
#include <stdbool.h>
|
||||
#include <getopt.h>
|
||||
|
||||
typedef struct {
|
||||
char* text;
|
||||
int* lines;
|
||||
} Index;
|
||||
|
||||
static Index* index_find(Index* base, const char* text)
|
||||
{
|
||||
for(size_t i = 0; i < sb_count(base); ++i){
|
||||
if(strcmp(base[i].text, text) == 0){
|
||||
return base + i;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void hmml_dump(HMML_Output* hmml, bool extra)
|
||||
{
|
||||
if(!hmml){
|
||||
puts("(null)");
|
||||
return;
|
||||
}
|
||||
|
||||
if(!hmml->well_formed){
|
||||
printf("Error:%d:%d %s\n", hmml->error.line, hmml->error.col, hmml->error.message);
|
||||
return;
|
||||
}
|
||||
|
||||
if(extra) {
|
||||
puts("Metadata:");
|
||||
static const char* meta[] = { "stream_platform", "project", "title", "vod_platform", "id", "output", "template", "medium" };
|
||||
for(size_t i = 0; i < countof(meta); ++i) {
|
||||
const char* value = ((char**)&hmml->metadata)[i];
|
||||
printf(" %s = %s\n", meta[i], value);
|
||||
}
|
||||
|
||||
puts(" Credits:");
|
||||
for(size_t i = 0; i < hmml->metadata.credit_count; ++i) {
|
||||
HMML_Credit* c = hmml->metadata.credits + i;
|
||||
printf(" %s [%s]\n", c->name, c->role);
|
||||
}
|
||||
|
||||
puts(" Custom:");
|
||||
for(size_t i = 0; i < hmml->metadata.custom_count; ++i) {
|
||||
HMML_VideoCustomMetaData* m = hmml->metadata.custom + i;
|
||||
printf(" %s = %s\n", m->key, m->value);
|
||||
}
|
||||
}
|
||||
|
||||
puts("Annotations:");
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
|
||||
char time_buf[256];
|
||||
char* tp = time_buf;
|
||||
|
||||
if(a->h) {
|
||||
*tp++ = (a->h%10) + '0';
|
||||
sprintf(tp, ":%02d:%02d", a->m, a->s);
|
||||
} else {
|
||||
sprintf(tp, " %2d:%02d", a->m, a->s);
|
||||
}
|
||||
|
||||
printf("\t%3d [%s] [%s]\n", a->line, time_buf, a->text);
|
||||
}
|
||||
|
||||
Index* authors = NULL;
|
||||
Index* markers[HMML_MARKER_COUNT] = {};
|
||||
int max_text_len = 0;
|
||||
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
|
||||
if(a->author){
|
||||
int len = strlen(a->author);
|
||||
if(len > max_text_len){
|
||||
max_text_len = len;
|
||||
}
|
||||
|
||||
Index* idx;
|
||||
if(!(idx = index_find(authors, a->author))){
|
||||
Index x = { .text = a->author };
|
||||
sb_push(authors, x);
|
||||
idx = &sb_last(authors);
|
||||
}
|
||||
|
||||
sb_push(idx->lines, a->line);
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
|
||||
for(size_t j = 0; j < a->marker_count; ++j){
|
||||
int type = a->markers[j].type;
|
||||
char* text = a->markers[j].marker;
|
||||
|
||||
int len = strlen(text);
|
||||
if(len > max_text_len){
|
||||
max_text_len = len;
|
||||
}
|
||||
|
||||
Index* idx;
|
||||
if(!(idx = index_find(markers[type], text))){
|
||||
Index x = { .text = text };
|
||||
sb_push(markers[type], x);
|
||||
idx = &sb_last(markers[type]);
|
||||
}
|
||||
|
||||
sb_push(idx->lines, a->line);
|
||||
}
|
||||
}
|
||||
|
||||
puts("Authors:");
|
||||
for(size_t i = 0; i < sb_count(authors); ++i){
|
||||
printf("\t %*s: ", max_text_len, authors[i].text);
|
||||
for(size_t j = 0; j < sb_count(authors[i].lines); ++j){
|
||||
printf("%3d ", authors[i].lines[j]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
|
||||
|
||||
static const char* m_tags[HMML_MARKER_COUNT] = { "Categories", "Members", "Projects" };
|
||||
|
||||
for(size_t i = 0; i < HMML_MARKER_COUNT; ++i){
|
||||
printf("%s:\n", m_tags[i]);
|
||||
for(size_t j = 0; j < sb_count(markers[i]); ++j){
|
||||
printf("\t %*s: ", max_text_len, markers[i][j].text);
|
||||
for(size_t k = 0; k < sb_count(markers[i][j].lines); ++k){
|
||||
printf("%3d ", markers[i][j].lines[k]);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
static const char* r_tags[] = { "Site", "Page", "URL", "Title", "Article", "Author", "Editor", "Publisher", "ISBN" };
|
||||
puts("References:");
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
for(size_t j = 0; j < a->reference_count; ++j){
|
||||
printf("\t%3d ", a->line);
|
||||
HMML_Reference* r = a->references + j;
|
||||
for(size_t k = 0; k < countof(r_tags); ++k){
|
||||
char* item = ((char**)r)[k];
|
||||
if(item){
|
||||
printf("[%s = %s] ", r_tags[k], item);
|
||||
}
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
puts("Quotes:");
|
||||
for(size_t i = 0; i < hmml->annotation_count; ++i){
|
||||
HMML_Annotation* a = hmml->annotations + i;
|
||||
if(a->quote.present){
|
||||
if(a->quote.author){
|
||||
printf("\t%3d [Quote #%d, by %s]", a->line, a->quote.id, a->quote.author);
|
||||
} else {
|
||||
printf("\t%3d [Quote #%d]", a->line, a->quote.id);
|
||||
}
|
||||
puts("");
|
||||
}
|
||||
}
|
||||
|
||||
for(size_t i = 0; i < sb_count(authors); ++i){
|
||||
sb_free(authors[i].lines);
|
||||
}
|
||||
sb_free(authors);
|
||||
|
||||
for(size_t i = 0; i < HMML_MARKER_COUNT; ++i){
|
||||
for(size_t j = 0; j < sb_count(markers[i]); ++j){
|
||||
sb_free(markers[i][j].lines);
|
||||
}
|
||||
sb_free(markers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void usage(char* argv0, FILE* out)
|
||||
{
|
||||
fprintf(out, "Usage: %s [-bx] [file]\n", argv0);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
bool dump_extra = false;
|
||||
bool breakpoint = false;
|
||||
int opt;
|
||||
|
||||
while((opt = getopt(argc, argv, "bx")) != -1) {
|
||||
if(opt == 'x') {
|
||||
dump_extra = true;
|
||||
} else if(opt == 'b') {
|
||||
breakpoint = true;
|
||||
} else {
|
||||
usage(argv[0], stderr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(optind >= argc){
|
||||
usage(argv[0], stderr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
argc -= (optind-1);
|
||||
argv += (optind-1);
|
||||
|
||||
FILE* f = fopen(argv[1], "r");
|
||||
if(!f) {
|
||||
perror(argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
char* mem = malloc(size+1);
|
||||
mem[size] = 0;
|
||||
|
||||
fread(mem, 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
HMML_Output out = hmml_parse(mem);
|
||||
free(mem);
|
||||
|
||||
if(breakpoint) {
|
||||
asm("int3");
|
||||
}
|
||||
|
||||
hmml_dump(&out, dump_extra);
|
||||
|
||||
hmml_free(&out);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
fuzz: fuzz.c ../../hmmlib.h
|
||||
afl-gcc -I../.. -g -D_GNU_SOURCE -fprofile-arcs -ftest-coverage $< -o $@
|
||||
|
||||
run: fuzz | output
|
||||
afl-fuzz -i tests -o output ./$<
|
||||
|
||||
cov: fuzz | output
|
||||
afl-cov -d output --coverage-cmd 'cat AFL_FILE | ./fuzz' --code-dir . --enable-branch-coverage --overwrite
|
||||
|
||||
output:
|
||||
mkdir -p $@
|
||||
|
||||
clean:
|
||||
rm -rf fuzz fuzz.gcno fuzz.gcda output
|
||||
|
||||
.PHONY: run cov clean
|
|
@ -0,0 +1,20 @@
|
|||
#define HMMLIB_IMPLEMENTATION
|
||||
#include "hmmlib.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
char* mem = NULL;
|
||||
size_t size = 0;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
while(fgets(buf, BUFSIZ, stdin)) {
|
||||
size_t n = strlen(buf) + 1;
|
||||
mem = realloc(mem, size + n);
|
||||
memcpy(mem + size, buf, n);
|
||||
size += n - 1;
|
||||
}
|
||||
|
||||
HMML_Output out = hmml_parse(mem);
|
||||
free(mem);
|
||||
hmml_free(&out);
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
[video member=nothings credit="inso:programmer" annotator=Miblo]
|
||||
[2:01][Recap and update the TODO list]
|
||||
[38:58][Continue implementing parse_tag()][:parsing :test]
|
||||
[41:40][@miblo][Ohhh, right. Yeah, the \[video\] and \[/video\] tags are the only :ones that [:have a s d f] that open-close format. All the [~other] [@tags abc] are "single" tags]
|
||||
[45:17][Enable parse_tag() to tokenise the \[video\] node][:parsing][quote bob 1]
|
||||
[3:42:11][@miblo][@nothings2: That's fine, yeah! They are also in: [ref
|
||||
site="GitLab: Annotation-Pushers / Annotation-Game"
|
||||
page="projects/nothings/obbg"
|
||||
url=http://git.handmadedev.org/Annotation-Pushers/Annotation-Game/tree/master/projects/nothings/obbg]]
|
||||
[3:50:44][Take a break][quote 5]
|
||||
[/video]
|
|
@ -0,0 +1,3 @@
|
|||
[video credit=inso:programmer]
|
||||
[2:01][Recap and :update the ~TODO @list]
|
||||
[/video]
|
|
@ -0,0 +1,25 @@
|
|||
[video member=nothings stream_platform=twitch stream_username=nothings2 project=obbg title="Open Block Building Game Development #32 (1/2)" vod_platform=youtube id=Vm-0ZUVMHHc annotator=Miblo]
|
||||
[2:01][Recap and update the TODO list]
|
||||
[10:08][Consult the example YouTube description file and the longest .hmml file][:test1 :test2 :abcd]
|
||||
[38:58][Continue implementing parse_tag()][:parsing]
|
||||
[41:40][@miblo][Ohhh, right. Yeah, the \[video\] and \[/video\] tags are the only ones that have that open-close format. All the other tags are "single" tags]
|
||||
[41:51][Continue writing parse_tag() anyway][:parsing]
|
||||
[43:10][@miblo][@nothings2: There isn't really, other than the rambling in: [ref
|
||||
site="GitLab: Annotation-Pushers / Annotation-System / Issues"
|
||||
page="Handmade Annotation Markup Language (previously MibloMarkup)"
|
||||
url=http://git.handmadedev.org/Annotation-Pushers/Annotation-System/issues/2]]
|
||||
[45:17][Enable parse_tag() to tokenise the \[video\] node][:parsing]
|
||||
[1:51:32][Parse out the embedded \: and \@ tags][:parsing]
|
||||
[1:57:50][:Run it to see if those two cases work and tweak the username conversion]
|
||||
[3:15:14][@experior][Add a space after the pound? Or another character]
|
||||
[3:16:40][Delete the \@ in the text node][:parsing]
|
||||
[3:42:11][@miblo][@nothings2: That's fine, yeah! They are also in: [ref
|
||||
site="GitLab: Annotation-Pushers / Annotation-Game"
|
||||
page="projects/nothings/obbg"
|
||||
url=http://git.handmadedev.org/Annotation-Pushers/Annotation-Game/tree/master/projects/nothings/obbg]]
|
||||
[3:47:14][@insofaras][[ref
|
||||
site="GitHub: nothings/obbg"
|
||||
page="Pull Request #8: get it building and running on linux by insofaras"
|
||||
url=https://github.com/nothings/obbg/pull/8/files#diff-90c561ba68b3be193f3378639ef489a0R1831]]
|
||||
[3:50:44][Take a break]
|
||||
[/video]
|
|
@ -0,0 +1,59 @@
|
|||
// stb stretchy_buffer.h v1.02 nothings.org/stb
|
||||
// with custom addtions sb_end, sb_pop, sb_erase
|
||||
|
||||
#ifndef STB_STRETCHY_BUFFER_H_INCLUDED
|
||||
#define STB_STRETCHY_BUFFER_H_INCLUDED
|
||||
|
||||
#ifndef NO_STRETCHY_BUFFER_SHORT_NAMES
|
||||
#define sb_free stb_sb_free
|
||||
#define sb_push stb_sb_push
|
||||
#define sb_count stb_sb_count
|
||||
#define sb_add stb_sb_add
|
||||
#define sb_last stb_sb_last
|
||||
#define sb_end stb_sb_end
|
||||
#define sb_pop stb_sb_pop
|
||||
#define sb_erase stb_sb_erase
|
||||
#define sb_each stb_sb_each
|
||||
#endif
|
||||
|
||||
#define stb_sb_free(a) ((a) ? free(stb__sbraw(a)),(a)=0,0 : 0)
|
||||
#define stb_sb_push(a,v) (stb__sbmaybegrow(a,1), (a)[stb__sbn(a)++] = (v))
|
||||
#define stb_sb_count(a) ((a) ? stb__sbn(a) : 0)
|
||||
#define stb_sb_add(a,n) (stb__sbmaybegrow(a,n), stb__sbn(a)+=(n), &(a)[stb__sbn(a)-(n)])
|
||||
#define stb_sb_last(a) ((a)[stb__sbn(a)-1])
|
||||
#define stb_sb_end(a) ((a) ? (a) + stb__sbn(a) : 0)
|
||||
#define stb_sb_pop(a) (--stb__sbn(a))
|
||||
#define stb_sb_erase(a,i) ((a) ? memmove((a)+(i), (a)+(i)+1, sizeof(*(a))*((--stb__sbn(a))-(i))),0 : 0);
|
||||
|
||||
#define stb__sbraw(a) ((size_t *) (a) - 2)
|
||||
#define stb__sbm(a) stb__sbraw(a)[0]
|
||||
#define stb__sbn(a) stb__sbraw(a)[1]
|
||||
|
||||
#define stb__sbneedgrow(a,n) ((a)==0 || stb__sbn(a)+(n) >= stb__sbm(a))
|
||||
#define stb__sbmaybegrow(a,n) (stb__sbneedgrow(a,(n)) ? stb__sbgrow(a,n) : 0)
|
||||
#define stb__sbgrow(a,n) ((a) = stb__sbgrowf((a), (n), sizeof(*(a))))
|
||||
|
||||
#define stb_sb_each(n,h) for(typeof(h) n = h; n < sb_end(h); ++n)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline void * stb__sbgrowf(void *arr, int increment, int itemsize)
|
||||
{
|
||||
size_t inc_cur = arr ? stb__sbm(arr) + (stb__sbm(arr) >> 1) : 0;
|
||||
size_t min_needed = stb_sb_count(arr) + increment;
|
||||
size_t m = inc_cur > min_needed ? inc_cur : min_needed;
|
||||
size_t *p = (size_t *) realloc(arr ? stb__sbraw(arr) : 0, itemsize * m + sizeof(size_t)*2);
|
||||
if (p) {
|
||||
if (!arr)
|
||||
p[1] = 0;
|
||||
p[0] = m;
|
||||
return p+2;
|
||||
} else {
|
||||
#ifdef STRETCHY_BUFFER_OUT_OF_MEMORY
|
||||
STRETCHY_BUFFER_OUT_OF_MEMORY ;
|
||||
#endif
|
||||
return (void *) (2*sizeof(size_t)); // try to force a NULL pointer exception later
|
||||
}
|
||||
}
|
||||
|
||||
#endif // STB_STRETCHY_BUFFER_H_INCLUDED
|