initial import
This commit is contained in:
commit
d6aeabcc22
26 changed files with 3019 additions and 0 deletions
24
.eslintrc.js
Normal file
24
.eslintrc.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
|
||||
export default [
|
||||
{
|
||||
files: ["**/*.{ts}"],
|
||||
plugins: ['@typescript-eslint/eslint-plugin', 'eslint-plugin-tsdoc'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
project: './tsconfig.json',
|
||||
tsconfigRootDir: __dirname,
|
||||
ecmaVersion: 'ES6',
|
||||
sourceType: 'module'
|
||||
},
|
||||
rules: {
|
||||
'tsdoc/syntax': 'warn'
|
||||
},
|
||||
languageOptions: {
|
||||
globals: globals.browser
|
||||
}
|
||||
},
|
||||
...tseslint.configs.recommended,
|
||||
];
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
node_modules
|
||||
docs
|
||||
package-lock.json
|
107
README.md
Normal file
107
README.md
Normal file
|
@ -0,0 +1,107 @@
|
|||
# Presentationmaker.js
|
||||
![PresentationMaker.js logo](public/img/presentationmaker.png)
|
||||
|
||||
## What is
|
||||
A simple(ish) tool to create presentation from XML source.
|
||||
For those who fight against typical presentation tools.
|
||||
|
||||
## Demo
|
||||
A live demo can be found [here](https://userdata.contentnation.net/a5970e0955da4472b5f84a8dbb740273/presentation/)
|
||||
|
||||
## Features
|
||||
* HTML output for use in browser
|
||||
* input from XML file (either single file or embedded into HTML)
|
||||
* transition between pages
|
||||
* HTML in elements supported
|
||||
* Custom templates, you define them, combine them and use it
|
||||
* powerful calculation inside description and templates thanks to [fparser](https://fparser.alexi.ch/)
|
||||
* presentation can be formatted via normal CSS
|
||||
|
||||
## Installation
|
||||
If you just want to use it, take a look at the [public/index.html](public/index.html) file. It is a good start to use it. Additionally, you need the [public/presentationmaker.js](public/presentationmaker.js) script.
|
||||
The CSS is optional, but encouraged.
|
||||
It provides all the needed boilerplate to get you running.
|
||||
### Development
|
||||
If you want to help with development or want to see live updates if you change your xml, check out the project and use
|
||||
```
|
||||
npm install
|
||||
npx webpack serve
|
||||
```
|
||||
and a browser pointing to localhost:8080
|
||||
|
||||
## Usage
|
||||
The main presentation file is pure XML with a <presentation> root node.
|
||||
Below this there are
|
||||
### <defintions>
|
||||
These are in the form of
|
||||
```<name>value<name>```
|
||||
Later "name" can be used via ```${name}``` in the templates/pages
|
||||
### <modules>
|
||||
Similar to the definitions, a <module_name>...</module_name>
|
||||
Creates a module that can be used later.
|
||||
The module itself can use other previously defined modules as
|
||||
```<module_name optional="value">optional inner content</module_name>```
|
||||
The parameter you add during use will be available to the module as ```${optional}```
|
||||
Existing internal modules are
|
||||
#### calc
|
||||
Calculates a formula and stores the result in a variable for later use.
|
||||
Parameters:
|
||||
* ```name``` the name of the variable
|
||||
inner text is the formular to be used to calculate the value
|
||||
#### img
|
||||
Shows an image.
|
||||
Parameters:
|
||||
* ```src``` file name of the image
|
||||
* ```x``` Left position of the image (relative to the page)
|
||||
* ```y``` Top position of the image (relative to the page)
|
||||
* ```width``` Image width
|
||||
* ```height``` Image height
|
||||
### options
|
||||
Creates an effect or transformation layer to affect content that is rendered inside.
|
||||
Parameters:
|
||||
* ```opacity``` optional opacity value 0: fully transparent, 1: fully visible
|
||||
* ```blendmode``` optional one the https://developer.mozilla.org/docs/Web/CSS/mix-blend-mode values
|
||||
* ```flip``` optional flipping of the image (currently only y supported)
|
||||
* ```rotate``` rotation values in X,Y,Z form
|
||||
* ```y``` optional y axis to flip at
|
||||
Inner XML is the content to display
|
||||
#### text
|
||||
Show a text in an invisible bounding box.
|
||||
Parameters:
|
||||
* ```x0``` left side of the bounding box.
|
||||
* ```y0``` top side of the bounding box.
|
||||
* ```x1``` right side of the bounding box (mutally exclusive to width)
|
||||
* ```y1``` bottom side of the bounding box (mutally exclisve to height)
|
||||
* ```pos``` shortcut to x0,y0,x1,y1 (mutually exclusive to above values)
|
||||
* ```halign``` horizontal alignment in the bounding box, possible values: ```left```, ```center```, ```right```, defaults to ```center```
|
||||
* ```valign``` vertical alignment in the bounding box, possible value: ```top```, ```center```, ```bottom```, default to ```top```
|
||||
* ```fontsize``` optional font size in pixel
|
||||
* ```color``` optional color
|
||||
Inside the XML is the text to display
|
||||
### page
|
||||
This is the section for the actual pages to show.
|
||||
In the pages, modules, variables as well as calulation can be used.
|
||||
Parameters:
|
||||
* ```id``` optional id of the page (useful for CSS styling)
|
||||
* ```width``` page width, default to the ```width``` variable in the definitions section
|
||||
* ```height``` page height, default to the ```height``` variable in the definitions section
|
||||
* ```x``` X position of the page in the canvas, defaults to 0
|
||||
* ```y``` Y position of the page in the canvas, defaults to 0
|
||||
* ```z``` Z position of the page in the canvas, defaults to 0
|
||||
* ```rx``` rotation of the page on the X-Axis in °, defaults to 0
|
||||
* ```ry``` rotation of the page on the Y-Axis in °, defaults to 0
|
||||
* ```rz``` rotation of the page on the Z-Axis in °, defaults to 0
|
||||
* ```vx``` viewport position in X, defaults to ```x```
|
||||
* ```vy``` viewport position in Y, defaults to ```y```
|
||||
* ```vz``` viewport position in Z, defaults to ```z```
|
||||
* ```vwidth``` viewport width, defaults to ```width```
|
||||
* ```vheight``` viewport width, defaults to ```height```
|
||||
* ```vrx``` rotation of the vieport on the X-Axis in °, defaults to 0
|
||||
* ```vry``` rotation of the vieport on the Y-Axis in °, defaults to 0
|
||||
* ```vrz``` rotation of the vieport on the Z-Axis in °, defaults to 0
|
||||
* ```name``` name of the page (shown in drop down), defaults to page number
|
||||
|
||||
## Example
|
||||
For a fully featured example, take a look at [public/example.xml](public/example.xml) file.
|
||||
It show multiple modules, some of them nested, many formular and some HTML inside the text.
|
||||
|
1
dist/presentationmaker.js
vendored
Normal file
1
dist/presentationmaker.js
vendored
Normal file
File diff suppressed because one or more lines are too long
23
package.json
Normal file
23
package.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"name": "presentationmake.js",
|
||||
"version": "0.0.1",
|
||||
"description": "A tool to create browser based presentations",
|
||||
"author": "Sascha Nitsch (grumpydeveloper https://contentnation.net/@grumpydevelop)",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^7.15.0",
|
||||
"@typescript-eslint/parser": "^7.15.0",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-tsdoc": "^0.3.0",
|
||||
"globals": "^15.6.0",
|
||||
"ts-loader": "^9.5.1",
|
||||
"typedoc": "^0.26.3",
|
||||
"typescript": "^5.5.2",
|
||||
"typescript-eslint": "^7.14.1",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^5.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"fparser": "^3.0.1"
|
||||
}
|
||||
}
|
143
public/example.xml
Normal file
143
public/example.xml
Normal file
|
@ -0,0 +1,143 @@
|
|||
<presentation>
|
||||
<definitions>
|
||||
<width>1920</width>
|
||||
<height>1080</height>
|
||||
<defaultfontcolor>#ffffff</defaultfontcolor>
|
||||
<path>img/</path>
|
||||
<boxwidth>1720</boxwidth>
|
||||
<boxinnerx>165</boxinnerx>
|
||||
<boxinnerwidth>1590</boxinnerwidth>
|
||||
<boxheight>175</boxheight>
|
||||
<mirrorline>880</mirrorline>
|
||||
<headerpos>0,35*${scale},1920*${scale},270*${scale}</headerpos>
|
||||
<headersize>90</headersize>
|
||||
<boxx>105</boxx>
|
||||
<box3_1>235</box3_1>
|
||||
<box3_2>445</box3_2>
|
||||
<box3_3>655</box3_3>
|
||||
<listsize>72</listsize>
|
||||
<transition>transform</transition>
|
||||
<scale>1</scale>
|
||||
</definitions>
|
||||
<modules>
|
||||
<defaultbg>
|
||||
<img src="${path}bg.jpg" x="0" y="0" width="${width}" height="${height}"></img>
|
||||
<img src="${path}logo.svg" x="40*${scale}" y="970*${scale}" width="82*${scale}" height="83*${scale}"></img>
|
||||
<text x0="0" y0="1000*${scale}" x1="1920*${scale}" y1="1060*${scale}" size="40*${scale}">Introduction to presentationmaker.js</text>
|
||||
<text x0="1700*${scale}" y0="20*${scale}" x1="1900*${scale}" y1="60*${scale}" size="20*${scale}" halign="right">${page}/${numpages}</text>
|
||||
</defaultbg>
|
||||
<boxx3>
|
||||
<defaultbg />
|
||||
<img src="${path}box.png" x="${boxx}*${scale}" y="${box3_1}*${scale}" width="${boxwidth}*${scale}" height="${boxheight}*${scale}"></img>
|
||||
<img src="${path}box.png" x="${boxx}*${scale}" y="${box3_2}*${scale}" width="${boxwidth}*${scale}" height="${boxheight}*${scale}"></img>
|
||||
<img src="${path}box.png" x="${boxx}*${scale}" y="${box3_3}*${scale}" width="${boxwidth}*${scale}" height="${boxheight}*${scale}"></img>
|
||||
</boxx3>
|
||||
<box3>
|
||||
<boxx3></boxx3>
|
||||
<text pos="${headerpos}" size="${headersize}" halign="center" valign="center">${headertext}</text>
|
||||
<text x0="${boxinnerx}*${scale}" y0="${box3_1}*${scale}" w="${boxinnerwidth}*${scale}" h="${boxheight}*${scale}" size="${listsize}*${scale}" halign="left" valign="center">${text1}</text>
|
||||
<text x0="${boxinnerx}*${scale}" y0="${box3_2}*${scale}" w="${boxinnerwidth}*${scale}" h="${boxheight}*${scale}" size="${listsize}*${scale}" halign="left" valign="center">${text2}</text>
|
||||
<text x0="${boxinnerx}*${scale}" y0="${box3_3}*${scale}" w="${boxinnerwidth}*${scale}" h="${boxheight}*${scale}" size="${listsize}*${scale}" halign="left" valign="center">${text3}</text>
|
||||
</box3>
|
||||
<box3r>
|
||||
<options rotate="0,0,90">
|
||||
<boxx3 width="${height}" heigh="${width}"></boxx3>
|
||||
<text pos="200,35,1080,220" size="${headersize}" halign="center" valign="center">${headertext}</text>
|
||||
<text x0="${boxinnerx}" y0="${box3_1}" w="${boxinnerwidth}" h="${boxheight}" size="${listsize}" halign="left" valign="center">${text1}</text>
|
||||
<text x0="${boxinnerx}" y0="${box3_2}" w="${boxinnerwidth}" h="${boxheight}" size="${listsize}" halign="left" valign="center">${text2}</text>
|
||||
<text x0="${boxinnerx}" y0="${box3_3}" w="${boxinnerwidth}" h="${boxheight}" size="${listsize}" halign="left" valign="center">${text3}</text>
|
||||
</options>
|
||||
</box3r>
|
||||
<mirrorimage>
|
||||
<calc name="y2">((${mirrorline} - ${y}) +${mirrorline} - ${h})</calc>
|
||||
<img src="${path}${img}" x="${x}*${scale}" y="${y}*${scale}" width="${w}*${scale}" height="${h}*${scale}"></img>
|
||||
<options opacity=".44" flip="v" y="${height}">
|
||||
<img src="${path}${img}" x="${x}*${scale}" y="(${height} - ${mirrorline}*${scale}) - ${scale} * (${mirrorline} - ${y})" width="${w}*${scale}" height="${h}*${scale}" mask-image="linear-gradient(0deg, rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.1) 40%)"></img>
|
||||
</options>
|
||||
</mirrorimage>
|
||||
</modules>
|
||||
<pages>
|
||||
<page name="Welcome">
|
||||
<defaultbg />
|
||||
<mirrorimage img="presentationmaker.svg" x="642" y="600" w="634" h="374"></mirrorimage>
|
||||
<text pos="${headerpos}" size="${headersize}" halign="center" valign="center">Welcome to the presentationmaker.js example</text>
|
||||
<text x0="100" y0="450" x1="1820" y1="550" size="80" halign="center" valign="top">A quick presentation of the why and how.</text>
|
||||
</page>
|
||||
<page x="1920" name="Why">
|
||||
<box3>
|
||||
<headertext>Why using presentationmaker.js</headertext>
|
||||
<text1>Powerpoint / Impress are hard to use.</text1>
|
||||
<text2>I wanted to concentrate on the content, not the quirks of the tools.</text2>
|
||||
<text3>I want to make use of modern browser features.</text3>
|
||||
</box3>
|
||||
</page>
|
||||
<page y="1180" vx="-100" vy="980" vwidth="1920*2+200" vheight="2460" width="1920*2" height="2160" name="Features">
|
||||
<calc name="scale">2</calc>
|
||||
<box3 headertext="Features" text1="Template based slides/pages." text2="you can create new templates than can even calulate positions or things, this is scaled by 2X." text3="Using those templates is easy."></box3>
|
||||
</page>
|
||||
<page x="2020*2" name="Navigation (I)">
|
||||
<box3 headertext="Navigation (I)" text1="A click/tap shows next page." text2="Swiping left/right works too." text3="Arrow on keyboard of course as well."></box3>
|
||||
</page>
|
||||
<page x="2020*2.5" y="1180" rz="-90" vx="2020*2.5" vy="1180" vrz="90" name="Navigation (II)">
|
||||
<box3 headertext="Navigation (II)" text1="On the top left is a fullscreen icon." text2="Forwards and backwards button and a quick jump." text3="This works in every rotation :)"></box3>
|
||||
</page>
|
||||
<page x="2020*3" y="0" name="Creating slides">
|
||||
<box3 headertext="Creating slides" text1="Presentations are based on easy to understand XML." text2="Basic elements can be combined to templates." text3="Templates can then form pages."></box3>
|
||||
</page>
|
||||
<page x="2020*3" y="1180" name="Example">
|
||||
<defaultbg />
|
||||
<text pos="${headerpos}" size="${headersize}" halign="center" valign="center">Example</text>
|
||||
<text pos="100,270,1820,860" size="40" halign="left" valign="top">
|
||||
This page is made by<br />
|
||||
<pre><code>
|
||||
<page x="2020*3" y="1180" name="Example">
|
||||
<defaultbg />
|
||||
<text pos="\${headerpos}" size="\${headersize}" halign="center"
|
||||
valign="center">Example</text>
|
||||
<text pos="100,270,1820,860" size="40" halign="left"
|
||||
valign="top">
|
||||
This page is made by<br />
|
||||
<pre><code>Recursion is nice</code>/</pre>
|
||||
</text>
|
||||
</page>
|
||||
</code></pre>
|
||||
</text>
|
||||
</page>
|
||||
<page x="2020*3" y="1180*2" name="Modules / Templates">
|
||||
<box3 headertext="Used Modules" text1="<strong>page</strong>: A page defintion." text2="<strong>defaultbg:</strong> a custom element that show the green background image" text3="<strong>text:</strong> A text box with given size and text"></box3>
|
||||
</page>
|
||||
<page x="2020*4" name="box3">
|
||||
<box3 headertext="Module box3" text1="This is rendered by using the box3 custom module." text2="It is based on the boxx3 module (background + background images for text)." text3="Plus text areas for the text."></box3>
|
||||
</page>
|
||||
<page x="2020*4" y="1180" name="Modules within modules">
|
||||
<calc name="math">sin(30*PI/180) + sqrt(9)</calc>
|
||||
<box3 headertext="Modules can include other modules" text1="As seen on last slide." text2="In modules you can calculate things that can be used later." text3="This was calulated by "sin(30*PI/180) + sqrt(9)" = ${math}"></box3>
|
||||
</page>
|
||||
<page x="2020*4" y="1180*2" name="Practical use for calc">
|
||||
<defaultbg />
|
||||
<mirrorimage img="presentationmaker.svg" x="642" y="600" w="634" h="374"></mirrorimage>
|
||||
<text pos="${headerpos}" size="${headersize}" halign="center" valign="center">The mirrored image is an example where calc helps.</text>
|
||||
<text x0="100" y0="450" x1="1820" y1="550" size="80" halign="center" valign="top">Also it uses some image effects.</text>
|
||||
</page>
|
||||
<page x="2020*4" y="1180*3" vx="2020*4-100" vy="1180*3-100" vwidth="2120" vheight="1280" name="Page position" rz="3">
|
||||
<box3 headertext="Page positions" text1="Pages can be positioned anywhere on the canvas." text2="Rotation of the page and the view can be different." text3="This can create nice effects, just don't over do it."></box3>
|
||||
</page>
|
||||
<page x="5320" y="1180*3" z="0" rx="55" ry="20" width="1920" height="1080" vx="5320-150" vy="4400" vz="450" vwidth="2120" vheight="1280" vrx="-50" name="3D">
|
||||
<box3 headertext="Rotation can also be in 3D" text1="Again, use just for rare effects." text2="Don't over do it." text3="Yes, we really mean that."></box3>
|
||||
</page>
|
||||
<page x="2020" y="1180*3" name="Get it">
|
||||
<box3 headertext="Get it an use it." text1="Licensed under GPL-3." text3="We love to get a shout-out if you use it.">
|
||||
<text2><a href="https://git.contentnation.net/grumpydevelop/presentationmaker.js" target="_blank">git.contentnation.net/presentationmaker</a></text2>
|
||||
</box3>
|
||||
</page>
|
||||
<page x="0" y="1180*3" name="Credits">
|
||||
<box3 headertext="Credits" text1="My own render engine I made for an old project.">
|
||||
<text2><a href="https://impress.js.org/" target="_blank">impress.js.org</a><br />(inspired, no code was used from the project.)</text2>
|
||||
<text3>Built by <a href="https://contentnatin.net/@grumpydevelop">GrumpyDeveloper</a></text3>
|
||||
</box3>
|
||||
</page>
|
||||
<page x="3500" y="1000" z="2000" vx="4000" vy="1800" vz="4000" width="3840" height="2160" vwidth="1920" vheight="1080" name="The end">
|
||||
<text x0="0" y0="0" w="${width}" h="${height}" size="1000" halign="center" valign="center">The end</text>
|
||||
</page>
|
||||
</pages>
|
||||
</presentation>
|
BIN
public/img/bg.jpg
Normal file
BIN
public/img/bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
BIN
public/img/box.png
Normal file
BIN
public/img/box.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 781 KiB |
584
public/img/contentnation.svg
Normal file
584
public/img/contentnation.svg
Normal file
|
@ -0,0 +1,584 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
sodipodi:docname="contentnation-trans-black.svg"
|
||||
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
||||
id="svg10485"
|
||||
version="1.1"
|
||||
viewBox="0 0 116.87181 29.368581"
|
||||
height="29.368582mm"
|
||||
width="116.87183mm"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<defs
|
||||
id="defs10479">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8566">
|
||||
<path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8564"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8584">
|
||||
<path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8582"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8612">
|
||||
<path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8610"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8624">
|
||||
<path
|
||||
d="m 271.674,749.573 v -64.657 l 18.3,-18.426 v 44.013 z"
|
||||
id="path8622"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-29.309916,29.309916,0,107.56319,51.61644)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8640">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8630" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.215824"
|
||||
id="stop8632" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.75"
|
||||
id="stop8634" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.76850016"
|
||||
id="stop8636" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8638" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8650">
|
||||
<path
|
||||
d="M 312.701,749.505 V 705.43 l 18.301,-38.937 v 64.659 z"
|
||||
id="path8648"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-29.284783,29.284783,0,122.03666,51.615502)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8666">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8656" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.422802"
|
||||
id="stop8658" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.972582"
|
||||
id="stop8660" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.97461095"
|
||||
id="stop8662" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8664" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8676">
|
||||
<path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8674"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8684">
|
||||
<path
|
||||
d="m 270.701,750.4 h 20.3 v -45.214 h -20.3 z"
|
||||
id="path8682"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8700">
|
||||
<path
|
||||
d="m 311.582,706.377 h 20.301 V 665.35 h -20.301 z"
|
||||
id="path8698"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8716">
|
||||
<path
|
||||
d="m 289.974,666.49 h -59.353 l -18.425,18.425 59.481,0.001 z"
|
||||
id="path8714"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(19.297539,-16.192559,-16.192559,-19.297539,84.195184,56.472015)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8732">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8722" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8724" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8726" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8728" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8730" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8742">
|
||||
<path
|
||||
d="m 212.196,731.148 v -46.226 l 18.301,0.002 v 46.224 z"
|
||||
id="path8740"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-16.307204,16.307204,0,86.58079,45.113934)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8766">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0"
|
||||
id="stop8748" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.25"
|
||||
id="stop8750" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.44050522"
|
||||
id="stop8752" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.5"
|
||||
id="stop8754" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.52936829"
|
||||
id="stop8756" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.75"
|
||||
id="stop8758" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.996319"
|
||||
id="stop8760" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.9965914"
|
||||
id="stop8762" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8764" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8776">
|
||||
<path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8774"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8784">
|
||||
<path
|
||||
d="m 211.196,687.809 h 20.301 v -3.887 h -20.301 z"
|
||||
id="path8782"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8800">
|
||||
<path
|
||||
d="m 211.196,732.223 h 20.301 v -3.887 h -20.301 z"
|
||||
id="path8798"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8816">
|
||||
<path
|
||||
d="m 267.565,749.573 h -36.944 l -18.425,-18.425 h 37.755 z"
|
||||
id="path8814"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(13.689206,12.765392,-12.765392,13.689206,83.04661,19.183338)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8832">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8822" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8824" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8826" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8828" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8830" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8862">
|
||||
<path
|
||||
d="m 331.011,666.473 -39.042,83.1 h -20.312 l 38.993,-83.1 z"
|
||||
id="path8860"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-16.76835,31.536681,-31.536681,-16.76835,119.95484,21.196219)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8878">
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8868" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8870" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8872" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8874" />
|
||||
<stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8876" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2069">
|
||||
<path
|
||||
d="M 0,0 H 23.3971 V -14.91 H 0 Z"
|
||||
clip-rule="evenodd"
|
||||
id="path2067"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2073">
|
||||
<path
|
||||
d="M 0,-14.91 H 209.76378 V 14.91 H 0 Z"
|
||||
id="path2071"
|
||||
inkscape:connector-curvature="0" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
id="i"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(19.29766,-16.19266,-16.19266,-19.29766,29.9802,59.309292)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#dfbd6a"
|
||||
id="stop2648" />
|
||||
<stop
|
||||
offset=".295"
|
||||
stop-color="#c78300"
|
||||
id="stop2650" />
|
||||
<stop
|
||||
offset=".662"
|
||||
stop-color="#6f3200"
|
||||
id="stop2652" />
|
||||
<stop
|
||||
offset=".687"
|
||||
stop-color="#6f3200"
|
||||
id="stop2654" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#6f3200"
|
||||
id="stop2656" />
|
||||
</linearGradient>
|
||||
<clipPath
|
||||
id="o"
|
||||
clipPathUnits="userSpaceOnUse">
|
||||
<path
|
||||
d="m 267.565,749.573 h -36.944 l -18.425,-18.425 h 37.755 z"
|
||||
id="path2620" />
|
||||
</clipPath>
|
||||
<linearGradient
|
||||
id="p"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(38.804048,-36.18536,-36.18536,-38.804048,228.9593,749.93786)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0">
|
||||
<stop
|
||||
offset="0"
|
||||
stop-color="#dfbd6a"
|
||||
id="stop2678" />
|
||||
<stop
|
||||
offset=".295"
|
||||
stop-color="#c78300"
|
||||
id="stop2680" />
|
||||
<stop
|
||||
offset=".662"
|
||||
stop-color="#6f3200"
|
||||
id="stop2682" />
|
||||
<stop
|
||||
offset=".687"
|
||||
stop-color="#6f3200"
|
||||
id="stop2684" />
|
||||
<stop
|
||||
offset="1"
|
||||
stop-color="#6f3200"
|
||||
id="stop2686" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
inkscape:guide-bbox="true"
|
||||
showguides="true"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:window-y="254"
|
||||
inkscape:window-x="193"
|
||||
inkscape:window-height="1761"
|
||||
inkscape:window-width="3631"
|
||||
fit-margin-bottom="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-top="0"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:cy="80.714286"
|
||||
inkscape:cx="215.35714"
|
||||
inkscape:zoom="5.6"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1">
|
||||
<sodipodi:guide
|
||||
id="guide3015"
|
||||
orientation="0,-1"
|
||||
position="36.967617,0.063223318"
|
||||
inkscape:locked="false" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata10482">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(-22.905362,-22.155916)"
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<g
|
||||
id="g2277"
|
||||
transform="matrix(0.35277777,0,0,-0.35277777,65.410913,51.461274)" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 79.101677,34.586067 a 4.0437834,4.0437834 0 0 1 -1.608264,-1.610121 4.9524783,4.9524783 0 0 1 -0.586668,-2.454035 4.9506282,4.9506282 0 0 1 0.582968,-2.450319 4.0437834,4.0437834 0 0 1 1.608262,-1.610118 4.7396478,4.7396478 0 0 1 2.313385,-0.555199 5.4059005,5.4059005 0 0 1 1.56384,0.207263 6.6625271,6.6625271 0 0 1 1.371365,0.592228 0.51634587,0.51634587 0 0 1 0.286856,0.477479 0.48118251,0.48118251 0 0 1 -0.140652,0.342378 0.49783881,0.49783881 0 0 1 -0.370137,0.148065 0.5237487,0.5237487 0 0 1 -0.231337,-0.05156 5.8963364,5.8963364 0 0 0 -1.110426,-0.451571 4.5416229,4.5416229 0 0 0 -1.249219,-0.153609 3.6551366,3.6551366 0 0 0 -1.885864,0.457127 2.9111545,2.9111545 0 0 0 -1.171493,1.249221 3.9753083,3.9753083 0 0 0 -0.394201,1.795181 3.9771578,3.9771578 0 0 0 0.394201,1.797039 2.9111545,2.9111545 0 0 0 1.171493,1.249221 3.6551366,3.6551366 0 0 0 1.884013,0.46637 4.6138002,4.6138002 0 0 0 1.24923,-0.153604 5.8963364,5.8963364 0 0 0 1.110415,-0.451572 0.5237487,0.5237487 0 0 1 0.231337,-0.05155 0.50709238,0.50709238 0 0 1 0.370145,0.142505 0.47377973,0.47377973 0 0 1 0.14065,0.347936 0.51634587,0.51634587 0 0 1 -0.283153,0.48858 6.6625271,6.6625271 0 0 1 -1.371372,0.59223 5.4059005,5.4059005 0 0 1 -1.561994,0.19617 4.7396478,4.7396478 0 0 1 -2.31338,-0.555205 z"
|
||||
id="path13"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 87.750008,34.556434 a 4.0585894,4.0585894 0 0 1 -1.561992,-1.635997 5.2282335,5.2282335 0 0 1 0,-4.791473 4.0585894,4.0585894 0 0 1 1.569393,-1.636031 5.0265069,5.0265069 0 0 1 4.734096,0 4.1215132,4.1215132 0 0 1 1.571248,1.643433 5.1690107,5.1690107 0 0 1 0,4.776663 4.1215132,4.1215132 0 0 1 -1.582351,1.643405 5.0265069,5.0265069 0 0 1 -4.734097,0 z m 4.160378,-0.966042 a 3.037002,3.037002 0 0 0 1.158545,-1.262184 3.9790099,3.9790099 0 0 0 0.399749,-1.804439 3.9771578,3.9771578 0 0 0 -0.399749,-1.802581 3.037002,3.037002 0 0 0 -1.158545,-1.262173 3.7014043,3.7014043 0 0 0 -3.586661,0 3.0740155,3.0740155 0 0 0 -1.152989,1.262173 3.9771578,3.9771578 0 0 0 -0.397896,1.802581 3.9790099,3.9790099 0 0 0 0.397896,1.804439 3.0740155,3.0740155 0 0 0 1.152989,1.262184 3.7014043,3.7014043 0 0 0 3.586661,0 z"
|
||||
id="path15"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 96.766628,34.91547 a 0.55521063,0.55521063 0 0 1 -0.168409,-0.410848 v -7.69151 a 0.82541414,0.82541414 0 0 1 0.244291,-0.597784 0.79395199,0.79395199 0 0 1 0.59222,-0.251694 h 0.168416 a 0.87538284,0.87538284 0 0 1 0.708818,0.386804 l 4.958136,7.162215 v -6.954945 a 0.58482187,0.58482187 0 0 1 0.16663,-0.418252 0.55521063,0.55521063 0 0 1 0.41254,-0.173969 0.59407531,0.59407531 0 0 1 0.59207,0.592221 v 7.689681 a 0.79395199,0.79395199 0 0 1 -0.25167,0.592215 0.82541414,0.82541414 0 0 1 -0.60503,0.244291 h -0.15549 a 0.82541414,0.82541414 0 0 1 -0.38671,-0.09625 0.88463599,0.88463599 0 0 1 -0.29446,-0.251668 L 97.76231,27.53673 v 6.96789 a 0.54410636,0.54410636 0 0 1 -0.17397,0.410848 0.57556829,0.57556829 0 0 1 -0.41826,0.168425 0.55521063,0.55521063 0 0 1 -0.403452,-0.168425 z"
|
||||
id="path17"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 109.19402,34.91547 a 0.55521063,0.55521063 0 0 1 -0.16839,-0.410848 v -7.380587 h -2.6262 a 0.52930072,0.52930072 0 0 1 -0.38681,-0.153613 0.5237487,0.5237487 0 0 1 -0.1555,-0.386789 0.54410636,0.54410636 0 0 1 0.1555,-0.392363 0.51449509,0.51449509 0 0 1 0.38681,-0.161007 h 6.41271 a 0.55521063,0.55521063 0 0 1 0.55561,0.555203 0.51449509,0.51449509 0 0 1 -0.16152,0.386798 0.55521063,0.55521063 0 0 1 -0.39409,0.153608 h -2.61291 v 7.37875 a 0.55521063,0.55521063 0 0 1 -0.17439,0.410848 0.57926969,0.57926969 0 0 1 -0.4201,0.168425 0.55521063,0.55521063 0 0 1 -0.41072,-0.168425 z"
|
||||
id="path19"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 114.94971,34.852571 a 0.56631481,0.56631481 0 0 1 -0.16631,-0.412727 v -7.811793 a 0.58112041,0.58112041 0 0 1 0.16631,-0.418275 0.55521063,0.55521063 0 0 1 0.41299,-0.173957 h 5.16517 a 0.55521063,0.55521063 0 0 1 0.555,0.555208 0.51449509,0.51449509 0 0 1 -0.16064,0.386792 0.55521063,0.55521063 0 0 1 -0.39265,0.153613 h -4.57495 v 2.838969 h 4.10156 a 0.55521063,0.55521063 0 0 1 0.55502,0.555218 0.51079377,0.51079377 0 0 1 -0.16112,0.386802 0.54225573,0.54225573 0 0 1 -0.3939,0.15731 h -4.10882 v 2.855632 h 4.57285 a 0.55521063,0.55521063 0 0 1 0.55557,0.555204 0.51634587,0.51634587 0 0 1 -0.16131,0.386787 0.55521063,0.55521063 0 0 1 -0.3922,0.153615 h -5.15958 a 0.56631481,0.56631481 0 0 1 -0.41299,-0.168398 z"
|
||||
id="path21"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 123.16718,34.91547 a 0.55521063,0.55521063 0 0 1 -0.16668,-0.410848 v -7.69151 a 0.82541414,0.82541414 0 0 1 0.24399,-0.597784 0.79395199,0.79395199 0 0 1 0.59244,-0.251694 h 0.16635 a 0.87353062,0.87353062 0 0 1 0.70886,0.386804 l 4.96735,7.162215 v -6.954945 a 0.57741901,0.57741901 0 0 1 0.16839,-0.418252 0.54410636,0.54410636 0 0 1 0.41075,-0.173969 0.59037391,0.59037391 0 0 1 0.59266,0.592221 v 7.689681 a 0.79765285,0.79765285 0 0 1 -0.24992,0.592215 0.83281503,0.83281503 0 0 1 -0.59969,0.244291 h -0.1538 a 0.81986106,0.81986106 0 0 1 -0.3866,-0.09625 0.89018674,0.89018674 0 0 1 -0.29641,-0.251668 l -4.98391,-7.199246 v 6.96789 a 0.54410636,0.54410636 0 0 1 -0.17353,0.410847 0.57741901,0.57741901 0 0 1 -0.41842,0.168425 0.55521063,0.55521063 0 0 1 -0.42183,-0.168425 z"
|
||||
id="path23"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 135.60159,34.91547 a 0.55521063,0.55521063 0 0 1 -0.16652,-0.410848 v -7.380587 h -2.62775 a 0.5255994,0.5255994 0 0 1 -0.54041,-0.540402 0.55521063,0.55521063 0 0 1 0.15334,-0.392363 0.51634587,0.51634587 0 0 1 0.38707,-0.161007 h 6.41472 a 0.55521063,0.55521063 0 0 1 0.55499,0.555203 0.51449509,0.51449509 0 0 1 -0.16096,0.386798 0.55521063,0.55521063 0 0 1 -0.39232,0.153608 h -2.62461 v 7.37875 a 0.54410636,0.54410636 0 0 1 -0.17362,0.410848 0.57556829,0.57556829 0 0 1 -0.41842,0.168425 0.55521063,0.55521063 0 0 1 -0.40551,-0.168425 z"
|
||||
id="path25"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 77.615566,47.54096 a 0.55521063,0.55521063 0 0 1 -0.168411,-0.410853 v -7.684111 a 0.81986106,0.81986106 0 0 1 0.246139,-0.603313 0.79025002,0.79025002 0 0 1 0.592227,-0.251708 h 0.166563 a 0.87353062,0.87353062 0 0 1 0.70326,0.392365 l 4.958035,7.160362 v -6.954935 a 0.57741901,0.57741901 0 0 1 0.168413,-0.418268 0.54410636,0.54410636 0 0 1 0.410857,-0.173957 0.59407531,0.59407531 0 0 1 0.592225,0.592225 v 7.689656 a 0.79765285,0.79765285 0 0 1 -0.249847,0.592235 0.83281503,0.83281503 0 0 1 -0.599628,0.244268 h -0.153607 a 0.81986106,0.81986106 0 0 1 -0.386794,-0.09622 0.87353062,0.87353062 0 0 1 -0.296115,-0.251703 l -4.983939,-7.199235 v 6.967918 a 0.55521063,0.55521063 0 0 1 -0.17397,0.410852 0.57926969,0.57926969 0 0 1 -0.420105,0.168392 0.55521063,0.55521063 0 0 1 -0.405303,-0.173966 z"
|
||||
id="path27"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 87.344703,47.54096 a 0.56816551,0.56816551 0 0 1 -0.16101,-0.410853 0.7032668,0.7032668 0 0 1 0.06459,-0.257229 l 3.28317,-7.754468 a 1.0104838,1.0104838 0 0 1 0.290568,-0.370125 0.71622143,0.71622143 0 0 1 0.457128,-0.14804 h 0.129547 a 0.71992298,0.71992298 0 0 1 0.457124,0.14804 0.9882749,0.9882749 0 0 1 0.288711,0.370125 l 3.286854,7.760013 a 0.7032668,0.7032668 0 0 1 0.06457,0.257259 0.57556829,0.57556829 0 0 1 -0.161013,0.410852 0.55521063,0.55521063 0 0 1 -0.42011,0.168392 0.59592602,0.59592602 0 0 1 -0.327558,-0.09622 0.63108943,0.63108943 0 0 1 -0.225783,-0.264643 l -0.836409,-2.009858 h -4.386163 l -0.830966,2.01169 a 0.63108943,0.63108943 0 0 1 -0.225784,0.264663 0.60703023,0.60703023 0 0 1 -0.329424,0.09624 0.55521063,0.55521063 0 0 1 -0.418261,-0.17584 z m 2.259713,-3.270175 h 3.477465 L 91.34407,40.084508 Z"
|
||||
id="path29"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="M 98.852371,47.54096 A 0.55521063,0.55521063 0 0 1 98.683954,47.130107 V 39.755064 H 96.05781 a 0.52745008,0.52745008 0 0 1 -0.542258,-0.542239 0.54410636,0.54410636 0 0 1 0.155463,-0.392372 0.51449509,0.51449509 0 0 1 0.386795,-0.161004 h 6.41642 a 0.55521063,0.55521063 0 0 1 0.55528,0.555206 0.51449509,0.51449509 0 0 1 -0.16124,0.38681 0.540405,0.540405 0 0 1 -0.39209,0.153599 h -2.618835 v 7.380618 a 0.55521063,0.55521063 0 0 1 -0.174027,0.410852 0.57926969,0.57926969 0 0 1 -0.4201,0.168392 0.55521063,0.55521063 0 0 1 -0.410847,-0.173966 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 104.60795,47.54096 a 0.55521063,0.55521063 0 0 1 -0.16661,-0.410853 v -7.94134 a 0.58482187,0.58482187 0 0 1 0.16661,-0.418268 0.55521063,0.55521063 0 0 1 0.41299,-0.173957 0.59407531,0.59407531 0 0 1 0.59214,0.592225 v 7.946915 a 0.54410636,0.54410636 0 0 1 -0.17782,0.405278 0.57556829,0.57556829 0 0 1 -0.41836,0.168426 0.55521063,0.55521063 0 0 1 -0.40895,-0.168426 z"
|
||||
id="path33"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 109.72153,47.187498 a 4.0511871,4.0511871 0 0 1 -1.57138,-1.636031 5.2430389,5.2430389 0 0 1 0,-4.791483 4.0511871,4.0511871 0 0 1 1.57138,-1.635995 5.0228053,5.0228053 0 0 1 4.73218,0 4.1085585,4.1085585 0 0 1 1.57138,1.643414 5.1542044,5.1542044 0 0 1 0,4.776648 4.1085585,4.1085585 0 0 1 -1.57138,1.643447 5.0228053,5.0228053 0 0 1 -4.73218,0 z m 4.16046,-0.966083 a 3.0610601,3.0610601 0 0 0 1.15852,-1.262188 4.267719,4.267719 0 0 0 0,-3.607002 3.0610601,3.0610601 0 0 0 -1.15852,-1.262188 3.7014043,3.7014043 0 0 0 -3.58654,0 3.0610601,3.0610601 0 0 0 -1.15298,1.262188 4.267719,4.267719 0 0 0 0,3.607002 3.0610601,3.0610601 0 0 0 1.15298,1.262188 3.7014043,3.7014043 0 0 0 3.58654,0 z"
|
||||
id="path35"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 118.73656,47.54096 a 0.55521063,0.55521063 0 0 1 -0.16668,-0.410853 v -7.684111 a 0.82541414,0.82541414 0 0 1 0.244,-0.603313 0.79395199,0.79395199 0 0 1 0.59255,-0.251708 h 0.16632 a 0.87353062,0.87353062 0 0 1 0.70887,0.386788 l 4.95608,7.165939 v -6.954935 a 0.57741901,0.57741901 0 0 1 0.16839,-0.418268 0.55521063,0.55521063 0 0 1 0.41306,-0.173957 0.56816551,0.56816551 0 0 1 0.41796,0.173957 0.57556829,0.57556829 0 0 1 0.1742,0.418268 v 7.689656 a 0.79950344,0.79950344 0 0 1 -0.25173,0.592235 0.83096538,0.83096538 0 0 1 -0.59969,0.244268 h -0.1538 a 0.81986106,0.81986106 0 0 1 -0.38661,-0.09622 0.89018674,0.89018674 0 0 1 -0.29631,-0.251703 l -4.98398,-7.199235 v 6.967918 a 0.54410636,0.54410636 0 0 1 -0.17355,0.410852 0.57741901,0.57741901 0 0 1 -0.41841,0.168392 0.55521063,0.55521063 0 0 1 -0.41067,-0.173966 z"
|
||||
id="path37"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 132.36619,47.662806 a 0.16656329,0.16656329 0 0 1 -0.0526,-0.123236 v -2.305248 a 0.2476239,0.2476239 0 0 1 0.0757,-0.181014 0.23818531,0.23818531 0 0 1 0.17736,-0.0755 h 0.0526 a 0.26205927,0.26205927 0 0 1 0.21265,0.11605 l 1.48691,2.149758 v -2.086452 a 0.17322576,0.17322576 0 0 1 0.053,-0.125508 0.16656329,0.16656329 0 0 1 0.1239,-0.05205 0.17044952,0.17044952 0 0 1 0.12542,0.05205 0.17267036,0.17267036 0 0 1 0.0537,0.125508 v 2.306901 a 0.23985104,0.23985104 0 0 1 -0.0756,0.177669 0.24928962,0.24928962 0 0 1 -0.17993,0.07328 h -0.0471 a 0.24595828,0.24595828 0 0 1 -0.11605,-0.02905 0.26705624,0.26705624 0 0 1 -0.089,-0.0755 l -1.49522,-2.15977 v 2.090368 a 0.16323178,0.16323178 0 0 1 -0.0542,0.123258 0.17322576,0.17322576 0 0 1 -0.12533,0.05061 0.16656329,0.16656329 0 0 1 -0.12329,-0.05205 z"
|
||||
id="path37-3"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 135.07399,47.664497 a 0.16989438,0.16989438 0 0 1 -0.0525,-0.123816 v -2.343552 a 0.17433613,0.17433613 0 0 1 0.0526,-0.125475 0.16656329,0.16656329 0 0 1 0.12399,-0.05205 h 1.54965 a 0.16656329,0.16656329 0 0 1 0.16636,0.166551 0.15434859,0.15434859 0 0 1 -0.0503,0.116035 0.16656329,0.16656329 0 0 1 -0.11765,0.04614 h -1.37251 v 0.851696 h 1.23043 a 0.16656329,0.16656329 0 0 1 0.16655,0.166554 0.15323809,0.15323809 0 0 1 -0.0503,0.116038 0.16267667,0.16267667 0 0 1 -0.11828,0.04711 h -1.23257 v 0.856687 h 1.37196 a 0.16656329,0.16656329 0 0 1 0.16661,0.166572 0.15490387,0.15490387 0 0 1 -0.0503,0.116017 0.16656329,0.16656329 0 0 1 -0.11768,0.04614 h -1.54784 a 0.16989438,0.16989438 0 0 1 -0.12371,-0.05061 z"
|
||||
id="path21-6"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<path
|
||||
class="cls-2"
|
||||
d="m 138.31938,47.664494 a 0.16656329,0.16656329 0 0 1 -0.0526,-0.12328 V 45.32703 h -0.78834 a 0.15767982,0.15767982 0 0 1 -0.16207,-0.162122 0.16656329,0.16656329 0 0 1 0.0471,-0.117704 0.15490387,0.15490387 0 0 1 0.11604,-0.04838 h 1.92434 a 0.16656329,0.16656329 0 0 1 0.16665,0.166585 0.15434859,0.15434859 0 0 1 -0.0503,0.116026 0.16656329,0.16656329 0 0 1 -0.11765,0.04614 h -0.78728 v 2.213598 a 0.16323178,0.16323178 0 0 1 -0.054,0.12328 0.17267036,0.17267036 0 0 1 -0.12548,0.05061 0.16656329,0.16656329 0 0 1 -0.12163,-0.05061 z"
|
||||
id="path25-7"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
||||
<circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path2370"
|
||||
cx="131.01605"
|
||||
cy="47.365242"
|
||||
r="0.34973946" />
|
||||
<g
|
||||
fill="#ffffff"
|
||||
id="g5"
|
||||
transform="matrix(0.99999435,0,0,0.99999435,22.886461,22.155914)">
|
||||
<path
|
||||
d="m 20.983,0 v 22.81 l 6.455,6.5 V 13.783 Z m 14.473,0.024 v 15.549 l 6.456,13.736 V 6.499 Z"
|
||||
fill-opacity="0.5"
|
||||
id="path1" />
|
||||
<path
|
||||
d="M 27.438,29.31 H 6.5 L 0,22.81 h 20.984 z"
|
||||
id="path2" />
|
||||
<path
|
||||
d="M 0,6.5 V 22.807 H 6.456 V 6.5 Z"
|
||||
fill-opacity="0.5"
|
||||
id="path3" />
|
||||
<path
|
||||
d="M 19.533,0 H 6.5 L 0,6.5 H 13.32 Z M 41.915,29.316 28.142,0 h -7.165 l 13.755,29.316 z"
|
||||
id="path4" />
|
||||
<path
|
||||
d="m 47.39,2.545 a 2.545,2.545 0 1 0 -5.09,0 2.545,2.545 0 1 0 5.09,0 m -0.33,0 c 0,1.216 -0.999,2.243 -2.215,2.243 -1.216,0 -2.214,-1.027 -2.214,-2.243 0,-1.216 0.998,-2.243 2.214,-2.243 1.216,0 2.214,1.027 2.214,2.243 m -1.173,1.406 -0.71,-1.202 c 0.372,-0.106 0.64,-0.372 0.64,-0.787 0,-0.478 -0.409,-0.83 -0.872,-0.83 h -0.9 v 2.82 H 44.36 V 2.776 h 0.464 L 45.52,3.95 Z m -0.387,-1.99 c 0,0.31 -0.253,0.535 -0.59,0.535 h -0.55 V 1.42 h 0.55 c 0.337,0 0.59,0.232 0.59,0.542"
|
||||
fill-opacity="0.51"
|
||||
id="path5" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 28 KiB |
42
public/img/logo.svg
Normal file
42
public/img/logo.svg
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="8.2602539mm"
|
||||
height="8.3228693mm"
|
||||
viewBox="0 0 8.2602539 8.3228693"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1" />
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-100.80624,-144.46251)">
|
||||
<rect
|
||||
style="fill:none;fill-opacity:1;stroke:#fffdfd;stroke-width:0.396875;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3"
|
||||
width="7.8633785"
|
||||
height="4.0744472"
|
||||
x="101.00468"
|
||||
y="145.71317" />
|
||||
<g
|
||||
id="g6"
|
||||
transform="matrix(0.44901262,0,0,0.30313405,81.948876,138.55801)"
|
||||
style="stroke:#ffffff;stroke-width:1.07574;stroke-dasharray:none;stroke-opacity:1">
|
||||
<path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1.07574;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 49.030808,37.632967 -2.348149,8.763414 m 6.348149,-8.763414 2.677863,8.763414"
|
||||
id="path6" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-opacity:1;stroke:none;stroke-width:0.661458;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path7"
|
||||
d="m 105.61076,145.15149 a 0.42403585,0.34019229 0 0 1 -0.21202,0.29461 0.42403585,0.34019229 0 0 1 -0.42404,0 0.42403585,0.34019229 0 0 1 -0.21201,-0.29461 h 0.42403 z" />
|
||||
<path
|
||||
style="fill:#fbfbfb;fill-opacity:1;stroke:none;stroke-width:0.661458;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path8"
|
||||
d="m 103.81304,145.58186 a 1.1233398,1.1193535 0 0 1 1.12334,-1.11935 1.1233398,1.1193535 0 0 1 1.12334,1.11935 h -1.12334 z" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
BIN
public/img/presentationmaker.png
Normal file
BIN
public/img/presentationmaker.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
423
public/img/presentationmaker.svg
Normal file
423
public/img/presentationmaker.svg
Normal file
|
@ -0,0 +1,423 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 176 48"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
width="176"
|
||||
height="48"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1"><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8566"><path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8564" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8584"><path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8582" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8612"><path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8610" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8624"><path
|
||||
d="m 271.674,749.573 v -64.657 l 18.3,-18.426 v 44.013 z"
|
||||
id="path8622" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-29.309916,29.309916,0,107.56319,51.61644)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8640"><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8630" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.215824"
|
||||
id="stop8632" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.75"
|
||||
id="stop8634" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.76850016"
|
||||
id="stop8636" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8638" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8650"><path
|
||||
d="M 312.701,749.505 V 705.43 l 18.301,-38.937 v 64.659 z"
|
||||
id="path8648" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-29.284783,29.284783,0,122.03666,51.615502)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8666"><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8656" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.422802"
|
||||
id="stop8658" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.972582"
|
||||
id="stop8660" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.97461095"
|
||||
id="stop8662" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8664" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8676"><path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8674" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8684"><path
|
||||
d="m 270.701,750.4 h 20.3 v -45.214 h -20.3 z"
|
||||
id="path8682" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8700"><path
|
||||
d="m 311.582,706.377 h 20.301 V 665.35 h -20.301 z"
|
||||
id="path8698" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8716"><path
|
||||
d="m 289.974,666.49 h -59.353 l -18.425,18.425 59.481,0.001 z"
|
||||
id="path8714" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(19.297539,-16.192559,-16.192559,-19.297539,84.195184,56.472015)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8732"><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8722" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8724" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8726" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8728" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8730" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8742"><path
|
||||
d="m 212.196,731.148 v -46.226 l 18.301,0.002 v 46.224 z"
|
||||
id="path8740" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0,-16.307204,16.307204,0,86.58079,45.113934)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8766"><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0"
|
||||
id="stop8748" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.25"
|
||||
id="stop8750" /><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.44050522"
|
||||
id="stop8752" /><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.5"
|
||||
id="stop8754" /><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0.52936829"
|
||||
id="stop8756" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.75"
|
||||
id="stop8758" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.996319"
|
||||
id="stop8760" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.9965914"
|
||||
id="stop8762" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8764" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8776"><path
|
||||
d="M 0,0 H 1280 V 800 H 0 Z"
|
||||
id="path8774" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8784"><path
|
||||
d="m 211.196,687.809 h 20.301 v -3.887 h -20.301 z"
|
||||
id="path8782" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8800"><path
|
||||
d="m 211.196,732.223 h 20.301 v -3.887 h -20.301 z"
|
||||
id="path8798" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8816"><path
|
||||
d="m 267.565,749.573 h -36.944 l -18.425,-18.425 h 37.755 z"
|
||||
id="path8814" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(13.689206,12.765392,-12.765392,13.689206,83.04661,19.183338)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8832"><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8822" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8824" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8826" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8828" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8830" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath8862"><path
|
||||
d="m 331.011,666.473 -39.042,83.1 h -20.312 l 38.993,-83.1 z"
|
||||
id="path8860" /></clipPath><linearGradient
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="1"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-16.76835,31.536681,-31.536681,-16.76835,119.95484,21.196219)"
|
||||
spreadMethod="pad"
|
||||
id="linearGradient8878"><stop
|
||||
style="stop-opacity:1;stop-color:#dfbd6a"
|
||||
offset="0"
|
||||
id="stop8868" /><stop
|
||||
style="stop-opacity:1;stop-color:#c78300"
|
||||
offset="0.29489"
|
||||
id="stop8870" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.662088"
|
||||
id="stop8872" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="0.6870937"
|
||||
id="stop8874" /><stop
|
||||
style="stop-opacity:1;stop-color:#6f3200"
|
||||
offset="1"
|
||||
id="stop8876" /></linearGradient><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2069"><path
|
||||
d="M 0,0 H 23.3971 V -14.91 H 0 Z"
|
||||
clip-rule="evenodd"
|
||||
id="path2067" /></clipPath><clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath2073"><path
|
||||
d="M 0,-14.91 H 209.76378 V 14.91 H 0 Z"
|
||||
id="path2071" /></clipPath><linearGradient
|
||||
id="i"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(19.29766,-16.19266,-16.19266,-19.29766,29.9802,59.309292)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0"><stop
|
||||
offset="0"
|
||||
stop-color="#dfbd6a"
|
||||
id="stop2648" /><stop
|
||||
offset=".295"
|
||||
stop-color="#c78300"
|
||||
id="stop2650" /><stop
|
||||
offset=".662"
|
||||
stop-color="#6f3200"
|
||||
id="stop2652" /><stop
|
||||
offset=".687"
|
||||
stop-color="#6f3200"
|
||||
id="stop2654" /><stop
|
||||
offset="1"
|
||||
stop-color="#6f3200"
|
||||
id="stop2656" /></linearGradient><clipPath
|
||||
id="o"
|
||||
clipPathUnits="userSpaceOnUse"><path
|
||||
d="m 267.565,749.573 h -36.944 l -18.425,-18.425 h 37.755 z"
|
||||
id="path2620" /></clipPath><linearGradient
|
||||
id="p"
|
||||
spreadMethod="pad"
|
||||
gradientTransform="matrix(38.804048,-36.18536,-36.18536,-38.804048,228.9593,749.93786)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="0"
|
||||
x2="1"
|
||||
y1="0"
|
||||
x1="0"><stop
|
||||
offset="0"
|
||||
stop-color="#dfbd6a"
|
||||
id="stop2678" /><stop
|
||||
offset=".295"
|
||||
stop-color="#c78300"
|
||||
id="stop2680" /><stop
|
||||
offset=".662"
|
||||
stop-color="#6f3200"
|
||||
id="stop2682" /><stop
|
||||
offset=".687"
|
||||
stop-color="#6f3200"
|
||||
id="stop2684" /><stop
|
||||
offset="1"
|
||||
stop-color="#6f3200"
|
||||
id="stop2686" /></linearGradient></defs><text
|
||||
xml:space="preserve"
|
||||
style="font-weight:bold;font-size:13.3333px;line-height:1.25;font-family:'DejaVu Serif';-inkscape-font-specification:'DejaVu Serif Bold';fill:#ffffff;fill-opacity:1"
|
||||
x="42.828514"
|
||||
y="15.528239"
|
||||
id="text1"><tspan
|
||||
id="tspan1"
|
||||
x="42.828514"
|
||||
y="15.528239"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3333px;font-family:Roboto;-inkscape-font-specification:Roboto;fill:#ffffff;fill-opacity:1">PresentationMaker.js</tspan></text><text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3333px;line-height:1.25;font-family:Roboto;-inkscape-font-specification:Roboto;fill:#ffffff;fill-opacity:1"
|
||||
x="53.405025"
|
||||
y="39.509506"
|
||||
id="text2"><tspan
|
||||
id="tspan2"
|
||||
x="53.405025"
|
||||
y="39.509506"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13.3333px;font-family:Roboto;-inkscape-font-specification:Roboto;fill:#ffffff;fill-opacity:1">by</tspan></text><g
|
||||
id="g2277"
|
||||
transform="matrix(1.3333333,0,0,-1.3333333,17.273461,90.445105)" /><path
|
||||
class="cls-2"
|
||||
d="m 116.17083,31.093495 a 2.7248604,2.7248604 0 0 1 -1.08371,-1.084962 3.3371748,3.3371748 0 0 1 -0.39532,-1.653626 3.3359281,3.3359281 0 0 1 0.39282,-1.651121 2.7248604,2.7248604 0 0 1 1.08371,-1.084961 3.1937612,3.1937612 0 0 1 1.55885,-0.374115 3.6427085,3.6427085 0 0 1 1.05378,0.139662 4.4894729,4.4894729 0 0 1 0.92408,0.399067 0.34793417,0.34793417 0 0 1 0.19329,0.321744 0.32423971,0.32423971 0 0 1 -0.0948,0.230707 0.33546338,0.33546338 0 0 1 -0.24942,0.09977 0.35292248,0.35292248 0 0 1 -0.15588,-0.03474 3.9731835,3.9731835 0 0 0 -0.74825,-0.304286 3.0603242,3.0603242 0 0 0 -0.84177,-0.103508 2.4629749,2.4629749 0 0 0 -1.27077,0.30803 1.9616505,1.9616505 0 0 0 -0.7894,0.841775 2.6787192,2.6787192 0 0 0 -0.26563,1.209663 2.6799654,2.6799654 0 0 0 0.26563,1.210916 1.9616505,1.9616505 0 0 0 0.7894,0.841774 2.4629749,2.4629749 0 0 0 1.26952,0.314259 3.1089601,3.1089601 0 0 0 0.84178,-0.103505 3.9731835,3.9731835 0 0 0 0.74824,-0.304287 0.35292248,0.35292248 0 0 1 0.15589,-0.03474 0.3416988,0.3416988 0 0 1 0.24942,0.09602 0.31925143,0.31925143 0 0 1 0.0948,0.234453 0.34793417,0.34793417 0 0 1 -0.1908,0.329225 4.4894729,4.4894729 0 0 1 -0.92408,0.399067 3.6427085,3.6427085 0 0 1 -1.05254,0.132188 3.1937612,3.1937612 0 0 1 -1.55884,-0.374119 z"
|
||||
id="path13"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 121.99841,31.073528 a 2.7348372,2.7348372 0 0 1 -1.05253,-1.1024 3.5229895,3.5229895 0 0 1 0,-3.228683 2.7348372,2.7348372 0 0 1 1.05752,-1.102422 3.3870581,3.3870581 0 0 1 3.19002,0 2.7772378,2.7772378 0 0 1 1.05877,1.10741 3.4830828,3.4830828 0 0 1 0,3.218704 2.7772378,2.7772378 0 0 1 -1.06625,1.107391 3.3870581,3.3870581 0 0 1 -3.19002,0 z m 2.80343,-0.650958 a 2.0464515,2.0464515 0 0 0 0.78067,-0.850509 2.6812134,2.6812134 0 0 0 0.26937,-1.215902 2.6799654,2.6799654 0 0 0 -0.26937,-1.21465 2.0464515,2.0464515 0 0 0 -0.78067,-0.850502 2.4941519,2.4941519 0 0 0 -2.41683,0 2.0713926,2.0713926 0 0 0 -0.77693,0.850502 2.6799654,2.6799654 0 0 0 -0.26812,1.21465 2.6812134,2.6812134 0 0 0 0.26812,1.215902 2.0713926,2.0713926 0 0 0 0.77693,0.850509 2.4941519,2.4941519 0 0 0 2.41683,0 z"
|
||||
id="path15"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 128.07417,31.31546 a 0.37412277,0.37412277 0 0 1 -0.11348,-0.276845 v -5.182843 a 0.55619653,0.55619653 0 0 1 0.16461,-0.40281 0.53499609,0.53499609 0 0 1 0.39906,-0.169601 h 0.11349 a 0.5898674,0.5898674 0 0 1 0.47762,0.260644 l 3.34099,4.826182 v -4.686516 a 0.39407599,0.39407599 0 0 1 0.11228,-0.281834 0.37412277,0.37412277 0 0 1 0.27799,-0.117228 0.40031132,0.40031132 0 0 1 0.39896,0.399062 v 5.18161 a 0.53499609,0.53499609 0 0 1 -0.16959,0.399058 0.55619653,0.55619653 0 0 1 -0.40769,0.164613 h -0.10477 a 0.55619653,0.55619653 0 0 1 -0.26058,-0.06486 0.59610254,0.59610254 0 0 1 -0.19842,-0.169583 l -3.35954,-4.851136 v 4.695238 a 0.36664028,0.36664028 0 0 1 -0.11723,0.276846 0.38784056,0.38784056 0 0 1 -0.28184,0.113491 0.37412277,0.37412277 0 0 1 -0.27186,-0.113491 z"
|
||||
id="path17"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 136.44823,31.31546 a 0.37412277,0.37412277 0 0 1 -0.11347,-0.276845 v -4.97333 h -1.76963 a 0.35666365,0.35666365 0 0 1 -0.26065,-0.103511 0.35292248,0.35292248 0 0 1 -0.10478,-0.260634 0.36664028,0.36664028 0 0 1 0.10478,-0.264389 0.34668704,0.34668704 0 0 1 0.26065,-0.108493 h 4.32113 a 0.37412277,0.37412277 0 0 1 0.3744,0.374118 0.34668704,0.34668704 0 0 1 -0.10884,0.260639 0.37412277,0.37412277 0 0 1 -0.26556,0.103507 h -1.76068 v 4.972093 a 0.37412277,0.37412277 0 0 1 -0.11751,0.276845 0.39033471,0.39033471 0 0 1 -0.28308,0.113492 0.37412277,0.37412277 0 0 1 -0.27676,-0.113492 z"
|
||||
id="path19"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 140.32664,31.273076 a 0.3816052,0.3816052 0 0 1 -0.11206,-0.278111 v -5.263894 a 0.3915818,0.3915818 0 0 1 0.11206,-0.28185 0.37412277,0.37412277 0 0 1 0.27829,-0.117219 h 3.4805 a 0.37412277,0.37412277 0 0 1 0.37398,0.374121 0.34668704,0.34668704 0 0 1 -0.10825,0.260636 0.37412277,0.37412277 0 0 1 -0.26458,0.10351 h -3.08278 v 1.913009 h 2.76379 a 0.37412277,0.37412277 0 0 1 0.37399,0.374128 0.34419294,0.34419294 0 0 1 -0.10856,0.260642 0.36539325,0.36539325 0 0 1 -0.26543,0.106002 h -2.76868 v 1.924237 h 3.08136 a 0.37412277,0.37412277 0 0 1 0.37437,0.374118 0.34793417,0.34793417 0 0 1 -0.1087,0.260633 0.37412277,0.37412277 0 0 1 -0.26428,0.103511 h -3.47673 a 0.3816052,0.3816052 0 0 1 -0.27829,-0.113473 z"
|
||||
id="path21"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 145.8639,31.31546 a 0.37412277,0.37412277 0 0 1 -0.11232,-0.276845 v -5.182843 a 0.55619653,0.55619653 0 0 1 0.16441,-0.40281 0.53499609,0.53499609 0 0 1 0.39921,-0.169601 h 0.11209 a 0.58861931,0.58861931 0 0 1 0.47766,0.260644 l 3.3472,4.826182 v -4.686516 a 0.38908765,0.38908765 0 0 1 0.11347,-0.281834 0.36664028,0.36664028 0 0 1 0.27678,-0.117228 0.39781717,0.39781717 0 0 1 0.39935,0.399062 v 5.18161 a 0.53748988,0.53748988 0 0 1 -0.1684,0.399058 0.56118354,0.56118354 0 0 1 -0.4041,0.164613 h -0.10363 a 0.55245464,0.55245464 0 0 1 -0.26051,-0.06486 0.59984285,0.59984285 0 0 1 -0.19973,-0.169583 l -3.35836,-4.851136 v 4.695239 a 0.36664028,0.36664028 0 0 1 -0.11693,0.276845 0.38908765,0.38908765 0 0 1 -0.28195,0.113491 0.37412277,0.37412277 0 0 1 -0.28424,-0.113491 z"
|
||||
id="path23"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 154.24269,31.31546 a 0.37412277,0.37412277 0 0 1 -0.11221,-0.276845 v -4.97333 h -1.77068 a 0.35416956,0.35416956 0 0 1 -0.36415,-0.364145 0.37412277,0.37412277 0 0 1 0.10333,-0.264389 0.34793417,0.34793417 0 0 1 0.26082,-0.108493 h 4.32249 a 0.37412277,0.37412277 0 0 1 0.37398,0.374118 0.34668704,0.34668704 0 0 1 -0.10846,0.260639 0.37412277,0.37412277 0 0 1 -0.26436,0.103507 h -1.76857 v 4.972093 a 0.36664028,0.36664028 0 0 1 -0.11699,0.276845 0.38784056,0.38784056 0 0 1 -0.28195,0.113492 0.37412277,0.37412277 0 0 1 -0.27325,-0.113492 z"
|
||||
id="path25"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 115.16943,39.823012 a 0.37412277,0.37412277 0 0 1 -0.11348,-0.276849 v -5.177856 a 0.55245464,0.55245464 0 0 1 0.16585,-0.406536 0.53250156,0.53250156 0 0 1 0.39907,-0.169611 h 0.11224 a 0.58861931,0.58861931 0 0 1 0.47388,0.264391 l 3.34092,4.824934 v -4.686509 a 0.38908765,0.38908765 0 0 1 0.11348,-0.281846 0.36664028,0.36664028 0 0 1 0.27685,-0.117219 0.40031132,0.40031132 0 0 1 0.39907,0.399065 v 5.181593 a 0.53748988,0.53748988 0 0 1 -0.16836,0.399071 0.56118354,0.56118354 0 0 1 -0.40405,0.164597 h -0.10351 a 0.55245464,0.55245464 0 0 1 -0.26063,-0.06484 0.58861931,0.58861931 0 0 1 -0.19954,-0.169607 l -3.35837,-4.851128 v 4.695258 a 0.37412277,0.37412277 0 0 1 -0.11723,0.276848 0.39033471,0.39033471 0 0 1 -0.28308,0.113469 0.37412277,0.37412277 0 0 1 -0.27311,-0.117225 z"
|
||||
id="path27"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 121.7253,39.823012 a 0.38285228,0.38285228 0 0 1 -0.10849,-0.276849 0.47388884,0.47388884 0 0 1 0.0435,-0.173331 l 2.21233,-5.225266 a 0.68090375,0.68090375 0 0 1 0.1958,-0.249404 0.48261818,0.48261818 0 0 1 0.30803,-0.09976 h 0.0873 a 0.48511243,0.48511243 0 0 1 0.30803,0.09976 0.66593852,0.66593852 0 0 1 0.19454,0.249404 l 2.21482,5.229003 a 0.47388884,0.47388884 0 0 1 0.0435,0.173351 0.38784056,0.38784056 0 0 1 -0.1085,0.276848 0.37412277,0.37412277 0 0 1 -0.28309,0.113469 0.4015584,0.4015584 0 0 1 -0.22072,-0.06484 0.42525289,0.42525289 0 0 1 -0.15214,-0.178326 l -0.56361,-1.354322 h -2.95557 l -0.55993,1.355556 a 0.42525289,0.42525289 0 0 1 -0.15215,0.17834 0.40904086,0.40904086 0 0 1 -0.22197,0.06485 0.37412277,0.37412277 0 0 1 -0.28184,-0.118488 z m 1.52269,-2.203573 h 2.34325 l -1.17101,-2.820878 z"
|
||||
id="path29"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 129.47962,39.823012 a 0.37412277,0.37412277 0 0 1 -0.11348,-0.276849 v -4.969594 h -1.7696 a 0.35541662,0.35541662 0 0 1 -0.3654,-0.365382 0.36664028,0.36664028 0 0 1 0.10476,-0.264396 0.34668704,0.34668704 0 0 1 0.26064,-0.108491 h 4.32363 a 0.37412277,0.37412277 0 0 1 0.37417,0.37412 0.34668704,0.34668704 0 0 1 -0.10865,0.260648 0.36414615,0.36414615 0 0 1 -0.2642,0.103501 h -1.76468 v 4.973351 a 0.37412277,0.37412277 0 0 1 -0.11726,0.276848 0.39033471,0.39033471 0 0 1 -0.28308,0.113469 0.37412277,0.37412277 0 0 1 -0.27685,-0.117225 z"
|
||||
id="path31"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 133.35796,39.823012 a 0.37412277,0.37412277 0 0 1 -0.11227,-0.276849 v -5.351187 a 0.39407599,0.39407599 0 0 1 0.11227,-0.281846 0.37412277,0.37412277 0 0 1 0.27829,-0.117219 0.40031132,0.40031132 0 0 1 0.399,0.399065 v 5.354944 a 0.36664028,0.36664028 0 0 1 -0.11982,0.273092 0.38784056,0.38784056 0 0 1 -0.28191,0.113492 0.37412277,0.37412277 0 0 1 -0.27556,-0.113492 z"
|
||||
id="path33"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 136.80369,39.584835 a 2.7298493,2.7298493 0 0 1 -1.05886,-1.102422 3.5329659,3.5329659 0 0 1 0,-3.228689 2.7298493,2.7298493 0 0 1 1.05886,-1.102398 3.3845639,3.3845639 0 0 1 3.18873,0 2.7685084,2.7685084 0 0 1 1.05886,1.107397 3.4731057,3.4731057 0 0 1 0,3.218693 2.7685084,2.7685084 0 0 1 -1.05886,1.107419 3.3845639,3.3845639 0 0 1 -3.18873,0 z m 2.80348,-0.650984 a 2.0626627,2.0626627 0 0 0 0.78066,-0.850512 2.875757,2.875757 0 0 0 0,-2.43054 2.0626627,2.0626627 0 0 0 -0.78066,-0.850512 2.4941519,2.4941519 0 0 0 -2.41675,0 2.0626627,2.0626627 0 0 0 -0.77692,0.850512 2.875757,2.875757 0 0 0 0,2.43054 2.0626627,2.0626627 0 0 0 0.77692,0.850512 2.4941519,2.4941519 0 0 0 2.41675,0 z"
|
||||
id="path35"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 142.87837,39.823012 a 0.37412277,0.37412277 0 0 1 -0.11231,-0.276849 v -5.177856 a 0.55619653,0.55619653 0 0 1 0.16441,-0.406536 0.53499609,0.53499609 0 0 1 0.39929,-0.169611 h 0.11207 a 0.58861931,0.58861931 0 0 1 0.47766,0.260633 l 3.33961,4.828692 v -4.686509 a 0.38908765,0.38908765 0 0 1 0.11346,-0.281846 0.37412277,0.37412277 0 0 1 0.27834,-0.117219 0.38285228,0.38285228 0 0 1 0.28164,0.117219 0.38784056,0.38784056 0 0 1 0.11738,0.281846 v 5.181593 a 0.53873688,0.53873688 0 0 1 -0.16963,0.399071 0.55993717,0.55993717 0 0 1 -0.40409,0.164597 h -0.10364 a 0.55245464,0.55245464 0 0 1 -0.26051,-0.06484 0.59984285,0.59984285 0 0 1 -0.19967,-0.169607 l -3.3584,-4.851128 v 4.695258 a 0.36664028,0.36664028 0 0 1 -0.11694,0.276848 0.38908765,0.38908765 0 0 1 -0.28194,0.113469 0.37412277,0.37412277 0 0 1 -0.27673,-0.117225 z"
|
||||
id="path37"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 152.06255,39.905117 a 0.1122369,0.1122369 0 0 1 -0.0354,-0.08304 v -1.553366 a 0.16685873,0.16685873 0 0 1 0.051,-0.121975 0.16049863,0.16049863 0 0 1 0.11951,-0.05088 h 0.0354 a 0.17658585,0.17658585 0 0 1 0.1433,0.0782 l 1.00193,1.448592 v -1.405933 a 0.11672633,0.11672633 0 0 1 0.0357,-0.08457 0.1122369,0.1122369 0 0 1 0.0835,-0.03507 0.11485559,0.11485559 0 0 1 0.0845,0.03507 0.11635208,0.11635208 0 0 1 0.0362,0.08457 v 1.55448 a 0.16162107,0.16162107 0 0 1 -0.0509,0.119721 0.16798116,0.16798116 0 0 1 -0.12124,0.04938 h -0.0317 a 0.16573637,0.16573637 0 0 1 -0.0782,-0.01958 0.179953,0.179953 0 0 1 -0.06,-0.05087 l -1.00754,-1.455338 v 1.408572 a 0.109992,0.109992 0 0 1 -0.0365,0.08306 0.11672633,0.11672633 0 0 1 -0.0844,0.0341 0.1122369,0.1122369 0 0 1 -0.0831,-0.03507 z"
|
||||
id="path37-3"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 153.88717,39.906256 a 0.11448152,0.11448152 0 0 1 -0.0354,-0.08343 v -1.579177 a 0.11747454,0.11747454 0 0 1 0.0354,-0.08455 0.1122369,0.1122369 0 0 1 0.0836,-0.03507 h 1.04422 a 0.1122369,0.1122369 0 0 1 0.1121,0.112229 0.10400615,0.10400615 0 0 1 -0.0339,0.07819 0.1122369,0.1122369 0 0 1 -0.0793,0.03109 h -0.92486 v 0.573906 h 0.82912 a 0.1122369,0.1122369 0 0 1 0.11222,0.112231 0.10325785,0.10325785 0 0 1 -0.0339,0.07819 0.10961794,0.10961794 0 0 1 -0.0797,0.03174 h -0.83056 v 0.57727 h 0.92448 a 0.1122369,0.1122369 0 0 1 0.11227,0.112242 0.10438032,0.10438032 0 0 1 -0.0339,0.07818 0.1122369,0.1122369 0 0 1 -0.0793,0.03109 h -1.04299 a 0.11448152,0.11448152 0 0 1 -0.0834,-0.0341 z"
|
||||
id="path21-6"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><path
|
||||
class="cls-2"
|
||||
d="m 156.07405,39.906254 a 0.1122369,0.1122369 0 0 1 -0.0354,-0.08307 V 38.33118 h -0.53121 a 0.10625087,0.10625087 0 0 1 -0.10921,-0.109244 0.1122369,0.1122369 0 0 1 0.0317,-0.07931 0.10438032,0.10438032 0 0 1 0.0782,-0.0326 h 1.29669 a 0.1122369,0.1122369 0 0 1 0.1123,0.112251 0.10400615,0.10400615 0 0 1 -0.0339,0.07818 0.1122369,0.1122369 0 0 1 -0.0793,0.03109 h -0.5305 v 1.49161 a 0.109992,0.109992 0 0 1 -0.0364,0.08307 0.11635208,0.11635208 0 0 1 -0.0846,0.0341 0.1122369,0.1122369 0 0 1 -0.082,-0.0341 z"
|
||||
id="path25-7"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.999998" /><circle
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:6.80315;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path2370"
|
||||
cx="151.15277"
|
||||
cy="39.704605"
|
||||
r="0.23566821" /><rect
|
||||
style="fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="rect3"
|
||||
width="29.719856"
|
||||
height="15.399486"
|
||||
x="9.3059111"
|
||||
y="12.942889" /><g
|
||||
id="g6"
|
||||
transform="matrix(1.6970556,0,0,1.1457035,-62.716054,-14.100197)"
|
||||
style="stroke-width:1.07574;stroke-dasharray:none;stroke:#ffffff;stroke-opacity:1"><path
|
||||
style="fill:none;stroke:#ffffff;stroke-width:1.07574;stroke-linecap:round;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 49.030808,37.632967 -2.348149,8.763414 m 6.348149,-8.763414 2.677863,8.763414"
|
||||
id="path6" /></g><path
|
||||
style="fill:none;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path7"
|
||||
d="m 26.714672,10.820005 a 1.6026552,1.2857661 0 0 1 -0.801328,1.113507 1.6026552,1.2857661 0 0 1 -1.602655,0 1.6026552,1.2857661 0 0 1 -0.801327,-1.113507 h 1.602655 z" /><path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path8"
|
||||
d="m 19.920145,12.446616 a 4.2456937,4.2306275 0 0 1 4.245693,-4.2306274 4.2456937,4.2306275 0 0 1 4.245694,4.2306274 h -4.245694 z" /><g
|
||||
id="g1"
|
||||
transform="matrix(0,0.13298493,-0.12521031,0,101.95019,26.354144)"
|
||||
style="stroke-width:7.74957"><path
|
||||
id="path8642"
|
||||
class="cls-1"
|
||||
d="M -30,76.61 H 92.8 l 35,-34.76 H 44.2 Z"
|
||||
style="fill:#d9e663;stroke-width:7.74957" /><path
|
||||
id="path8668"
|
||||
class="cls-1"
|
||||
d="M -29.87,-1.31 H 53.8 l 74,-34.75 H 4.99 Z"
|
||||
style="fill:#d9e663;stroke-width:7.74957" /><path
|
||||
id="path8734"
|
||||
class="cls-2"
|
||||
d="m 127.8,41.85 v 112.72 l -35,35 v -113 z"
|
||||
style="fill:#edfe60;stroke-width:7.74957" /><path
|
||||
id="path8702"
|
||||
class="cls-3"
|
||||
d="m 53.94,-1.08 73.94,-34.76 h 0.17"
|
||||
style="fill:#371900;stroke-width:7.74957" /><path
|
||||
id="path8768"
|
||||
class="cls-1"
|
||||
d="M 5,189.56 H 92.8 V 154.81 H 5 Z"
|
||||
style="fill:#d9e663;stroke-width:7.74957" /><path
|
||||
id="path8834"
|
||||
class="cls-2"
|
||||
d="m -30,84.38 v 70.19 l 35,35 v -71.7 z"
|
||||
style="fill:#edfe60;stroke-width:7.74957" /><path
|
||||
id="path8880"
|
||||
class="cls-2"
|
||||
d="M 127.8,-36.08 -30,38.06 v 38.58 l 157.82,-74 z"
|
||||
style="fill:#edfe60;stroke-width:7.74957" /><path
|
||||
id="Pfad_210"
|
||||
data-name="Pfad 210"
|
||||
class="cls-1"
|
||||
d="m -16.55,-66 a 13.07,13.07 0 0 0 -13.07,13.06 v 0 a 13.08,13.08 0 0 0 13.06,13.07 v 0 a 13.06,13.06 0 0 0 13.07,-13.05 v 0 a 13.06,13.06 0 0 0 -13.05,-13.07 v 0 m 0,1.7 a 11.37,11.37 0 1 1 -11.52,11.37 11.54,11.54 0 0 1 11.52,-11.37 m 7.22,6 -6.18,3.67 a 4.11,4.11 0 0 0 -4.05,-3.29 4.37,4.37 0 0 0 -4.26,4.45 v 4.66 h 14.48 v -1.62 h -6 v -2.39 l 6,-3.57 z m -10.21,2 a 2.83,2.83 0 0 1 2.75,2.88 v 3 h -5.54 v -2.82 a 2.84,2.84 0 0 1 2.65,-3 h 0.13"
|
||||
style="fill:#d9e663;stroke-width:7.74957" /></g></svg>
|
After Width: | Height: | Size: 27 KiB |
34
public/index.html
Normal file
34
public/index.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Example</title>
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1,maximum-scale=1, user-scalable=no">
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="ar">
|
||||
<div id="render">
|
||||
<div class="ui">
|
||||
<a href="#" data-action="fullscreen">⛶</a>
|
||||
<a href="#" data-action="prev">🠈</a>
|
||||
<select data-id="pages"></select>
|
||||
<a href="#" data-action="next">🠊</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="presentationmaker.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
const config = {
|
||||
targetSelector: '#render',
|
||||
sourceURI: 'example.xml',
|
||||
transitionType: 'transform',
|
||||
};
|
||||
const pm = new PresentationMaker(config);
|
||||
await pm.generate();
|
||||
pm.present();
|
||||
// custom script logic
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
BIN
public/roboto.woff2
Normal file
BIN
public/roboto.woff2
Normal file
Binary file not shown.
106
public/style.css
Normal file
106
public/style.css
Normal file
|
@ -0,0 +1,106 @@
|
|||
@font-face {
|
||||
font-family:'Roboto';
|
||||
font-style:bold;
|
||||
font-weight:600;
|
||||
src:url(roboto.woff2) format('woff2');
|
||||
font-display:swap
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
body {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: #000000;
|
||||
font-size: min(1vw, 1.778vh);
|
||||
overflow:clip;
|
||||
font-family: Roboto, sans-serif;
|
||||
}
|
||||
|
||||
#ar {
|
||||
width: 100em;
|
||||
height: 56.25em;
|
||||
}
|
||||
|
||||
#render {
|
||||
font-size: 1em;
|
||||
a {
|
||||
color: #BBBBff;
|
||||
img {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
.ui {
|
||||
position: fixed;
|
||||
z-index: 999999;
|
||||
color: #ffffff;
|
||||
top: 20px;
|
||||
left: 20px;
|
||||
text-shadow: #000000 2px 0 0;
|
||||
opacity: 0;
|
||||
transition: opacity 1s ease-in-out;
|
||||
font-size:2em;
|
||||
&.visible {
|
||||
opacity: 0.75;
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
font-size: 1.0em;
|
||||
}
|
||||
a.disabled {
|
||||
color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
select {
|
||||
margin: 0 5px;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#fullscreen {
|
||||
font-weight: bold;
|
||||
}
|
||||
#fs {
|
||||
margin-left:10px;
|
||||
}
|
||||
|
||||
.page {
|
||||
position: absolute;
|
||||
transform-origin: top left 0px;
|
||||
transition: opacity .5s ease-in-out;
|
||||
}
|
||||
.page.inactive {
|
||||
opacity: 0.5;
|
||||
transition: opacity .5s ease-in-out;
|
||||
}
|
||||
|
||||
[data-action] {
|
||||
height: 2em;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#viewport {
|
||||
transition: all 1s ease-in-out;
|
||||
transform-style: preserve-3d;
|
||||
transform-origin: top left 0px;
|
||||
}
|
||||
#render {
|
||||
overflow: clip;
|
||||
height:100vh;
|
||||
perspective: 1000px;
|
||||
}
|
||||
|
||||
.option {
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
432
src/presentationmaker.ts
Normal file
432
src/presentationmaker.ts
Normal file
|
@ -0,0 +1,432 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
**/
|
||||
|
||||
import { RenderTree } from './rendertree/rendertree';
|
||||
import { RTPage, RTTransformation } from './rendertree/rtpage';
|
||||
|
||||
/**
|
||||
* configuration options for PresentationMaker
|
||||
*/
|
||||
export interface initialConfig {
|
||||
/** selector for source tree inside a <script type="presentationmaker">...</script> */
|
||||
sourceSelector?: string,
|
||||
/** alternative URL instead of script tag */
|
||||
sourceURI?: string,
|
||||
/** position to attach generated tree to */
|
||||
targetSelector: string,
|
||||
/** optional transition type, defaults to flip */
|
||||
transitionType?: string
|
||||
/** option ui selector string */
|
||||
uiSelector?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* main class
|
||||
*/
|
||||
export class PresentationMaker {
|
||||
/** generated render tree */
|
||||
private tree: RenderTree;
|
||||
/** definitions for variable replacements */
|
||||
private definitions: Array<Map<string, string>>;
|
||||
/** custom modules defined by the import document */
|
||||
private modules: Map<string, RenderTree>;
|
||||
/** current page index */
|
||||
private currentPage: number;
|
||||
/** number of slide */
|
||||
private numPages: number;
|
||||
/** our viewport (window to the presentation) */
|
||||
private viewportElement: HTMLDivElement;
|
||||
/** transition type [flip / transition] */
|
||||
private transition: string;
|
||||
/** time for autohiding of UI */
|
||||
private timer: number;
|
||||
/** ui root node */
|
||||
private ui: HTMLDivElement;
|
||||
/** page selector */
|
||||
private select: HTMLSelectElement;
|
||||
/** X start position to detect slide left/right */
|
||||
private touchStartX: number;
|
||||
/** initial config from caller */
|
||||
private config: initialConfig;
|
||||
|
||||
/**
|
||||
* change slide to given number
|
||||
* @param slideNum slide number 0-based
|
||||
*/
|
||||
private changeSlide(slideNum: number) {
|
||||
if (slideNum < 0 && slideNum >= this.numPages) {
|
||||
return;
|
||||
}
|
||||
const newPage = this.tree.getElement(slideNum);
|
||||
const page = <RTPage>newPage;
|
||||
const pages = this.viewportElement.querySelectorAll('.page');
|
||||
if (this.currentPage >= 0 && this.currentPage < this.numPages) {
|
||||
(<HTMLElement>pages[this.currentPage]).classList.add('inactive');
|
||||
}
|
||||
switch (this.transition) {
|
||||
case 'transform':
|
||||
// this.transform = page.getView();
|
||||
this.currentPage = slideNum;
|
||||
this.moveViewpoint();
|
||||
break;
|
||||
default:
|
||||
if (this.currentPage >= 0 && this.currentPage < this.numPages) {
|
||||
(<HTMLElement>pages[this.currentPage]).style.display = 'none';
|
||||
}
|
||||
this.currentPage = slideNum;
|
||||
const newPage = <HTMLElement>pages[this.currentPage];
|
||||
newPage.style.display = 'block'
|
||||
break;
|
||||
}
|
||||
if (this.currentPage >= 0 && this.currentPage < this.numPages) {
|
||||
(<HTMLElement>pages[this.currentPage]).classList.remove('inactive');
|
||||
}
|
||||
document.location.hash = (this.currentPage + 1).toString();
|
||||
this.select.value = this.currentPage.toString();
|
||||
const prev = document.querySelector('[data-action="prev"]');
|
||||
if (this.currentPage == 0) {
|
||||
prev.classList.add('disabled');
|
||||
} else {
|
||||
prev.classList.remove('disabled');
|
||||
}
|
||||
const next = document.querySelector('[data-action="next"]');
|
||||
if (this.currentPage + 1 >= this.numPages) {
|
||||
next.classList.add('disabled');
|
||||
} else {
|
||||
next.classList.remove('disabled');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
*/
|
||||
constructor(config: initialConfig) {
|
||||
if (config === undefined) {
|
||||
throw('please supply a configuration');
|
||||
}
|
||||
this.definitions = [];
|
||||
this.modules = new Map<string, RenderTree>();
|
||||
this.currentPage = 0;
|
||||
this.numPages = 0;
|
||||
this.transition = config.transitionType || 'flip';
|
||||
this.tree = new RenderTree(this, null);
|
||||
this.ui = document.querySelector(config.uiSelector || '.ui');
|
||||
this.select = this.ui.querySelector('select[data-id=pages]');
|
||||
if (document.location.hash) {
|
||||
this.currentPage = parseInt(document.location.hash.substring(1)) - 1;
|
||||
}
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* create definitions from element tree
|
||||
* @param elem <definition>...</definition> node tree
|
||||
*/
|
||||
private createDefinitions(elem: HTMLElement): void {
|
||||
const definitions: Map<string, string> = new Map<string, string>();
|
||||
elem.childNodes.forEach((def) => {
|
||||
if (def.nodeType == 1) {
|
||||
const definitionElement = <HTMLElement>def;
|
||||
definitions.set(definitionElement.localName, definitionElement.innerHTML);
|
||||
}
|
||||
});
|
||||
this.definitions.push(definitions);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* create a custom module from input
|
||||
* @param elem <module>...</module> node tree
|
||||
*/
|
||||
private createModules(elem: HTMLElement): void {
|
||||
elem.childNodes.forEach((module) => {
|
||||
if (module.nodeType == 1) {
|
||||
const moduleElement = <HTMLElement>module;
|
||||
const tree = new RenderTree(this);
|
||||
tree.createFromElem(moduleElement);
|
||||
this.modules.set(moduleElement.localName, tree);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* create pages from input
|
||||
* @param elem <slides>...</slides> node tree
|
||||
*/
|
||||
private createPages(elem: HTMLElement): void {
|
||||
const pageElement = <HTMLElement>elem;
|
||||
this.tree.createFromElem(pageElement);
|
||||
this.numPages = this.tree.getElementCount();
|
||||
this.definitions[0].set('numpages', this.numPages.toString());
|
||||
this.definitions[0].set('page', '0');
|
||||
for (let i = 0; i < this.numPages; ++i) {
|
||||
const newPage = this.tree.getElement(i);
|
||||
const page = <RTPage>newPage;
|
||||
const option = document.createElement('option');
|
||||
option.value = i.toString();
|
||||
option.innerText = page.getName();
|
||||
this.select.append(option);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* generate HTML tree from input XML
|
||||
*/
|
||||
async generate(): Promise<void> {
|
||||
let root;
|
||||
const parser = new DOMParser();
|
||||
if (this.config.sourceSelector !== undefined) {
|
||||
const source = document.querySelector(this.config.sourceSelector);
|
||||
root = <HTMLElement>parser.parseFromString(source.outerHTML, 'application/xml').querySelector('script');
|
||||
} else {
|
||||
const response = await fetch(this.config.sourceURI);
|
||||
const data = await response.blob();
|
||||
root = <HTMLElement>parser.parseFromString(await data.text(), 'application/xml').querySelector('presentation');
|
||||
}
|
||||
|
||||
// iterate over the elements
|
||||
root.childNodes.forEach((node) => {
|
||||
const elem = <HTMLElement>node;
|
||||
switch (elem.localName) {
|
||||
case 'definitions':
|
||||
this.createDefinitions(elem);
|
||||
break;
|
||||
case 'modules':
|
||||
this.createModules(elem);
|
||||
break;
|
||||
case 'pages':
|
||||
this.createPages(elem);
|
||||
break;
|
||||
}
|
||||
node = node.nextSibling;
|
||||
});
|
||||
// render pages
|
||||
this.viewportElement = <HTMLDivElement>document.createElement('div');
|
||||
this.viewportElement.id = 'viewport';
|
||||
this.tree.render(this.viewportElement);
|
||||
const renderTarget = <HTMLDivElement>document.querySelector(this.config.targetSelector);
|
||||
renderTarget.append(this.viewportElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a definition (value) for given name
|
||||
* @param name name to look up
|
||||
* @returns value or '' if not found
|
||||
* @internal
|
||||
*/
|
||||
getDefinition(name: string): string {
|
||||
let ret = '';
|
||||
this.definitions.forEach((definitions) => {
|
||||
const i = definitions.get(name);
|
||||
if (i !== undefined) {
|
||||
ret = i;
|
||||
}
|
||||
});
|
||||
if (ret === '') {
|
||||
console.log('failed to get definition for', name);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a new module (copy) with given name
|
||||
* @param name name of module
|
||||
* @return copy of module or null if not found
|
||||
* @internal
|
||||
*/
|
||||
getNewModule(name: string): RenderTree {
|
||||
const i = this.modules.get(name);
|
||||
if (i !== undefined) {
|
||||
return (new RenderTree(this, i));
|
||||
}
|
||||
console.log('unknown render element', name);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle mouse click or tap events
|
||||
* @param ev brower event
|
||||
*/
|
||||
private handleClick = (ev?: MouseEvent) => {
|
||||
const target = <HTMLElement>ev.target;
|
||||
let action = target.getAttribute('data-action');
|
||||
if (action === null) {
|
||||
action = target.getAttribute("data-id");
|
||||
}
|
||||
let slideNum;
|
||||
switch (action) {
|
||||
case 'fullscreen':
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen();
|
||||
} else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
break;
|
||||
case 'prev':
|
||||
slideNum = Math.max(this.currentPage - 1, 0);
|
||||
break;
|
||||
case 'next':
|
||||
case null:
|
||||
slideNum = Math.min(this.currentPage + 1, this.numPages - 1);
|
||||
break;
|
||||
}
|
||||
if (slideNum !== undefined) {
|
||||
this.changeSlide(slideNum);
|
||||
}
|
||||
if (target.closest('.ui')) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle a change of the page dropdown
|
||||
*/
|
||||
private handleDropdown = (ev?: Event) => {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.changeSlide(parseInt(this.select.value));
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle key presses
|
||||
* @param ev pressed key
|
||||
*/
|
||||
private handleKey = (ev?: KeyboardEvent) => {
|
||||
switch (ev.key) {
|
||||
case 'ArrowLeft':
|
||||
this.changeSlide(Math.max(this.currentPage - 1, 0));
|
||||
break;
|
||||
case 'ArrowRight':
|
||||
this.changeSlide(Math.min(this.currentPage + 1, this.numPages - 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle mouse move and show ui
|
||||
*/
|
||||
private handleMouseMove = () => {
|
||||
if (this.timer) {
|
||||
window.clearTimeout(this.timer);
|
||||
}
|
||||
this.ui.classList.add('visible');
|
||||
document.body.style.cursor = 'auto';
|
||||
this.timer = window.setTimeout(this.hideUI, 2000);
|
||||
}
|
||||
|
||||
/**
|
||||
* handle end of touch event
|
||||
* creates slide left or right if swipe was long enough
|
||||
* @param ev browser touch event
|
||||
*/
|
||||
private handleTouchEnd = (ev: TouchEvent) => {
|
||||
const touchEndX = ev.changedTouches[0].screenX;
|
||||
if (Math.abs(this.touchStartX - touchEndX) > 100) {
|
||||
let slideNum;
|
||||
if (this.touchStartX < touchEndX) {
|
||||
slideNum = Math.max(this.currentPage - 1, 0);
|
||||
} else {
|
||||
slideNum = Math.min(this.currentPage + 1, this.numPages - 1);
|
||||
}
|
||||
this.changeSlide(slideNum);
|
||||
} else {
|
||||
this.handleMouseMove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle start of touch
|
||||
* saves position to detect swipes
|
||||
*/
|
||||
private handleTouchStart = (ev: TouchEvent) => {
|
||||
this.touchStartX = ev.changedTouches[0].screenX;
|
||||
}
|
||||
|
||||
/**
|
||||
* hide ui
|
||||
* called by timer function
|
||||
*/
|
||||
private hideUI = () => {
|
||||
this.ui.classList.remove('visible');
|
||||
document.body.style.cursor = 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* move viewpoint to area defined by current page
|
||||
*/
|
||||
private moveViewpoint = () => {
|
||||
const view = (<RTPage>this.tree.getElement(this.currentPage)).getView();
|
||||
let transform = '';
|
||||
if (view.viewRotation.x) {
|
||||
transform += ' rotateX(' + (-view.viewRotation.x) + 'deg) ' + transform;
|
||||
}
|
||||
if (view.viewRotation.y) {
|
||||
transform += ' rotateY(' + (-view.viewRotation.y) + 'deg) ' + transform;
|
||||
}
|
||||
if (view.viewRotation.z) {
|
||||
transform += ' rotateZ(' + (-view.viewRotation.z) + 'deg) ' + transform;
|
||||
}
|
||||
transform += ' translate3d(' + (-view.position.x) + 'px,' + (-view.position.y) + 'px, ' + (-view.position.z) + 'px)';
|
||||
|
||||
// calculate zoom
|
||||
const wc = parseInt(this.getDefinition('width')) / view.size.w;
|
||||
const hc = parseInt(this.getDefinition('height')) / view.size.h;
|
||||
const scale = Math.min(wc, hc);
|
||||
const zoom = this.viewportElement.parentElement.clientHeight / parseFloat(this.getDefinition('height')) * scale;
|
||||
if (zoom != 1) {
|
||||
transform = 'scale(' + zoom + ')' + transform;
|
||||
}
|
||||
this.viewportElement.style.transform = transform;
|
||||
}
|
||||
|
||||
/**
|
||||
* pop defintion list to remove last definition from stack
|
||||
* @internal
|
||||
*/
|
||||
pop() {
|
||||
this.definitions.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* add handles for presentation and start it
|
||||
*/
|
||||
present() {
|
||||
window.addEventListener('resize', this.moveViewpoint);
|
||||
const list = document.querySelectorAll('body, [data-action]');
|
||||
list.forEach((e) => {
|
||||
e.addEventListener('click', this.handleClick);
|
||||
});
|
||||
window.addEventListener('keydown', this.handleKey);
|
||||
this.select.addEventListener('change', this.handleDropdown);
|
||||
window.addEventListener('mousemove', this.handleMouseMove);
|
||||
document.body.addEventListener('touchstart', this.handleTouchStart);
|
||||
document.body.addEventListener('touchend', this.handleTouchEnd);
|
||||
this.moveViewpoint();
|
||||
this.changeSlide(this.currentPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* push a new empty definition list to stack
|
||||
* @internal
|
||||
*/
|
||||
push(): void {
|
||||
this.definitions.push(new Map());
|
||||
}
|
||||
|
||||
/**
|
||||
* set a value to current definition list on stack
|
||||
* @internal
|
||||
*/
|
||||
set(key: string, value: string): void {
|
||||
const definition = this.definitions.at(-1);
|
||||
definition.set(key, value);
|
||||
}
|
||||
}
|
178
src/rendertree/rendertree.ts
Normal file
178
src/rendertree/rendertree.ts
Normal file
|
@ -0,0 +1,178 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
**/
|
||||
|
||||
import { PresentationMaker } from '../presentationmaker';
|
||||
import { RTModule } from './rtmodule';
|
||||
import { RTNode } from './rtnode';
|
||||
import { RTImg } from './rtimg';
|
||||
import { RTCalc } from './rtcalc';
|
||||
import { RTText } from './rttext';
|
||||
import { RTOptions } from './rtoptions';
|
||||
import { RTPage } from './rtpage';
|
||||
|
||||
/**
|
||||
* the root of render tree
|
||||
* @internal
|
||||
*/
|
||||
export class RenderTree {
|
||||
/** handle to main instance */
|
||||
private main: PresentationMaker;
|
||||
/** our child elements */
|
||||
private elements: RTNode[];
|
||||
/** definitions from input */
|
||||
private definitions: Map<string, string>;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param pm handle to main instance
|
||||
* @param other optional other tree to copy data from
|
||||
*/
|
||||
constructor(pm: PresentationMaker, other: RenderTree = null) {
|
||||
this.main = pm;
|
||||
this.elements = [];
|
||||
this.definitions = new Map<string, string>();
|
||||
if (other !== null) {
|
||||
other.elements.forEach((e) => {
|
||||
this.elements.push(e.clone());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create elements from given parent
|
||||
* @param baseElem root element to create new render tree nodes
|
||||
*/
|
||||
createFromElem(baseElem: HTMLElement) {
|
||||
const nodes = baseElem.childNodes;
|
||||
nodes.forEach((node) => {
|
||||
if (node.nodeType === 1) {
|
||||
const newNode = this.createNodeFromElem(<HTMLElement>node);
|
||||
if (newNode !== null) {
|
||||
this.elements.push(newNode);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create a new node from given element
|
||||
*
|
||||
* currently supports 'calc', 'img', 'options', 'page', 'text'
|
||||
* @param elem to create from
|
||||
*/
|
||||
createNodeFromElem(elem: HTMLElement): RTNode {
|
||||
const name = elem.localName;
|
||||
// final types
|
||||
switch (name) {
|
||||
case 'calc':
|
||||
return RTCalc.fromElem(this, elem);
|
||||
case 'img':
|
||||
return RTImg.fromElem(this, elem);
|
||||
case 'options':
|
||||
return RTOptions.fromElem(this.main, this, elem);
|
||||
case 'page':
|
||||
return RTPage.fromElem(this.main, this, elem);
|
||||
case 'text':
|
||||
return RTText.fromElem(this, elem);
|
||||
}
|
||||
// still here, probably a module
|
||||
const tree = this.main.getNewModule(name);
|
||||
if (tree === null) {
|
||||
console.log('unknown module', name);
|
||||
return null;
|
||||
}
|
||||
tree.definitions.clear();
|
||||
// add attributes to node
|
||||
for (let i = 0; i < elem.attributes.length; ++i) {
|
||||
const attr = elem.attributes[i];
|
||||
tree.definitions.set(attr.localName, attr.textContent);
|
||||
}
|
||||
elem.childNodes.forEach((child) => {
|
||||
if (child.nodeType === 1) {
|
||||
const childElem = <HTMLElement>child;
|
||||
tree.definitions.set(childElem.localName, childElem.innerHTML);
|
||||
}
|
||||
});
|
||||
return new RTModule(this, tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* get current definition for given name
|
||||
* @param name name to look up
|
||||
* @returns value or ''
|
||||
*/
|
||||
getDefinition(name: string): string {
|
||||
return this.main.getDefinition(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* get node with given index
|
||||
* @param num index
|
||||
* @return node or null if invalid index
|
||||
*/
|
||||
getElement(num: number): RTNode {
|
||||
if (num >= 0 && num <= this.elements.length) {
|
||||
return this.elements[num];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* return the number of elements in the root tree
|
||||
*/
|
||||
getElementCount(): number {
|
||||
return this.elements.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* get main instance
|
||||
* @returns main instance
|
||||
*/
|
||||
getMain(): PresentationMaker {
|
||||
return this.main;
|
||||
}
|
||||
|
||||
/**
|
||||
* pop defintion list to remove last definition from stack
|
||||
*/
|
||||
pop() {
|
||||
this.main.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* push a new empty definition list to stack
|
||||
*/
|
||||
push(): void {
|
||||
this.main.push();
|
||||
}
|
||||
|
||||
/**
|
||||
* render tree to given target
|
||||
* @param target target to render into
|
||||
*/
|
||||
render(target: HTMLElement) {
|
||||
this.main.push();
|
||||
// save current definitions on the stack
|
||||
this.definitions.forEach((v, k) => {
|
||||
this.main.set(k, v);
|
||||
});
|
||||
this.elements.forEach((element) => {
|
||||
element.render(target);
|
||||
});
|
||||
this.main.pop();
|
||||
}
|
||||
|
||||
/**
|
||||
* set definition
|
||||
* @param key key name
|
||||
* @param value value data
|
||||
*/
|
||||
set(key: string, value: string) {
|
||||
this.main.set(key, value);
|
||||
}
|
||||
|
||||
};
|
67
src/rendertree/rtcalc.ts
Normal file
67
src/rendertree/rtcalc.ts
Normal file
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
import Formula from 'fparser';
|
||||
|
||||
/**
|
||||
* calculate new defintions based on formula
|
||||
*/
|
||||
export class RTCalc extends RTNode {
|
||||
/** name of the definition */
|
||||
private target: string;
|
||||
/** expression to calculate */
|
||||
private expression: string;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTCalc {
|
||||
return new RTCalc(this.root, this.target, this.expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root our parent RenderTree
|
||||
* @param target name of the new definition
|
||||
* @param expression expression to calculate
|
||||
*/
|
||||
constructor(root: RenderTree, target: string, expression: string) {
|
||||
super(root);
|
||||
this.target = target;
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
/**
|
||||
* create RTCalc from given node into given RenderTree
|
||||
* @param root render tree to insert to
|
||||
* @param node input node
|
||||
* @returns new RTCalc node
|
||||
*/
|
||||
static fromElem(root: RenderTree, node: HTMLElement): RTCalc {
|
||||
return new RTCalc(
|
||||
root,
|
||||
node.getAttribute('name') || '',
|
||||
node.innerHTML
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* render our element into target
|
||||
* @param target target to render into
|
||||
*/
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
render(target: HTMLElement): void {
|
||||
const exp = this.resolveString(this.expression);
|
||||
const fObj = new Formula(exp);
|
||||
const result = fObj.evaluate({});
|
||||
this.root.set(this.target, result.toString());
|
||||
}
|
||||
}
|
99
src/rendertree/rtimg.ts
Normal file
99
src/rendertree/rtimg.ts
Normal file
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
|
||||
/**
|
||||
* renders an image from <img> tag
|
||||
*/
|
||||
export class RTImg extends RTNode {
|
||||
/** src URI */
|
||||
private src: string;
|
||||
/** x position */
|
||||
private x: string;
|
||||
/** y position */
|
||||
private y: string;
|
||||
/** width */
|
||||
private width: string;
|
||||
/** height */
|
||||
private height: string;
|
||||
/** mask-image css string */
|
||||
private maskImage: string;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTImg {
|
||||
return new RTImg(
|
||||
this.root,
|
||||
this.src,
|
||||
this.x,
|
||||
this.y,
|
||||
this.width,
|
||||
this.height,
|
||||
this.maskImage
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root our parent RenderTree
|
||||
* @param src source URI
|
||||
* @param x x position
|
||||
* @param y y position
|
||||
* @param width image width
|
||||
* @param height image height
|
||||
* @param maskImage optional css for mask-image
|
||||
*/
|
||||
constructor(root: RenderTree, src: string, x: string, y: string, width: string, height: string, maskImage: string) {
|
||||
super(root);
|
||||
this.src = src;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.maskImage = maskImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* create RTImg from given node into given RenderTree
|
||||
* @param root render tree to insert to
|
||||
* @param node input node
|
||||
* @returns new RTImg node
|
||||
*/
|
||||
static fromElem(root: RenderTree, node: HTMLElement): RTImg {
|
||||
return new RTImg(
|
||||
root,
|
||||
this.getField(node, 'src'),
|
||||
this.getField(node, 'x'),
|
||||
this.getField(node, 'y'),
|
||||
this.getField(node, 'width'),
|
||||
this.getField(node, 'height'),
|
||||
this.getField(node, 'mask-image')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* render image to HTML target
|
||||
* @param target target to render to
|
||||
*/
|
||||
render(target: HTMLElement): void {
|
||||
const img = document.createElement('img');
|
||||
img.style.position = 'absolute';
|
||||
img.style.top = this.calc(this.resolveString(this.y)) + 'px';
|
||||
img.style.left = this.calc(this.resolveString(this.x)) + 'px';
|
||||
img.setAttribute('width', this.calc(this.resolveString(this.width)).toString());
|
||||
img.setAttribute('height', this.calc(this.resolveString(this.height)).toString());
|
||||
img.setAttribute('src', this.resolveString(this.src));
|
||||
if (this.maskImage) {
|
||||
img.style.maskImage = this.maskImage;
|
||||
}
|
||||
target.append(img);
|
||||
}
|
||||
}
|
43
src/rendertree/rtmodule.ts
Normal file
43
src/rendertree/rtmodule.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
**/
|
||||
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
|
||||
/**
|
||||
* custom user declared module
|
||||
*/
|
||||
export class RTModule extends RTNode {
|
||||
/** render tree for our children */
|
||||
private tree: RenderTree;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTModule {
|
||||
const tree = new RenderTree(this.root.getMain(), this.tree);
|
||||
return new RTModule(this.root, tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root parent RenderTree
|
||||
* @param tree child renderTree
|
||||
*/
|
||||
constructor(root: RenderTree, tree: RenderTree) {
|
||||
super(root);
|
||||
this.tree = tree;
|
||||
}
|
||||
|
||||
/**
|
||||
* render module content to given target
|
||||
* @param target target to render to
|
||||
*/
|
||||
render(target: HTMLElement): void {
|
||||
this.tree.render(target);
|
||||
}
|
||||
}
|
105
src/rendertree/rtnode.ts
Normal file
105
src/rendertree/rtnode.ts
Normal file
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { RenderTree } from './rendertree';
|
||||
import Formula from 'fparser';
|
||||
|
||||
/**
|
||||
* base class for all RenderTree nodes
|
||||
*/
|
||||
export abstract class RTNode {
|
||||
/** root render tree */
|
||||
protected root: RenderTree;
|
||||
|
||||
/**
|
||||
* calculate given expression
|
||||
* @param exp expression string
|
||||
* @returns result as number or 0 in case of error
|
||||
*/
|
||||
calc(exp: string): number {
|
||||
if (exp === '') {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
const fObj = new Formula(exp);
|
||||
return <number>fObj.evaluate({});
|
||||
} catch(e) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract function to clone the node
|
||||
* must be implemented by every sub class
|
||||
*/
|
||||
abstract clone(): RTNode;
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root parent RenderTree
|
||||
*/
|
||||
constructor(root: RenderTree) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper function to get value from attribute or from named child node
|
||||
* @param node current HTML element
|
||||
* @param name name of element to fetch
|
||||
* @return value or '' in case of error
|
||||
*/
|
||||
static getField(node: HTMLElement, name: string): string {
|
||||
// try attribute
|
||||
let field = node.getAttribute(name);
|
||||
// try child nodes
|
||||
node.childNodes.forEach((child) => {
|
||||
if (child.nodeType === 1) {
|
||||
const childElem = <HTMLElement>child;
|
||||
if (childElem.localName === name) {
|
||||
field = childElem.innerHTML;
|
||||
}
|
||||
}
|
||||
});
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* abstract function to render the node
|
||||
* must be implemented by every sub class
|
||||
* @param target target to render into
|
||||
*/
|
||||
abstract render(target: HTMLElement): void;
|
||||
|
||||
/**
|
||||
* resolve a string using variable replacements
|
||||
* @param input input string
|
||||
* @returns input strings with replaced variables
|
||||
*/
|
||||
resolveString(input: string): string {
|
||||
if (!input || input.indexOf('$') < 0) {
|
||||
return input;
|
||||
}
|
||||
let str = input;
|
||||
let dollar;
|
||||
let lastDollar = 0;
|
||||
while ((dollar = str.indexOf('${', lastDollar)) >= 0) {
|
||||
if (str.at(dollar - 1) == '\\') {
|
||||
str = str.substring(0, dollar - 1) + str.substring(dollar);
|
||||
lastDollar = dollar + 1;
|
||||
continue;
|
||||
}
|
||||
const end = str.indexOf('}', dollar);
|
||||
if (end < 0) break;
|
||||
const search = str.substring(dollar + 2, end);
|
||||
const replace = this.root.getDefinition(search);
|
||||
str = str.replace(str.substring(dollar, end + 1), replace);
|
||||
}
|
||||
return (str);
|
||||
}
|
||||
|
||||
|
||||
}
|
125
src/rendertree/rtoptions.ts
Normal file
125
src/rendertree/rtoptions.ts
Normal file
|
@ -0,0 +1,125 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { PresentationMaker } from '../presentationmaker';
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
|
||||
/**
|
||||
* transform subtree by given options
|
||||
*/
|
||||
export class RTOptions extends RTNode {
|
||||
/** blend mode */
|
||||
private blendmode: string;
|
||||
/** flip axis */
|
||||
private flip: string;
|
||||
/** opactity */
|
||||
private opacity: string;
|
||||
/** rotate */
|
||||
private rotate: string;
|
||||
/** subtee to transform */
|
||||
private subtree: RenderTree;
|
||||
/** y position when flipping */
|
||||
private y: string;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTOptions {
|
||||
return new RTOptions(
|
||||
this.root,
|
||||
this.subtree,
|
||||
this.opacity,
|
||||
this.blendmode,
|
||||
this.flip,
|
||||
this.rotate,
|
||||
this.y
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root parent RenderTree
|
||||
* @param subtree child sub tree
|
||||
* @param opacity opacity value
|
||||
* @param blendmode blend mode
|
||||
* @param flip flip axis
|
||||
* @param rotate rotation in degree X, Y, Z
|
||||
* @param y y position when flipping
|
||||
*/
|
||||
constructor(root: RenderTree, subtree: RenderTree, opacity: string, blendmode: string, flip: string, rotate: string, y: string) {
|
||||
super(root);
|
||||
this.subtree = subtree;
|
||||
this.opacity = opacity;
|
||||
this.blendmode = blendmode;
|
||||
this.flip = flip;
|
||||
this.rotate = rotate;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
/**
|
||||
* create RTOptions from given node into given RenderTree
|
||||
* @param root render tree to insert to
|
||||
* @param node input node
|
||||
* @returns new RTOptions node
|
||||
*/
|
||||
static fromElem(main: PresentationMaker, root: RenderTree, node: HTMLElement): RTOptions {
|
||||
const subtree = new RenderTree(main);
|
||||
subtree.createFromElem(node);
|
||||
return new RTOptions(
|
||||
root,
|
||||
subtree,
|
||||
this.getField(node, 'opacity') || '',
|
||||
this.getField(node, 'blend') || '',
|
||||
this.getField(node, 'flip') || '',
|
||||
this.getField(node, 'rotate') || '',
|
||||
this.getField(node, 'y') || ''
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* render our element into target
|
||||
* @param target target to render into
|
||||
*/
|
||||
render(target: HTMLElement): void {
|
||||
const div = document.createElement('div');
|
||||
div.classList.add('option');
|
||||
if (this.opacity !== '') {
|
||||
div.style.opacity = this.opacity;
|
||||
}
|
||||
if (this.blendmode !== '') {
|
||||
div.style.mixBlendMode = this.blendmode;
|
||||
}
|
||||
if (this.flip !== '') {
|
||||
if (this.flip == 'v') {
|
||||
div.style.transform = 'scaleY(-1)';
|
||||
}
|
||||
}
|
||||
if (this.y) {
|
||||
div.style.position = 'absolute';
|
||||
div.style.bottom = '0px';
|
||||
}
|
||||
if (this.rotate !== '') {
|
||||
const r = this.rotate.split(',');
|
||||
let transform = '';
|
||||
if (r[0]) {
|
||||
transform += 'rotateX(' + (this.calc(this.resolveString(r[0]))) + 'deg)';
|
||||
}
|
||||
if (r[1]) {
|
||||
transform += 'rotateY(' + (this.calc(this.resolveString(r[1]))) + 'deg)';
|
||||
}
|
||||
if (r[2]) {
|
||||
transform += 'rotateZ(' + (this.calc(this.resolveString(r[2]))) + 'deg)';
|
||||
}
|
||||
div.style.transform = transform;
|
||||
div.style.transformOrigin = 'top left';
|
||||
}
|
||||
this.subtree.render(div);
|
||||
target.append(div);
|
||||
}
|
||||
}
|
257
src/rendertree/rtpage.ts
Normal file
257
src/rendertree/rtpage.ts
Normal file
|
@ -0,0 +1,257 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
import { PresentationMaker } from '../presentationmaker';
|
||||
|
||||
/**
|
||||
* view transformations as strings
|
||||
*/
|
||||
export interface TransformationS {
|
||||
/** position on HTML space */
|
||||
position: {x: string, y: string, z: string};
|
||||
/** rotation in HTML space */
|
||||
rotation: {x: string, y: string, z: string};
|
||||
/** page size in pixels */
|
||||
size: {w: string, h: string};
|
||||
/** view position in HTML space */
|
||||
viewpos: {x: string, y: string, z: string};
|
||||
/** view size in pixels */
|
||||
viewSize: {w: string, h: string};
|
||||
/** view rotation in degree */
|
||||
viewRotation: {x: string, y: string, z: string};
|
||||
}
|
||||
|
||||
/**
|
||||
* view transformation as numbers
|
||||
*/
|
||||
export interface RTTransformation {
|
||||
/** view position */
|
||||
position: {x: number, y: number, z: number};
|
||||
/** view size */
|
||||
size: {w: number, h: number};
|
||||
/** view rotation in degrees */
|
||||
viewRotation: {x: number, y: number, z: number};
|
||||
}
|
||||
|
||||
/**
|
||||
* page node
|
||||
*/
|
||||
export class RTPage extends RTNode {
|
||||
/** page id */
|
||||
private id: string;
|
||||
/** page name */
|
||||
private name: string;
|
||||
/** tree to render on page */
|
||||
private subtree: RenderTree;
|
||||
/** tranform informations */
|
||||
private transformation: TransformationS;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTPage {
|
||||
return new RTPage(
|
||||
this.root,
|
||||
this.subtree,
|
||||
this.id,
|
||||
this.transformation.size.w,
|
||||
this.transformation.size.h,
|
||||
this.transformation.position.x,
|
||||
this.transformation.position.y,
|
||||
this.transformation.position.z,
|
||||
this.transformation.rotation.y,
|
||||
this.transformation.rotation.y,
|
||||
this.transformation.rotation.z,
|
||||
this.transformation.viewpos.x,
|
||||
this.transformation.viewpos.y,
|
||||
this.transformation.viewpos.z,
|
||||
this.transformation.viewSize.w,
|
||||
this.transformation.viewSize.h,
|
||||
this.transformation.viewRotation.x,
|
||||
this.transformation.viewRotation.y,
|
||||
this.transformation.viewRotation.z,
|
||||
this.name
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root parent RenderTree
|
||||
* @param subtree RenderTree for page content
|
||||
* @param id page id
|
||||
* @param width page width
|
||||
* @param height page height
|
||||
* @param x x position
|
||||
* @param y y position
|
||||
* @param z z position
|
||||
* @param rx rotation on X-axis
|
||||
* @param ry rotation on Y-axis
|
||||
* @param rz rotation on Z-axis
|
||||
* @param vx view position on X-axis
|
||||
* @param vy view position on Y-axis
|
||||
* @param vz view position on Z-axis
|
||||
* @param vrx view rotation on X-axis
|
||||
* @param vry view rotation on Y-axis
|
||||
* @param vrz view rotation on Z-axis
|
||||
*/
|
||||
constructor(root: RenderTree, subtree: RenderTree, id: string, width: string, height: string, x: string, y: string, z: string, rx: string, ry: string, rz:string, vx: string, vy: string, vz: string, vw: string, vh: string, vrx: string, vry: string, vrz: string, name: string) {
|
||||
super(root);
|
||||
this.subtree = subtree;
|
||||
this.id = id;
|
||||
this.transformation = {
|
||||
size: { w: width, h: height},
|
||||
position: {x: x, y: y, z: z},
|
||||
rotation: {x: rx, y: ry, z: rz},
|
||||
viewpos: {x: vx, y: vy, z: vz},
|
||||
viewSize: {w: vw, h: vh},
|
||||
viewRotation: {x: vrx, y: vry, z: vrz}
|
||||
};
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* create RTPage from given node into given RenderTree
|
||||
* @param root render tree to insert to
|
||||
* @param node input node
|
||||
* @returns new RTOptions node
|
||||
*/
|
||||
static fromElem(main:PresentationMaker, root: RenderTree, node: HTMLElement): RTPage {
|
||||
const subtree = new RenderTree(main);
|
||||
subtree.createFromElem(node);
|
||||
return new RTPage(
|
||||
root,
|
||||
subtree,
|
||||
node.getAttribute('id') || '',
|
||||
node.getAttribute('width') || '${width}',
|
||||
node.getAttribute('height') || '${height}',
|
||||
node.getAttribute('x') || '0',
|
||||
node.getAttribute('y') || '0',
|
||||
node.getAttribute('z') || '0',
|
||||
node.getAttribute('rx') || '0',
|
||||
node.getAttribute('ry') || '0',
|
||||
node.getAttribute('rz') || '0',
|
||||
node.getAttribute('vx') || '',
|
||||
node.getAttribute('vy') || '',
|
||||
node.getAttribute('vz') || '',
|
||||
node.getAttribute('vwidth') || '',
|
||||
node.getAttribute('vheight') || '',
|
||||
node.getAttribute('vrx') || '',
|
||||
node.getAttribute('vry') || '',
|
||||
node.getAttribute('vrz') || '',
|
||||
node.getAttribute('name') || '${page}',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get page name
|
||||
* @returns page name
|
||||
*/
|
||||
getName(): string {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* get view transformation
|
||||
* @return RTTransformation
|
||||
*/
|
||||
getView(): RTTransformation {
|
||||
let position;
|
||||
if (this.transformation.viewpos.x !== '' || this.transformation.viewpos.y !== '' || this.transformation.viewpos.z !=='') {
|
||||
position = {
|
||||
x: this.calc(this.resolveString(this.transformation.viewpos.x)),
|
||||
y: this.calc(this.resolveString(this.transformation.viewpos.y)),
|
||||
z: this.calc(this.resolveString(this.transformation.viewpos.z))
|
||||
};
|
||||
} else {
|
||||
position = {
|
||||
x: this.calc(this.resolveString(this.transformation.position.x)),
|
||||
y: this.calc(this.resolveString(this.transformation.position.y)),
|
||||
z: this.calc(this.resolveString(this.transformation.position.z))
|
||||
}
|
||||
}
|
||||
let size;
|
||||
if (this.transformation.viewSize.w !== '' || this.transformation.viewSize.h !== '') {
|
||||
size = {
|
||||
w: this.calc(this.resolveString(this.transformation.viewSize.w)),
|
||||
h: this.calc(this.resolveString(this.transformation.viewSize.h))
|
||||
};
|
||||
} else {
|
||||
size = {
|
||||
w: this.calc(this.resolveString(this.transformation.size.w)),
|
||||
h: this.calc(this.resolveString(this.transformation.size.h))
|
||||
}
|
||||
}
|
||||
let viewRotation;
|
||||
if (this.transformation.viewRotation.x !== '' || this.transformation.viewRotation.y !== '' || this.transformation.viewRotation.z !== '') {
|
||||
viewRotation = {
|
||||
x: this.calc(this.resolveString(this.transformation.viewRotation.x)),
|
||||
y: this.calc(this.resolveString(this.transformation.viewRotation.y)),
|
||||
z: this.calc(this.resolveString(this.transformation.viewRotation.z))
|
||||
}
|
||||
} else {
|
||||
viewRotation = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
z: 0
|
||||
}
|
||||
}
|
||||
return {
|
||||
position: position,
|
||||
size: size,
|
||||
viewRotation: viewRotation
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* render our element into target
|
||||
* @param target target to render into
|
||||
*/
|
||||
render(target: HTMLElement): void {
|
||||
this.root.set('page', (parseInt(this.root.getDefinition('page')) + 1).toString());
|
||||
const pageDiv = document.createElement('article');
|
||||
pageDiv.classList.add('page');
|
||||
pageDiv.classList.add('inactive');
|
||||
let transform = '';
|
||||
const x = this.calc(this.resolveString(this.transformation.position.x));
|
||||
const y = this.calc(this.resolveString(this.transformation.position.y));
|
||||
const z = this.calc(this.resolveString(this.transformation.position.z));
|
||||
if (x || y || z) {
|
||||
transform += 'translate3d(' + x + 'px, ' + y + 'px, ' + z + 'px)';
|
||||
}
|
||||
const rx = -this.calc(this.resolveString(this.transformation.rotation.x));
|
||||
const ry = -this.calc(this.resolveString(this.transformation.rotation.y));
|
||||
const rz = -this.calc(this.resolveString(this.transformation.rotation.z));
|
||||
if (rx) {
|
||||
transform += 'rotateX(' + rx + 'deg)';
|
||||
}
|
||||
if (ry) {
|
||||
transform += 'rotateY(' + ry + 'deg)';
|
||||
}
|
||||
if (rz) {
|
||||
transform += 'rotateZ(' + rz + 'deg)';
|
||||
}
|
||||
if (transform !== '') {
|
||||
pageDiv.style.transform = transform;
|
||||
}
|
||||
const width = this.calc(this.resolveString(this.transformation.size.w)).toString();
|
||||
const height = this.calc(this.resolveString(this.transformation.size.h)).toString();
|
||||
pageDiv.style.width = width + 'px';
|
||||
pageDiv.style.height = height + 'px';
|
||||
if (this.id) {
|
||||
pageDiv.id = this.id;
|
||||
}
|
||||
target.append(pageDiv);
|
||||
this.root.push()
|
||||
this.subtree.set('width', width);
|
||||
this.subtree.set('height', height);
|
||||
this.subtree.render(pageDiv);
|
||||
this.root.pop()
|
||||
}
|
||||
}
|
179
src/rendertree/rttext.ts
Normal file
179
src/rendertree/rttext.ts
Normal file
|
@ -0,0 +1,179 @@
|
|||
/**
|
||||
* SPDX-FileCopyrightText: 2024 Sascha Nitsch (grumpydeveloper) https://contentnation.net/@grumpydevelop
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
* @author Author: Sascha Nitsch (grumpydeveloper)
|
||||
* @internal
|
||||
**/
|
||||
|
||||
import { RTNode } from './rtnode';
|
||||
import { RenderTree } from './rendertree';
|
||||
|
||||
/**
|
||||
* Text node
|
||||
*/
|
||||
export class RTText extends RTNode {
|
||||
/** left position of text box */
|
||||
private x0: string;
|
||||
/** top position of text box */
|
||||
private y0: string;
|
||||
/** rigth position of text box */
|
||||
private x1: string;
|
||||
/** left bottom of text box */
|
||||
private y1: string;
|
||||
/** width of text box */
|
||||
private width: string;
|
||||
/** height of text box */
|
||||
private height: string;
|
||||
/** compact list of [left, top, right, bottom] */
|
||||
private pos: string;
|
||||
/** horizontal alignment of text in box */
|
||||
private halign: string;
|
||||
/** vertical alignment of text in box */
|
||||
private valign: string;
|
||||
/** font size */
|
||||
private fontSize: string;
|
||||
/** actual text */
|
||||
private text: string;
|
||||
/** text color */
|
||||
private color: string;
|
||||
|
||||
/**
|
||||
* clone function
|
||||
* @return a copy of us
|
||||
*/
|
||||
clone(): RTText {
|
||||
return new RTText(
|
||||
this.root,
|
||||
this.x0,
|
||||
this.y0,
|
||||
this.x1,
|
||||
this.y1,
|
||||
this.width,
|
||||
this.height,
|
||||
this.pos,
|
||||
this.halign,
|
||||
this.valign,
|
||||
this.fontSize,
|
||||
this.text,
|
||||
this.color
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* create Node from HTMLElement
|
||||
* @internal
|
||||
* */
|
||||
static fromElem(root: RenderTree, node: HTMLElement): RTText {
|
||||
return new RTText(
|
||||
root,
|
||||
node.getAttribute('x0'),
|
||||
node.getAttribute('y0'),
|
||||
node.getAttribute('x1'),
|
||||
node.getAttribute('y1'),
|
||||
node.getAttribute('w'),
|
||||
node.getAttribute('h'),
|
||||
node.getAttribute('pos'),
|
||||
node.getAttribute('halign') || 'center',
|
||||
node.getAttribute('valign'),
|
||||
node.getAttribute('size'),
|
||||
node.innerHTML,
|
||||
node.getAttribute('color') || root.getDefinition('defaultfontcolor')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* constructor
|
||||
* @param root parent RenderTree
|
||||
* @param x0 left position of text box
|
||||
* @param y0 top position of text box
|
||||
* @param width width of text box
|
||||
* @param height heightof text box
|
||||
* @param pos short version of [left, top, right, bottom]
|
||||
* @param halign horizontal alignment in text box
|
||||
* @param valign vertical alignment in text box
|
||||
* @param fontSize font size
|
||||
* @param text actural text
|
||||
* @param color text color
|
||||
*/
|
||||
constructor(root: RenderTree, x0: string, y0: string, x1: string, y1: string, width: string, height: string, pos: string, halign: string, valign: string, fontSize: string, text: string, color: string) {
|
||||
super(root);
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pos = pos;
|
||||
this.halign = halign;
|
||||
this.valign = valign;
|
||||
this.fontSize = fontSize;
|
||||
this.text = text;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
/**
|
||||
* render image to HTML target
|
||||
* @param target target to render to
|
||||
*/
|
||||
render(target: HTMLElement): void {
|
||||
let x0: number;
|
||||
let y0: number;
|
||||
let x1: number;
|
||||
let y1: number;
|
||||
if (this.pos) {
|
||||
const posLookup = this.resolveString(this.pos);
|
||||
const tokens = posLookup.split(',');
|
||||
if (tokens.length != 4) {
|
||||
return;
|
||||
}
|
||||
x0 = this.calc(this.resolveString(tokens[0]));
|
||||
y0 = this.calc(this.resolveString(tokens[1]));
|
||||
x1 = this.calc(this.resolveString(tokens[2]));
|
||||
y1 = this.calc(this.resolveString(tokens[3]));
|
||||
} else {
|
||||
x0 = this.calc(this.resolveString(this.x0));
|
||||
y0 = this.calc(this.resolveString(this.y0));
|
||||
if (this.x1) {
|
||||
x1 = this.calc(this.resolveString(this.x1));
|
||||
y1 = this.calc(this.resolveString(this.y1));
|
||||
} else {
|
||||
x1 = x0 + this.calc(this.resolveString(this.width));
|
||||
y1 = y0 + this.calc(this.resolveString(this.height));
|
||||
}
|
||||
}
|
||||
const halign = this.resolveString(this.halign);
|
||||
const valign = this.resolveString(this.valign);
|
||||
const text = this.resolveString(this.text);
|
||||
const div = document.createElement('div');
|
||||
if (this.color) {
|
||||
div.style.color = this.resolveString(this.color);
|
||||
}
|
||||
div.style.position = 'absolute';
|
||||
if (this.fontSize) {
|
||||
div.style.fontSize = this.calc(this.resolveString(this.fontSize)) + 'px';
|
||||
}
|
||||
div.style.left = x0 + 'px';
|
||||
div.style.top = y0 + 'px';
|
||||
div.style.width = (x1 - x0) + 'px';
|
||||
div.style.height = (y1 - y0) + 'px';
|
||||
div.style.overflow = 'clip';
|
||||
switch (halign) {
|
||||
case 'center':
|
||||
div.style.textAlign = 'center';
|
||||
break;
|
||||
case 'right':
|
||||
div.style.textAlign = 'right';
|
||||
break;
|
||||
}
|
||||
switch (valign) {
|
||||
case 'center':
|
||||
div.style.alignContent = 'center';
|
||||
break;
|
||||
case 'bottom':
|
||||
div.style.alignContent = 'end';
|
||||
break;
|
||||
}
|
||||
div.insertAdjacentHTML('afterbegin', text);
|
||||
target.append(div);
|
||||
}
|
||||
}
|
21
tsconfig.json
Normal file
21
tsconfig.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "./dist/",
|
||||
"noImplicitAny": true,
|
||||
"module": "ES6",
|
||||
"target": "ES6",
|
||||
"allowJs": true,
|
||||
"moduleResolution": "Bundler",
|
||||
},
|
||||
"typedocOptions": {
|
||||
"entryPoints": ["./src", "./src/rendertree"],
|
||||
"entryPointStrategy": "expand",
|
||||
"out": "docs",
|
||||
"excludePrivate": false,
|
||||
},
|
||||
"visibilityFilters": {
|
||||
"protected": true,
|
||||
"private": true,
|
||||
"inherited": true,
|
||||
}
|
||||
}
|
23
webpack.config.js
Normal file
23
webpack.config.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: './src/presentationmaker.ts',
|
||||
mode: 'production',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/,
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.tsx', '.ts', '.js'],
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'presentationmaker.js',
|
||||
libraryTarget: 'global',
|
||||
},
|
||||
};
|
Loading…
Reference in a new issue