dataforge
This commit is contained in:
parent
0380d76926
commit
67fa9b7079
@ -4,40 +4,36 @@ import logo from "../../images/dataforge/df_logo.png"
|
|||||||
|
|
||||||
import "../../styles/dataforge/header.css"
|
import "../../styles/dataforge/header.css"
|
||||||
import "../../styles/bootstrap.min.css"
|
import "../../styles/bootstrap.min.css"
|
||||||
|
import {Navbar, Nav} from "react-bootstrap"
|
||||||
|
|
||||||
const Header = () => {
|
const Header = () => {
|
||||||
let curActive = [' ', ' ', ' ', ' ', ' '];
|
let curActive = [' ', ' ', ' ', ' ', ' ', ' '];
|
||||||
if (window.location.pathname === '/dataforge/news'){curActive[0] = 'styled';}
|
if (document.location.pathname === '/dataforge/news'){curActive[0] = 'active';}
|
||||||
if (window.location.pathname === '/dataforge/docs'){curActive[1] = 'styled';}
|
if (document.location.pathname === '/dataforge/docs'){curActive[1] = 'active';}
|
||||||
if (window.location.pathname === '/dataforge/modules'){curActive[2] = 'styled';}
|
if (document.location.pathname === '/dataforge/modules'){curActive[2] = 'active';}
|
||||||
if (window.location.pathname === '/dataforge/releases'){curActive[3] = 'styled';}
|
if (document.location.pathname === '/dataforge/releases'){curActive[3] = 'active';}
|
||||||
if (window.location.pathname === '/dataforge/apps'){curActive[4] = 'styled';}
|
if (document.location.pathname === '/dataforge/apps'){curActive[4] = 'active';}
|
||||||
return(
|
if (document.location.pathname === '/dataforge/misc'){curActive[5] = 'active';}
|
||||||
<header id="df">
|
|
||||||
<nav class="navbar navbar-expand-lg navbar-light" id="collapsedNavbarDF">
|
|
||||||
<div class="container">
|
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
|
||||||
<span class="navbar-toggler-icon"></span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
return(
|
||||||
{/* style={{paddingTop: `15px`, marginTop: `10px`, marginBottom: `25px`}} */}
|
<header id="df">
|
||||||
<Link to="/dataforge/"><img alt="DataForge" height="55" src={logo}/></Link>
|
<Navbar expand="lg" fixed="top">
|
||||||
<ul class="navbar-nav mr-auto">
|
<div class="container">
|
||||||
<li class="nav-item" id={`${curActive[0]}`}><Link class="nav-link" to="/dataforge/news">News</Link></li>
|
<Navbar.Toggle aria-controls="basic-navbar-nav" />
|
||||||
<li class="nav-item" id={`${curActive[1]}`}><Link class="nav-link" to="/dataforge/docs">Documentation</Link></li>
|
<Navbar.Collapse id="basic-navbar-nav">
|
||||||
<li class="nav-item" id={`${curActive[2]}`}><Link class="nav-link" to="/dataforge/modules">Modules</Link></li>
|
<Nav className="mr-auto">
|
||||||
<li class="nav-item" id={`${curActive[3]}`}><Link class="nav-link" to="/dataforge/releases">Releases</Link></li>
|
<Navbar.Brand><Link to="./dataforge"><img src={logo} height="50px" alt="dataforge logo" id="logo"/></Link></Navbar.Brand>
|
||||||
<li class="nav-item" id={`${curActive[4]}`}><Link class="nav-link" to="/dataforge/apps">Applications</Link></li>
|
<Nav.Link><Link id={`${curActive[0]}`} to="./dataforge/news">News</Link></Nav.Link>
|
||||||
</ul>
|
<Nav.Link><Link id={`${curActive[1]}`} to="./dataforge/docs">Documentation</Link></Nav.Link>
|
||||||
|
<Nav.Link><Link id={`${curActive[2]}`} to="./dataforge/modules">Modules</Link></Nav.Link>
|
||||||
<ul class="nav navbar-nav navbar-right" style={{marginBottom: `10px`}}>
|
<Nav.Link><Link id={`${curActive[3]}`} to="./dataforge/releases">Releases</Link></Nav.Link>
|
||||||
<li class="nav-item"><Link class="nav-link" to="/dataforge/misc">See also</Link></li>
|
<Nav.Link><Link id={`${curActive[4]}`} to="./dataforge/apps">Applications</Link></Nav.Link>
|
||||||
</ul>
|
<Nav.Link><Link id={`${curActive[5]}`} to="./dataforge/misc">See also</Link></Nav.Link>
|
||||||
</div>
|
</Nav>
|
||||||
</div>
|
</Navbar.Collapse>
|
||||||
</nav>
|
</div>
|
||||||
</header>
|
</Navbar>
|
||||||
|
</header>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
export default Header
|
export default Header
|
@ -8,7 +8,7 @@ import "../../styles/dataforge/layout.css"
|
|||||||
const Layout = ({children}) => (
|
const Layout = ({children}) => (
|
||||||
<>
|
<>
|
||||||
<Header id="df"/>
|
<Header id="df"/>
|
||||||
<div class = "container" id="df">
|
<div class = "container">
|
||||||
<main id="df">{children}</main>
|
<main id="df">{children}</main>
|
||||||
</div>
|
</div>
|
||||||
<Footer id="df"/>
|
<Footer id="df"/>
|
||||||
|
BIN
src/images/dataforge/sms_logo.png
Normal file
BIN
src/images/dataforge/sms_logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
23
src/pages/content/dataforge/docs/control/control.md
Normal file
23
src/pages/content/dataforge/docs/control/control.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Control plugin"
|
||||||
|
ordering: [2000]
|
||||||
|
label: "control"
|
||||||
|
version: 1.0
|
||||||
|
date: 2016-02-08
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
DataForge control subsystem defines a general api for data acquisition processes. It could be used to issue commands to devices, read data and communicate with storage system or other devices.
|
||||||
|
|
||||||
|
The center of control API is a `Device` class.
|
||||||
|
The device has following important features:
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>States:</strong> each device has a number of states that could be accessed by `getStatus` method. States could be either stored as some internal variables or calculated on demand. States calculation is synchronous!
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>Listeners:</strong> some external class which listens device state changes and events. By default listeners are represented by weak references so they could be finalized any time if not used.
|
||||||
|
<li>
|
||||||
|
<strong>Connections:</strong> any external device connectors which are used by device. The difference between listener and connection is that device is obligated to notify all registered listeners about all changes, but connection is used by device at its own discretion. Also usually only one connection is used for each single purpose.
|
||||||
|
</li>
|
||||||
|
</ul>
|
11
src/pages/content/dataforge/docs/data_flow/actions.md
Normal file
11
src/pages/content/dataforge/docs/data_flow/actions.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Push model"
|
||||||
|
ordering: [20,1]
|
||||||
|
label: "actions"
|
||||||
|
version: 1.0
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
Actions
|
||||||
|
![Push data flow model](${r '/docs/images/actions.png'})
|
10
src/pages/content/dataforge/docs/data_flow/data_flow.md
Normal file
10
src/pages/content/dataforge/docs/data_flow/data_flow.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Data flow"
|
||||||
|
ordering: [20]
|
||||||
|
label: "data_flow"
|
||||||
|
version: 1.0
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
One of the most important features of DataForge framework is the data flow control. Any
|
11
src/pages/content/dataforge/docs/data_flow/tasks.md
Normal file
11
src/pages/content/dataforge/docs/data_flow/tasks.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Tasks"
|
||||||
|
ordering: [20,2]
|
||||||
|
label: "tasks"
|
||||||
|
version: 1.0
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
![Pull data flow model](${r '/docs/images/tasks.png'})
|
||||||
|
Tasks
|
31
src/pages/content/dataforge/docs/envelopes/binary_meta.md
Normal file
31
src/pages/content/dataforge/docs/envelopes/binary_meta.md
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Binary meta"
|
||||||
|
chapter: envelope
|
||||||
|
ordering: 50
|
||||||
|
label: "binary_meta"
|
||||||
|
published: false
|
||||||
|
---
|
||||||
|
Binary meta format is made to limit size and simplify parsing to automatic messages. The notation for the node looks the following way (all numeric values use BigEndian encoding):
|
||||||
|
|
||||||
|
<br>
|
||||||
|
All strings are encoded in a following way: 2 bytes for string length, byte array of given length representing UTF-8 encoded string.
|
||||||
|
<br>
|
||||||
|
|
||||||
|
1. Meta name as string.
|
||||||
|
2. 2 bytes unsigned integer representing the number of values in the node. Could be zero.
|
||||||
|
3. For each of values an encoded name of the value and then:
|
||||||
|
* `0` for Null value.
|
||||||
|
* `T` for `TIME` value, followed by two unsigned long values representing epoch second and nanosecond adjustment.
|
||||||
|
* `S` for `STRING` value followed by encoded string.
|
||||||
|
* `D` for double based `NUMBER` followed by double (double encoding specified by [Java serialization](https://docs.oracle.com/javase/8/docs/api/java/io/DataOutput.html#writeDouble-double-)).
|
||||||
|
* `I` for integer based `NUMBER` followed by signed 4-bytes integer value.
|
||||||
|
* `B` for [`BigDecimal`](https://docs.oracle.com/javase/8/docs/api/java/math/BigDecimal.html) based `NUMBER` followed by 2-byte unsigned integer defining the number of bytes in representation, bytes themselves and 4-byte scale factor.
|
||||||
|
* `+` for boolean `true`.
|
||||||
|
* `-` for boolean `false`.
|
||||||
|
* `L` for list value and then 2-byte list size followed by sequence of values (as in item 3, but without a name).
|
||||||
|
4. 2 bytes unsigned integer representing the number of child nodes in this node. Could be zero.
|
||||||
|
5. For each of child nodes:
|
||||||
|
* child node name,
|
||||||
|
* 2-byte unsigned integer representing number of children with this name.
|
||||||
|
* The sequence of nodes with given name encoding like the root node, but without name.
|
37
src/pages/content/dataforge/docs/envelopes/default_format.md
Normal file
37
src/pages/content/dataforge/docs/envelopes/default_format.md
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Streaming envelope format"
|
||||||
|
chapter: envelope
|
||||||
|
ordering: 1
|
||||||
|
label: "envelope_format"
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
|
||||||
|
The default envelope format is developed for storage of binary data or transferring data via byte stream. The structure of this format is the following:
|
||||||
|
|
||||||
|
* **Tag**. First 20 bytes of file or stream is reserved for envelope properties binary representation:
|
||||||
|
1. `#~` - two ASCII symbols, beginning of binary string.
|
||||||
|
2. 4 bytes - properties `type` field: envelope format type and version. For default format the string `DF02` is used, but in principle other envelope types could use the same format.
|
||||||
|
3. 2 bytes - properties `metaType` field: metadata encoding type.
|
||||||
|
4. 4 bytes - properties `metaLength` field: metadata length in bytes including new lines and other separators.
|
||||||
|
5. 4 bytes - properties `dataLength` field: the data length in bytes.
|
||||||
|
6. `~#` - two ASCII symbols, end of binary string.
|
||||||
|
7. `\r\n` - two bytes, new line.
|
||||||
|
|
||||||
|
The values are read as binary and transformed into 4-byte unsigned tag codes (Big endian).
|
||||||
|
|
||||||
|
* **Metadata block**. Metadata in any accepted format. Additional formats could be provided by modules. The default metadata format is *UTF-8* encoded *XML* (tag code 0x584d). *JSON* format is provided by storage module.
|
||||||
|
|
||||||
|
One must note that `metaLength` property is very important and in most cases is mandatory. It could be set to `0xffffffff` or `-1` value in order to force envelope reader to derive meta length automatically, but different readers do it in a different ways, so it strongly not recommended to do it if data block is not empty.
|
||||||
|
|
||||||
|
* **Data block**. Any other data. If `dataLength` property is set to `0xffffffff` or `-1`, then it is supposed that data block ends with the end of file or stream. It is discouraged to use infinite data length for streaming data. Data block does not have any limitations for its content. It could even contain envelopes inside it!
|
||||||
|
|
||||||
|
### Meta encoding
|
||||||
|
|
||||||
|
DataForge server supports following metadata encoding types:
|
||||||
|
|
||||||
|
1. **XML** encoding. The full name for this encoding is `XML`, the tag code is `XM`.
|
||||||
|
2. **JSON** encoding (currently supported only with `storage` module attached). The full name is `JSON`, the tag code is `JS`.
|
||||||
|
3. **Binary** encoding. DataForge own binary meta representation. The full name is `binary`, the tag code is `BI`.
|
||||||
|
|
||||||
|
To avoid confusion. All full names are case insensitive. All meta is supposed to always use **UTF-8** character encoding.
|
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Envelope description"
|
||||||
|
chapter: envelope
|
||||||
|
ordering: 20
|
||||||
|
label: "envelope_description"
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
Interpretation of envelope contents is basically left for user, but for convenience purposes there is convention for envelope description encoded inside meta block.
|
||||||
|
|
||||||
|
The envelope description is placed into hidden `@envelope` meta node. The description could contain following values:
|
||||||
|
|
||||||
|
- `@envelope.type` (STRING): Type of the envelope content
|
||||||
|
- `@envelope.dataType` (STRING): Type of the envelope data
|
||||||
|
- `@envelope.description` (STRING): Description of the envelope content
|
||||||
|
- `@envelope.time` (TIME): Time of envelope creation
|
||||||
|
|
||||||
|
Both envelope type and data type are supposed to be presented in reversed Internet domain name like java packages.
|
19
src/pages/content/dataforge/docs/envelopes/envelopes.md
Normal file
19
src/pages/content/dataforge/docs/envelopes/envelopes.md
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Envelopes"
|
||||||
|
chapter: envelope
|
||||||
|
label: "envelopes"
|
||||||
|
version: 1.0
|
||||||
|
date: 2016-02-08
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
|
||||||
|
The DataForge functionality is largely based on metadata exchange and therefore the main medium for messages between different parts of the system is `Meta` object and its derivatives. But sometimes one needs not only to transfer metadata but some binary or object data as well. For this DataForge supports an 'Envelope' entity, which contains both meta block and binary data block. Envelope could be automatically serialized to or from a byte stream.
|
||||||
|
|
||||||
|
DataForge supports an extensible list of Envelope encoding methods. Specific method is defined by so-called encoding *properties* - the list of key-value pairs that define the specific way the meta and data are encoded. Meta-data itself also could have different encoding. Out of the box DataForge server supports two envelope formats and three meta formats.
|
||||||
|
|
||||||
|
<!-- In order to do so one should use an `Envelope` entity. It is a combined format for both text metadata and data in single block. An `Envelope` container consists of three main components: -->
|
||||||
|
|
||||||
|
<!-- 0. **Properties**. A set of key-value bindings defining envelope format: metadata format and length, data length and general envelope version. Properties in fact are not considered to be a part of envelope itself, but it is usually a part of envelope container. -->
|
||||||
|
<!-- 1. **Meta**. A text metadata in any supported format. -->
|
||||||
|
<!-- 2. **Data**. Ant binary or textual data. The rules to read this data could be derived either from properties header or from envelope meta. -->
|
25
src/pages/content/dataforge/docs/envelopes/tagless_format.md
Normal file
25
src/pages/content/dataforge/docs/envelopes/tagless_format.md
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Tagless envelope format"
|
||||||
|
chapter: envelope
|
||||||
|
ordering: 2
|
||||||
|
label: "tagless_format"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
Tagless format is developed to store textual data without need for binary block at the beginning. It is not recommended to use it for binary data or for streaming. The structure of this format is the following:
|
||||||
|
|
||||||
|
|
||||||
|
1. **The header line**. `#~DFTL~#`. The line is used only for identify the DataForge envelope. Standard reader is also configured to skip any lines starting with # before this line, so it is compatible with [shebang](https://en.wikipedia.org/wiki/Shebang_(Unix)). All header lines in tagless format must have at least new line `\n` character after them (DOS/Windows new line `\r\n` is also supported).
|
||||||
|
|
||||||
|
2. **Properties**. Properties are defined in a textual form. Each property is defined in its own lined in a following way:
|
||||||
|
|
||||||
|
```#? <property key> : <property value>; <new line>```
|
||||||
|
|
||||||
|
Any whitespaces before `<property value>` begin are ignored. The `;` symbol is optional, but everything after it is ignored. Every property **must** be on a separate line. The end of line is defined by `\n` character so both Windows and Linux line endings are valid.
|
||||||
|
Properties are accepted both in their textual representation or tag code.
|
||||||
|
|
||||||
|
3. **Meta block start**. Meta block start string is defined by `metaSeparator` property. The default value is `#~META~#`. Meta block start could be omitted if meta is empty.
|
||||||
|
4. **Meta block**. Everything between meta block start and data block start (or end of file) is treated like meta. `metaLength` property is ignored. It is not recommended to use binary meta encoding in this format.
|
||||||
|
5. **Data start block**. Data block start string is defined by `dataSeparator` property. The default value is `#~DATA~#`. Data block start could be omitted if data is empty.
|
||||||
|
6. **Data block**. The data itself. If `dataLength` property is defined, then it is used to trim the remaining bytes in the stream or file. Otherwise the end of stream or file is used to define the end of data.
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Language extensions"
|
||||||
|
chapter: extensions
|
||||||
|
label: "extensions"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
DataForge also supports a number of language extensions inside JVM.
|
12
src/pages/content/dataforge/docs/extensions/grind.md
Normal file
12
src/pages/content/dataforge/docs/extensions/grind.md
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "GRoovy INteractive Dataforge"
|
||||||
|
chapter: extensions
|
||||||
|
ordering: 1
|
||||||
|
label: "grind"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
Grind is a thin layer overlay for DataForge framework written in dynamic Java dialect [Groovy](http://groovy-lang.org/). Groovy is a great language to write fast dynamic scripts with Java interoperability. Also it is used to work with interactive environments like [beaker](http://beakernotebook.com/).
|
||||||
|
|
||||||
|
GRIND module contains some basic extensions and operator overloading for DataForge, a DSL for building Meta. Also in separate modules is an interactive console using GroovyShell and some mathematical extensions.
|
10
src/pages/content/dataforge/docs/extensions/kodex.md
Normal file
10
src/pages/content/dataforge/docs/extensions/kodex.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "KOtlin Dataforge EXtension"
|
||||||
|
chapter: extensions
|
||||||
|
ordering: 2
|
||||||
|
label: "kodex"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
Kotlin is one of the best efforts to make a "better Java". The language is probably not the best way to write a complex architecture like the one used in DataForge, but it definitely should be used in end-user application. KODEX contains some basic DataForge classes extensions as well as operator override for values and metas. It is planned to also include a JavaFX extension library based on the great [tornadofx](https://github.com/edvin/tornadofx).
|
18
src/pages/content/dataforge/docs/how_to_read.md
Normal file
18
src/pages/content/dataforge/docs/how_to_read.md
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "How to read this documentation"
|
||||||
|
chapter: "howto"
|
||||||
|
label: "how_to_read"
|
||||||
|
version: 1.1
|
||||||
|
date: 2015-09-02
|
||||||
|
published: true
|
||||||
|
order: 1
|
||||||
|
---
|
||||||
|
An important feature of DataForge framework is ability to work with [meta-data](#meta).
|
||||||
|
This documentation is automatically generated by [grain](http://sysgears.com/grain/)
|
||||||
|
script from [markdown](https://en.wikipedia.org/wiki/Markdown) and html pieces.
|
||||||
|
Such pieces are called shards. The shard consists of data in one of supported formats and meta-data header.
|
||||||
|
The ordering of shards is automatically inferred from meta-data by the [script](https://bitbucket.org/Altavir/dataforge-grain).
|
||||||
|
|
||||||
|
The meta-data of each shards includes version of this precise shard last update date,
|
||||||
|
it's label for reference and ordering information.
|
21
src/pages/content/dataforge/docs/meta/configuration.md
Normal file
21
src/pages/content/dataforge/docs/meta/configuration.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Configuration"
|
||||||
|
chapter: "meta"
|
||||||
|
ordering: 6
|
||||||
|
label: "configuration"
|
||||||
|
version: 1.0
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
The configuration is a very important extension of basic [Meta](#meta_structure) class.
|
||||||
|
It is basically a mutable meta which incorporates
|
||||||
|
external observers. It is also important that while simple Meta knows its children knows its children,
|
||||||
|
but could be attached freely to any ancestor, configuration has one designated ancestor that is
|
||||||
|
notified than configuration is changed.
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
**Note** that putting elements or values to configuration follows the same naming convention as getting from it.
|
||||||
|
Meaning putting to `some_name.something` will actually create or put to the node `some_name` if it exists.
|
||||||
|
Otherwise, new node is created.
|
||||||
|
<hr>
|
13
src/pages/content/dataforge/docs/meta/hidden_values.md
Normal file
13
src/pages/content/dataforge/docs/meta/hidden_values.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Hidden values"
|
||||||
|
chapter: "meta"
|
||||||
|
ordering: 10
|
||||||
|
label: "hidden_values"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
|
||||||
|
Meta structure supports so-called *hidden* values and nodes. These values and nodes exist in the meta and could be requested either by user or framework, but are not shown by casual listing. These values and nodes are considered *system* and are not intended to be defined by user in most cases.
|
||||||
|
|
||||||
|
Hidden values and nodes names starts with symbol `@` like `@node`. Not all meta-data representations allow this symbol so in could be replaced by escaped sequence `_at_` in text format (`<_at_node/>` in XML).
|
33
src/pages/content/dataforge/docs/meta/meta-data.md
Normal file
33
src/pages/content/dataforge/docs/meta/meta-data.md
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Meta-data processor"
|
||||||
|
chapter: "meta"
|
||||||
|
label: "meta"
|
||||||
|
version: 2.0
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
The main and the most distinguishing feature of DataForge framework is a concept of data analysis as a meta-data processor.
|
||||||
|
First of all, one need to define main terms:
|
||||||
|
|
||||||
|
* **Data**. Any information from experiment or simulation provided by user. The data format is not governed by DataForge so it could be presented in any form. The important point concerning data is that data is by default immutable. Meaning the program could create its modified copies (which is not recommended), but could not modify initial input in any way.
|
||||||
|
|
||||||
|
* **Meta-data**. Meta-data contrary to data has a fixed internal representation provided by Meta object. Meta is simple [tree-like object](#meta_structure) that can conveniently store values and Meta nodes. Meta-data is either provided by user or generated in analysis process. Inside the analysis process Meta is immutable, but for some purposes, changeable meta nodes could be used during analysis configuration and results representation (see [Configuration](#configuration)).
|
||||||
|
|
||||||
|
The fundamental point of the whole DataForge philosophy is that every external input could be either data or meta-data. This point could seem dull at first glance, but in fact, it have a number of very important consequences:
|
||||||
|
|
||||||
|
* *No scripts*. DataForge encourages user not to use imperative code to manipulate data. Any procedure to be performed on data should be presented either by some hard-coded meta-data processor rule (the function that takes data and metadata and produces some output without any additional external information) or as declarative process definition in form of meta-data. Since the most of data analysis nowadays is made by different scripts, the loss of scripting capability could seem to be a tremendous blow to framework functionality, but in fact every thing one could do with script, one also can do with declaration and declaration processing rules. Also purely declarative description allows for easy error check and analysis scaling (via parallelism).
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
**Note:** Those, who still like scripting, can still either use DataForge as a library, or use [GRIND](#grind)
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
* *Automatic scaling*. Since particular analysis of some piece of data depends only on that piece and on it's meta-data, such analysis could be easily scaled for any number of such data pieces.
|
||||||
|
|
||||||
|
* *Meta composition*. Since the configuration of analysis and meta-data ara both have fixed representation, one could easily combine specific analysis configuration from different parts taken from different sources. For example, one could have a general configuration for the whole data set and specific changes for some specific point. One do not have to write a specific script to work with this particular point, just override its meta-data!
|
||||||
|
|
||||||
|
* *No global state*. Since neither data, nor meta-data account for global states, there are no global states! The closest to the global states as you get is context variables (see [context](#context)), which are used to connect analysis process to system environment, but these states are not used in the analysis itself.
|
||||||
|
|
||||||
|
* *Automatic data flow organisation*. Since user does not in general control the order and time of actions performed by the framework, the work of arranging data flow, result caching, etc. could be actually done by the framework itself.
|
22
src/pages/content/dataforge/docs/meta/meta-layers.md
Normal file
22
src/pages/content/dataforge/docs/meta/meta-layers.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Meta-data composition"
|
||||||
|
chapter: "meta"
|
||||||
|
ordering: 5
|
||||||
|
label: "meta-layers"
|
||||||
|
version: 1.0
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
|
||||||
|
An important part of working with meta is *composition*. Let us work with two use-cases:
|
||||||
|
|
||||||
|
1. There is a data supplied with meta and one needs modified version of the meta.
|
||||||
|
2. There is a list of data with the same meta and one needs to change meta only for one data piece.
|
||||||
|
|
||||||
|
DataForge provides instruments to easily modify meta (or, since meta is immutable, create a modified instance), but it is not a good solution. A much better way is to use instrument called `Laminate`. Laminate implements meta specification, but stores not one tree of values, but multiple layers of meta. When one requests a Laminate for a value ore meta, it automatically forwards request to the first meta layer. If required node or value is not found in the first layer, the request is forwarded to second layer etc. Laminate also contains meta descriptor, which could be used for default values. Laminate functionality also allows to use information from all of its layers, for example join lists of nodes instead of replacing them. Laminate layers also could be merged together to create classical meta and increase performance. Of course, in this case special features like custom use of all layers is lost.
|
||||||
|
|
||||||
|
Using Laminate in case 1 looks like this: if one needs just to change or add some value, one creates a Laminate with initial meta as second layer and override layer containing only values to be changed as first.
|
||||||
|
|
||||||
|
For case 2 the solution is even simpler: `DataNode` structures automatically uses laminates to define meta for specific data pieces. So one needs just to define meta for specific data, it will be automatically layered with node meta (or multiple meta elements if node data node structure has many levels).
|
||||||
|
|
||||||
|
The typical usage of data layering could be demonstrated on `Actions` (push data flow). Action has 3 arguments: `Context`, `DataNode` and `Meta`. The actual configuration for specific `Data` is defined as a laminate containing data meta layer, node meta layer(s) and action meta layer. Meaning that actual action meta is used only if appropriate positions are not defined in data meta (data knows best about how it should be analyzed).
|
42
src/pages/content/dataforge/docs/meta/meta_structure.md
Normal file
42
src/pages/content/dataforge/docs/meta/meta_structure.md
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
---
|
||||||
|
content_type: "doc_shard"
|
||||||
|
title: "Meta-data object structure"
|
||||||
|
chapter: "meta"
|
||||||
|
ordering: 4
|
||||||
|
label: "meta_structure"
|
||||||
|
version: 1.1
|
||||||
|
date: 2015-08-27
|
||||||
|
published: true
|
||||||
|
---
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img src="${img 'meta.svg'}" alt="Meta structure"/>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
The Meta object is a tree-like structure, which can contain other meta objects as branches (which are
|
||||||
|
called
|
||||||
|
elements) and <a href="#value">Value</a> objects as leafs.
|
||||||
|
Both Values and Meta elements are organized in String-keyed maps. And each map element is a list of
|
||||||
|
appropriate type. By requesting single Value or Meta element one is supposed to request first element of
|
||||||
|
this list.
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
<p><strong>Note</strong> that such lists are always immutable. Trying to change it may cause a error.</p>
|
||||||
|
<hr>
|
||||||
|
<p>
|
||||||
|
While meta itself does not have any write methods and is considered to be immutable, some of its
|
||||||
|
extensions do have methods that can change meta structure. One should be careful not to use mutable meta
|
||||||
|
elements when one need immutable one.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
In order to conveniently edit meta, there is MetaBuilder class.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
<tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
The naming of meta elements and values follows basic DataForge [naming and navigation](#navigation) convention.
|
||||||
|
Meaning that elements and values could be called like `child_name.grand_child_name.value_name`.
|
||||||
|
One can event use numbers as queries in such paths like `child_name.grand_child_name[3].value_name`.
|
@ -1,15 +1,16 @@
|
|||||||
import React from "react"
|
import React from "react"
|
||||||
|
import Layout from "../../components/dataforge/layout"
|
||||||
|
|
||||||
const AppPage = () => (
|
const AppPage = () => (
|
||||||
<div>
|
<Layout>
|
||||||
<h1>Troitsk nu-mass</h1>
|
<h1>Troitsk nu-mass</h1>
|
||||||
<img src="http://www.inr.ru/~trdat/img/spectrometer900.jpg"/>
|
<img src="http://www.inr.ru/~trdat/img/spectrometer900.jpg" alt="spectrometer"/>
|
||||||
<p>
|
<p>
|
||||||
The main aim of <a href="http://www.inr.ru/~trdat/">Troitsk nu-mass</a> is a search for masses of active and sterile
|
The main aim of <a href="http://www.inr.ru/~trdat/">Troitsk nu-mass</a> is a search for masses of active and sterile
|
||||||
neutrinos in the beta-spectrum of tritium.
|
neutrinos in the beta-spectrum of tritium.
|
||||||
</p>
|
</p>
|
||||||
<hr/>
|
<hr/>
|
||||||
</div>
|
</Layout>
|
||||||
)
|
)
|
||||||
|
|
||||||
export default AppPage
|
export default AppPage
|
@ -0,0 +1,76 @@
|
|||||||
|
import React from "react"
|
||||||
|
import Layout from "../../components/dataforge/layout"
|
||||||
|
|
||||||
|
import sms_logo from "../../images/dataforge/sms_logo.png"
|
||||||
|
|
||||||
|
const MiscPage = () => (
|
||||||
|
<Layout>
|
||||||
|
<h1 id="about">About us...</h1>
|
||||||
|
|
||||||
|
<img width="150" src={sms_logo} style={{marginRight: `25px`}} alt="sms"/>
|
||||||
|
The DataForge is currently being developed in Sector for mathematical support of <a href="http://www.inr.ru/">Institute for Nuclear Research of Russian academy of Sciences </a>.
|
||||||
|
|
||||||
|
<p/>
|
||||||
|
<hr style={{height: `1px`}}/>
|
||||||
|
|
||||||
|
<h1>Other data analysis framework</h1>
|
||||||
|
<div class="col-lg-12">
|
||||||
|
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<a href="https://root.cern.ch/">
|
||||||
|
<img align="left" alt="root" style={{marginRight: `25px`, marginBottom: `0`, marginTop: `10px`}} width="150" src="https://root.cern.ch/root/htmldoc/guides/users-guide/pictures/rootlogo.png"/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<p>Root is the most used data analysis framework in particle physics. The documentation for this
|
||||||
|
platform is extensive and it has good scientific community support. Its main problem is its
|
||||||
|
architecture which originates in 1980-s and holds a lot of legacy drawbacks of older FORTRAN
|
||||||
|
platforms. Also the general problem is C++. While being very flexible, C++ requires a lot of
|
||||||
|
programming expertise to write safe and consistent code. Sadly, physicists seldom are not very
|
||||||
|
good programmers. Nowadays Root hits the roof of its usability.</p>
|
||||||
|
|
||||||
|
<p>Additional information about Root criticism could be found <a href="https://en.wikipedia.org/wiki/ROOT#Criticisms">here</a>. </p>
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr style={{height: `1px`}}/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
{/* <td><a href="http://jas.freehep.org/jas3/"> <img style={{marginRight: `25px`}} width="300" src="http://jas.freehep.org/jas3/images/jas3Title.png"/></a></td> */}
|
||||||
|
<td>
|
||||||
|
<p>The java analysis studio is quite advanced data visualization framework developed in Standford accelerator center. It is modular and has good object oriented design</p>
|
||||||
|
<p>It is intended to make an interface to integrate DataForge framework with JAS3 visualization via <a href="modules.html#aida">AIDA plugin</a></p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="jwork.org/dmelt/">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<img src="http://jwork.org/dmelt/data_dm/images/dm_logo125px.png" alt="dataMelt"/>
|
||||||
|
</tr>
|
||||||
|
<tr align="center"><h3>DataMelt</h3></tr>
|
||||||
|
</table>
|
||||||
|
</a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<p>
|
||||||
|
DataMelt is huge collection of scientific libraries accompanied by visual framework which allows to
|
||||||
|
write analysis scripts in different JVM languages. It is a good memory-safe alternative to Root, but
|
||||||
|
sadly it inherits a lot of Root architectural drawbacks as well.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
|
</div>
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default MiscPage
|
@ -5,23 +5,22 @@ import Layout from "../../components/dataforge/layout"
|
|||||||
const NewsPage = ({ data }) => (
|
const NewsPage = ({ data }) => (
|
||||||
<Layout>
|
<Layout>
|
||||||
{data.posts.nodes.map(post => {
|
{data.posts.nodes.map(post => {
|
||||||
const title = post.frontmatter.title;
|
const title = post.frontmatter.title;
|
||||||
const date = post.frontmatter.date;
|
const date = post.frontmatter.date;
|
||||||
return(
|
return(
|
||||||
<div class="post">
|
<div class = "card" style={{marginBottom: `15px`, borderRadius: `0px`, boxShadow: `0 2px 2px #A2A2A2`}}>
|
||||||
<div class="col-lg-12">
|
<div class = "card-body">
|
||||||
<h2><small style={{color: `rgb(119,119,119)`, fontSize: `19.5px`}}>{date}</small> {title}</h2>
|
<h2 class = "title">
|
||||||
</div>
|
{title}<span id="date">{date}</span>
|
||||||
|
</h2>
|
||||||
<p
|
<p
|
||||||
dangerouslySetInnerHTML = {{
|
dangerouslySetInnerHTML = {{
|
||||||
__html: post.frontmatter.description || post.html,
|
__html: post.frontmatter.description || post.html,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<hr/>
|
</div>
|
||||||
</div>
|
)
|
||||||
)
|
|
||||||
})}
|
})}
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
import React from "react"
|
||||||
|
import Layout from "../../components/dataforge/layout"
|
||||||
|
|
||||||
|
const ReleasesPage = () => (
|
||||||
|
<Layout>
|
||||||
|
<h2>Versioning</h2>
|
||||||
|
<p>DataForge uses <a href="https://docs.oracle.com/middleware/1212/core/MAVEN/maven_version.htm">Maven version</a> policy.</p>
|
||||||
|
<h2>Source code and documentation consistency</h2>
|
||||||
|
<p>Be warned that for SNAPSHOT versions source code and documentation could be slightly inconsistent due to not synchronized update of this site.</p>
|
||||||
|
|
||||||
|
<hr style={{height: `1px`}}/>
|
||||||
|
|
||||||
|
<table class="table table-bordered table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="release-table-block">Version</th>
|
||||||
|
<th class="release-table-block">Javadoc</th>
|
||||||
|
<th class="release-table-block">Release notes</th>
|
||||||
|
<th class="release-table-block">Info</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="release-table-block">0.1.0</td>
|
||||||
|
<td class="release-table-block"></td>
|
||||||
|
<td class="release-table-block"></td>
|
||||||
|
<td></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="release-table-block">0.1.1</td>
|
||||||
|
<td class="release-table-block"></td>
|
||||||
|
<td class="release-table-block"></td>
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<li>Annotations are renamed to Meta.</li>
|
||||||
|
<li>Deprecated and removed Items from meta package and replaced by immutable lists.</li>
|
||||||
|
<li>TimeValue produces Instant instead of LocalDateTime since Instant is absolute while LocalDateTime is not.</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="release-table-block">0.4.0 - SNAPSHOT</td>
|
||||||
|
<td class="release-table-block">
|
||||||
|
<a href="http://npm.mipt.ru/dataforge/docs/0.4.0 - SNAPSHOT/javadoc/index.html" type="text/html">HTML</a>
|
||||||
|
</td>
|
||||||
|
<td class="release-table-block"></td>
|
||||||
|
<td><p><strong>For list of features see documentation</strong></p></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</Layout>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ReleasesPage
|
@ -2,10 +2,10 @@ footer#df * {
|
|||||||
text-align: left;
|
text-align: left;
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
left: 0;
|
left: 0;
|
||||||
bottom: 0;}
|
bottom: 0; }
|
||||||
|
|
||||||
footer#df p { font-size: 15px; }
|
footer#df p { font-size: 18px; }
|
||||||
|
|
||||||
footer#df a { color: rgb(54, 117, 185); text-decoration: none; }
|
footer#df a { color: rgb(54, 117, 185); text-decoration: none; }
|
||||||
footer#df a:hover { color: rgb(54, 117, 185); text-decoration: underline; }
|
footer#df a:hover { color: rgb(39, 88, 141); text-decoration: underline; }
|
||||||
footer#df a:visited { color: rgb(54, 117, 185); }
|
footer#df a:visited { color: rgb(54, 117, 185); }
|
@ -1,51 +1,46 @@
|
|||||||
header#df {
|
header#df {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
height: 70px;
|
||||||
top: 0;
|
font-size: 20px; }
|
||||||
position: fixed;
|
|
||||||
z-index: 1000;
|
|
||||||
height: 70px; }
|
|
||||||
|
|
||||||
/* ----- navbar ----------------------------- */
|
/* ----- navbar ----------------------------- */
|
||||||
.navbar#collapsedNavbarDF {
|
header#df .navbar {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 75px;
|
height: 75px;
|
||||||
background: rgb(114, 111, 111);
|
background-color: rgb(114, 111, 111);
|
||||||
border: none; }
|
border: none; }
|
||||||
|
|
||||||
header#df ul.navbar-nav.mr-auto { padding-bottom: 20px; }
|
header#df img#logo { opacity: 0.8; margin-top: 5px; }
|
||||||
header#df ul.navbar-nav .nav-item a[aria-current="page"] { padding: 18px }
|
header#df img#logo:hover { opacity: 1; }
|
||||||
|
a[aria-current="page"] img#logo { opacity: 1; }
|
||||||
|
|
||||||
header#df a.nav-link:hover { color: black; background-color: rgb(182, 188, 192); }
|
header#df a.nav-link:hover { color: black; background-color: rgb(182, 188, 192); }
|
||||||
header#df a.nav-link {
|
header#df a.nav-link { margin-top: 7px; }
|
||||||
font-family: Arial, Helvetica, sans-serif;
|
header#df a.nav-link a { padding: 15px; }
|
||||||
font-size: 20px;
|
header#df a.nav-link a#active {
|
||||||
color: rgb(240, 240, 240);
|
background-color: rgb(182, 188, 192);
|
||||||
padding-right: 20px; }
|
padding-top: 11px;
|
||||||
|
padding-bottom: 18px; }
|
||||||
|
|
||||||
header#df button.navbar-toggler {
|
header#df button.navbar-toggler.collapsed {
|
||||||
background-color: rgb(228, 228, 228);
|
background-color: rgb(228, 228, 228);
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
margin-top: 10px; }
|
margin-top: 0px; }
|
||||||
|
|
||||||
header#df div#navbarSupportedContent.navbar-collapse.collapse.show {
|
header#df button.navbar-toggler { background-color: rgb(228, 228, 228); }
|
||||||
|
|
||||||
|
header#df div.mr-auto.navbar-nav {
|
||||||
background-color: rgb(114, 111, 111);
|
background-color: rgb(114, 111, 111);
|
||||||
padding-bottom: 400px; }
|
height: 75px; }
|
||||||
|
|
||||||
header#df li#styled.nav-item {
|
/* ------------------------------------------------- */
|
||||||
background-color: rgb(182, 188, 192);
|
|
||||||
height: 60px;
|
/* ------ media ------------------------------------ */
|
||||||
padding-top: 14px;
|
@media (max-width: 769px){
|
||||||
margin-top: 10px;
|
header#df a.nav-link { margin-left: 40px; margin-right: 40px; padding: 15px; }
|
||||||
color: black; }
|
header#df img#logo { margin-left: 20px; margin-right: 0px;}
|
||||||
|
header#df div#basic-navbar-nav.navbar-collapse.collapse.show {
|
||||||
header#df a[aria-current="page"] {
|
background-color: rgb(114,111,111);
|
||||||
color: rgb(0, 0, 0);
|
padding-bottom: 450px; }
|
||||||
font-size: 20px;
|
}
|
||||||
text-decoration: none; }
|
|
||||||
|
|
||||||
header#df img {
|
|
||||||
padding-right: 10px;
|
|
||||||
margin-top: 25px;
|
|
||||||
margin-right: 20px; }
|
|
||||||
/* ------------------------------------------------- */
|
/* ------------------------------------------------- */
|
@ -1,11 +1,37 @@
|
|||||||
|
main#df { margin-top: 20px; min-height: 84vh; }
|
||||||
main#df * { font-family: Arial, Helvetica, sans-serif; }
|
main#df * { font-family: Arial, Helvetica, sans-serif; }
|
||||||
main#df p { font-size: 20px; margin: 10px 0 10px 0; }
|
main#df p { font-size: 20px; margin: 10px 0 10px 0; }
|
||||||
main#df h1 { font-size: 56px; font-weight: 500; }
|
main#df h1 { font-size: 48px; font-weight: 500; }
|
||||||
main#df h2 { font-size: 45px; font-weight: 500; }
|
main#df h2 { font-size: 43px; font-weight: 500; }
|
||||||
main#df h3 { font-size: 24px; }
|
main#df h3 { font-size: 24px; }
|
||||||
main#df hr { margin: 20px 0 20px 0; border: none; }
|
main#df hr { margin: 20px 0 20px 0; border: none; }
|
||||||
main#df li { font-size: 15px; }
|
main#df li { font-size: 20px; }
|
||||||
main#df a { color: rgb(54, 117, 185); text-decoration: none; }
|
main#df a { color: rgb(54, 117, 185); text-decoration: none; }
|
||||||
main#df a:hover { color: rgb(54, 117, 185); text-decoration: underline; }
|
main#df a:hover { color: rgb(40, 87, 138); text-decoration: underline; }
|
||||||
main#df a:visited { color: rgb(54, 117, 185); }
|
main#df a:visited { color: rgb(54, 117, 185); }
|
||||||
main#df div.post:last-of-type { margin-bottom: 150px; }
|
main#df div.post:last-of-type { margin-bottom: 150px; }
|
||||||
|
|
||||||
|
/* --------- news -------------- */
|
||||||
|
main#df span#date {
|
||||||
|
background-color: rgb(101, 141, 184);
|
||||||
|
border: none;
|
||||||
|
padding: 10px;
|
||||||
|
position: absolute;
|
||||||
|
right: 15px;
|
||||||
|
top: 15px;
|
||||||
|
margin: 10px;
|
||||||
|
}
|
||||||
|
/* ----------------------------- */
|
||||||
|
|
||||||
|
/* ----- media ---------------------------- */
|
||||||
|
@media (max-width: 769px) {
|
||||||
|
main#df span#date {
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
margin: 0px;
|
||||||
|
}
|
||||||
|
button#togglerButton.navbar-toggler.collapsed {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-left: 10px; }
|
||||||
|
}
|
||||||
|
/* ---------------------------------------- */
|
Loading…
Reference in New Issue
Block a user