Rework publication theme system to use flat files, it makes things easier

This commit is contained in:
Skylar Ittner 2018-02-06 23:45:42 -07:00
parent c5f234bb11
commit a91209a420
25 changed files with 411 additions and 299 deletions

View File

@ -50,8 +50,8 @@ switch ($VARS['action']) {
if (!is_numeric($VARS['columns'])) {
returnToSender('invalid_parameters');
}
if (!$database->has('pub_styles', ["styleid" => $VARS['style']])) {
returnToSender('invalid_parameters');
if (!preg_match("/([A-Za-z0-9_])+/", $VARS['style'])) {
$VARS['style'] = "";
}
if (!$database->has('pub_permissions', ["permid" => $VARS['perm']])) {
returnToSender('invalid_parameters');
@ -77,7 +77,7 @@ switch ($VARS['action']) {
$data = [
'pubname' => $VARS['name'],
'pubdate' => date("Y-m-d H:i:s"),
'styleid' => $VARS['style'],
'style' => $VARS['style'],
'columns' => $VARS['columns'],
'permid' => $permission,
'pwd' => $password,

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -83,5 +83,6 @@ define("STRINGS", [
"adding list" => "Adding mailing list",
"cloning list" => "Copying {olist} <i class=\"fa fa-angle-right\"></i> {nlist}",
"editing list" => "Editing {list}",
"addresses" => "Addresses"
"addresses" => "Addresses",
"theme" => "Theme"
]);

View File

@ -9,7 +9,7 @@ if (!defined("IN_NEWSPEN")) {
if (is_numeric($VARS['pubid'])) {
if ($database->has('publications', ['pubid' => $VARS['pubid']])) {
$pub = $VARS['pubid'];
$pubdata = $database->get("publications", ["[>]pub_permissions" => ["permid" => "permid"]], ["pubname", "uid", "pubdate", "styleid", "columns", "page_size", "landscape", "publications.permid", "permname", "pwd"], ["pubid" => $pub]);
$pubdata = $database->get("publications", ["[>]pub_permissions" => ["permid" => "permid"]], ["pubname", "uid", "pubdate", "style", "columns", "page_size", "landscape", "publications.permid", "permname", "pwd"], ["pubid" => $pub]);
if ($pubdata["permname"] != "LINK") {
dieifnotloggedin();
}
@ -84,32 +84,27 @@ if (defined("EDIT_MODE") && EDIT_MODE == true) {
}
?>
<style nonce="<?php echo $SECURE_NONCE; ?>">
<?php $pubcss = $database->get("pub_styles", ["css", "cssvars", "cssextra", "background"], ["styleid" => $pubdata["styleid"]]); ?>
<?php $pubcss = file_get_contents(__DIR__ . "/../themes/" . $pubdata['style'] . "/pub.css"); ?>
.pub-content {
<?php
$pubvars = json_decode($pubcss["cssvars"], TRUE);
$pubvars = json_decode(file_get_contents(__DIR__ . "/../themes/" . $pubdata['style'] . "/vars.json"), TRUE);
foreach ($pubvars as $name => $val) {
echo "--$name: $val;\n";
echo "\t--$name: $val;\n";
}
echo $pubcss;
if (file_exists(__DIR__ . "/../themes/" . $pubdata['style'] . "/background.png")) {
echo "\n\tbackground-image: url('data:image/png;base64," . base64_encode(file_get_contents(__DIR__ . "/../themes/" . $pubdata['style'] . "/background.png")) . "');";
}
$pagesize = $database->get("page_sizes", ["sizewidth (width)", "sizeheight (height)"], ["sizeid" => $pubdata["page_size"]]);
?>
}
.pub-content {
<?php echo $pubcss["css"]; ?>
}
<?php echo $pubcss["cssextra"]; ?>
.pub-content {
background-image: url('data:image/png;base64,<?php echo $pubcss["background"]; ?>');
}
<?php $pagesize = $database->get("page_sizes", ["sizewidth (width)", "sizeheight (height)"], ["sizeid" => $pubdata["page_size"]]); ?>
.pub-content {
max-width: <?php echo ($pubdata["landscape"] == 0 ? $pagesize["width"] : $pagesize["height"]); ?>;
height: <?php echo ($pubdata["landscape"] == 0 ? $pagesize["height"] : $pagesize["width"]); ?>;
}
<?php echo file_get_contents(__DIR__ . "/../themes/" . $pubdata['style'] . "/extra.css"); ?>
@media (max-width: 900px) {
.pub-content {
height: auto;

View File

@ -34,7 +34,7 @@ switch ($VARS['order'][0]['column']) {
$order = ["pubdate" => $sortby];
break;
case 5:
$order = ["stylename" => $sortby];
$order = ["style" => $sortby];
break;
case 6:
$order = ["columns" => $sortby];
@ -54,7 +54,7 @@ if (!is_empty($VARS['search']['value'])) {
$wherenolimit["AND"]["OR"] = [
"pubname[~]" => $VARS['search']['value'],
"pubdate[~]" => $VARS['search']['value'],
"stylename[~]" => $VARS['search']['value'],
"style[~]" => $VARS['search']['value'],
"sizename[~]" => $VARS['search']['value'],
"permname[~]" => $VARS['search']['value']
];
@ -76,7 +76,6 @@ $where["OR #perms"] = [
//var_dump($where);
$pubs = $database->select('publications', [
'[>]pub_styles' => ['styleid' => 'styleid'],
'[>]pub_permissions' => ['permid' => 'permid'],
'[>]page_sizes' => ['page_size' => 'sizeid']
], [
@ -84,7 +83,7 @@ $pubs = $database->select('publications', [
'pubname',
'uid',
'pubdate',
'stylename',
'style',
'columns',
'permname',
'pwd',
@ -98,7 +97,6 @@ $pubs = $database->select('publications', [
$out['status'] = "OK";
if ($filter) {
$recordsFiltered = $database->count('publications', [
'[>]pub_styles' => ['styleid' => 'styleid'],
'[>]pub_permissions' => ['permid' => 'permid']
], 'pubid', $wherenolimit);
} else {

View File

@ -17,7 +17,7 @@ $edit = false;
if (is_numeric($VARS['pubid'])) {
if ($database->has('publications', ['pubid' => $VARS['pubid']])) {
$pub = $VARS['pubid'];
$pubdata = $database->get("publications", ["[>]pub_permissions" => ["permid" => "permid"]], ["pubname", "uid", "pubdate", "styleid", "columns", "page_size", "landscape", "publications.permid", "permname"], ["pubid" => $pub]);
$pubdata = $database->get("publications", ["[>]pub_permissions" => ["permid" => "permid"]], ["pubname", "uid", "pubdate", "style", "columns", "page_size", "landscape", "publications.permid", "permname"], ["pubid" => $pub]);
if ($pubdata["uid"] == $_SESSION['uid']) {
$edit = true;
} else {

View File

@ -11,7 +11,7 @@ redirectifnotloggedin();
$pubdata = [
'name' => '',
'pubdate' => '',
'styleid' => '',
'style' => '',
'columns' => '',
'permid' => '',
'page_size' => 1,
@ -31,7 +31,7 @@ if (!is_empty($VARS['id'])) {
'publications', [
'pubname (name)',
'pubdate',
'styleid',
'style',
'columns',
'permid',
'page_size',
@ -78,15 +78,18 @@ if (!is_empty($VARS['id'])) {
<div class="row">
<div class="col-12 col-sm-6 col-md-4">
<div class="form-group">
<label for="style"><i class="fas fa-star"></i> <?php lang('style'); ?></label>
<label for="style"><i class="fas fa-star"></i> <?php lang('theme'); ?></label>
<select name="style" class="form-control" required>
<?php
$styles = $database->select("pub_styles", ['styleid', 'stylename']);
$themedir = __DIR__ . "/../themes/";
$styles = array_diff(scandir($themedir), array('..', '.'));//$database->select("pub_styles", ['styleid', 'stylename']);
foreach ($styles as $s) {
$si = $s['styleid'];
$sn = $s['stylename'];
$ss = $pubdata["styleid"] == $si ? " selected" : "";
echo "<option value=\"$si\"$ss>$sn</option>\n";
if (!file_exists($themedir . "$s/info.json")) {
continue;
}
$info = json_decode(file_get_contents($themedir . "$s/info.json"), TRUE);
$ss = $pubdata["style"] == $s ? " selected" : "";
echo "<option value=\"$s\"$ss>" . $info['name'] . "</option>\n";
}
?>
</select>

View File

@ -21,7 +21,7 @@ redirectifnotloggedin();
<th data-priority="1"><i class="fas fa-fw fa-font d-none d-md-inline"></i> <?php lang('name'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-calendar d-none d-md-inline"></i> <?php lang('date'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-user d-none d-md-inline"></i> <?php lang('author'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-star d-none d-md-inline"></i> <?php lang('style'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-star d-none d-md-inline"></i> <?php lang('theme'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-columns d-none d-md-inline"></i> <?php lang('columns'); ?></th>
<th data-priority="3"><i class="fas fa-fw fa-file d-none d-md-inline"></i> <?php lang('page size'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-eye d-none d-md-inline"></i> <?php lang('visibility'); ?></th>
@ -36,7 +36,7 @@ redirectifnotloggedin();
<th data-priority="1"><i class="fas fa-fw fa-font d-none d-md-inline"></i> <?php lang('name'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-calendar d-none d-md-inline"></i> <?php lang('date'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-user d-none d-md-inline"></i> <?php lang('author'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-star d-none d-md-inline"></i> <?php lang('style'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-star d-none d-md-inline"></i> <?php lang('theme'); ?></th>
<th data-priority="4"><i class="fas fa-fw fa-columns d-none d-md-inline"></i> <?php lang('columns'); ?></th>
<th data-priority="3"><i class="fas fa-fw fa-file d-none d-md-inline"></i> <?php lang('page size'); ?></th>
<th data-priority="2"><i class="fas fa-fw fa-eye d-none d-md-inline"></i> <?php lang('visibility'); ?></th>

View File

@ -44,7 +44,7 @@ var pubtable = $('#pubtable').DataTable({
row.pubname,
row.pubdate,
row.username,
row.stylename,
row.style,
row.columns,
row.pagesize,
row.visibility

226
style_dev/doc.php Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

25
themes/flowers/extra.css Normal file
View File

@ -0,0 +1,25 @@
.tile-html h1,h2,h3,h4,h5,h6 {
color: var(--text);
}
.tile-html pre {
background-color: var(--light-alpha);
border-left: 3px solid var(--medium);
padding: 5px 10px;
display: inline-block;
border-radius: 8px;
}
.tile-html blockquote {
background-color: var(--secondary-alpha);
border: 1px solid var(--primary);
border-left: 3px solid var(--primary);
padding: 5px 10px;
display: inline-block;
border-radius: 8px;
}
.tile-html ul li {
padding-top: 3px;
list-style-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTYiCiAgIGhlaWdodD0iMTYiCiAgIHZpZXdCb3g9IjAgMCAxNi4wMDAwMDEgMTUuOTk5OTk5IgogICBpZD0ic3ZnODkwMCIKICAgdmVyc2lvbj0iMS4xIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkxIHIxMzcyNSIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYnVsbGV0LnN2ZyIKICAgaW5rc2NhcGU6ZXhwb3J0LWZpbGVuYW1lPSIvaG9tZS9za3lsYXIvRG9jdW1lbnRzL1Byb2plY3RzL0Fzc2V0cy9OZXdzUGVuL3RoZW1lcy9zcHJpbmdfZmxvd2Vycy9idWxsZXQucG5nIgogICBpbmtzY2FwZTpleHBvcnQteGRwaT0iMTQuMzgiCiAgIGlua3NjYXBlOmV4cG9ydC15ZHBpPSIxNC4zOCI+CiAgPGRlZnMKICAgICBpZD0iZGVmczg5MDIiIC8+CiAgPHNvZGlwb2RpOm5hbWVkdmlldwogICAgIGlkPSJiYXNlIgogICAgIHBhZ2Vjb2xvcj0iI2ZmZmZmZiIKICAgICBib3JkZXJjb2xvcj0iIzY2NjY2NiIKICAgICBib3JkZXJvcGFjaXR5PSIxLjAiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PSIyIgogICAgIGlua3NjYXBlOnpvb209IjEuOTc5ODk5IgogICAgIGlua3NjYXBlOmN4PSIxMDMuNjMzNzkiCiAgICAgaW5rc2NhcGU6Y3k9IjcuNjI1Nzg3MiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0icHgiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICBmaXQtbWFyZ2luLXRvcD0iMCIKICAgICBmaXQtbWFyZ2luLWxlZnQ9IjAiCiAgICAgZml0LW1hcmdpbi1yaWdodD0iMCIKICAgICBmaXQtbWFyZ2luLWJvdHRvbT0iMCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjEyODAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iNzQyIgogICAgIGlua3NjYXBlOndpbmRvdy14PSIwIgogICAgIGlua3NjYXBlOndpbmRvdy15PSIwIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgdW5pdHM9InB4IiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTg5MDUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlPjwvZGM6dGl0bGU+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xNjYuNTYyODgsLTIzOC4yNzM3MSkiPgogICAgPGcKICAgICAgIGlkPSJnOTQ3NiIKICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuMTU4MTY1MDYsMCwwLDAuMTU4MTY1MDYsMTQwLjIxODQ1LDIxMy42Mjg4KSI+CiAgICAgIDxnCiAgICAgICAgIHN0eWxlPSJmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjEiCiAgICAgICAgIGlkPSJnOTQ2OCI+CiAgICAgICAgPHBhdGgKICAgICAgICAgICBzdHlsZT0ib3BhY2l0eToxO2ZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6ZXZlbm9kZDtzdHJva2U6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MTtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZTtzdHJva2Utb3BhY2l0eToxIgogICAgICAgICAgIGQ9Im0gNDEuMDU2NjQxLDAgYyAtMTIuNzEwMTcsMCAtMjMuMDEwNzY2LDkuMTkxNzMgLTIzLjAwOTc2NiwyMC41MzEyNSAtMS4xN2UtNCwwLjgzODAzMyAwLjA2MjYzLDEuNjYyODc5IDAuMTcxODc1LDIuNDc0NjA5IEMgNy44MDk3NTIyLDI0Ljk3MzMzMyAtOC43MDY3MjcyZS00LDMzLjIxNjg0MiAwLDQzLjA4OTg0NCBjIC0wLjAwMTE3Njc1LDguNDQ1NDYyIDUuNzE2OTgwNCwxNS42OTI5OTYgMTMuODg0NzY2LDE4Ljg0NTcwMyAtMS4zNzkzODEsMi42MzU4MzkgLTIuMTU0NTcxLDUuNTc0NTk5IC0yLjE1NDI5Nyw4LjY3NTc4MSAtMC4wMDE2LDExLjMzOTUyIDEwLjI5OTU5NSwyMC41MzEyNSAyMy4wMDk3NjUsMjAuNTMxMjUgMy41NTUwODYsMCA2LjkwODM2MywtMC43NDA5OTEgOS45MTQwNjMsLTIuMDI1MzkgNC4xMjM1MDIsMy40ODM1MjMgOS42NzcwNTYsNS42MzQ3NjUgMTUuODA0Njg3LDUuNjM0NzY1IDEyLjcwODYsMCAyMy4wMTA4MTMsLTkuMTkxNzMgMjMuMDA3ODEzLC0yMC41MzEyNSAxLjc3ZS00LC0wLjYzNzA1NyAtMC4wMzYxMywtMS4yNjY0MTggLTAuMDk5NjEsLTEuODg4NjcyIDkuNjg3OTQzLC0yLjQyMDMxOSAxNi43OTU0NjMsLTEwLjM1MDY2MSAxNi43OTI5NzMsLTE5Ljc2NzU3OCAwLjAwMiwtNi44ODk0MTYgLTMuODEzNDQyLC0xMi45NzExNDUgLTkuNjQ4NDQyLC0xNi42OTUzMTIgMi4zODk5NjMsLTMuMjM3MjUyIDMuNzg0MzA1LC03LjExMDcxMiAzLjc4MzIwMywtMTEuMjc3MzQ0IDAuMDAzMiwtMTEuMzM5NTIgLTEwLjMwMTE3NiwtMjAuNTMxNTcwMSAtMjMuMDA5NzY2LC0yMC41MzEyNTAxIC00LjYzMzc1NywwIC04LjkzNzg2LDEuMjMxODkxMiAtMTIuNTQ4ODI4LDMuMzMzOTg0MyBDIDU0LjUxNTUxOSwyLjg3NzIzNDcgNDguMTYzNTg5LC0xLjczMzU5M2UtNCA0MS4wNTY2NDEsMCBaIG0gOS4wMjM0MzcsMzAuMTMwODU5IGMgOC45NzIyNiwwIDE2LjI0NDM3OCw3LjgzMjk3NCAxNi4yNDIxODgsMTcuNDk2MDk0IDAuMDAzLDkuNjYwOTIgLTcuMjY5OTI4LDE3LjQ5NDE0MSAtMTYuMjQyMTg4LDE3LjQ5NDE0MSAtOC45NzIyOCwwIC0xNi4yNDQzNjcsLTcuODMzMjIxIC0xNi4yNDIxODcsLTE3LjQ5NDE0MSAtMC4wMDMsLTkuNjYzMTIgNy4yNjk5MDcsLTE3LjQ5NjA5NCAxNi4yNDIxODcsLTE3LjQ5NjA5NCB6IgogICAgICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE2Ny4wNjI4OCwxNTkuMDIxNzUpIgogICAgICAgICAgIGlkPSJwYXRoNDE4NSIKICAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgICA8L2c+CiAgICA8L2c+CiAgPC9nPgo8L3N2Zz4K');
}

4
themes/flowers/info.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "Flowers",
"colors": ["#ffd5d5", "#fc8a5b", "#77ff77", "#008000"]
}

2
themes/flowers/pub.css Normal file
View File

@ -0,0 +1,2 @@
background-position: right bottom;
background-repeat: no-repeat;

9
themes/flowers/vars.json Normal file
View File

@ -0,0 +1,9 @@
{
"primary": "#008000",
"secondary": "#77ff77",
"secondary-alpha": "rgba(119,255,119,.25)",
"text": "#008000",
"light": "#ffd5d5",
"light-alpha": "rgba(255,213,213,.25)",
"medium": "#fc8a5b"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

18
themes/harvest/extra.css Normal file
View File

@ -0,0 +1,18 @@
.tile-html h1,h2,h3,h4,h5,h6 {
color: var(--text);
}
.tile-html blockquote {
background-color: var(--light-alpha);
border-left: 3px solid var(--secondary);
padding: 5px 10px;
display: inline-block;
}
.tile-html pre {
background-color: var(--light-alpha);
border: 1px solid var(--secondary);
border-left: 3px solid var(--secondary);
padding: 5px 10px;
display: inline-block;
}

4
themes/harvest/info.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "Harvest",
"colors": ["#973b01", "#bc525b", "#ffe46f", "#ff9e01"]
}

2
themes/harvest/pub.css Normal file
View File

@ -0,0 +1,2 @@
background-position: right bottom;
background-repeat: no-repeat;

8
themes/harvest/vars.json Normal file
View File

@ -0,0 +1,8 @@
{
"primary": "#973b01",
"secondary": "#bc525b",
"text": "#2f0701",
"light": "#ffe46f",
"light-alpha": "rgba(255,228,111,.25)",
"medium": "#ff9e01"
}

0
themes/plain/extra.css Normal file
View File

4
themes/plain/info.json Normal file
View File

@ -0,0 +1,4 @@
{
"name": "Plain",
"colors": ["#ffffff", "#000000", "#2196F3"]
}

0
themes/plain/pub.css Normal file
View File