Compare commits
44 Commits
c6e2439a91
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
f0edfe5b23
|
|||
|
fd371d1c51
|
|||
|
d4e603c5b1
|
|||
|
c866a6a1d9
|
|||
|
66610fdac9
|
|||
|
7ac1d880d7
|
|||
|
d55c5e325c
|
|||
|
11420c690c
|
|||
|
4340e4dff2
|
|||
|
ef2d74e889
|
|||
|
49d5d321c8
|
|||
|
10f9f35496
|
|||
|
4cc0846887
|
|||
|
75f847c213
|
|||
|
7232ef2252
|
|||
|
0a2b40d092
|
|||
|
a8c63d502e
|
|||
|
e6c8689ae8
|
|||
|
08f81bf4da
|
|||
|
cc39119789
|
|||
|
64b8a33c7d
|
|||
|
4ec15ee6dd
|
|||
| cfeef63ae2 | |||
|
9d80ca7fd4
|
|||
|
2e1ded20f4
|
|||
|
5cdb22c32c
|
|||
|
2e97ce9f4c
|
|||
|
c8e8f59eb6
|
|||
|
d76884fc9c
|
|||
|
5e724c6b40
|
|||
|
15c6ec899e
|
|||
|
95e166a058
|
|||
|
9620e35838
|
|||
|
9317ce370f
|
|||
|
cc6198951c
|
|||
|
99248b2ba8
|
|||
|
93a3331a87
|
|||
|
78ecda082e
|
|||
|
a8a6da5661
|
|||
|
4014f6f4e5
|
|||
|
ec4d2473d3
|
|||
|
08dc9dd5e9
|
|||
|
d5ed18d9be
|
|||
|
98f94206ac
|
2
.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
.vscode
|
.vscode
|
||||||
|
bibliography.bib.bak
|
||||||
|
bibliography.bib.sav
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#set text(font: "Source Sans 3")
|
#set text(font: "Source Sans 3")
|
||||||
|
|
||||||
= General Planning
|
= Initial Planning
|
||||||
|
|
||||||
#table(
|
#table(
|
||||||
columns: (auto, 1fr),
|
columns: (auto, 1fr),
|
||||||
@@ -16,3 +16,20 @@
|
|||||||
[*8*],
|
[*8*],
|
||||||
[*9*],
|
[*9*],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
= History
|
||||||
|
|
||||||
|
#table(
|
||||||
|
columns: (auto, 1fr),
|
||||||
|
align: (center, left + horizon),
|
||||||
|
table.header[*Week*][*Objectives*],
|
||||||
|
[*1*], [Kickoff, setup project, start prototyping a syntax],
|
||||||
|
[*2*], [Syntax prototype, simple parser],
|
||||||
|
[*3*], [Basic type checker (assignments, functions, operations)],
|
||||||
|
[*4*], [Diagnostics, type check control flow, refine architecture, subtyping],
|
||||||
|
[*5*], [Generic types, methods and overloads, simple code generator],
|
||||||
|
[*6*], [For loops, generate assertions, generate stubs, constraints, variance, type unification],
|
||||||
|
[*7*], [],
|
||||||
|
[*8*], [],
|
||||||
|
[*9*], [],
|
||||||
|
)
|
||||||
117
assets/icon.svg
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:export-filename="logo.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.4.4 (1:1.4.4+202605061436+dcaf3e7d9e)"
|
||||||
|
sodipodi:docname="logo.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.9332778"
|
||||||
|
inkscape:cx="-8.2760999"
|
||||||
|
inkscape:cy="112.2446"
|
||||||
|
inkscape:window-width="2584"
|
||||||
|
inkscape:window-height="1028"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1">
|
||||||
|
<inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="px"
|
||||||
|
originx="0"
|
||||||
|
originy="0"
|
||||||
|
spacingx="4"
|
||||||
|
spacingy="4"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="4"
|
||||||
|
enabled="true"
|
||||||
|
visible="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4689"
|
||||||
|
id="linearGradient1478"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
|
||||||
|
x1="26.648937"
|
||||||
|
y1="20.603781"
|
||||||
|
x2="135.66525"
|
||||||
|
y2="114.39767" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4689">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e1be1e;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4691" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffeb82;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4693" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4671"
|
||||||
|
id="linearGradient1475"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
|
||||||
|
x1="150.96111"
|
||||||
|
y1="192.35176"
|
||||||
|
x2="112.03144"
|
||||||
|
y2="137.27299" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4671">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffdc21;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4673" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffeb82;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4675" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Calque 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
transform="translate(2.911719,3.414527)">
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient1478);fill-opacity:1"
|
||||||
|
d="m 60.510156,6.3979729 c -4.583653,0.021298 -8.960939,0.4122177 -12.8125,1.09375 C 36.35144,9.4962267 34.291407,13.691825 34.291406,21.429223 v 10.21875 h 26.8125 v 3.40625 h -26.8125 -10.0625 c -7.792459,0 -14.6157592,4.683717 -16.7500002,13.59375 -2.46182,10.212966 -2.5710151,16.586023 0,27.25 1.9059283,7.937852 6.4575432,13.593748 14.2500002,13.59375 h 9.21875 v -12.25 c 0,-8.849902 7.657144,-16.656248 16.75,-16.65625 h 26.78125 c 7.454951,0 13.406253,-6.138164 13.40625,-13.625 v -25.53125 c 0,-7.266339 -6.12998,-12.7247775 -13.40625,-13.9375001 -4.605987,-0.7667253 -9.385097,-1.1150483 -13.96875,-1.09375 z m -14.5,8.2187501 c 2.769547,0 5.03125,2.298646 5.03125,5.125 -2e-6,2.816336 -2.261703,5.09375 -5.03125,5.09375 -2.779476,-1e-6 -5.03125,-2.277415 -5.03125,-5.09375 -1e-6,-2.826353 2.251774,-5.125 5.03125,-5.125 z"
|
||||||
|
id="path1948" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient1475);fill-opacity:1"
|
||||||
|
d="m 91.228906,35.054223 v 11.90625 c 0,9.230755 -7.825895,16.999999 -16.75,17 h -26.78125 c -7.335833,0 -13.406249,6.278483 -13.40625,13.625 v 25.531247 c 0,7.26634 6.318588,11.54032 13.40625,13.625 8.487331,2.49561 16.626237,2.94663 26.78125,0 6.750155,-1.95439 13.406253,-5.88761 13.40625,-13.625 V 92.897973 h -26.78125 v -3.40625 h 26.78125 13.406254 c 7.79246,0 10.69625,-5.435408 13.40624,-13.59375 2.79933,-8.398886 2.68022,-16.475776 0,-27.25 -1.92578,-7.757441 -5.60387,-13.59375 -13.40624,-13.59375 z m -15.0625,64.65625 c 2.779478,3e-6 5.03125,2.277417 5.03125,5.093747 -2e-6,2.82635 -2.251775,5.125 -5.03125,5.125 -2.76955,0 -5.03125,-2.29865 -5.03125,-5.125 2e-6,-2.81633 2.261697,-5.093747 5.03125,-5.093747 z"
|
||||||
|
id="path1950" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.7 KiB |
262
design/calculus_rules.typ
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#import "@preview/curryst:0.6.0": rule, prooftree, rule-set
|
||||||
|
#import "@preview/codly:1.3.0": codly-init
|
||||||
|
|
||||||
|
#show: codly-init
|
||||||
|
|
||||||
|
#let syntax(body) = {
|
||||||
|
set text(weight: "bold", fill: rgb(100, 50, 0))
|
||||||
|
body
|
||||||
|
}
|
||||||
|
|
||||||
|
#let mk-box(title, body, ..args) = block(
|
||||||
|
inset: 1em,
|
||||||
|
stroke: black,
|
||||||
|
..args,
|
||||||
|
)[
|
||||||
|
=== #title
|
||||||
|
|
||||||
|
#body
|
||||||
|
]
|
||||||
|
|
||||||
|
#let blank(r, c) = grid.cell(
|
||||||
|
rowspan: r,
|
||||||
|
colspan: c
|
||||||
|
)[]
|
||||||
|
|
||||||
|
#let tab = sym.arrow.r.stop
|
||||||
|
#let nl = move(dx: -2pt, dy: 2pt, sym.arrow.curve.l)
|
||||||
|
#let syntax-preamble = doc => {
|
||||||
|
show tab: set text(fill: gray.darken(20%))
|
||||||
|
show sym.arrow.curve.l: set text(fill: gray.darken(20%))
|
||||||
|
set math.cases(gap: 4pt)
|
||||||
|
|
||||||
|
show math.equation: set align(left)
|
||||||
|
|
||||||
|
doc
|
||||||
|
}
|
||||||
|
|
||||||
|
#let python-syntax = mk-box(width: 100%)[Python Syntax][
|
||||||
|
#show: syntax-preamble
|
||||||
|
#grid(
|
||||||
|
columns: (auto, auto, 1fr, auto),
|
||||||
|
align: (left, left, left, right).map(a => a + horizon),
|
||||||
|
column-gutter: .4em,
|
||||||
|
row-gutter: 1.2em,
|
||||||
|
$"t"$, $::=$, none, [_terms_],
|
||||||
|
blank(11, 2),
|
||||||
|
$"x"$, [_variable_],
|
||||||
|
$"i"$, [_integer literal_],
|
||||||
|
$"f"$, [_float literal_],
|
||||||
|
$"z"$, [_string literal_],
|
||||||
|
$"True"$, [_constant true_],
|
||||||
|
$"False"$, [_constant false_],
|
||||||
|
$"None"$, [_constant none_],
|
||||||
|
$f("t")$, [_call_],
|
||||||
|
$"t"_21 #syntax[if] "t"_1 #syntax[else] "t"_22$, [_ternary_],
|
||||||
|
$"t"_1 "op" "t"_2$, [_operation_],
|
||||||
|
$"s"; "t"$, [_sequence_],
|
||||||
|
grid.cell(colspan: 4)[],
|
||||||
|
|
||||||
|
$"v"$, $::=$, none, [_values_],
|
||||||
|
blank(6, 2),
|
||||||
|
$"i"$, [_integer literal_],
|
||||||
|
$"f"$, [_float literal_],
|
||||||
|
$"z"$, [_string literal_],
|
||||||
|
$"True"$, [_constant true_],
|
||||||
|
$"False"$, [_constant false_],
|
||||||
|
$"None"$, [_constant none_],
|
||||||
|
grid.cell(colspan: 4)[],
|
||||||
|
|
||||||
|
$"s"$, $::=$, none, [_statements_],
|
||||||
|
blank(4, 2),
|
||||||
|
$"x" = "t"$, [_assignment_],
|
||||||
|
$"x": "T"$, [_variable declaration_],
|
||||||
|
$ cases(
|
||||||
|
#syntax[def] f("x": "T") -> "T": #nl,
|
||||||
|
#tab "t" #nl,
|
||||||
|
delim: "["
|
||||||
|
) $, [_def_],
|
||||||
|
$ cases(
|
||||||
|
#syntax[if] "t": #nl,
|
||||||
|
tab "s" #nl,
|
||||||
|
#syntax[else]: #nl,
|
||||||
|
tab "s" #nl,
|
||||||
|
delim: "["
|
||||||
|
) $, [_if / else_],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
#let midas-syntax = mk-box(width: 100%)[Midas Syntax][
|
||||||
|
#show: syntax-preamble
|
||||||
|
#grid(
|
||||||
|
columns: (auto, auto, 1fr, auto),
|
||||||
|
align: (left, left, left, right).map(a => a + horizon),
|
||||||
|
column-gutter: .4em,
|
||||||
|
row-gutter: 1.2em,
|
||||||
|
$"T"$, $::=$, none, [_types_],
|
||||||
|
blank(5, 2),
|
||||||
|
$"X"$, [_named type_],
|
||||||
|
$"T" ["T"]$, [_type application_],
|
||||||
|
$"T" #syntax[where] "c"$, [_constraint type_],
|
||||||
|
${attach("p"_i: "T"_i, tr: i in 1..n)}$, [_complex type_],
|
||||||
|
$(attach("a"_i: "T"_i, tr: i in 1..n)) -> "T"$, [_function type_],
|
||||||
|
grid.cell(colspan: 4)[],
|
||||||
|
|
||||||
|
$"s"$, $::=$, none, [_statements_],
|
||||||
|
blank(2, 2),
|
||||||
|
$#syntax[type] "X" = "T"$, [_type definition_],
|
||||||
|
$#syntax[type] "X"["Y"] = "T"$, [_generic definition_],
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
#grid(
|
||||||
|
columns: (1fr, 1fr),
|
||||||
|
column-gutter: 1em,
|
||||||
|
python-syntax,
|
||||||
|
midas-syntax
|
||||||
|
)
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
#let abs-typ-rules = (
|
||||||
|
int: rule($Gamma tack "i": "Int"$, name: [(T-Int)]),
|
||||||
|
float: rule($Gamma tack "f": "Float"$, name: [(T-Float)]),
|
||||||
|
str: rule($Gamma tack "z": "Str"$, name: [(T-Str)]),
|
||||||
|
"true": rule($Gamma tack "True": "Bool"$, name: [(T-True)]),
|
||||||
|
"false": rule($Gamma tack "False": "Bool"$, name: [(T-False)]),
|
||||||
|
"none": rule($Gamma tack "None": "None"$, name: [(T-None)]),
|
||||||
|
var: rule(
|
||||||
|
$"x": "T" in Gamma$,
|
||||||
|
$Gamma tack "x": "T"$,
|
||||||
|
name: [(T-Var)]
|
||||||
|
),
|
||||||
|
def: rule(
|
||||||
|
$Gamma, f: "T"_1 -> "T"_2, "x": "T"_1 tack "t": "T"_2$,
|
||||||
|
$Gamma tack #syntax[def] f("x": "T"_1) -> "T"_2: "t" space tack.l space Gamma, f: "T"_1 -> "T"_2 $,
|
||||||
|
name: [(T-Def)]
|
||||||
|
),
|
||||||
|
call: rule(
|
||||||
|
$Gamma tack f: "T"_1 -> "T"_2$,
|
||||||
|
$Gamma tack "t": "T"_1$,
|
||||||
|
$Gamma tack f("t"): "T"_2$,
|
||||||
|
name: [(T-Call)]
|
||||||
|
),
|
||||||
|
ternary: rule(
|
||||||
|
$Gamma tack "t"_1: "Bool"$,
|
||||||
|
$Gamma tack "t"_21: "T"$,
|
||||||
|
$Gamma tack "t"_22: "T"$,
|
||||||
|
$Gamma tack "t"_21 #syntax[if] "t"_1 #syntax[else] "t"_22: "T"$,
|
||||||
|
name: [(T-Tern)]
|
||||||
|
),
|
||||||
|
op: rule(
|
||||||
|
$Gamma tack "t"_1: "T"_1$,
|
||||||
|
$Gamma tack "t"_2: "T"_2$,
|
||||||
|
$"op": "T"_1 -> "T"_2 -> "T"_3 in Gamma$,
|
||||||
|
$Gamma tack "t"_1 "op" "t"_2: "T"_3$,
|
||||||
|
name: [(T-Op)]
|
||||||
|
),
|
||||||
|
seq: rule(
|
||||||
|
$Gamma tack "s" tack.l Gamma'$,
|
||||||
|
$Gamma' tack "t": "T"$,
|
||||||
|
$Gamma tack "s"; "t": "T"$,
|
||||||
|
name: [(T-Seq)]
|
||||||
|
),
|
||||||
|
annot: rule(
|
||||||
|
$Gamma tack "x": "T" tack.l Gamma, "x": "T"$,
|
||||||
|
name: [(T-Annot)]
|
||||||
|
),
|
||||||
|
if-else: rule(
|
||||||
|
$Gamma tack "t": "Bool"$,
|
||||||
|
$Gamma tack "s"_1 tack.l Gamma'$,
|
||||||
|
$Gamma tack "s"_2 tack.l Gamma''$,
|
||||||
|
$Gamma tack #syntax[if] "t": "s"_1 #syntax[else]: "s"_2 tack.l Gamma$,
|
||||||
|
name: [(T-IfElse)]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let py-typ-rules = (
|
||||||
|
int: ```py 12: int```,
|
||||||
|
float: ```py 12.34: float```,
|
||||||
|
str: ```py "foo": str```,
|
||||||
|
"true": ```py True: bool```,
|
||||||
|
"false": ```py False: bool```,
|
||||||
|
"none": ```py None: None```,
|
||||||
|
var: ```py x```,
|
||||||
|
def: ```py
|
||||||
|
def func(a: S) -> T:
|
||||||
|
return ...: T
|
||||||
|
```,
|
||||||
|
call: ```py
|
||||||
|
def func(a: S) -> T: ...
|
||||||
|
...
|
||||||
|
func(a: S): T
|
||||||
|
```,
|
||||||
|
ternary: ```py (true if cond else false): T ```,
|
||||||
|
op: ```py (a + b): T```,
|
||||||
|
annot: ```py x: T```,
|
||||||
|
if-else: ```py
|
||||||
|
if cond:
|
||||||
|
...
|
||||||
|
else:
|
||||||
|
...
|
||||||
|
```,
|
||||||
|
)
|
||||||
|
|
||||||
|
#let reading-keys = (
|
||||||
|
def: [
|
||||||
|
_Gamma_ judges that $#syntax[def] f("x": "T"_1) -> "T"_2: "t"$ adds $f: "T"_1 -> "T"_2$ to the context, iff by adding $f: "T"_1 -> "T"_2$ and $"x": "T"_1$ to _Gamma_, it can judge that $"t": "T"_2$
|
||||||
|
],
|
||||||
|
annot: [
|
||||||
|
_Gamma_ judges that $"x": "T"$ adds $"x": "T"$ to the context
|
||||||
|
],
|
||||||
|
if-else: [
|
||||||
|
_Gamma_ judges that $#syntax[if] "t": "s"_1 #syntax[else]: "s"_2$ produces an the unchanged context $Gamma'$, iff _Gamma_ judges that $"t": "Bool"$, that $"s"_1$ produces the context $Gamma'$, and $"s"_2$ produces the context $Gamma''$. This means that statements in
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
#mk-box[Python Typing][
|
||||||
|
#v(1em)
|
||||||
|
#stack(dir: ltr, spacing: 1fr)[_*Rule*_][_*Python example*_]
|
||||||
|
|
||||||
|
#for (i, (k, abs-rule)) in abs-typ-rules.pairs().enumerate() {
|
||||||
|
let py-rule = py-typ-rules.at(k, default: none)
|
||||||
|
let reading-key = reading-keys.at(k, default: none)
|
||||||
|
let cells = (
|
||||||
|
prooftree(abs-rule),
|
||||||
|
py-rule
|
||||||
|
)
|
||||||
|
if reading-key != none {
|
||||||
|
cells.push(
|
||||||
|
grid.cell(
|
||||||
|
colspan: 2,
|
||||||
|
inset: (x: .8em, y: .4em),
|
||||||
|
stroke: (left: gray.lighten(50%) + 2pt),
|
||||||
|
)[
|
||||||
|
#set text(size: .8em)
|
||||||
|
#show math.equation: box.with(
|
||||||
|
fill: red.lighten(90%),
|
||||||
|
outset: (y: .3em, x: 1pt),
|
||||||
|
)
|
||||||
|
*Reading key*:\
|
||||||
|
#reading-key
|
||||||
|
]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
box(
|
||||||
|
fill: if calc.even(i) {gray.lighten(95%)} else {},
|
||||||
|
outset: (x: .5em),
|
||||||
|
inset: (y: .5em),
|
||||||
|
align(
|
||||||
|
horizon,
|
||||||
|
grid(
|
||||||
|
columns: (auto, 1fr),
|
||||||
|
column-gutter: 1em,
|
||||||
|
row-gutter: .5em,
|
||||||
|
align: (left + horizon, right + horizon),
|
||||||
|
..cells,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
]
|
||||||
4000
halfway-presentation/hei.svg
Normal file
|
After Width: | Height: | Size: 130 KiB |
117
halfway-presentation/langs.typ
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#let translations = (
|
||||||
|
fr: (
|
||||||
|
_date-fmt: "[day] $month [year repr:full]",
|
||||||
|
title: "Midas: mieux typer Python",
|
||||||
|
subtitle: "Présentation intermédiaire",
|
||||||
|
short-title: "Midas",
|
||||||
|
supervisor: "Superviseure",
|
||||||
|
"context": "Contexte",
|
||||||
|
problematic: "Problématique",
|
||||||
|
case-1: [Cas 1 -- Type != sémantique],
|
||||||
|
case-2: [Cas 2 -- Erreur de type _at runtime_],
|
||||||
|
goal: "Objectif",
|
||||||
|
gradual-typing: [Typage graduel (_gradual typing_)],
|
||||||
|
optional-typing: "Typage optionnel",
|
||||||
|
static-type-checking: "Vérification statique",
|
||||||
|
dynamic-checks: "Vérificiations dynamiques",
|
||||||
|
runtime-assertions: [Assertions _at runtime_],
|
||||||
|
value-constraints: "Contraintes de valeur",
|
||||||
|
example: "Exemple",
|
||||||
|
lat-lon-error: "Invalide, même si float+float est valide",
|
||||||
|
planning: "Planification",
|
||||||
|
initial-planning: "Planification initiale",
|
||||||
|
week: "Semaine",
|
||||||
|
objectives: "Objectifs",
|
||||||
|
initial-week1: "Kickoff, setup projet, début de prototype de syntaxe",
|
||||||
|
initial-week2: [Prototype de syntaxe, _parser_ simple],
|
||||||
|
initial-week3-6: [Implémentation d'un _type checker_],
|
||||||
|
initial-week7-9: "Générateur de code, améliorations, rapport",
|
||||||
|
current-status: "État actuel",
|
||||||
|
current-week1: "Kickoff, setup projet, début de prototype de syntaxe",
|
||||||
|
current-week2: [Prototype de syntaxe, _parser_ simple],
|
||||||
|
current-week3: [_Type checker_ basique(assign., fonctions, opérations)],
|
||||||
|
current-week4: [Diagnostiques, _control flow_, améliorer l'architecture],
|
||||||
|
current-week5: "Types génériques, sous-typage",
|
||||||
|
current-week6: "Contraintes",
|
||||||
|
current-week7-9: "Générateur de code, améliorations, rapport",
|
||||||
|
demo: "Démo",
|
||||||
|
def-custom-types: "Définition de types",
|
||||||
|
write-program: "Écrire un programme",
|
||||||
|
valid: "Valide",
|
||||||
|
invalid: "Invalide",
|
||||||
|
),
|
||||||
|
en: (
|
||||||
|
_date-fmt: "$month [day], [year repr:full]",
|
||||||
|
title: "Midas: better type checking in Python",
|
||||||
|
subtitle: "Halfway presentation",
|
||||||
|
short-title: "Midas",
|
||||||
|
supervisor: "Supervisor",
|
||||||
|
"context": "Context",
|
||||||
|
problematic: "Problematic",
|
||||||
|
case-1: [Case 1 -- Type != semantic],
|
||||||
|
case-2: [Case 2 -- Runtime type error],
|
||||||
|
goal: "Goal",
|
||||||
|
gradual-typing: "Gradual typing",
|
||||||
|
optional-typing: "Optional typing",
|
||||||
|
static-type-checking: "Static type checking",
|
||||||
|
dynamic-checks: "Dynamic checks",
|
||||||
|
runtime-assertions: "Runtime assertions",
|
||||||
|
value-constraints: "Value constraints",
|
||||||
|
example: "Example",
|
||||||
|
lat-lon-error: "Invalid, even though float+float is valid",
|
||||||
|
planning: "Planning",
|
||||||
|
initial-planning: "Initial planning",
|
||||||
|
week: "Week",
|
||||||
|
objectives: "Objectives",
|
||||||
|
initial-week1: "Kickoff, setup project, start prototyping a syntax",
|
||||||
|
initial-week2: "Syntax prototype, simple parser",
|
||||||
|
initial-week3-6: "Implement a type checker",
|
||||||
|
initial-week7-9: "Code generator, refinements, report",
|
||||||
|
current-status: "Current status",
|
||||||
|
current-week1: "Kickoff, setup project, start prototyping a syntax",
|
||||||
|
current-week2: "Syntax prototype, simple parser",
|
||||||
|
current-week3: "Basic type checker (assignments, functions, operations)",
|
||||||
|
current-week4: "Diagnostics, type check control flow, refine architecture",
|
||||||
|
current-week5: "Generic types, subtyping",
|
||||||
|
current-week6: "Constraints",
|
||||||
|
current-week7-9: "Code generator, refinements, report",
|
||||||
|
demo: "Demo",
|
||||||
|
def-custom-types: "Defining custom types",
|
||||||
|
write-program: "Writing a program",
|
||||||
|
valid: "Valid",
|
||||||
|
invalid: "Invalid",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let months = (
|
||||||
|
fr: (
|
||||||
|
"Janvier", "Février", "Mars", "Avril",
|
||||||
|
"Mai", "Juin", "Juillet", "Août",
|
||||||
|
"Septembre", "Octobre", "Novembre", "Décembre"
|
||||||
|
),
|
||||||
|
en: (
|
||||||
|
"January", "February", "March", "April",
|
||||||
|
"May", "June", "July", "August",
|
||||||
|
"September", "October", "November", "December"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let i18n(lang, key) = {
|
||||||
|
let dict = translations.at(lang, default: (:))
|
||||||
|
return dict.at(
|
||||||
|
key,
|
||||||
|
default: "[" + lang + ":" + key + "]"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let i18n-date(lang, date) = {
|
||||||
|
let month = date.month() - 1
|
||||||
|
let month-name = months.at(lang, default: ()).at(
|
||||||
|
month,
|
||||||
|
default: "[" + lang + ":month[" + str(month) + "]]"
|
||||||
|
)
|
||||||
|
|
||||||
|
let fmt = i18n(lang, "_date-fmt").replace("$month", month-name)
|
||||||
|
|
||||||
|
return date.display(fmt)
|
||||||
|
}
|
||||||
988
halfway-presentation/logo_black.svg
Normal file
@@ -0,0 +1,988 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="482.222" height="84.6667" viewBox="0 0 482.222 84.6667">
|
||||||
|
<defs>
|
||||||
|
<g>
|
||||||
|
<g id="glyph-0-0">
|
||||||
|
<path d="M 6.6875 0 L 1.8125 0 L 1.8125 -18.765625 L 6.6875 -18.765625 Z M 6.6875 0 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-1">
|
||||||
|
<path d="M 5.96875 -13.640625 L 5.96875 -12.375 C 6.28125 -12.84375 6.796875 -13.21875 7.515625 -13.5 C 8.234375 -13.78125 8.976562 -13.921875 9.75 -13.921875 C 11.613281 -13.921875 12.992188 -13.394531 13.890625 -12.34375 C 14.785156 -11.300781 15.234375 -9.847656 15.234375 -7.984375 L 15.234375 0 L 10.53125 0 L 10.53125 -6.890625 C 10.53125 -7.972656 10.359375 -8.742188 10.015625 -9.203125 C 9.679688 -9.660156 9.066406 -9.890625 8.171875 -9.890625 C 7.503906 -9.890625 6.863281 -9.71875 6.25 -9.375 L 6.25 0 L 1.546875 0 L 1.546875 -13.640625 Z M 5.96875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-2">
|
||||||
|
<path d="M 2.796875 -13.640625 L 2.796875 -14.28125 C 2.796875 -16 3.335938 -17.3125 4.421875 -18.21875 C 5.503906 -19.132812 6.894531 -19.59375 8.59375 -19.59375 C 9.5625 -19.59375 10.410156 -19.519531 11.140625 -19.375 L 11.140625 -15.453125 C 10.640625 -15.546875 10.164062 -15.59375 9.71875 -15.59375 C 8.238281 -15.59375 7.5 -14.941406 7.5 -13.640625 L 11.140625 -13.640625 L 11.140625 -9.859375 L 7.5 -9.859375 L 7.5 0 L 2.796875 0 L 2.796875 -9.859375 L 0.84375 -9.859375 L 0.84375 -13.640625 Z M 2.796875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-3">
|
||||||
|
<path d="M 0.984375 -6.828125 C 0.984375 -8.847656 1.710938 -10.535156 3.171875 -11.890625 C 4.640625 -13.242188 6.457031 -13.921875 8.625 -13.921875 C 10.789062 -13.921875 12.613281 -13.242188 14.09375 -11.890625 C 15.582031 -10.535156 16.328125 -8.847656 16.328125 -6.828125 C 16.328125 -4.816406 15.585938 -3.128906 14.109375 -1.765625 C 12.617188 -0.398438 10.789062 0.28125 8.625 0.28125 C 6.457031 0.28125 4.640625 -0.398438 3.171875 -1.765625 C 1.710938 -3.128906 0.984375 -4.816406 0.984375 -6.828125 Z M 6.53125 -4.640625 C 7.050781 -4.066406 7.75 -3.78125 8.625 -3.78125 C 9.5 -3.78125 10.207031 -4.0625 10.75 -4.625 C 11.289062 -5.195312 11.5625 -5.929688 11.5625 -6.828125 C 11.5625 -7.703125 11.289062 -8.429688 10.75 -9.015625 C 10.207031 -9.597656 9.5 -9.890625 8.625 -9.890625 C 7.769531 -9.890625 7.070312 -9.597656 6.53125 -9.015625 C 6 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6 -5.203125 6.53125 -4.640625 Z M 6.53125 -4.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-4">
|
||||||
|
<path d="M 1.546875 -13.640625 L 5.96875 -13.640625 L 5.96875 -12.234375 C 6.25 -12.734375 6.6875 -13.113281 7.28125 -13.375 C 7.875 -13.644531 8.507812 -13.78125 9.1875 -13.78125 C 9.65625 -13.78125 10.140625 -13.722656 10.640625 -13.609375 L 10.640625 -9.375 C 10.046875 -9.4375 9.457031 -9.46875 8.875 -9.46875 C 7.8125 -9.46875 6.9375 -9.328125 6.25 -9.046875 L 6.25 0 L 1.546875 0 Z M 1.546875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-5">
|
||||||
|
<path d="M 5.96875 -13.640625 L 5.96875 -12.375 C 6.28125 -12.84375 6.796875 -13.21875 7.515625 -13.5 C 8.234375 -13.78125 8.976562 -13.921875 9.75 -13.921875 C 11.707031 -13.921875 13.148438 -13.320312 14.078125 -12.125 C 14.421875 -12.644531 14.988281 -13.070312 15.78125 -13.40625 C 16.570312 -13.75 17.367188 -13.921875 18.171875 -13.921875 C 20.078125 -13.921875 21.5625 -13.382812 22.625 -12.3125 C 23.6875 -11.25 24.21875 -9.804688 24.21875 -7.984375 L 24.21875 0 L 19.515625 0 L 19.515625 -6.890625 C 19.515625 -7.972656 19.347656 -8.742188 19.015625 -9.203125 C 18.679688 -9.660156 18.066406 -9.890625 17.171875 -9.890625 C 16.472656 -9.890625 15.796875 -9.710938 15.140625 -9.359375 C 15.203125 -8.921875 15.234375 -8.460938 15.234375 -7.984375 L 15.234375 0 L 10.53125 0 L 10.53125 -6.890625 C 10.53125 -7.972656 10.359375 -8.742188 10.015625 -9.203125 C 9.679688 -9.660156 9.066406 -9.890625 8.171875 -9.890625 C 7.503906 -9.890625 6.863281 -9.71875 6.25 -9.375 L 6.25 0 L 1.546875 0 L 1.546875 -13.640625 Z M 5.96875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-6">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.410156 -13.921875 10.625 -13.472656 11.3125 -12.578125 L 11.3125 -13.640625 L 15.734375 -13.640625 L 15.734375 0 L 11.3125 0 L 11.3125 -1.0625 C 10.601562 -0.164062 9.390625 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.847656 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.457031 -3.75 10.269531 -3.992188 11.09375 -4.484375 L 11.09375 -9.1875 C 10.34375 -9.65625 9.53125 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-7">
|
||||||
|
<path d="M 2.796875 -13.640625 L 2.796875 -17.046875 L 7.5 -17.046875 L 7.5 -13.640625 L 11.140625 -13.640625 L 11.140625 -9.859375 L 7.5 -9.859375 L 7.5 -6.078125 C 7.5 -5.273438 7.6875 -4.703125 8.0625 -4.359375 C 8.4375 -4.023438 8.988281 -3.859375 9.71875 -3.859375 C 10.164062 -3.859375 10.640625 -3.90625 11.140625 -4 L 11.140625 -0.078125 C 10.410156 0.0664062 9.5625 0.140625 8.59375 0.140625 C 6.851562 0.140625 5.453125 -0.273438 4.390625 -1.109375 C 3.328125 -1.941406 2.796875 -3.207031 2.796875 -4.90625 L 2.796875 -9.859375 L 0.84375 -9.859375 L 0.84375 -13.640625 Z M 2.796875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-8">
|
||||||
|
<path d="M 1.546875 0 L 1.546875 -13.640625 L 6.25 -13.640625 L 6.25 0 Z M 1.203125 -17.78125 C 1.203125 -18.488281 1.460938 -19.097656 1.984375 -19.609375 C 2.503906 -20.128906 3.140625 -20.390625 3.890625 -20.390625 C 4.640625 -20.390625 5.273438 -20.128906 5.796875 -19.609375 C 6.316406 -19.097656 6.578125 -18.488281 6.578125 -17.78125 C 6.578125 -17.070312 6.316406 -16.460938 5.796875 -15.953125 C 5.273438 -15.429688 4.640625 -15.171875 3.890625 -15.171875 C 3.140625 -15.171875 2.503906 -15.425781 1.984375 -15.9375 C 1.460938 -16.457031 1.203125 -17.070312 1.203125 -17.78125 Z M 1.203125 -17.78125 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-9">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.390625 -13.921875 10.601562 -13.472656 11.3125 -12.578125 L 11.3125 -13.640625 L 15.734375 -13.640625 L 15.734375 5.59375 L 11.03125 5.59375 L 11.03125 -0.75 C 10.25 -0.0625 9.128906 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.785156 0.984375 -6.796875 C 0.984375 -8.835938 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.53125 -3.75 10.34375 -3.984375 11.09375 -4.453125 L 11.09375 -9.15625 C 10.269531 -9.644531 9.457031 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.691406 5.734375 -6.796875 C 5.734375 -5.921875 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-10">
|
||||||
|
<path d="M 1.40625 -13.640625 L 6.109375 -13.640625 L 6.109375 -6.1875 C 6.109375 -5.382812 6.28125 -4.773438 6.625 -4.359375 C 6.96875 -3.953125 7.578125 -3.75 8.453125 -3.75 C 9.109375 -3.75 9.71875 -3.898438 10.28125 -4.203125 L 10.28125 -13.640625 L 14.984375 -13.640625 L 14.984375 0 L 10.578125 0 L 10.578125 -1.140625 C 10.242188 -0.710938 9.722656 -0.367188 9.015625 -0.109375 C 8.304688 0.148438 7.597656 0.28125 6.890625 0.28125 C 5.023438 0.28125 3.644531 -0.238281 2.75 -1.28125 C 1.851562 -2.332031 1.40625 -3.789062 1.40625 -5.65625 Z M 1.40625 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-11">
|
||||||
|
<path d="M 15.625 -6.796875 C 15.625 -6.347656 15.597656 -5.898438 15.546875 -5.453125 L 5.59375 -5.453125 C 6.175781 -4.191406 7.53125 -3.5625 9.65625 -3.5625 C 11.132812 -3.5625 12.609375 -3.820312 14.078125 -4.34375 L 14.078125 -0.59375 C 12.703125 -0.0078125 11.085938 0.28125 9.234375 0.28125 C 6.703125 0.28125 4.691406 -0.359375 3.203125 -1.640625 C 1.722656 -2.929688 0.984375 -4.660156 0.984375 -6.828125 C 0.984375 -8.867188 1.675781 -10.5625 3.0625 -11.90625 C 4.457031 -13.25 6.207031 -13.921875 8.3125 -13.921875 C 10.425781 -13.921875 12.171875 -13.25 13.546875 -11.90625 C 14.929688 -10.5625 15.625 -8.859375 15.625 -6.796875 Z M 8.3125 -10.109375 C 6.875 -10.109375 5.941406 -9.472656 5.515625 -8.203125 L 11.03125 -8.203125 C 10.625 -9.472656 9.71875 -10.109375 8.3125 -10.109375 Z M 8.3125 -10.109375 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-12">
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-13">
|
||||||
|
<path d="M 2.4375 -12.65625 C 3.40625 -13.5 4.75 -13.921875 6.46875 -13.921875 C 8.28125 -13.921875 9.894531 -13.65625 11.3125 -13.125 L 11.3125 -9.484375 C 9.632812 -10.015625 8.046875 -10.28125 6.546875 -10.28125 C 5.671875 -10.28125 5.234375 -10.070312 5.234375 -9.65625 C 5.234375 -9.46875 5.34375 -9.320312 5.5625 -9.21875 C 5.789062 -9.125 6.203125 -9.007812 6.796875 -8.875 L 7.984375 -8.625 C 9.472656 -8.300781 10.5625 -7.816406 11.25 -7.171875 C 11.945312 -6.535156 12.296875 -5.617188 12.296875 -4.421875 C 12.296875 -3.023438 11.769531 -1.890625 10.71875 -1.015625 C 9.675781 -0.148438 8.164062 0.28125 6.1875 0.28125 C 4.4375 0.28125 2.820312 -0.0234375 1.34375 -0.640625 L 1.34375 -4.484375 C 3.039062 -3.773438 4.722656 -3.421875 6.390625 -3.421875 C 7.472656 -3.421875 8.015625 -3.660156 8.015625 -4.140625 C 8.015625 -4.347656 7.910156 -4.503906 7.703125 -4.609375 C 7.492188 -4.710938 7.09375 -4.816406 6.5 -4.921875 L 5.1875 -5.203125 C 2.382812 -5.804688 0.984375 -7.191406 0.984375 -9.359375 C 0.984375 -10.710938 1.46875 -11.8125 2.4375 -12.65625 Z M 2.4375 -12.65625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-14">
|
||||||
|
<path d="M 0.140625 -13.640625 L 5.234375 -13.640625 L 8.203125 -6.828125 L 11.203125 -13.640625 L 16.21875 -13.640625 L 7.03125 5.59375 L 2.078125 5.59375 L 5.796875 -1.875 Z M 0.140625 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-15">
|
||||||
|
<path d="M 9.21875 -19.40625 L 10.046875 -15.171875 L 6.546875 -15.171875 L 4.3125 -19.40625 Z M 15.625 -6.796875 C 15.625 -6.347656 15.597656 -5.898438 15.546875 -5.453125 L 5.59375 -5.453125 C 6.175781 -4.191406 7.53125 -3.5625 9.65625 -3.5625 C 11.132812 -3.5625 12.609375 -3.820312 14.078125 -4.34375 L 14.078125 -0.59375 C 12.703125 -0.0078125 11.085938 0.28125 9.234375 0.28125 C 6.703125 0.28125 4.691406 -0.359375 3.203125 -1.640625 C 1.722656 -2.929688 0.984375 -4.660156 0.984375 -6.828125 C 0.984375 -8.867188 1.675781 -10.5625 3.0625 -11.90625 C 4.457031 -13.25 6.207031 -13.921875 8.3125 -13.921875 C 10.425781 -13.921875 12.171875 -13.25 13.546875 -11.90625 C 14.929688 -10.5625 15.625 -8.859375 15.625 -6.796875 Z M 8.3125 -10.109375 C 6.875 -10.109375 5.941406 -9.472656 5.515625 -8.203125 L 11.03125 -8.203125 C 10.625 -9.472656 9.71875 -10.109375 8.3125 -10.109375 Z M 8.3125 -10.109375 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-16">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.128906 -13.921875 10.25 -13.570312 11.03125 -12.875 L 11.03125 -19.3125 L 15.734375 -19.3125 L 15.734375 0 L 11.375 0 L 11.375 -1.140625 C 10.65625 -0.191406 9.421875 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.847656 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.457031 -3.75 10.269531 -3.992188 11.09375 -4.484375 L 11.09375 -9.1875 C 10.34375 -9.65625 9.53125 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-17">
|
||||||
|
<path d="M 3.140625 -11.90625 C 4.578125 -13.25 6.40625 -13.921875 8.625 -13.921875 C 10.28125 -13.921875 11.800781 -13.65625 13.1875 -13.125 L 13.1875 -9.046875 C 11.882812 -9.609375 10.644531 -9.890625 9.46875 -9.890625 C 8.269531 -9.890625 7.347656 -9.601562 6.703125 -9.03125 C 6.054688 -8.457031 5.734375 -7.722656 5.734375 -6.828125 C 5.734375 -5.910156 6.054688 -5.171875 6.703125 -4.609375 C 7.347656 -4.054688 8.269531 -3.78125 9.46875 -3.78125 C 10.582031 -3.78125 11.820312 -4.0625 13.1875 -4.625 L 13.1875 -0.5 C 11.800781 0.0195312 10.28125 0.28125 8.625 0.28125 C 6.40625 0.28125 4.578125 -0.394531 3.140625 -1.75 C 1.703125 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.867188 1.703125 -10.5625 3.140625 -11.90625 Z M 3.140625 -11.90625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-18">
|
||||||
|
<path d="M 1.546875 -13.25 C 1.546875 -15.050781 2.179688 -16.488281 3.453125 -17.5625 C 4.734375 -18.644531 6.398438 -19.1875 8.453125 -19.1875 C 10.660156 -19.1875 12.734375 -18.8125 14.671875 -18.0625 L 14.671875 -13.78125 C 12.578125 -14.613281 10.609375 -15.03125 8.765625 -15.03125 C 7.117188 -15.03125 6.296875 -14.582031 6.296875 -13.6875 C 6.296875 -13.238281 6.484375 -12.90625 6.859375 -12.6875 C 7.234375 -12.476562 7.882812 -12.234375 8.8125 -11.953125 L 10.1875 -11.5625 C 12 -11.0625 13.367188 -10.351562 14.296875 -9.4375 C 15.234375 -8.519531 15.703125 -7.332031 15.703125 -5.875 C 15.703125 -3.882812 15.007812 -2.335938 13.625 -1.234375 C 12.25 -0.128906 10.378906 0.421875 8.015625 0.421875 C 5.941406 0.421875 3.929688 0.046875 1.984375 -0.703125 L 1.984375 -5.046875 C 4.097656 -4.203125 6.097656 -3.78125 7.984375 -3.78125 C 8.953125 -3.78125 9.6875 -3.925781 10.1875 -4.21875 C 10.695312 -4.519531 10.953125 -4.929688 10.953125 -5.453125 C 10.953125 -5.941406 10.78125 -6.285156 10.4375 -6.484375 C 10.101562 -6.691406 9.441406 -6.929688 8.453125 -7.203125 L 6.9375 -7.609375 C 3.34375 -8.617188 1.546875 -10.5 1.546875 -13.25 Z M 1.546875 -13.25 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-19">
|
||||||
|
<path d="M 3.953125 -16.375 C 5.847656 -18.25 8.367188 -19.1875 11.515625 -19.1875 C 13.878906 -19.1875 15.976562 -18.820312 17.8125 -18.09375 L 17.8125 -13.5 C 15.945312 -14.238281 14.03125 -14.609375 12.0625 -14.609375 C 10.195312 -14.609375 8.738281 -14.125 7.6875 -13.15625 C 6.644531 -12.1875 6.125 -10.925781 6.125 -9.375 C 6.125 -7.832031 6.644531 -6.570312 7.6875 -5.59375 C 8.738281 -4.625 10.195312 -4.140625 12.0625 -4.140625 C 14.03125 -4.140625 15.945312 -4.515625 17.8125 -5.265625 L 17.8125 -0.671875 C 15.976562 0.0546875 13.878906 0.421875 11.515625 0.421875 C 8.367188 0.421875 5.84375 -0.515625 3.9375 -2.390625 C 2.039062 -4.265625 1.09375 -6.59375 1.09375 -9.375 C 1.09375 -12.15625 2.046875 -14.488281 3.953125 -16.375 Z M 3.953125 -16.375 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<clipPath id="clip-0">
|
||||||
|
<path clip-rule="nonzero" d="M 2 44 L 80 44 L 80 81 L 2 81 Z M 2 44 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-1">
|
||||||
|
<path clip-rule="nonzero" d="M 20.523438 44.191406 C 10.375 44.191406 2.144531 52.421875 2.144531 62.570312 C 2.144531 72.71875 10.375 80.949219 20.523438 80.949219 L 60.722656 80.949219 C 70.871094 80.949219 79.097656 72.71875 79.097656 62.570312 C 79.097656 52.421875 70.871094 44.191406 60.722656 44.191406 Z M 20.523438 44.191406 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-0" gradientUnits="userSpaceOnUse" x1="0.00000772817" y1="0" x2="1.000005" y2="0" gradientTransform="matrix(-76.952225, 0, 0, -76.952225, 79.098595, 62.570047)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(100%, 100%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(100%, 100%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(100%, 100%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(100%, 99.607849%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(100%, 99.607849%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 99.607849%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(100%, 99.607849%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(100%, 99.607849%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(100%, 99.607849%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 99.607849%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(100%, 99.607849%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(100%, 99.215698%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117187" stop-color="rgb(100%, 99.215698%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(99.607849%, 99.215698%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(99.607849%, 99.215698%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(99.607849%, 99.215698%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(99.607849%, 99.215698%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(99.607849%, 99.215698%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(99.607849%, 99.215698%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(99.607849%, 98.823547%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(99.607849%, 98.823547%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(99.607849%, 98.823547%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(99.607849%, 98.823547%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(99.607849%, 98.823547%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(99.607849%, 98.823547%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(99.607849%, 98.823547%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(99.607849%, 98.823547%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(99.607849%, 98.431396%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(99.607849%, 98.431396%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(99.607849%, 98.431396%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(99.607849%, 98.431396%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(99.607849%, 98.431396%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(99.607849%, 98.431396%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(99.607849%, 98.431396%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(99.607849%, 98.431396%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(99.607849%, 98.431396%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304688" stop-color="rgb(99.607849%, 98.431396%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(99.607849%, 98.431396%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(99.607849%, 98.039246%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(99.607849%, 98.039246%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335938" stop-color="rgb(99.215698%, 98.039246%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(99.215698%, 98.039246%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(99.215698%, 98.039246%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(99.215698%, 98.039246%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(99.215698%, 98.039246%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(99.215698%, 98.039246%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(99.215698%, 97.647095%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(99.215698%, 97.647095%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(99.215698%, 97.647095%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(99.215698%, 97.647095%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(99.215698%, 97.647095%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(99.215698%, 97.647095%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(99.215698%, 97.647095%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(99.215698%, 97.647095%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(99.215698%, 97.254944%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(99.215698%, 97.254944%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(99.215698%, 97.254944%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(99.215698%, 97.254944%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(99.215698%, 97.254944%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(99.215698%, 97.254944%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(98.823547%, 97.254944%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(98.823547%, 97.254944%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(98.823547%, 96.862793%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(98.823547%, 96.862793%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(98.823547%, 96.862793%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(98.823547%, 96.862793%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(98.823547%, 96.862793%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(98.823547%, 96.862793%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554688" stop-color="rgb(98.823547%, 96.862793%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(98.823547%, 96.862793%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(98.823547%, 96.862793%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(98.823547%, 96.862793%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(98.823547%, 96.470642%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(98.823547%, 96.470642%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(98.823547%, 96.470642%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(98.823547%, 96.470642%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(98.431396%, 96.470642%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(98.431396%, 96.470642%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(98.431396%, 96.470642%, 74.902344%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(98.431396%, 96.470642%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(98.431396%, 96.078491%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(98.431396%, 96.078491%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(98.431396%, 96.078491%, 73.33374%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(98.431396%, 96.078491%, 73.33374%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(98.431396%, 96.078491%, 72.941589%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(98.431396%, 96.078491%, 72.549438%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(98.431396%, 96.078491%, 72.157288%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(98.431396%, 96.078491%, 71.765137%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(98.431396%, 96.078491%, 71.372986%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(98.431396%, 96.078491%, 71.372986%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(98.431396%, 95.68634%, 70.980835%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(98.431396%, 95.68634%, 70.588684%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(98.431396%, 95.68634%, 70.196533%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(98.431396%, 95.68634%, 69.804382%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(98.431396%, 95.68634%, 69.412231%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(98.431396%, 95.68634%, 69.412231%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(98.431396%, 95.68634%, 69.020081%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(98.431396%, 95.68634%, 68.62793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(98.431396%, 95.68634%, 68.62793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(98.039246%, 95.68634%, 68.235779%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(98.039246%, 95.68634%, 67.843628%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(98.039246%, 95.294189%, 67.451477%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(98.039246%, 95.294189%, 67.059326%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(98.039246%, 95.294189%, 66.667175%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(98.039246%, 95.294189%, 66.667175%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(98.039246%, 95.294189%, 66.275024%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(98.039246%, 95.294189%, 65.882874%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(98.039246%, 95.294189%, 65.490723%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(98.039246%, 95.294189%, 65.490723%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(98.039246%, 95.294189%, 65.098572%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(98.039246%, 95.294189%, 64.706421%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(98.039246%, 94.902039%, 64.31427%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(98.039246%, 94.902039%, 64.31427%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(98.039246%, 94.902039%, 63.922119%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914062" stop-color="rgb(98.039246%, 94.902039%, 63.529968%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(98.039246%, 94.902039%, 63.137817%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(98.039246%, 94.902039%, 62.745667%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(98.039246%, 94.902039%, 62.745667%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(98.039246%, 94.902039%, 62.353516%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960937" stop-color="rgb(98.039246%, 94.902039%, 61.961365%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(98.039246%, 94.902039%, 61.569214%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(98.039246%, 94.509888%, 61.177063%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(98.039246%, 94.509888%, 60.784912%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-2">
|
||||||
|
<path clip-rule="nonzero" d="M 13 15 L 80 15 L 80 81 L 13 81 Z M 13 15 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-3">
|
||||||
|
<path clip-rule="nonzero" d="M 19.300781 21.152344 C 12.125 28.328125 12.125 39.964844 19.300781 47.140625 L 47.726562 75.566406 C 51.316406 79.15625 56.019531 80.949219 60.722656 80.949219 C 65.425781 80.949219 70.128906 79.15625 73.714844 75.566406 C 80.894531 68.386719 80.894531 56.753906 73.714844 49.574219 L 45.292969 21.152344 C 41.703125 17.5625 37 15.769531 32.296875 15.769531 C 27.59375 15.769531 22.890625 17.5625 19.300781 21.152344 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-1" gradientUnits="userSpaceOnUse" x1="-0.115399" y1="0" x2="1.115408" y2="0" gradientTransform="matrix(-54.414318, -54.414318, 54.414318, -54.414318, 73.71669, 75.565292)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0976562" stop-color="rgb(99.607849%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(99.607849%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.105469" stop-color="rgb(99.215698%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(99.215698%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.113281" stop-color="rgb(98.823547%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(98.431396%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.121094" stop-color="rgb(98.431396%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(98.039246%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.128906" stop-color="rgb(98.039246%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(97.647095%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.136719" stop-color="rgb(97.254944%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(97.254944%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.144531" stop-color="rgb(96.862793%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(96.470642%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.152344" stop-color="rgb(96.078491%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(95.68634%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.160156" stop-color="rgb(95.68634%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(95.294189%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.167969" stop-color="rgb(94.902039%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(94.902039%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.175781" stop-color="rgb(94.509888%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(94.509888%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.183594" stop-color="rgb(94.117737%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(93.725586%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.191406" stop-color="rgb(93.725586%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(93.333435%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.199219" stop-color="rgb(93.333435%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(92.941284%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.207031" stop-color="rgb(92.549133%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(92.549133%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.214844" stop-color="rgb(92.156982%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(91.764832%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.222656" stop-color="rgb(91.372681%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226563" stop-color="rgb(90.98053%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.230469" stop-color="rgb(90.98053%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(90.588379%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.238281" stop-color="rgb(90.588379%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(90.196228%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.246094" stop-color="rgb(89.804077%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(89.804077%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.253906" stop-color="rgb(89.411926%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(89.411926%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.261719" stop-color="rgb(89.019775%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(88.627625%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.269531" stop-color="rgb(88.627625%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(88.235474%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.277344" stop-color="rgb(88.235474%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(87.843323%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.285156" stop-color="rgb(87.451172%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(87.451172%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.292969" stop-color="rgb(87.059021%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(86.66687%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.300781" stop-color="rgb(86.66687%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304688" stop-color="rgb(86.274719%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.308594" stop-color="rgb(85.882568%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(85.490417%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.316406" stop-color="rgb(85.098267%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(85.098267%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.324219" stop-color="rgb(84.706116%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(84.706116%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.332031" stop-color="rgb(84.313965%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335938" stop-color="rgb(83.921814%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.339844" stop-color="rgb(83.921814%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(83.529663%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.347656" stop-color="rgb(83.529663%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(83.137512%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.355469" stop-color="rgb(82.745361%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(82.35321%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.363281" stop-color="rgb(81.96106%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(81.96106%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.371094" stop-color="rgb(81.568909%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(81.176758%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.378906" stop-color="rgb(81.176758%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(80.784607%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.386719" stop-color="rgb(80.784607%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(80.392456%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.394531" stop-color="rgb(80.000305%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398438" stop-color="rgb(80.000305%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.402344" stop-color="rgb(79.608154%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(79.608154%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.410156" stop-color="rgb(79.216003%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(78.823853%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.417969" stop-color="rgb(78.431702%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(78.431702%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.425781" stop-color="rgb(78.039551%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(77.6474%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.433594" stop-color="rgb(77.255249%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(77.255249%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.441406" stop-color="rgb(76.863098%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(76.470947%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.449219" stop-color="rgb(76.470947%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(76.078796%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.457031" stop-color="rgb(75.686646%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(75.686646%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.464844" stop-color="rgb(75.294495%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(74.902344%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.472656" stop-color="rgb(74.510193%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476563" stop-color="rgb(74.510193%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.480469" stop-color="rgb(74.118042%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(73.725891%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.488281" stop-color="rgb(73.33374%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(72.941589%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.496094" stop-color="rgb(72.941589%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(72.549438%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.503906" stop-color="rgb(72.157288%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(72.157288%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.511719" stop-color="rgb(71.765137%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(71.765137%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.519531" stop-color="rgb(71.372986%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523437" stop-color="rgb(70.980835%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.527344" stop-color="rgb(70.588684%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(70.196533%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(70.196533%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(69.804382%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(69.412231%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(69.412231%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.550781" stop-color="rgb(69.020081%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(68.62793%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.558594" stop-color="rgb(68.235779%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(67.843628%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.566406" stop-color="rgb(67.843628%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(67.451477%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.574219" stop-color="rgb(67.059326%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(66.667175%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.582031" stop-color="rgb(66.275024%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585937" stop-color="rgb(66.275024%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.589844" stop-color="rgb(65.882874%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(65.490723%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.597656" stop-color="rgb(65.490723%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(65.098572%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.605469" stop-color="rgb(64.706421%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(64.31427%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.613281" stop-color="rgb(63.922119%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(63.922119%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.621094" stop-color="rgb(63.529968%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(63.137817%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.628906" stop-color="rgb(63.137817%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(62.745667%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(62.353516%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(61.961365%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(61.961365%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(61.569214%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.652344" stop-color="rgb(61.177063%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(60.784912%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.660156" stop-color="rgb(60.392761%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664063" stop-color="rgb(60.392761%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.667969" stop-color="rgb(60.00061%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(59.608459%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.675781" stop-color="rgb(59.608459%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(59.216309%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.683594" stop-color="rgb(58.824158%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(58.432007%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.691406" stop-color="rgb(58.039856%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695313" stop-color="rgb(58.039856%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.699219" stop-color="rgb(57.647705%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(57.255554%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.707031" stop-color="rgb(56.863403%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(56.471252%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.714844" stop-color="rgb(56.471252%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(56.079102%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.722656" stop-color="rgb(55.686951%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726563" stop-color="rgb(55.686951%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.730469" stop-color="rgb(55.2948%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(54.902649%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.738281" stop-color="rgb(54.510498%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(54.118347%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.746094" stop-color="rgb(54.118347%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(53.726196%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.753906" stop-color="rgb(53.334045%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(53.334045%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.761719" stop-color="rgb(52.941895%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(52.549744%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.769531" stop-color="rgb(52.157593%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(52.157593%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.777344" stop-color="rgb(51.765442%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(51.373291%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.785156" stop-color="rgb(50.98114%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(50.588989%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.792969" stop-color="rgb(50.588989%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(50.196838%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.800781" stop-color="rgb(49.803162%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804687" stop-color="rgb(49.803162%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.808594" stop-color="rgb(49.411011%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(49.01886%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.816406" stop-color="rgb(48.626709%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(48.234558%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.824219" stop-color="rgb(47.842407%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(47.450256%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.832031" stop-color="rgb(47.450256%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835937" stop-color="rgb(47.058105%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.839844" stop-color="rgb(46.665955%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(46.665955%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.847656" stop-color="rgb(46.273804%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(45.881653%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.855469" stop-color="rgb(45.489502%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(45.097351%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.863281" stop-color="rgb(45.097351%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867188" stop-color="rgb(44.7052%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.871094" stop-color="rgb(44.313049%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(43.920898%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.878906" stop-color="rgb(43.528748%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(43.528748%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.886719" stop-color="rgb(43.136597%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(42.744446%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.894531" stop-color="rgb(42.744446%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(42.352295%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.902344" stop-color="rgb(42.352295%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-4">
|
||||||
|
<path clip-rule="nonzero" d="M 42 3 L 80 3 L 80 81 L 42 81 Z M 42 3 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-5">
|
||||||
|
<path clip-rule="nonzero" d="M 42.34375 22.371094 L 42.34375 62.570312 C 42.34375 72.71875 50.570312 80.949219 60.722656 80.949219 C 70.871094 80.949219 79.097656 72.71875 79.097656 62.570312 L 79.097656 22.371094 C 79.097656 12.222656 70.871094 3.996094 60.722656 3.996094 C 50.570312 3.996094 42.34375 12.222656 42.34375 22.371094 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-2" gradientUnits="userSpaceOnUse" x1="0.00000321492" y1="0" x2="0.999994" y2="0" gradientTransform="matrix(0, -76.95372, 76.95372, 0, 60.721073, 80.947947)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0078125" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(99.607849%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(99.607849%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(99.215698%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(98.823547%, 98.431396%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(98.431396%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(98.431396%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(98.039246%, 97.254944%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(97.647095%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(97.254944%, 96.470642%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(97.254944%, 96.078491%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(96.862793%, 95.68634%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(96.470642%, 95.294189%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(96.078491%, 94.902039%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(96.078491%, 94.509888%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(95.68634%, 94.117737%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(95.294189%, 93.725586%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(94.902039%, 93.333435%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(94.902039%, 92.941284%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(94.509888%, 92.549133%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(94.117737%, 92.156982%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(93.725586%, 91.764832%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(93.725586%, 91.372681%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(93.333435%, 90.98053%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(92.941284%, 90.588379%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(92.549133%, 90.196228%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(92.549133%, 89.804077%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(92.156982%, 89.411926%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(91.764832%, 89.019775%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(91.372681%, 88.627625%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242187" stop-color="rgb(91.372681%, 88.235474%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(90.98053%, 87.843323%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(90.98053%, 87.451172%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(90.588379%, 87.451172%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(90.196228%, 87.059021%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(90.196228%, 86.66687%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(89.804077%, 86.274719%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(89.411926%, 85.882568%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(89.019775%, 85.490417%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(89.019775%, 85.098267%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(88.627625%, 84.706116%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(88.627625%, 84.313965%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(88.235474%, 83.921814%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(87.843323%, 83.529663%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(87.451172%, 83.137512%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(87.451172%, 82.745361%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(87.059021%, 82.35321%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(87.059021%, 81.96106%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(86.66687%, 81.568909%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(86.274719%, 81.176758%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(85.882568%, 80.784607%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(85.882568%, 80.784607%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(85.490417%, 80.392456%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(85.490417%, 80.000305%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(85.098267%, 79.608154%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(84.706116%, 79.216003%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(84.313965%, 78.823853%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(84.313965%, 78.431702%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(83.921814%, 78.039551%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(83.921814%, 77.6474%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(83.529663%, 77.255249%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(83.529663%, 76.863098%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492188" stop-color="rgb(83.137512%, 76.470947%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(82.745361%, 76.470947%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(82.745361%, 76.078796%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(82.35321%, 76.078796%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(81.96106%, 75.686646%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(81.96106%, 75.294495%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(81.568909%, 74.902344%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(81.568909%, 74.510193%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(81.176758%, 74.118042%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(81.176758%, 73.725891%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570313" stop-color="rgb(80.784607%, 73.33374%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(80.784607%, 73.33374%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(80.392456%, 72.941589%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(80.000305%, 72.549438%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(79.608154%, 72.157288%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(79.608154%, 71.765137%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(79.216003%, 71.372986%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(79.216003%, 70.980835%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(78.823853%, 70.588684%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(78.823853%, 70.588684%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648437" stop-color="rgb(78.431702%, 70.196533%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(78.431702%, 69.804382%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664063" stop-color="rgb(78.039551%, 69.412231%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(78.039551%, 69.020081%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(77.6474%, 68.62793%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(77.255249%, 68.62793%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(76.863098%, 68.235779%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(76.863098%, 67.843628%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(76.470947%, 67.451477%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(76.470947%, 67.059326%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(76.078796%, 66.667175%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(76.078796%, 66.667175%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(75.686646%, 66.275024%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(75.686646%, 65.882874%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757813" stop-color="rgb(75.686646%, 65.490723%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(75.294495%, 65.098572%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773438" stop-color="rgb(75.294495%, 65.098572%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(74.902344%, 64.706421%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(74.902344%, 64.31427%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(74.510193%, 63.922119%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(74.510193%, 63.922119%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(74.118042%, 63.529968%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(74.118042%, 63.137817%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(73.725891%, 62.745667%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(73.33374%, 62.353516%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(72.941589%, 61.961365%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851563" stop-color="rgb(72.941589%, 61.961365%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(72.549438%, 61.569214%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867188" stop-color="rgb(72.549438%, 61.177063%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(72.157288%, 60.784912%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(71.765137%, 60.392761%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898437" stop-color="rgb(71.765137%, 60.392761%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(71.765137%, 60.00061%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914063" stop-color="rgb(71.765137%, 59.608459%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(71.372986%, 59.216309%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(70.980835%, 58.824158%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(70.980835%, 58.824158%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(70.588684%, 58.432007%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960938" stop-color="rgb(70.588684%, 58.039856%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(70.196533%, 57.647705%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(69.804382%, 57.255554%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(69.804382%, 56.863403%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-6">
|
||||||
|
<path clip-rule="nonzero" d="M 42 15 L 108 15 L 108 81 L 42 81 Z M 42 15 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-7">
|
||||||
|
<path clip-rule="nonzero" d="M 76.152344 21.152344 L 47.726562 49.574219 C 40.550781 56.75 40.550781 68.386719 47.726562 75.566406 C 51.316406 79.15625 56.019531 80.949219 60.722656 80.949219 C 65.425781 80.949219 70.128906 79.152344 73.714844 75.566406 L 102.140625 47.140625 C 109.316406 39.964844 109.316406 28.328125 102.140625 21.152344 C 98.550781 17.5625 93.847656 15.769531 89.144531 15.769531 C 84.441406 15.769531 79.738281 17.5625 76.152344 21.152344 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-3" gradientUnits="userSpaceOnUse" x1="-0.115406" y1="0" x2="1.115401" y2="0" gradientTransform="matrix(54.414692, -54.414692, 54.414692, 54.414692, 47.726387, 75.56548)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(100%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.113281" stop-color="rgb(100%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(100%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(100%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(100%, 98.431396%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(100%, 98.431396%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(99.607849%, 98.039246%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.152344" stop-color="rgb(99.607849%, 97.647095%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(99.607849%, 97.254944%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(99.607849%, 97.254944%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(99.607849%, 96.862793%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.175781" stop-color="rgb(99.607849%, 96.862793%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179687" stop-color="rgb(99.607849%, 96.470642%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(99.607849%, 96.470642%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.191406" stop-color="rgb(99.607849%, 96.078491%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(99.607849%, 95.68634%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(99.607849%, 95.68634%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210938" stop-color="rgb(99.607849%, 95.294189%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.214844" stop-color="rgb(99.607849%, 94.902039%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(99.607849%, 94.902039%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(99.607849%, 94.509888%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(99.215698%, 94.117737%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242187" stop-color="rgb(99.215698%, 94.117737%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(99.215698%, 93.725586%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.253906" stop-color="rgb(99.215698%, 93.333435%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(99.215698%, 93.333435%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(99.215698%, 92.941284%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273437" stop-color="rgb(99.215698%, 92.549133%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(99.215698%, 92.549133%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(99.215698%, 92.156982%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.292969" stop-color="rgb(99.215698%, 91.764832%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(99.215698%, 91.372681%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(99.215698%, 91.372681%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(98.823547%, 90.98053%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.316406" stop-color="rgb(98.823547%, 90.588379%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(98.823547%, 90.588379%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.324219" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(98.823547%, 89.804077%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(98.823547%, 89.411926%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.355469" stop-color="rgb(98.823547%, 89.019775%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(98.823547%, 89.019775%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.363281" stop-color="rgb(98.823547%, 88.627625%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367187" stop-color="rgb(98.823547%, 88.627625%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(98.823547%, 88.235474%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.378906" stop-color="rgb(98.823547%, 88.235474%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(98.823547%, 88.235474%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.386719" stop-color="rgb(98.431396%, 87.843323%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(98.431396%, 87.843323%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.394531" stop-color="rgb(98.431396%, 87.451172%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398438" stop-color="rgb(98.431396%, 87.451172%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(98.431396%, 87.059021%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(98.431396%, 86.66687%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(98.431396%, 86.66687%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429687" stop-color="rgb(98.431396%, 86.274719%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.433594" stop-color="rgb(98.431396%, 85.882568%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(98.431396%, 85.882568%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(98.431396%, 85.490417%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(98.039246%, 85.098267%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.457031" stop-color="rgb(98.039246%, 85.098267%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460937" stop-color="rgb(98.039246%, 84.706116%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.464844" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(98.039246%, 83.921814%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.488281" stop-color="rgb(98.039246%, 83.529663%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492188" stop-color="rgb(98.039246%, 83.529663%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.496094" stop-color="rgb(98.039246%, 83.529663%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(98.039246%, 83.137512%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.503906" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(98.039246%, 82.35321%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(97.647095%, 81.96106%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(97.647095%, 81.96106%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539063" stop-color="rgb(97.647095%, 81.568909%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554688" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(97.647095%, 80.784607%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(97.647095%, 80.392456%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.574219" stop-color="rgb(97.647095%, 80.000305%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(97.647095%, 80.000305%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.582031" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(97.254944%, 79.216003%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.605469" stop-color="rgb(97.254944%, 78.823853%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(97.254944%, 78.431702%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617187" stop-color="rgb(97.254944%, 78.431702%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(97.254944%, 78.039551%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632813" stop-color="rgb(97.254944%, 78.039551%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(97.254944%, 77.6474%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(97.254944%, 77.255249%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(97.254944%, 77.255249%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(97.254944%, 76.863098%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(97.254944%, 76.863098%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(96.862793%, 76.470947%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(96.862793%, 76.078796%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.675781" stop-color="rgb(96.862793%, 76.078796%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(96.862793%, 75.686646%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.683594" stop-color="rgb(96.862793%, 75.686646%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(96.862793%, 75.294495%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(96.862793%, 75.294495%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(96.862793%, 74.902344%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710937" stop-color="rgb(96.862793%, 74.510193%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(96.862793%, 74.510193%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(96.862793%, 74.118042%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.730469" stop-color="rgb(96.862793%, 73.725891%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(96.470642%, 73.725891%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(96.470642%, 73.33374%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(96.470642%, 72.941589%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(96.470642%, 72.941589%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(96.470642%, 72.549438%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.769531" stop-color="rgb(96.470642%, 72.157288%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773438" stop-color="rgb(96.470642%, 72.157288%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(96.470642%, 71.765137%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789063" stop-color="rgb(96.470642%, 71.372986%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(96.470642%, 71.372986%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(96.470642%, 70.980835%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(96.470642%, 70.980835%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(96.078491%, 70.588684%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(96.078491%, 70.196533%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.832031" stop-color="rgb(96.078491%, 69.804382%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(96.078491%, 69.804382%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.839844" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(96.078491%, 69.020081%, 74.902344%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(96.078491%, 68.62793%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(96.078491%, 68.62793%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882813" stop-color="rgb(96.078491%, 68.235779%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(96.078491%, 68.235779%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(96.078491%, 67.843628%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-8">
|
||||||
|
<path clip-rule="nonzero" d="M 42 44 L 120 44 L 120 81 L 42 81 Z M 42 44 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-9">
|
||||||
|
<path clip-rule="nonzero" d="M 60.722656 44.191406 C 50.570312 44.191406 42.34375 52.421875 42.34375 62.570312 C 42.34375 72.71875 50.570312 80.949219 60.722656 80.949219 L 100.917969 80.949219 C 111.066406 80.949219 119.296875 72.71875 119.296875 62.570312 C 119.296875 52.421875 111.066406 44.191406 100.917969 44.191406 Z M 60.722656 44.191406 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-4" gradientUnits="userSpaceOnUse" x1="-0.00000221172" y1="0" x2="1.000001" y2="0" gradientTransform="matrix(76.95372, 0, 0, 76.95372, 42.34317, 62.570047)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0078125" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(99.607849%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(99.215698%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(98.823547%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(98.431396%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(98.039246%, 98.823547%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(97.647095%, 98.823547%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(97.254944%, 98.431396%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(96.862793%, 98.431396%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(96.470642%, 98.039246%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(96.078491%, 98.039246%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(95.68634%, 98.039246%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(95.68634%, 98.039246%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(95.294189%, 97.647095%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117187" stop-color="rgb(94.902039%, 97.647095%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(94.509888%, 97.254944%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(94.117737%, 97.254944%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(93.725586%, 96.862793%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(93.333435%, 96.862793%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(92.941284%, 96.470642%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(92.549133%, 96.470642%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(92.156982%, 96.078491%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(91.764832%, 96.078491%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(91.372681%, 95.68634%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(90.98053%, 95.68634%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(90.588379%, 95.294189%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210938" stop-color="rgb(90.196228%, 95.294189%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(89.804077%, 94.902039%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(89.411926%, 94.902039%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(89.019775%, 94.509888%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(88.627625%, 94.509888%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(88.235474%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(87.843323%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(87.451172%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(87.059021%, 93.725586%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(86.66687%, 93.725586%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(86.274719%, 93.333435%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(85.882568%, 93.333435%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(85.490417%, 92.941284%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(85.098267%, 92.941284%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(84.706116%, 92.549133%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(84.313965%, 92.549133%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(83.921814%, 92.156982%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(83.529663%, 92.156982%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(83.137512%, 92.156982%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(82.745361%, 92.156982%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367187" stop-color="rgb(82.35321%, 91.764832%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(81.96106%, 91.764832%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(81.568909%, 91.372681%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(81.176758%, 91.372681%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(80.784607%, 90.98053%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(80.392456%, 90.98053%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(80.000305%, 90.588379%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(79.608154%, 90.588379%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429687" stop-color="rgb(79.216003%, 90.196228%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(78.823853%, 90.196228%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(78.431702%, 89.804077%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(78.039551%, 89.804077%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460937" stop-color="rgb(77.6474%, 89.411926%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(77.255249%, 89.411926%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(76.863098%, 89.019775%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(76.470947%, 89.019775%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(76.078796%, 88.627625%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(75.686646%, 88.627625%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(75.686646%, 88.627625%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(75.294495%, 88.627625%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523437" stop-color="rgb(74.902344%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.527344" stop-color="rgb(74.118042%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(74.118042%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(73.725891%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(73.33374%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(73.33374%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(72.941589%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(72.941589%, 87.451172%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(72.549438%, 87.451172%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(72.157288%, 87.059021%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(71.765137%, 87.059021%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585937" stop-color="rgb(71.372986%, 86.66687%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(70.980835%, 86.66687%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(70.588684%, 86.274719%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(70.196533%, 86.274719%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617187" stop-color="rgb(69.804382%, 85.882568%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(69.412231%, 85.882568%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(69.020081%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(68.62793%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(68.235779%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(67.843628%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648437" stop-color="rgb(67.451477%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.652344" stop-color="rgb(67.451477%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(67.059326%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(67.059326%, 84.706116%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(66.667175%, 84.706116%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679687" stop-color="rgb(66.275024%, 84.313965%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(65.882874%, 84.313965%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(65.490723%, 84.313965%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(65.098572%, 84.313965%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710937" stop-color="rgb(64.706421%, 83.921814%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(64.31427%, 83.921814%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(63.922119%, 83.529663%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(63.529968%, 83.529663%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742187" stop-color="rgb(63.137817%, 83.137512%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.746094" stop-color="rgb(62.745667%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(62.353516%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.753906" stop-color="rgb(62.353516%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(61.961365%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.761719" stop-color="rgb(61.569214%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(61.569214%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(61.177063%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(60.784912%, 82.35321%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(60.392761%, 82.35321%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(60.00061%, 82.35321%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804687" stop-color="rgb(59.608459%, 82.35321%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(59.216309%, 81.96106%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(58.824158%, 81.96106%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(58.432007%, 81.568909%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835937" stop-color="rgb(58.039856%, 81.568909%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(57.647705%, 81.176758%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(57.255554%, 81.176758%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(56.863403%, 80.784607%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(56.471252%, 80.784607%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(56.079102%, 80.784607%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(55.686951%, 80.784607%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(55.2948%, 80.392456%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898437" stop-color="rgb(54.902649%, 80.392456%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(54.510498%, 80.000305%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914062" stop-color="rgb(54.118347%, 80.000305%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(53.726196%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.929687" stop-color="rgb(53.334045%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(52.941895%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(52.549744%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(52.157593%, 79.216003%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960937" stop-color="rgb(51.765442%, 79.216003%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(51.373291%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.976562" stop-color="rgb(51.373291%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(50.98114%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.992187" stop-color="rgb(50.588989%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(50.196838%, 78.431702%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g clip-path="url(#clip-0)">
|
||||||
|
<g clip-path="url(#clip-1)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-0)" d="M 79.097656 80.949219 L 79.097656 44.191406 L 2.144531 44.191406 L 2.144531 80.949219 Z M 79.097656 80.949219 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-2)">
|
||||||
|
<g clip-path="url(#clip-3)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-1)" d="M 46.507812 115.332031 L 113.484375 48.359375 L 46.507812 -18.617188 L -20.464844 48.359375 Z M 46.507812 115.332031 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-4)">
|
||||||
|
<g clip-path="url(#clip-5)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-2)" d="M 42.34375 80.949219 L 79.097656 80.949219 L 79.097656 3.996094 L 42.34375 3.996094 Z M 42.34375 80.949219 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-6)">
|
||||||
|
<g clip-path="url(#clip-7)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-3)" d="M 7.960938 48.359375 L 74.933594 115.332031 L 141.90625 48.359375 L 74.933594 -18.617188 Z M 7.960938 48.359375 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-8)">
|
||||||
|
<g clip-path="url(#clip-9)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-4)" d="M 42.34375 44.191406 L 42.34375 80.949219 L 119.296875 80.949219 L 119.296875 44.191406 Z M 42.34375 44.191406 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 79.097656 62.570312 C 79.097656 72.71875 70.871094 80.949219 60.722656 80.949219 C 50.570312 80.949219 42.34375 72.71875 42.34375 62.570312 C 42.34375 52.421875 50.570312 44.191406 60.722656 44.191406 C 70.871094 44.191406 79.097656 52.421875 79.097656 62.570312 "/>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-0" x="133.1255" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-1" x="141.8111" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-2" x="158.2975" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="170.0435" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-4" x="187.3475" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="198.5587" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-6" x="224.2543" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="241.4435" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="253.7943" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-9" x="261.5951" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-10" x="279.0391" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="295.5983" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="312.1183" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-11" x="316.5983" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="332.8551" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="344.9791" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-13" x="349.4591" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-14" x="362.3475" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-13" x="378.3775" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="391.1511" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-15" x="403.2219" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="419.8231" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="445.4655" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-13" x="462.0303" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-16" x="133.1255" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="150.4547" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="166.9747" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-17" x="171.4547" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="185.8383" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-5" x="203.1423" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="228.9331" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-10" x="254.6539" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-1" x="271.2971" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="288.0467" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-17" x="295.7887" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-6" x="310.2927" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="327.4847" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="339.8327" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="347.5747" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-1" x="364.8787" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="381.5107" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="385.9907" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-0" x="390.4707" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-18" x="399.0331" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(21.960449%, 21.960449%, 21.960449%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-19" x="415.7099" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(86.66687%, 0%, 41.175842%)" fill-opacity="1" d="M 453.445312 65.542969 C 453.445312 66.425781 454.160156 67.140625 455.039062 67.140625 L 472.71875 67.140625 C 473.597656 67.140625 474.3125 66.425781 474.3125 65.542969 L 474.3125 47.867188 C 474.3125 46.984375 473.597656 46.273438 472.71875 46.273438 L 455.039062 46.273438 C 454.160156 46.273438 453.445312 46.984375 453.445312 47.867188 Z M 453.445312 65.542969 "/>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 465.027344 52.910156 L 462.621094 52.910156 C 462.5 54.304688 462.382812 55.492188 462.273438 56.386719 C 462.160156 57.277344 462.054688 57.957031 461.953125 58.597656 C 461.84375 59.242188 461.738281 59.824219 461.628906 60.351562 C 461.535156 60.765625 461.40625 61.085938 461.226562 61.316406 C 461.050781 61.550781 460.796875 61.710938 460.460938 61.800781 C 460.175781 61.867188 459.902344 61.816406 459.625 61.632812 C 459.351562 61.453125 459.191406 61.238281 459.128906 60.988281 C 459.089844 60.800781 459.078125 60.644531 459.101562 60.515625 C 459.117188 60.386719 459.15625 60.265625 459.214844 60.15625 C 459.269531 60.046875 459.332031 59.945312 459.40625 59.851562 C 459.46875 59.761719 459.542969 59.671875 459.617188 59.582031 C 459.644531 59.554688 459.761719 59.414062 459.984375 59.15625 C 460.203125 58.898438 460.363281 58.664062 460.476562 58.453125 C 460.585938 58.242188 460.828125 57.773438 460.949219 57.195312 C 461.070312 56.617188 461.320312 54.632812 461.316406 52.910156 L 460.300781 52.910156 C 460.015625 52.910156 459.734375 53.003906 459.472656 53.140625 C 459.21875 53.273438 458.992188 53.5 458.890625 53.632812 C 458.78125 53.765625 458.503906 54.210938 458.441406 54.296875 C 458.375 54.382812 458.242188 54.582031 458.144531 54.550781 C 458.035156 54.515625 458.058594 54.394531 458.074219 54.296875 C 458.09375 54.199219 458.292969 53.699219 458.441406 53.324219 C 458.589844 52.945312 458.792969 52.578125 459.046875 52.226562 C 459.246094 51.925781 459.519531 51.710938 459.859375 51.496094 C 460.203125 51.273438 460.597656 51.164062 461.050781 51.164062 L 468.429688 51.164062 C 468.5625 51.164062 469.253906 51.21875 469.253906 52.03125 C 469.253906 52.839844 468.515625 52.910156 468.429688 52.910156 L 466.335938 52.910156 C 466.160156 54.570312 466.074219 56.28125 466.074219 57.964844 C 466.074219 58.269531 466.125 58.570312 466.230469 58.859375 C 466.335938 59.152344 466.464844 59.375 466.617188 59.523438 C 466.816406 59.707031 467.050781 59.824219 467.332031 59.875 C 467.617188 59.925781 467.902344 59.839844 468.191406 59.609375 C 468.351562 59.484375 468.46875 59.34375 468.542969 59.1875 C 468.617188 59.023438 468.660156 58.871094 468.683594 58.726562 C 468.703125 58.578125 468.738281 58.371094 468.742188 58.320312 C 468.746094 58.273438 468.738281 58.089844 468.945312 58.074219 C 469.152344 58.058594 469.171875 58.242188 469.191406 58.441406 C 469.210938 58.640625 469.101562 59.382812 468.9375 59.84375 C 468.769531 60.308594 468.570312 60.679688 468.339844 60.957031 C 468.109375 61.242188 467.886719 61.445312 467.664062 61.566406 C 467.410156 61.71875 467.117188 61.8125 466.785156 61.84375 C 466.449219 61.878906 466.140625 61.796875 465.867188 61.613281 C 465.40625 61.277344 465.054688 60.753906 464.824219 60.039062 C 464.683594 59.621094 464.617188 59.070312 464.597656 58.386719 C 464.578125 57.703125 464.601562 57.035156 464.664062 56.382812 Z M 465.027344 52.910156 "/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 96 KiB |
1
halfway-presentation/logo_symbol.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?><svg id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 172.11 113.06"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:url(#Dégradé_sans_nom_5);}.cls-3{fill:url(#Dégradé_sans_nom_7);}.cls-4{fill:url(#Dégradé_sans_nom_8);}.cls-5{fill:url(#Dégradé_sans_nom_9);}.cls-6{fill:url(#Dégradé_sans_nom_6);}</style><linearGradient id="Dégradé_sans_nom_6" x1="113.05" y1="86.06" x2="0" y2="86.06" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".28" stop-color="#fcfae1"/><stop offset=".76" stop-color="#f8f3b1"/><stop offset="1" stop-color="#f7f19f"/></linearGradient><linearGradient id="Dégradé_sans_nom_5" x1="105.15" y1="105.15" x2="25.2" y2="25.21" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".38" stop-color="#cee6f4"/><stop offset=".79" stop-color="#9ecfea"/><stop offset="1" stop-color="#8cc6e6"/></linearGradient><linearGradient id="Dégradé_sans_nom_7" x1="86.06" y1="113.06" x2="86.06" y2="0" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".36" stop-color="#dbd2e5"/><stop offset=".79" stop-color="#b6a2ca"/><stop offset="1" stop-color="#a890c0"/></linearGradient><linearGradient id="Dégradé_sans_nom_8" x1="66.96" y1="105.15" x2="146.91" y2="25.21" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".19" stop-color="#f8edf0"/><stop offset=".73" stop-color="#e8bdc9"/><stop offset="1" stop-color="#e2abba"/></linearGradient><linearGradient id="Dégradé_sans_nom_9" x1="59.06" y1="86.06" x2="172.11" y2="86.06" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#fff"/><stop offset=".32" stop-color="#daeae8"/><stop offset=".77" stop-color="#aad1ca"/><stop offset="1" stop-color="#98c7bf"/></linearGradient></defs><path class="cls-6" d="M86.06,113.06H27c-14.91,0-27-12.09-27-27s12.09-27,27-27h59.06c14.91,0,27,12.09,27,27s-12.09,27-27,27Z"/><path class="cls-2" d="M86.06,113.06c-6.91,0-13.82-2.64-19.09-7.91L25.2,63.39c-10.54-10.54-10.54-27.64,0-38.18,10.54-10.54,27.64-10.54,38.18,0l41.76,41.76c10.54,10.54,10.54,27.64,0,38.18-5.27,5.27-12.18,7.91-19.09,7.91Z"/><path class="cls-3" d="M86.06,113.06c-14.91,0-27-12.09-27-27V27c0-14.91,12.09-27,27-27s27,12.09,27,27v59.06c0,14.91-12.09,27-27,27Z"/><path class="cls-4" d="M86.06,113.06c-6.91,0-13.82-2.64-19.09-7.91-10.54-10.54-10.54-27.64,0-38.18L108.72,25.21c10.54-10.54,27.64-10.54,38.18,0,10.54,10.54,10.54,27.64,0,38.18l-41.76,41.76c-5.27,5.27-12.18,7.91-19.09,7.91Z"/><path class="cls-5" d="M145.11,113.06h-59.06c-14.91,0-27-12.09-27-27s12.09-27,27-27h59.06c14.91,0,27,12.09,27,27s-12.09,27-27,27Z"/><circle class="cls-1" cx="86.06" cy="86.06" r="27"/></svg>
|
||||||
|
After Width: | Height: | Size: 2.7 KiB |
988
halfway-presentation/logo_white.svg
Normal file
@@ -0,0 +1,988 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="482.222" height="84.6667" viewBox="0 0 482.222 84.6667">
|
||||||
|
<defs>
|
||||||
|
<g>
|
||||||
|
<g id="glyph-0-0">
|
||||||
|
<path d="M 6.6875 0 L 1.8125 0 L 1.8125 -18.765625 L 6.6875 -18.765625 Z M 6.6875 0 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-1">
|
||||||
|
<path d="M 5.96875 -13.640625 L 5.96875 -12.375 C 6.28125 -12.84375 6.796875 -13.21875 7.515625 -13.5 C 8.234375 -13.78125 8.976562 -13.921875 9.75 -13.921875 C 11.613281 -13.921875 12.992188 -13.394531 13.890625 -12.34375 C 14.785156 -11.300781 15.234375 -9.847656 15.234375 -7.984375 L 15.234375 0 L 10.53125 0 L 10.53125 -6.890625 C 10.53125 -7.972656 10.359375 -8.742188 10.015625 -9.203125 C 9.679688 -9.660156 9.066406 -9.890625 8.171875 -9.890625 C 7.503906 -9.890625 6.863281 -9.71875 6.25 -9.375 L 6.25 0 L 1.546875 0 L 1.546875 -13.640625 Z M 5.96875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-2">
|
||||||
|
<path d="M 2.796875 -13.640625 L 2.796875 -14.28125 C 2.796875 -16 3.335938 -17.3125 4.421875 -18.21875 C 5.503906 -19.132812 6.894531 -19.59375 8.59375 -19.59375 C 9.5625 -19.59375 10.410156 -19.519531 11.140625 -19.375 L 11.140625 -15.453125 C 10.640625 -15.546875 10.164062 -15.59375 9.71875 -15.59375 C 8.238281 -15.59375 7.5 -14.941406 7.5 -13.640625 L 11.140625 -13.640625 L 11.140625 -9.859375 L 7.5 -9.859375 L 7.5 0 L 2.796875 0 L 2.796875 -9.859375 L 0.84375 -9.859375 L 0.84375 -13.640625 Z M 2.796875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-3">
|
||||||
|
<path d="M 0.984375 -6.828125 C 0.984375 -8.847656 1.710938 -10.535156 3.171875 -11.890625 C 4.640625 -13.242188 6.457031 -13.921875 8.625 -13.921875 C 10.789062 -13.921875 12.613281 -13.242188 14.09375 -11.890625 C 15.582031 -10.535156 16.328125 -8.847656 16.328125 -6.828125 C 16.328125 -4.816406 15.585938 -3.128906 14.109375 -1.765625 C 12.617188 -0.398438 10.789062 0.28125 8.625 0.28125 C 6.457031 0.28125 4.640625 -0.398438 3.171875 -1.765625 C 1.710938 -3.128906 0.984375 -4.816406 0.984375 -6.828125 Z M 6.53125 -4.640625 C 7.050781 -4.066406 7.75 -3.78125 8.625 -3.78125 C 9.5 -3.78125 10.207031 -4.0625 10.75 -4.625 C 11.289062 -5.195312 11.5625 -5.929688 11.5625 -6.828125 C 11.5625 -7.703125 11.289062 -8.429688 10.75 -9.015625 C 10.207031 -9.597656 9.5 -9.890625 8.625 -9.890625 C 7.769531 -9.890625 7.070312 -9.597656 6.53125 -9.015625 C 6 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6 -5.203125 6.53125 -4.640625 Z M 6.53125 -4.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-4">
|
||||||
|
<path d="M 1.546875 -13.640625 L 5.96875 -13.640625 L 5.96875 -12.234375 C 6.25 -12.734375 6.6875 -13.113281 7.28125 -13.375 C 7.875 -13.644531 8.507812 -13.78125 9.1875 -13.78125 C 9.65625 -13.78125 10.140625 -13.722656 10.640625 -13.609375 L 10.640625 -9.375 C 10.046875 -9.4375 9.457031 -9.46875 8.875 -9.46875 C 7.8125 -9.46875 6.9375 -9.328125 6.25 -9.046875 L 6.25 0 L 1.546875 0 Z M 1.546875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-5">
|
||||||
|
<path d="M 5.96875 -13.640625 L 5.96875 -12.375 C 6.28125 -12.84375 6.796875 -13.21875 7.515625 -13.5 C 8.234375 -13.78125 8.976562 -13.921875 9.75 -13.921875 C 11.707031 -13.921875 13.148438 -13.320312 14.078125 -12.125 C 14.421875 -12.644531 14.988281 -13.070312 15.78125 -13.40625 C 16.570312 -13.75 17.367188 -13.921875 18.171875 -13.921875 C 20.078125 -13.921875 21.5625 -13.382812 22.625 -12.3125 C 23.6875 -11.25 24.21875 -9.804688 24.21875 -7.984375 L 24.21875 0 L 19.515625 0 L 19.515625 -6.890625 C 19.515625 -7.972656 19.347656 -8.742188 19.015625 -9.203125 C 18.679688 -9.660156 18.066406 -9.890625 17.171875 -9.890625 C 16.472656 -9.890625 15.796875 -9.710938 15.140625 -9.359375 C 15.203125 -8.921875 15.234375 -8.460938 15.234375 -7.984375 L 15.234375 0 L 10.53125 0 L 10.53125 -6.890625 C 10.53125 -7.972656 10.359375 -8.742188 10.015625 -9.203125 C 9.679688 -9.660156 9.066406 -9.890625 8.171875 -9.890625 C 7.503906 -9.890625 6.863281 -9.71875 6.25 -9.375 L 6.25 0 L 1.546875 0 L 1.546875 -13.640625 Z M 5.96875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-6">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.410156 -13.921875 10.625 -13.472656 11.3125 -12.578125 L 11.3125 -13.640625 L 15.734375 -13.640625 L 15.734375 0 L 11.3125 0 L 11.3125 -1.0625 C 10.601562 -0.164062 9.390625 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.847656 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.457031 -3.75 10.269531 -3.992188 11.09375 -4.484375 L 11.09375 -9.1875 C 10.34375 -9.65625 9.53125 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-7">
|
||||||
|
<path d="M 2.796875 -13.640625 L 2.796875 -17.046875 L 7.5 -17.046875 L 7.5 -13.640625 L 11.140625 -13.640625 L 11.140625 -9.859375 L 7.5 -9.859375 L 7.5 -6.078125 C 7.5 -5.273438 7.6875 -4.703125 8.0625 -4.359375 C 8.4375 -4.023438 8.988281 -3.859375 9.71875 -3.859375 C 10.164062 -3.859375 10.640625 -3.90625 11.140625 -4 L 11.140625 -0.078125 C 10.410156 0.0664062 9.5625 0.140625 8.59375 0.140625 C 6.851562 0.140625 5.453125 -0.273438 4.390625 -1.109375 C 3.328125 -1.941406 2.796875 -3.207031 2.796875 -4.90625 L 2.796875 -9.859375 L 0.84375 -9.859375 L 0.84375 -13.640625 Z M 2.796875 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-8">
|
||||||
|
<path d="M 1.546875 0 L 1.546875 -13.640625 L 6.25 -13.640625 L 6.25 0 Z M 1.203125 -17.78125 C 1.203125 -18.488281 1.460938 -19.097656 1.984375 -19.609375 C 2.503906 -20.128906 3.140625 -20.390625 3.890625 -20.390625 C 4.640625 -20.390625 5.273438 -20.128906 5.796875 -19.609375 C 6.316406 -19.097656 6.578125 -18.488281 6.578125 -17.78125 C 6.578125 -17.070312 6.316406 -16.460938 5.796875 -15.953125 C 5.273438 -15.429688 4.640625 -15.171875 3.890625 -15.171875 C 3.140625 -15.171875 2.503906 -15.425781 1.984375 -15.9375 C 1.460938 -16.457031 1.203125 -17.070312 1.203125 -17.78125 Z M 1.203125 -17.78125 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-9">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.390625 -13.921875 10.601562 -13.472656 11.3125 -12.578125 L 11.3125 -13.640625 L 15.734375 -13.640625 L 15.734375 5.59375 L 11.03125 5.59375 L 11.03125 -0.75 C 10.25 -0.0625 9.128906 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.785156 0.984375 -6.796875 C 0.984375 -8.835938 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.53125 -3.75 10.34375 -3.984375 11.09375 -4.453125 L 11.09375 -9.15625 C 10.269531 -9.644531 9.457031 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.691406 5.734375 -6.796875 C 5.734375 -5.921875 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-10">
|
||||||
|
<path d="M 1.40625 -13.640625 L 6.109375 -13.640625 L 6.109375 -6.1875 C 6.109375 -5.382812 6.28125 -4.773438 6.625 -4.359375 C 6.96875 -3.953125 7.578125 -3.75 8.453125 -3.75 C 9.109375 -3.75 9.71875 -3.898438 10.28125 -4.203125 L 10.28125 -13.640625 L 14.984375 -13.640625 L 14.984375 0 L 10.578125 0 L 10.578125 -1.140625 C 10.242188 -0.710938 9.722656 -0.367188 9.015625 -0.109375 C 8.304688 0.148438 7.597656 0.28125 6.890625 0.28125 C 5.023438 0.28125 3.644531 -0.238281 2.75 -1.28125 C 1.851562 -2.332031 1.40625 -3.789062 1.40625 -5.65625 Z M 1.40625 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-11">
|
||||||
|
<path d="M 15.625 -6.796875 C 15.625 -6.347656 15.597656 -5.898438 15.546875 -5.453125 L 5.59375 -5.453125 C 6.175781 -4.191406 7.53125 -3.5625 9.65625 -3.5625 C 11.132812 -3.5625 12.609375 -3.820312 14.078125 -4.34375 L 14.078125 -0.59375 C 12.703125 -0.0078125 11.085938 0.28125 9.234375 0.28125 C 6.703125 0.28125 4.691406 -0.359375 3.203125 -1.640625 C 1.722656 -2.929688 0.984375 -4.660156 0.984375 -6.828125 C 0.984375 -8.867188 1.675781 -10.5625 3.0625 -11.90625 C 4.457031 -13.25 6.207031 -13.921875 8.3125 -13.921875 C 10.425781 -13.921875 12.171875 -13.25 13.546875 -11.90625 C 14.929688 -10.5625 15.625 -8.859375 15.625 -6.796875 Z M 8.3125 -10.109375 C 6.875 -10.109375 5.941406 -9.472656 5.515625 -8.203125 L 11.03125 -8.203125 C 10.625 -9.472656 9.71875 -10.109375 8.3125 -10.109375 Z M 8.3125 -10.109375 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-12">
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-13">
|
||||||
|
<path d="M 2.4375 -12.65625 C 3.40625 -13.5 4.75 -13.921875 6.46875 -13.921875 C 8.28125 -13.921875 9.894531 -13.65625 11.3125 -13.125 L 11.3125 -9.484375 C 9.632812 -10.015625 8.046875 -10.28125 6.546875 -10.28125 C 5.671875 -10.28125 5.234375 -10.070312 5.234375 -9.65625 C 5.234375 -9.46875 5.34375 -9.320312 5.5625 -9.21875 C 5.789062 -9.125 6.203125 -9.007812 6.796875 -8.875 L 7.984375 -8.625 C 9.472656 -8.300781 10.5625 -7.816406 11.25 -7.171875 C 11.945312 -6.535156 12.296875 -5.617188 12.296875 -4.421875 C 12.296875 -3.023438 11.769531 -1.890625 10.71875 -1.015625 C 9.675781 -0.148438 8.164062 0.28125 6.1875 0.28125 C 4.4375 0.28125 2.820312 -0.0234375 1.34375 -0.640625 L 1.34375 -4.484375 C 3.039062 -3.773438 4.722656 -3.421875 6.390625 -3.421875 C 7.472656 -3.421875 8.015625 -3.660156 8.015625 -4.140625 C 8.015625 -4.347656 7.910156 -4.503906 7.703125 -4.609375 C 7.492188 -4.710938 7.09375 -4.816406 6.5 -4.921875 L 5.1875 -5.203125 C 2.382812 -5.804688 0.984375 -7.191406 0.984375 -9.359375 C 0.984375 -10.710938 1.46875 -11.8125 2.4375 -12.65625 Z M 2.4375 -12.65625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-14">
|
||||||
|
<path d="M 0.140625 -13.640625 L 5.234375 -13.640625 L 8.203125 -6.828125 L 11.203125 -13.640625 L 16.21875 -13.640625 L 7.03125 5.59375 L 2.078125 5.59375 L 5.796875 -1.875 Z M 0.140625 -13.640625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-15">
|
||||||
|
<path d="M 9.21875 -19.40625 L 10.046875 -15.171875 L 6.546875 -15.171875 L 4.3125 -19.40625 Z M 15.625 -6.796875 C 15.625 -6.347656 15.597656 -5.898438 15.546875 -5.453125 L 5.59375 -5.453125 C 6.175781 -4.191406 7.53125 -3.5625 9.65625 -3.5625 C 11.132812 -3.5625 12.609375 -3.820312 14.078125 -4.34375 L 14.078125 -0.59375 C 12.703125 -0.0078125 11.085938 0.28125 9.234375 0.28125 C 6.703125 0.28125 4.691406 -0.359375 3.203125 -1.640625 C 1.722656 -2.929688 0.984375 -4.660156 0.984375 -6.828125 C 0.984375 -8.867188 1.675781 -10.5625 3.0625 -11.90625 C 4.457031 -13.25 6.207031 -13.921875 8.3125 -13.921875 C 10.425781 -13.921875 12.171875 -13.25 13.546875 -11.90625 C 14.929688 -10.5625 15.625 -8.859375 15.625 -6.796875 Z M 8.3125 -10.109375 C 6.875 -10.109375 5.941406 -9.472656 5.515625 -8.203125 L 11.03125 -8.203125 C 10.625 -9.472656 9.71875 -10.109375 8.3125 -10.109375 Z M 8.3125 -10.109375 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-16">
|
||||||
|
<path d="M 2.828125 -11.90625 C 4.054688 -13.25 5.671875 -13.921875 7.671875 -13.921875 C 9.128906 -13.921875 10.25 -13.570312 11.03125 -12.875 L 11.03125 -19.3125 L 15.734375 -19.3125 L 15.734375 0 L 11.375 0 L 11.375 -1.140625 C 10.65625 -0.191406 9.421875 0.28125 7.671875 0.28125 C 5.671875 0.28125 4.054688 -0.394531 2.828125 -1.75 C 1.597656 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.847656 1.597656 -10.539062 2.828125 -11.90625 Z M 6.546875 -4.625 C 7.085938 -4.039062 7.789062 -3.75 8.65625 -3.75 C 9.457031 -3.75 10.269531 -3.992188 11.09375 -4.484375 L 11.09375 -9.1875 C 10.34375 -9.65625 9.53125 -9.890625 8.65625 -9.890625 C 7.789062 -9.890625 7.085938 -9.597656 6.546875 -9.015625 C 6.003906 -8.429688 5.734375 -7.703125 5.734375 -6.828125 C 5.734375 -5.929688 6.003906 -5.195312 6.546875 -4.625 Z M 6.546875 -4.625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-17">
|
||||||
|
<path d="M 3.140625 -11.90625 C 4.578125 -13.25 6.40625 -13.921875 8.625 -13.921875 C 10.28125 -13.921875 11.800781 -13.65625 13.1875 -13.125 L 13.1875 -9.046875 C 11.882812 -9.609375 10.644531 -9.890625 9.46875 -9.890625 C 8.269531 -9.890625 7.347656 -9.601562 6.703125 -9.03125 C 6.054688 -8.457031 5.734375 -7.722656 5.734375 -6.828125 C 5.734375 -5.910156 6.054688 -5.171875 6.703125 -4.609375 C 7.347656 -4.054688 8.269531 -3.78125 9.46875 -3.78125 C 10.582031 -3.78125 11.820312 -4.0625 13.1875 -4.625 L 13.1875 -0.5 C 11.800781 0.0195312 10.28125 0.28125 8.625 0.28125 C 6.40625 0.28125 4.578125 -0.394531 3.140625 -1.75 C 1.703125 -3.101562 0.984375 -4.796875 0.984375 -6.828125 C 0.984375 -8.867188 1.703125 -10.5625 3.140625 -11.90625 Z M 3.140625 -11.90625 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-18">
|
||||||
|
<path d="M 1.546875 -13.25 C 1.546875 -15.050781 2.179688 -16.488281 3.453125 -17.5625 C 4.734375 -18.644531 6.398438 -19.1875 8.453125 -19.1875 C 10.660156 -19.1875 12.734375 -18.8125 14.671875 -18.0625 L 14.671875 -13.78125 C 12.578125 -14.613281 10.609375 -15.03125 8.765625 -15.03125 C 7.117188 -15.03125 6.296875 -14.582031 6.296875 -13.6875 C 6.296875 -13.238281 6.484375 -12.90625 6.859375 -12.6875 C 7.234375 -12.476562 7.882812 -12.234375 8.8125 -11.953125 L 10.1875 -11.5625 C 12 -11.0625 13.367188 -10.351562 14.296875 -9.4375 C 15.234375 -8.519531 15.703125 -7.332031 15.703125 -5.875 C 15.703125 -3.882812 15.007812 -2.335938 13.625 -1.234375 C 12.25 -0.128906 10.378906 0.421875 8.015625 0.421875 C 5.941406 0.421875 3.929688 0.046875 1.984375 -0.703125 L 1.984375 -5.046875 C 4.097656 -4.203125 6.097656 -3.78125 7.984375 -3.78125 C 8.953125 -3.78125 9.6875 -3.925781 10.1875 -4.21875 C 10.695312 -4.519531 10.953125 -4.929688 10.953125 -5.453125 C 10.953125 -5.941406 10.78125 -6.285156 10.4375 -6.484375 C 10.101562 -6.691406 9.441406 -6.929688 8.453125 -7.203125 L 6.9375 -7.609375 C 3.34375 -8.617188 1.546875 -10.5 1.546875 -13.25 Z M 1.546875 -13.25 "/>
|
||||||
|
</g>
|
||||||
|
<g id="glyph-0-19">
|
||||||
|
<path d="M 3.953125 -16.375 C 5.847656 -18.25 8.367188 -19.1875 11.515625 -19.1875 C 13.878906 -19.1875 15.976562 -18.820312 17.8125 -18.09375 L 17.8125 -13.5 C 15.945312 -14.238281 14.03125 -14.609375 12.0625 -14.609375 C 10.195312 -14.609375 8.738281 -14.125 7.6875 -13.15625 C 6.644531 -12.1875 6.125 -10.925781 6.125 -9.375 C 6.125 -7.832031 6.644531 -6.570312 7.6875 -5.59375 C 8.738281 -4.625 10.195312 -4.140625 12.0625 -4.140625 C 14.03125 -4.140625 15.945312 -4.515625 17.8125 -5.265625 L 17.8125 -0.671875 C 15.976562 0.0546875 13.878906 0.421875 11.515625 0.421875 C 8.367188 0.421875 5.84375 -0.515625 3.9375 -2.390625 C 2.039062 -4.265625 1.09375 -6.59375 1.09375 -9.375 C 1.09375 -12.15625 2.046875 -14.488281 3.953125 -16.375 Z M 3.953125 -16.375 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<clipPath id="clip-0">
|
||||||
|
<path clip-rule="nonzero" d="M 2 44 L 80 44 L 80 81 L 2 81 Z M 2 44 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-1">
|
||||||
|
<path clip-rule="nonzero" d="M 20.523438 44.191406 C 10.375 44.191406 2.144531 52.421875 2.144531 62.570312 C 2.144531 72.71875 10.375 80.949219 20.523438 80.949219 L 60.722656 80.949219 C 70.871094 80.949219 79.097656 72.71875 79.097656 62.570312 C 79.097656 52.421875 70.871094 44.191406 60.722656 44.191406 Z M 20.523438 44.191406 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-0" gradientUnits="userSpaceOnUse" x1="0.00000772817" y1="0" x2="1.000005" y2="0" gradientTransform="matrix(-76.952225, 0, 0, -76.952225, 79.098595, 62.570047)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(100%, 100%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(100%, 100%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(100%, 100%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(100%, 99.607849%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(100%, 99.607849%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 99.607849%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(100%, 99.607849%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(100%, 99.607849%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(100%, 99.607849%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 99.607849%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(100%, 99.607849%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(100%, 99.215698%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117187" stop-color="rgb(100%, 99.215698%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(99.607849%, 99.215698%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(99.607849%, 99.215698%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(99.607849%, 99.215698%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(99.607849%, 99.215698%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(99.607849%, 99.215698%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(99.607849%, 99.215698%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(99.607849%, 98.823547%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(99.607849%, 98.823547%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(99.607849%, 98.823547%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(99.607849%, 98.823547%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(99.607849%, 98.823547%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(99.607849%, 98.823547%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(99.607849%, 98.823547%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(99.607849%, 98.823547%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(99.607849%, 98.431396%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(99.607849%, 98.431396%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(99.607849%, 98.431396%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(99.607849%, 98.431396%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(99.607849%, 98.431396%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(99.607849%, 98.431396%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(99.607849%, 98.431396%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(99.607849%, 98.431396%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(99.607849%, 98.431396%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304688" stop-color="rgb(99.607849%, 98.431396%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(99.607849%, 98.431396%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(99.607849%, 98.039246%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(99.607849%, 98.039246%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335938" stop-color="rgb(99.215698%, 98.039246%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(99.215698%, 98.039246%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(99.215698%, 98.039246%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(99.215698%, 98.039246%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(99.215698%, 98.039246%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(99.215698%, 98.039246%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(99.215698%, 97.647095%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(99.215698%, 97.647095%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(99.215698%, 97.647095%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(99.215698%, 97.647095%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(99.215698%, 97.647095%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(99.215698%, 97.647095%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(99.215698%, 97.647095%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(99.215698%, 97.647095%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(99.215698%, 97.254944%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(99.215698%, 97.254944%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(99.215698%, 97.254944%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(99.215698%, 97.254944%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(99.215698%, 97.254944%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(99.215698%, 97.254944%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(98.823547%, 97.254944%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(98.823547%, 97.254944%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(98.823547%, 96.862793%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(98.823547%, 96.862793%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(98.823547%, 96.862793%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(98.823547%, 96.862793%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(98.823547%, 96.862793%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(98.823547%, 96.862793%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554688" stop-color="rgb(98.823547%, 96.862793%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(98.823547%, 96.862793%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(98.823547%, 96.862793%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(98.823547%, 96.862793%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(98.823547%, 96.470642%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(98.823547%, 96.470642%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(98.823547%, 96.470642%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(98.823547%, 96.470642%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(98.431396%, 96.470642%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(98.431396%, 96.470642%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(98.431396%, 96.470642%, 74.902344%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(98.431396%, 96.470642%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(98.431396%, 96.078491%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(98.431396%, 96.078491%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(98.431396%, 96.078491%, 73.33374%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(98.431396%, 96.078491%, 73.33374%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(98.431396%, 96.078491%, 72.941589%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(98.431396%, 96.078491%, 72.549438%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(98.431396%, 96.078491%, 72.157288%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(98.431396%, 96.078491%, 71.765137%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(98.431396%, 96.078491%, 71.372986%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(98.431396%, 96.078491%, 71.372986%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(98.431396%, 95.68634%, 70.980835%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(98.431396%, 95.68634%, 70.588684%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(98.431396%, 95.68634%, 70.196533%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(98.431396%, 95.68634%, 69.804382%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(98.431396%, 95.68634%, 69.412231%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(98.431396%, 95.68634%, 69.412231%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(98.431396%, 95.68634%, 69.020081%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(98.431396%, 95.68634%, 68.62793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(98.431396%, 95.68634%, 68.62793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(98.039246%, 95.68634%, 68.235779%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(98.039246%, 95.68634%, 67.843628%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(98.039246%, 95.294189%, 67.451477%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(98.039246%, 95.294189%, 67.059326%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(98.039246%, 95.294189%, 66.667175%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(98.039246%, 95.294189%, 66.667175%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(98.039246%, 95.294189%, 66.275024%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(98.039246%, 95.294189%, 65.882874%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(98.039246%, 95.294189%, 65.490723%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(98.039246%, 95.294189%, 65.490723%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(98.039246%, 95.294189%, 65.098572%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(98.039246%, 95.294189%, 64.706421%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(98.039246%, 94.902039%, 64.31427%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(98.039246%, 94.902039%, 64.31427%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(98.039246%, 94.902039%, 63.922119%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914062" stop-color="rgb(98.039246%, 94.902039%, 63.529968%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(98.039246%, 94.902039%, 63.137817%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(98.039246%, 94.902039%, 62.745667%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(98.039246%, 94.902039%, 62.745667%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(98.039246%, 94.902039%, 62.353516%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960937" stop-color="rgb(98.039246%, 94.902039%, 61.961365%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(98.039246%, 94.902039%, 61.569214%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(98.039246%, 94.509888%, 61.177063%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(98.039246%, 94.509888%, 60.784912%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-2">
|
||||||
|
<path clip-rule="nonzero" d="M 13 15 L 80 15 L 80 81 L 13 81 Z M 13 15 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-3">
|
||||||
|
<path clip-rule="nonzero" d="M 19.300781 21.152344 C 12.125 28.328125 12.125 39.964844 19.300781 47.140625 L 47.726562 75.566406 C 51.316406 79.15625 56.019531 80.949219 60.722656 80.949219 C 65.425781 80.949219 70.128906 79.15625 73.714844 75.566406 C 80.894531 68.386719 80.894531 56.753906 73.714844 49.574219 L 45.292969 21.152344 C 41.703125 17.5625 37 15.769531 32.296875 15.769531 C 27.59375 15.769531 22.890625 17.5625 19.300781 21.152344 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-1" gradientUnits="userSpaceOnUse" x1="-0.115399" y1="0" x2="1.115408" y2="0" gradientTransform="matrix(-54.414318, -54.414318, 54.414318, -54.414318, 73.71669, 75.565292)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0976562" stop-color="rgb(99.607849%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(99.607849%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.105469" stop-color="rgb(99.215698%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(99.215698%, 99.607849%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.113281" stop-color="rgb(98.823547%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(98.431396%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.121094" stop-color="rgb(98.431396%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(98.039246%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.128906" stop-color="rgb(98.039246%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(97.647095%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.136719" stop-color="rgb(97.254944%, 98.823547%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(97.254944%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.144531" stop-color="rgb(96.862793%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(96.470642%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.152344" stop-color="rgb(96.078491%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(95.68634%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.160156" stop-color="rgb(95.68634%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(95.294189%, 98.431396%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.167969" stop-color="rgb(94.902039%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(94.902039%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.175781" stop-color="rgb(94.509888%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(94.509888%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.183594" stop-color="rgb(94.117737%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(93.725586%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.191406" stop-color="rgb(93.725586%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(93.333435%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.199219" stop-color="rgb(93.333435%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(92.941284%, 97.254944%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.207031" stop-color="rgb(92.549133%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(92.549133%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.214844" stop-color="rgb(92.156982%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(91.764832%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.222656" stop-color="rgb(91.372681%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226563" stop-color="rgb(90.98053%, 96.470642%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.230469" stop-color="rgb(90.98053%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(90.588379%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.238281" stop-color="rgb(90.588379%, 96.078491%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(90.196228%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.246094" stop-color="rgb(89.804077%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(89.804077%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.253906" stop-color="rgb(89.411926%, 95.68634%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(89.411926%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.261719" stop-color="rgb(89.019775%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(88.627625%, 95.294189%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.269531" stop-color="rgb(88.627625%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(88.235474%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.277344" stop-color="rgb(88.235474%, 94.902039%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(87.843323%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.285156" stop-color="rgb(87.451172%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(87.451172%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.292969" stop-color="rgb(87.059021%, 94.509888%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(86.66687%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.300781" stop-color="rgb(86.66687%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304688" stop-color="rgb(86.274719%, 94.117737%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.308594" stop-color="rgb(85.882568%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(85.490417%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.316406" stop-color="rgb(85.098267%, 93.725586%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(85.098267%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.324219" stop-color="rgb(84.706116%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(84.706116%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.332031" stop-color="rgb(84.313965%, 93.333435%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335938" stop-color="rgb(83.921814%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.339844" stop-color="rgb(83.921814%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(83.529663%, 92.941284%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.347656" stop-color="rgb(83.529663%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(83.137512%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.355469" stop-color="rgb(82.745361%, 92.549133%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(82.35321%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.363281" stop-color="rgb(81.96106%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(81.96106%, 92.156982%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.371094" stop-color="rgb(81.568909%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(81.176758%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.378906" stop-color="rgb(81.176758%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(80.784607%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.386719" stop-color="rgb(80.784607%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(80.392456%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.394531" stop-color="rgb(80.000305%, 91.764832%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398438" stop-color="rgb(80.000305%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.402344" stop-color="rgb(79.608154%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(79.608154%, 91.372681%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.410156" stop-color="rgb(79.216003%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(78.823853%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.417969" stop-color="rgb(78.431702%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(78.431702%, 90.98053%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.425781" stop-color="rgb(78.039551%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(77.6474%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.433594" stop-color="rgb(77.255249%, 90.588379%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(77.255249%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.441406" stop-color="rgb(76.863098%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(76.470947%, 90.196228%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.449219" stop-color="rgb(76.470947%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(76.078796%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.457031" stop-color="rgb(75.686646%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(75.686646%, 89.804077%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.464844" stop-color="rgb(75.294495%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(74.902344%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.472656" stop-color="rgb(74.510193%, 89.411926%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476563" stop-color="rgb(74.510193%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.480469" stop-color="rgb(74.118042%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(73.725891%, 89.019775%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.488281" stop-color="rgb(73.33374%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(72.941589%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.496094" stop-color="rgb(72.941589%, 88.627625%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(72.549438%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.503906" stop-color="rgb(72.157288%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(72.157288%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.511719" stop-color="rgb(71.765137%, 88.235474%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(71.765137%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.519531" stop-color="rgb(71.372986%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523437" stop-color="rgb(70.980835%, 87.843323%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.527344" stop-color="rgb(70.588684%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(70.196533%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(70.196533%, 87.451172%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(69.804382%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(69.412231%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(69.412231%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.550781" stop-color="rgb(69.020081%, 87.059021%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(68.62793%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.558594" stop-color="rgb(68.235779%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(67.843628%, 86.66687%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.566406" stop-color="rgb(67.843628%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(67.451477%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.574219" stop-color="rgb(67.059326%, 86.66687%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(66.667175%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.582031" stop-color="rgb(66.275024%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585937" stop-color="rgb(66.275024%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.589844" stop-color="rgb(65.882874%, 86.274719%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(65.490723%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.597656" stop-color="rgb(65.490723%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(65.098572%, 85.882568%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.605469" stop-color="rgb(64.706421%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(64.31427%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.613281" stop-color="rgb(63.922119%, 85.490417%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(63.922119%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.621094" stop-color="rgb(63.529968%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(63.137817%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.628906" stop-color="rgb(63.137817%, 85.098267%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(62.745667%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(62.353516%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(61.961365%, 84.706116%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(61.961365%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(61.569214%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.652344" stop-color="rgb(61.177063%, 84.313965%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(60.784912%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.660156" stop-color="rgb(60.392761%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664063" stop-color="rgb(60.392761%, 83.921814%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.667969" stop-color="rgb(60.00061%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(59.608459%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.675781" stop-color="rgb(59.608459%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(59.216309%, 83.529663%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.683594" stop-color="rgb(58.824158%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(58.432007%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.691406" stop-color="rgb(58.039856%, 83.137512%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695313" stop-color="rgb(58.039856%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.699219" stop-color="rgb(57.647705%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(57.255554%, 83.137512%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.707031" stop-color="rgb(56.863403%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(56.471252%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.714844" stop-color="rgb(56.471252%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(56.079102%, 82.745361%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.722656" stop-color="rgb(55.686951%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726563" stop-color="rgb(55.686951%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.730469" stop-color="rgb(55.2948%, 82.35321%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(54.902649%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.738281" stop-color="rgb(54.510498%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(54.118347%, 81.96106%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.746094" stop-color="rgb(54.118347%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(53.726196%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.753906" stop-color="rgb(53.334045%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(53.334045%, 81.568909%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.761719" stop-color="rgb(52.941895%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(52.549744%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.769531" stop-color="rgb(52.157593%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(52.157593%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.777344" stop-color="rgb(51.765442%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(51.373291%, 81.176758%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.785156" stop-color="rgb(50.98114%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(50.588989%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.792969" stop-color="rgb(50.588989%, 80.784607%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(50.196838%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.800781" stop-color="rgb(49.803162%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804687" stop-color="rgb(49.803162%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.808594" stop-color="rgb(49.411011%, 80.392456%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(49.01886%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.816406" stop-color="rgb(48.626709%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(48.234558%, 80.000305%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.824219" stop-color="rgb(47.842407%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(47.450256%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.832031" stop-color="rgb(47.450256%, 80.000305%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835937" stop-color="rgb(47.058105%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.839844" stop-color="rgb(46.665955%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(46.665955%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.847656" stop-color="rgb(46.273804%, 79.608154%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(45.881653%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.855469" stop-color="rgb(45.489502%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(45.097351%, 79.216003%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.863281" stop-color="rgb(45.097351%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867188" stop-color="rgb(44.7052%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.871094" stop-color="rgb(44.313049%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(43.920898%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.878906" stop-color="rgb(43.528748%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(43.528748%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.886719" stop-color="rgb(43.136597%, 78.823853%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(42.744446%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.894531" stop-color="rgb(42.744446%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(42.352295%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.902344" stop-color="rgb(42.352295%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(41.960144%, 78.431702%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-4">
|
||||||
|
<path clip-rule="nonzero" d="M 42 3 L 80 3 L 80 81 L 42 81 Z M 42 3 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-5">
|
||||||
|
<path clip-rule="nonzero" d="M 42.34375 22.371094 L 42.34375 62.570312 C 42.34375 72.71875 50.570312 80.949219 60.722656 80.949219 C 70.871094 80.949219 79.097656 72.71875 79.097656 62.570312 L 79.097656 22.371094 C 79.097656 12.222656 70.871094 3.996094 60.722656 3.996094 C 50.570312 3.996094 42.34375 12.222656 42.34375 22.371094 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-2" gradientUnits="userSpaceOnUse" x1="0.00000321492" y1="0" x2="0.999994" y2="0" gradientTransform="matrix(0, -76.95372, 76.95372, 0, 60.721073, 80.947947)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0078125" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(99.607849%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(99.607849%, 99.215698%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(99.215698%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(98.823547%, 98.431396%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(98.431396%, 98.039246%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(98.431396%, 97.647095%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(98.039246%, 97.254944%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(97.647095%, 96.862793%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(97.254944%, 96.470642%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(97.254944%, 96.078491%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(96.862793%, 95.68634%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(96.470642%, 95.294189%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(96.078491%, 94.902039%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(96.078491%, 94.509888%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(95.68634%, 94.117737%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(95.294189%, 93.725586%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(94.902039%, 93.333435%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(94.902039%, 92.941284%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(94.509888%, 92.549133%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(94.117737%, 92.156982%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(93.725586%, 91.764832%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(93.725586%, 91.372681%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(93.333435%, 90.98053%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(92.941284%, 90.588379%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(92.549133%, 90.196228%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210937" stop-color="rgb(92.549133%, 89.804077%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(92.156982%, 89.411926%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(91.764832%, 89.019775%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(91.372681%, 88.627625%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242187" stop-color="rgb(91.372681%, 88.235474%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(90.98053%, 87.843323%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(90.98053%, 87.451172%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(90.588379%, 87.451172%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(90.196228%, 87.059021%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(90.196228%, 86.66687%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(89.804077%, 86.274719%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(89.411926%, 85.882568%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(89.019775%, 85.490417%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(89.019775%, 85.098267%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(88.627625%, 84.706116%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(88.627625%, 84.313965%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(88.235474%, 83.921814%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(87.843323%, 83.529663%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(87.451172%, 83.137512%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(87.451172%, 82.745361%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367188" stop-color="rgb(87.059021%, 82.35321%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(87.059021%, 81.96106%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(86.66687%, 81.568909%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(86.274719%, 81.176758%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(85.882568%, 80.784607%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(85.882568%, 80.784607%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(85.490417%, 80.392456%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(85.490417%, 80.000305%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429688" stop-color="rgb(85.098267%, 79.608154%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(84.706116%, 79.216003%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(84.313965%, 78.823853%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(84.313965%, 78.431702%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460938" stop-color="rgb(83.921814%, 78.039551%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(83.921814%, 77.6474%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(83.529663%, 77.255249%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(83.529663%, 76.863098%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492188" stop-color="rgb(83.137512%, 76.470947%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(82.745361%, 76.470947%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(82.745361%, 76.078796%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(82.35321%, 76.078796%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(81.96106%, 75.686646%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(81.96106%, 75.294495%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(81.568909%, 74.902344%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(81.568909%, 74.510193%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(81.176758%, 74.118042%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(81.176758%, 73.725891%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570313" stop-color="rgb(80.784607%, 73.33374%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(80.784607%, 73.33374%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(80.392456%, 72.941589%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(80.000305%, 72.549438%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(79.608154%, 72.157288%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(79.608154%, 71.765137%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617188" stop-color="rgb(79.216003%, 71.372986%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(79.216003%, 70.980835%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(78.823853%, 70.588684%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(78.823853%, 70.588684%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648437" stop-color="rgb(78.431702%, 70.196533%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(78.431702%, 69.804382%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664063" stop-color="rgb(78.039551%, 69.412231%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(78.039551%, 69.020081%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(77.6474%, 68.62793%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(77.255249%, 68.62793%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(76.863098%, 68.235779%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(76.863098%, 67.843628%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710938" stop-color="rgb(76.470947%, 67.451477%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(76.470947%, 67.059326%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(76.078796%, 66.667175%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(76.078796%, 66.667175%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(75.686646%, 66.275024%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(75.686646%, 65.882874%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757813" stop-color="rgb(75.686646%, 65.490723%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(75.294495%, 65.098572%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773438" stop-color="rgb(75.294495%, 65.098572%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(74.902344%, 64.706421%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(74.902344%, 64.31427%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(74.510193%, 63.922119%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(74.510193%, 63.922119%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(74.118042%, 63.529968%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(74.118042%, 63.137817%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(73.725891%, 62.745667%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(73.33374%, 62.353516%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(72.941589%, 61.961365%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851563" stop-color="rgb(72.941589%, 61.961365%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(72.549438%, 61.569214%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867188" stop-color="rgb(72.549438%, 61.177063%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(72.157288%, 60.784912%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(71.765137%, 60.392761%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898437" stop-color="rgb(71.765137%, 60.392761%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(71.765137%, 60.00061%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914063" stop-color="rgb(71.765137%, 59.608459%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(71.372986%, 59.216309%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(70.980835%, 58.824158%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(70.980835%, 58.824158%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(70.588684%, 58.432007%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960938" stop-color="rgb(70.588684%, 58.039856%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(70.196533%, 57.647705%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(69.804382%, 57.255554%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(69.804382%, 56.863403%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-6">
|
||||||
|
<path clip-rule="nonzero" d="M 42 15 L 108 15 L 108 81 L 42 81 Z M 42 15 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-7">
|
||||||
|
<path clip-rule="nonzero" d="M 76.152344 21.152344 L 47.726562 49.574219 C 40.550781 56.75 40.550781 68.386719 47.726562 75.566406 C 51.316406 79.15625 56.019531 80.949219 60.722656 80.949219 C 65.425781 80.949219 70.128906 79.152344 73.714844 75.566406 L 102.140625 47.140625 C 109.316406 39.964844 109.316406 28.328125 102.140625 21.152344 C 98.550781 17.5625 93.847656 15.769531 89.144531 15.769531 C 84.441406 15.769531 79.738281 17.5625 76.152344 21.152344 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-3" gradientUnits="userSpaceOnUse" x1="-0.115406" y1="0" x2="1.115401" y2="0" gradientTransform="matrix(54.414692, -54.414692, 54.414692, 54.414692, 47.726387, 75.56548)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(100%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.113281" stop-color="rgb(100%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117188" stop-color="rgb(100%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(100%, 98.823547%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(100%, 98.431396%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(100%, 98.431396%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(99.607849%, 98.039246%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.152344" stop-color="rgb(99.607849%, 97.647095%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(99.607849%, 97.254944%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(99.607849%, 97.254944%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(99.607849%, 96.862793%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.175781" stop-color="rgb(99.607849%, 96.862793%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179687" stop-color="rgb(99.607849%, 96.470642%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(99.607849%, 96.470642%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.191406" stop-color="rgb(99.607849%, 96.078491%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(99.607849%, 95.68634%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(99.607849%, 95.68634%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210938" stop-color="rgb(99.607849%, 95.294189%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.214844" stop-color="rgb(99.607849%, 94.902039%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(99.607849%, 94.902039%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(99.607849%, 94.509888%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(99.215698%, 94.117737%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242187" stop-color="rgb(99.215698%, 94.117737%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(99.215698%, 93.725586%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.253906" stop-color="rgb(99.215698%, 93.333435%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(99.215698%, 93.333435%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(99.215698%, 92.941284%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273437" stop-color="rgb(99.215698%, 92.549133%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(99.215698%, 92.549133%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(99.215698%, 92.156982%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.292969" stop-color="rgb(99.215698%, 91.764832%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(99.215698%, 91.372681%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(99.215698%, 91.372681%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(98.823547%, 90.98053%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.316406" stop-color="rgb(98.823547%, 90.588379%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(98.823547%, 90.588379%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.324219" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(98.823547%, 90.196228%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(98.823547%, 89.804077%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(98.823547%, 89.411926%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.355469" stop-color="rgb(98.823547%, 89.019775%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(98.823547%, 89.019775%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.363281" stop-color="rgb(98.823547%, 88.627625%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367187" stop-color="rgb(98.823547%, 88.627625%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(98.823547%, 88.235474%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.378906" stop-color="rgb(98.823547%, 88.235474%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(98.823547%, 88.235474%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.386719" stop-color="rgb(98.431396%, 87.843323%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(98.431396%, 87.843323%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.394531" stop-color="rgb(98.431396%, 87.451172%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398438" stop-color="rgb(98.431396%, 87.451172%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(98.431396%, 87.059021%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(98.431396%, 86.66687%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(98.431396%, 86.66687%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429687" stop-color="rgb(98.431396%, 86.274719%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.433594" stop-color="rgb(98.431396%, 85.882568%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(98.431396%, 85.882568%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(98.431396%, 85.490417%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(98.039246%, 85.098267%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.457031" stop-color="rgb(98.039246%, 85.098267%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460937" stop-color="rgb(98.039246%, 84.706116%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.464844" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(98.039246%, 84.313965%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(98.039246%, 83.921814%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.488281" stop-color="rgb(98.039246%, 83.529663%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492188" stop-color="rgb(98.039246%, 83.529663%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.496094" stop-color="rgb(98.039246%, 83.529663%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(98.039246%, 83.137512%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.503906" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(98.039246%, 82.745361%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523438" stop-color="rgb(98.039246%, 82.35321%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(97.647095%, 81.96106%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(97.647095%, 81.96106%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539063" stop-color="rgb(97.647095%, 81.568909%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554688" stop-color="rgb(97.647095%, 81.176758%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(97.647095%, 80.784607%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(97.647095%, 80.392456%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.574219" stop-color="rgb(97.647095%, 80.000305%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(97.647095%, 80.000305%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.582031" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585938" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(97.647095%, 79.608154%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(97.254944%, 79.216003%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.605469" stop-color="rgb(97.254944%, 78.823853%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(97.254944%, 78.431702%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617187" stop-color="rgb(97.254944%, 78.431702%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(97.254944%, 78.039551%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632813" stop-color="rgb(97.254944%, 78.039551%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(97.254944%, 77.6474%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(97.254944%, 77.255249%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(97.254944%, 77.255249%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648438" stop-color="rgb(97.254944%, 76.863098%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(97.254944%, 76.863098%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(96.862793%, 76.470947%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(96.862793%, 76.078796%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.675781" stop-color="rgb(96.862793%, 76.078796%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679688" stop-color="rgb(96.862793%, 75.686646%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.683594" stop-color="rgb(96.862793%, 75.686646%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(96.862793%, 75.294495%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(96.862793%, 75.294495%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(96.862793%, 74.902344%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710937" stop-color="rgb(96.862793%, 74.510193%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(96.862793%, 74.510193%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(96.862793%, 74.118042%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.730469" stop-color="rgb(96.862793%, 73.725891%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(96.470642%, 73.725891%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742188" stop-color="rgb(96.470642%, 73.33374%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(96.470642%, 72.941589%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(96.470642%, 72.941589%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(96.470642%, 72.549438%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.769531" stop-color="rgb(96.470642%, 72.157288%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773438" stop-color="rgb(96.470642%, 72.157288%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(96.470642%, 71.765137%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789063" stop-color="rgb(96.470642%, 71.372986%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(96.470642%, 71.372986%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804688" stop-color="rgb(96.470642%, 70.980835%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(96.470642%, 70.980835%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(96.078491%, 70.588684%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(96.078491%, 70.196533%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.832031" stop-color="rgb(96.078491%, 69.804382%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835938" stop-color="rgb(96.078491%, 69.804382%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.839844" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(96.078491%, 69.412231%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(96.078491%, 69.020081%, 74.902344%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(96.078491%, 68.62793%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(96.078491%, 68.62793%, 74.510193%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882813" stop-color="rgb(96.078491%, 68.235779%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(96.078491%, 68.235779%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898438" stop-color="rgb(96.078491%, 67.843628%, 74.118042%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(95.68634%, 67.451477%, 73.725891%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
<clipPath id="clip-8">
|
||||||
|
<path clip-rule="nonzero" d="M 42 44 L 120 44 L 120 81 L 42 81 Z M 42 44 "/>
|
||||||
|
</clipPath>
|
||||||
|
<clipPath id="clip-9">
|
||||||
|
<path clip-rule="nonzero" d="M 60.722656 44.191406 C 50.570312 44.191406 42.34375 52.421875 42.34375 62.570312 C 42.34375 72.71875 50.570312 80.949219 60.722656 80.949219 L 100.917969 80.949219 C 111.066406 80.949219 119.296875 72.71875 119.296875 62.570312 C 119.296875 52.421875 111.066406 44.191406 100.917969 44.191406 Z M 60.722656 44.191406 "/>
|
||||||
|
</clipPath>
|
||||||
|
<linearGradient id="linear-pattern-4" gradientUnits="userSpaceOnUse" x1="-0.00000221172" y1="0" x2="1.000001" y2="0" gradientTransform="matrix(76.95372, 0, 0, 76.95372, 42.34317, 62.570047)">
|
||||||
|
<stop offset="0" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0078125" stop-color="rgb(100%, 100%, 100%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.015625" stop-color="rgb(99.607849%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0234375" stop-color="rgb(99.215698%, 99.607849%, 99.607849%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.03125" stop-color="rgb(98.823547%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0390625" stop-color="rgb(98.431396%, 99.215698%, 99.215698%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.046875" stop-color="rgb(98.039246%, 98.823547%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0546875" stop-color="rgb(97.647095%, 98.823547%, 98.823547%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0625" stop-color="rgb(97.254944%, 98.431396%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0703125" stop-color="rgb(96.862793%, 98.431396%, 98.431396%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.078125" stop-color="rgb(96.470642%, 98.039246%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.0859375" stop-color="rgb(96.078491%, 98.039246%, 98.039246%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.09375" stop-color="rgb(95.68634%, 98.039246%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.101562" stop-color="rgb(95.68634%, 98.039246%, 97.647095%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.109375" stop-color="rgb(95.294189%, 97.647095%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.117187" stop-color="rgb(94.902039%, 97.647095%, 97.254944%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.125" stop-color="rgb(94.509888%, 97.254944%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.132812" stop-color="rgb(94.117737%, 97.254944%, 96.862793%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.140625" stop-color="rgb(93.725586%, 96.862793%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.148438" stop-color="rgb(93.333435%, 96.862793%, 96.470642%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.15625" stop-color="rgb(92.941284%, 96.470642%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.164062" stop-color="rgb(92.549133%, 96.470642%, 96.078491%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.171875" stop-color="rgb(92.156982%, 96.078491%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.179688" stop-color="rgb(91.764832%, 96.078491%, 95.68634%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.1875" stop-color="rgb(91.372681%, 95.68634%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.195312" stop-color="rgb(90.98053%, 95.68634%, 95.294189%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.203125" stop-color="rgb(90.588379%, 95.294189%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.210938" stop-color="rgb(90.196228%, 95.294189%, 94.902039%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.21875" stop-color="rgb(89.804077%, 94.902039%, 94.509888%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.226562" stop-color="rgb(89.411926%, 94.902039%, 94.117737%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.234375" stop-color="rgb(89.019775%, 94.509888%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.242188" stop-color="rgb(88.627625%, 94.509888%, 93.725586%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.25" stop-color="rgb(88.235474%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.257812" stop-color="rgb(87.843323%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.265625" stop-color="rgb(87.451172%, 94.117737%, 93.333435%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.273438" stop-color="rgb(87.059021%, 93.725586%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.28125" stop-color="rgb(86.66687%, 93.725586%, 92.941284%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.289062" stop-color="rgb(86.274719%, 93.333435%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.296875" stop-color="rgb(85.882568%, 93.333435%, 92.549133%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.304687" stop-color="rgb(85.490417%, 92.941284%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.3125" stop-color="rgb(85.098267%, 92.941284%, 92.156982%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.320312" stop-color="rgb(84.706116%, 92.549133%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.328125" stop-color="rgb(84.313965%, 92.549133%, 91.764832%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.335937" stop-color="rgb(83.921814%, 92.156982%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.34375" stop-color="rgb(83.529663%, 92.156982%, 91.372681%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.351562" stop-color="rgb(83.137512%, 92.156982%, 90.98053%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.359375" stop-color="rgb(82.745361%, 92.156982%, 90.588379%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.367187" stop-color="rgb(82.35321%, 91.764832%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.375" stop-color="rgb(81.96106%, 91.764832%, 90.196228%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.382812" stop-color="rgb(81.568909%, 91.372681%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.390625" stop-color="rgb(81.176758%, 91.372681%, 89.804077%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.398437" stop-color="rgb(80.784607%, 90.98053%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.40625" stop-color="rgb(80.392456%, 90.98053%, 89.411926%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.414062" stop-color="rgb(80.000305%, 90.588379%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.421875" stop-color="rgb(79.608154%, 90.588379%, 89.019775%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.429687" stop-color="rgb(79.216003%, 90.196228%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.4375" stop-color="rgb(78.823853%, 90.196228%, 88.627625%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.445312" stop-color="rgb(78.431702%, 89.804077%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.453125" stop-color="rgb(78.039551%, 89.804077%, 88.235474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.460937" stop-color="rgb(77.6474%, 89.411926%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.46875" stop-color="rgb(77.255249%, 89.411926%, 87.843323%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.476562" stop-color="rgb(76.863098%, 89.019775%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.484375" stop-color="rgb(76.470947%, 89.019775%, 87.451172%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.492187" stop-color="rgb(76.078796%, 88.627625%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5" stop-color="rgb(75.686646%, 88.627625%, 87.059021%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.507812" stop-color="rgb(75.686646%, 88.627625%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.515625" stop-color="rgb(75.294495%, 88.627625%, 86.66687%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.523437" stop-color="rgb(74.902344%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.527344" stop-color="rgb(74.118042%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.53125" stop-color="rgb(74.118042%, 88.235474%, 86.274719%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.535156" stop-color="rgb(73.725891%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.539062" stop-color="rgb(73.33374%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.542969" stop-color="rgb(73.33374%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.546875" stop-color="rgb(72.941589%, 87.843323%, 85.882568%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.554687" stop-color="rgb(72.941589%, 87.451172%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.5625" stop-color="rgb(72.549438%, 87.451172%, 85.490417%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.570312" stop-color="rgb(72.157288%, 87.059021%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.578125" stop-color="rgb(71.765137%, 87.059021%, 85.098267%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.585937" stop-color="rgb(71.372986%, 86.66687%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.59375" stop-color="rgb(70.980835%, 86.66687%, 84.706116%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.601562" stop-color="rgb(70.588684%, 86.274719%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.609375" stop-color="rgb(70.196533%, 86.274719%, 84.313965%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.617187" stop-color="rgb(69.804382%, 85.882568%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.625" stop-color="rgb(69.412231%, 85.882568%, 83.921814%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.632812" stop-color="rgb(69.020081%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.636719" stop-color="rgb(68.62793%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.640625" stop-color="rgb(68.235779%, 85.490417%, 83.529663%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.644531" stop-color="rgb(67.843628%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.648437" stop-color="rgb(67.451477%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.652344" stop-color="rgb(67.451477%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.65625" stop-color="rgb(67.059326%, 85.098267%, 83.137512%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.664062" stop-color="rgb(67.059326%, 84.706116%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.671875" stop-color="rgb(66.667175%, 84.706116%, 82.745361%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.679687" stop-color="rgb(66.275024%, 84.313965%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.6875" stop-color="rgb(65.882874%, 84.313965%, 82.35321%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.695312" stop-color="rgb(65.490723%, 84.313965%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.703125" stop-color="rgb(65.098572%, 84.313965%, 81.96106%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.710937" stop-color="rgb(64.706421%, 83.921814%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.71875" stop-color="rgb(64.31427%, 83.921814%, 81.568909%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.726562" stop-color="rgb(63.922119%, 83.529663%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.734375" stop-color="rgb(63.529968%, 83.529663%, 81.176758%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.742187" stop-color="rgb(63.137817%, 83.137512%, 80.784607%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.746094" stop-color="rgb(62.745667%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.75" stop-color="rgb(62.353516%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.753906" stop-color="rgb(62.353516%, 83.137512%, 80.392456%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.757812" stop-color="rgb(61.961365%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.761719" stop-color="rgb(61.569214%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.765625" stop-color="rgb(61.569214%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.773437" stop-color="rgb(61.177063%, 82.745361%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.78125" stop-color="rgb(60.784912%, 82.35321%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.789062" stop-color="rgb(60.392761%, 82.35321%, 80.000305%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.796875" stop-color="rgb(60.00061%, 82.35321%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.804687" stop-color="rgb(59.608459%, 82.35321%, 79.608154%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.8125" stop-color="rgb(59.216309%, 81.96106%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.820312" stop-color="rgb(58.824158%, 81.96106%, 79.216003%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.828125" stop-color="rgb(58.432007%, 81.568909%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.835937" stop-color="rgb(58.039856%, 81.568909%, 78.823853%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.84375" stop-color="rgb(57.647705%, 81.176758%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.851562" stop-color="rgb(57.255554%, 81.176758%, 78.431702%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.859375" stop-color="rgb(56.863403%, 80.784607%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.867187" stop-color="rgb(56.471252%, 80.784607%, 78.039551%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.875" stop-color="rgb(56.079102%, 80.784607%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.882812" stop-color="rgb(55.686951%, 80.784607%, 77.6474%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.890625" stop-color="rgb(55.2948%, 80.392456%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.898437" stop-color="rgb(54.902649%, 80.392456%, 77.255249%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.90625" stop-color="rgb(54.510498%, 80.000305%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.914062" stop-color="rgb(54.118347%, 80.000305%, 76.863098%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.921875" stop-color="rgb(53.726196%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.929687" stop-color="rgb(53.334045%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.9375" stop-color="rgb(52.941895%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.945312" stop-color="rgb(52.549744%, 79.608154%, 76.470947%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.953125" stop-color="rgb(52.157593%, 79.216003%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.960937" stop-color="rgb(51.765442%, 79.216003%, 76.078796%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.96875" stop-color="rgb(51.373291%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.976562" stop-color="rgb(51.373291%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.984375" stop-color="rgb(50.98114%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="0.992187" stop-color="rgb(50.588989%, 78.823853%, 75.686646%)" stop-opacity="1"/>
|
||||||
|
<stop offset="1" stop-color="rgb(50.196838%, 78.431702%, 75.294495%)" stop-opacity="1"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g clip-path="url(#clip-0)">
|
||||||
|
<g clip-path="url(#clip-1)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-0)" d="M 79.097656 80.949219 L 79.097656 44.191406 L 2.144531 44.191406 L 2.144531 80.949219 Z M 79.097656 80.949219 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-2)">
|
||||||
|
<g clip-path="url(#clip-3)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-1)" d="M 46.507812 115.332031 L 113.484375 48.359375 L 46.507812 -18.617188 L -20.464844 48.359375 Z M 46.507812 115.332031 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-4)">
|
||||||
|
<g clip-path="url(#clip-5)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-2)" d="M 42.34375 80.949219 L 79.097656 80.949219 L 79.097656 3.996094 L 42.34375 3.996094 Z M 42.34375 80.949219 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-6)">
|
||||||
|
<g clip-path="url(#clip-7)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-3)" d="M 7.960938 48.359375 L 74.933594 115.332031 L 141.90625 48.359375 L 74.933594 -18.617188 Z M 7.960938 48.359375 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g clip-path="url(#clip-8)">
|
||||||
|
<g clip-path="url(#clip-9)">
|
||||||
|
<path fill-rule="nonzero" fill="url(#linear-pattern-4)" d="M 42.34375 44.191406 L 42.34375 80.949219 L 119.296875 80.949219 L 119.296875 44.191406 Z M 42.34375 44.191406 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 79.097656 62.570312 C 79.097656 72.71875 70.871094 80.949219 60.722656 80.949219 C 50.570312 80.949219 42.34375 72.71875 42.34375 62.570312 C 42.34375 52.421875 50.570312 44.191406 60.722656 44.191406 C 70.871094 44.191406 79.097656 52.421875 79.097656 62.570312 "/>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-0" x="133.1255" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-1" x="141.8111" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-2" x="158.2975" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="170.0435" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-4" x="187.3475" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="198.5587" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-6" x="224.2543" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="241.4435" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="253.7943" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-9" x="261.5951" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-10" x="279.0391" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="295.5983" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="312.1183" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-11" x="316.5983" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="332.8551" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="344.9791" y="39.8591"/>
|
||||||
|
<use xlink:href="#glyph-0-13" x="349.4591" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-14" x="362.3475" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-13" x="378.3775" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="391.1511" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-15" x="403.2219" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="419.8231" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="445.4655" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-13" x="462.0303" y="39.8591"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-16" x="133.1255" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-11" x="150.4547" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="166.9747" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-17" x="171.4547" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="185.8383" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-5" x="203.1423" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-5" x="228.9331" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-10" x="254.6539" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-1" x="271.2971" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="288.0467" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-17" x="295.7887" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-6" x="310.2927" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-7" x="327.4847" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-8" x="339.8327" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-3" x="347.5747" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-1" x="364.8787" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="381.5107" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-12" x="385.9907" y="66.8511"/>
|
||||||
|
<use xlink:href="#glyph-0-0" x="390.4707" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-18" x="399.0331" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<g fill="rgb(100%, 100%, 100%)" fill-opacity="1">
|
||||||
|
<use xlink:href="#glyph-0-19" x="415.7099" y="66.8511"/>
|
||||||
|
</g>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(86.66687%, 0%, 41.175842%)" fill-opacity="1" d="M 453.445312 65.542969 C 453.445312 66.425781 454.160156 67.140625 455.039062 67.140625 L 472.71875 67.140625 C 473.597656 67.140625 474.3125 66.425781 474.3125 65.542969 L 474.3125 47.867188 C 474.3125 46.984375 473.597656 46.273438 472.71875 46.273438 L 455.039062 46.273438 C 454.160156 46.273438 453.445312 46.984375 453.445312 47.867188 Z M 453.445312 65.542969 "/>
|
||||||
|
<path fill-rule="nonzero" fill="rgb(100%, 100%, 100%)" fill-opacity="1" d="M 465.027344 52.910156 L 462.621094 52.910156 C 462.5 54.304688 462.382812 55.492188 462.273438 56.386719 C 462.160156 57.277344 462.054688 57.957031 461.953125 58.597656 C 461.84375 59.242188 461.738281 59.824219 461.628906 60.351562 C 461.535156 60.765625 461.40625 61.085938 461.226562 61.316406 C 461.050781 61.550781 460.796875 61.710938 460.460938 61.800781 C 460.175781 61.867188 459.902344 61.816406 459.625 61.632812 C 459.351562 61.453125 459.191406 61.238281 459.128906 60.988281 C 459.089844 60.800781 459.078125 60.644531 459.101562 60.515625 C 459.117188 60.386719 459.15625 60.265625 459.214844 60.15625 C 459.269531 60.046875 459.332031 59.945312 459.40625 59.851562 C 459.46875 59.761719 459.542969 59.671875 459.617188 59.582031 C 459.644531 59.554688 459.761719 59.414062 459.984375 59.15625 C 460.203125 58.898438 460.363281 58.664062 460.476562 58.453125 C 460.585938 58.242188 460.828125 57.773438 460.949219 57.195312 C 461.070312 56.617188 461.320312 54.632812 461.316406 52.910156 L 460.300781 52.910156 C 460.015625 52.910156 459.734375 53.003906 459.472656 53.140625 C 459.21875 53.273438 458.992188 53.5 458.890625 53.632812 C 458.78125 53.765625 458.503906 54.210938 458.441406 54.296875 C 458.375 54.382812 458.242188 54.582031 458.144531 54.550781 C 458.035156 54.515625 458.058594 54.394531 458.074219 54.296875 C 458.09375 54.199219 458.292969 53.699219 458.441406 53.324219 C 458.589844 52.945312 458.792969 52.578125 459.046875 52.226562 C 459.246094 51.925781 459.519531 51.710938 459.859375 51.496094 C 460.203125 51.273438 460.597656 51.164062 461.050781 51.164062 L 468.429688 51.164062 C 468.5625 51.164062 469.253906 51.21875 469.253906 52.03125 C 469.253906 52.839844 468.515625 52.910156 468.429688 52.910156 L 466.335938 52.910156 C 466.160156 54.570312 466.074219 56.28125 466.074219 57.964844 C 466.074219 58.269531 466.125 58.570312 466.230469 58.859375 C 466.335938 59.152344 466.464844 59.375 466.617188 59.523438 C 466.816406 59.707031 467.050781 59.824219 467.332031 59.875 C 467.617188 59.925781 467.902344 59.839844 468.191406 59.609375 C 468.351562 59.484375 468.46875 59.34375 468.542969 59.1875 C 468.617188 59.023438 468.660156 58.871094 468.683594 58.726562 C 468.703125 58.578125 468.738281 58.371094 468.742188 58.320312 C 468.746094 58.273438 468.738281 58.089844 468.945312 58.074219 C 469.152344 58.058594 469.171875 58.242188 469.191406 58.441406 C 469.210938 58.640625 469.101562 59.382812 468.9375 59.84375 C 468.769531 60.308594 468.570312 60.679688 468.339844 60.957031 C 468.109375 61.242188 467.886719 61.445312 467.664062 61.566406 C 467.410156 61.71875 467.117188 61.8125 466.785156 61.84375 C 466.449219 61.878906 466.140625 61.796875 465.867188 61.613281 C 465.40625 61.277344 465.054688 60.753906 464.824219 60.039062 C 464.683594 59.621094 464.617188 59.070312 464.597656 58.386719 C 464.578125 57.703125 464.601562 57.035156 464.664062 56.382812 Z M 465.027344 52.910156 "/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 96 KiB |
16606
halfway-presentation/main.pdf
Normal file
259
halfway-presentation/main.typ
Normal file
@@ -0,0 +1,259 @@
|
|||||||
|
#import "@preview/touying:0.7.3": *
|
||||||
|
#import "@preview/touying-unistra-pristine:1.4.3": *
|
||||||
|
#import "@preview/codly:1.3.0": codly, codly-init
|
||||||
|
#import "@preview/codly-languages:0.1.10": codly-languages
|
||||||
|
#import "@preview/cetz:0.5.2": canvas, draw
|
||||||
|
#import "langs.typ": i18n, i18n-date
|
||||||
|
#import "utils.typ": title-slide
|
||||||
|
|
||||||
|
#let langs = (
|
||||||
|
fr: ("fr", "ch"),
|
||||||
|
en: ("en", "gb")
|
||||||
|
)
|
||||||
|
#let (lang, region) = langs.en
|
||||||
|
|
||||||
|
#let i18n = i18n.with(lang)
|
||||||
|
#let i18n-date = i18n-date.with(lang)
|
||||||
|
|
||||||
|
#show raw.where(lang: "midas"): set raw(syntaxes: "midas.sublime-syntax")
|
||||||
|
|
||||||
|
#show: codly-init
|
||||||
|
#codly(languages: codly-languages + (
|
||||||
|
midas: (
|
||||||
|
name: "Midas",
|
||||||
|
color: rgb("#000000"),
|
||||||
|
icon: box(
|
||||||
|
image(
|
||||||
|
"midas.svg",
|
||||||
|
height: 130%,
|
||||||
|
fit: "contain",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
))
|
||||||
|
|
||||||
|
#let regexp = regex(`\[\[(.*?)\]\]`.text)
|
||||||
|
#show raw: it => {
|
||||||
|
show regexp: m => {
|
||||||
|
let key = m.text.slice(2, -2)
|
||||||
|
return i18n(key)
|
||||||
|
}
|
||||||
|
it
|
||||||
|
}
|
||||||
|
|
||||||
|
#pdfpc.config(
|
||||||
|
duration-minutes: 15,
|
||||||
|
start-time: datetime(hour: 9, minute: 30, second: 0),
|
||||||
|
end-time: datetime(hour: 9, minute: 45, second: 0),
|
||||||
|
last-minutes: 2,
|
||||||
|
note-font-size: 12,
|
||||||
|
disable-markdown: false
|
||||||
|
)
|
||||||
|
|
||||||
|
#set text(lang: lang, region: region)
|
||||||
|
#show: unistra-theme.with(
|
||||||
|
aspect-ratio: "16-9",
|
||||||
|
config-common(
|
||||||
|
enable-pdfpc: true
|
||||||
|
),
|
||||||
|
config-info(
|
||||||
|
title: i18n("title"),
|
||||||
|
subtitle: i18n("subtitle"),
|
||||||
|
short-title: i18n("short-title"),
|
||||||
|
author: [Louis Heredero],
|
||||||
|
date: i18n-date(datetime(day: 3, month: 6, year: 2026)),
|
||||||
|
institution: [ISC \@ HEI Sion],
|
||||||
|
logo: stack(
|
||||||
|
dir: ltr,
|
||||||
|
spacing: 1em,
|
||||||
|
image("logo_symbol.svg", height: 100%),
|
||||||
|
image("hei.svg", height: 80%),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
config-store(
|
||||||
|
font: "Source Sans 3",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#title-slide(
|
||||||
|
logo: image("logo_white.svg", height: 3em),
|
||||||
|
extra-body: place(
|
||||||
|
bottom + right,
|
||||||
|
dx: -2em,
|
||||||
|
dy: -2em
|
||||||
|
)[
|
||||||
|
#text(
|
||||||
|
fill: white,
|
||||||
|
weight: "bold"
|
||||||
|
)[#i18n("supervisor"): Dr D. Racordon]
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#focus-slide(
|
||||||
|
theme: "pink",
|
||||||
|
show-counter: false,
|
||||||
|
)[
|
||||||
|
#i18n("context")
|
||||||
|
]
|
||||||
|
|
||||||
|
== #i18n("context")
|
||||||
|
|
||||||
|
==== #i18n("case-1")
|
||||||
|
|
||||||
|
#[
|
||||||
|
#set text(size: .8em)
|
||||||
|
```python
|
||||||
|
df = pd.read_csv(...)
|
||||||
|
value = df["distance"] / df["time"]
|
||||||
|
...
|
||||||
|
value += df["age"]
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
|
#pause
|
||||||
|
|
||||||
|
==== #i18n("case-2")
|
||||||
|
|
||||||
|
#[
|
||||||
|
#set text(size: .8em)
|
||||||
|
```sh
|
||||||
|
louis@powerful-server:$ ./start.sh
|
||||||
|
99%|██████████| 5410/5432 [90:10:06<22:33, 60.00s/it]
|
||||||
|
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
|
== #i18n("goal")
|
||||||
|
|
||||||
|
- #i18n("gradual-typing")
|
||||||
|
- #i18n("optional-typing")
|
||||||
|
- #i18n("static-type-checking")
|
||||||
|
- #i18n("dynamic-checks")
|
||||||
|
|
||||||
|
- #i18n("runtime-assertions")
|
||||||
|
- #i18n("value-constraints")
|
||||||
|
|
||||||
|
|
||||||
|
#let wah = place(
|
||||||
|
right + horizon,
|
||||||
|
dx: (
|
||||||
|
-.4em // inset
|
||||||
|
-100% // width
|
||||||
|
),
|
||||||
|
box(
|
||||||
|
inset: .4em,
|
||||||
|
text(
|
||||||
|
fill: std.red,
|
||||||
|
weight: "bold",
|
||||||
|
$->$
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
== #i18n("example")
|
||||||
|
|
||||||
|
#[
|
||||||
|
#set text(size: .8em)
|
||||||
|
```python
|
||||||
|
df: Frame[
|
||||||
|
verified: bool,
|
||||||
|
birth_date: date,
|
||||||
|
height: float & (0 < _ < 250),
|
||||||
|
name: Optional[str],
|
||||||
|
home: GeoCoordinate,
|
||||||
|
] = pd.read_csv(...)
|
||||||
|
lat = df["home"].lat
|
||||||
|
lon = df["home"].lon
|
||||||
|
invalid = lat + lon # [[lat-lon-error]]
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
|
#focus-slide(
|
||||||
|
theme: "yellow",
|
||||||
|
show-counter: false
|
||||||
|
)[#i18n("planning")]
|
||||||
|
|
||||||
|
== #i18n("initial-planning")
|
||||||
|
|
||||||
|
#table(
|
||||||
|
columns: (auto, 1fr),
|
||||||
|
align: (center, left + horizon),
|
||||||
|
inset: (x: .4em, y: .25em),
|
||||||
|
table.header[*#i18n("week")*][*#i18n("objectives")*],
|
||||||
|
[*1*], i18n("initial-week1"),
|
||||||
|
[*2*], i18n("initial-week2"),
|
||||||
|
[*3*], table.cell(rowspan: 4, i18n("initial-week3-6")),
|
||||||
|
[*4*#wah],
|
||||||
|
[*5*],
|
||||||
|
[*6*],
|
||||||
|
[*7*], table.cell(rowspan: 3, i18n("initial-week7-9")),
|
||||||
|
[*8*],
|
||||||
|
[*9*],
|
||||||
|
)
|
||||||
|
|
||||||
|
== #i18n("current-status")
|
||||||
|
|
||||||
|
#table(
|
||||||
|
columns: (auto, 1fr),
|
||||||
|
align: (center, left + horizon),
|
||||||
|
inset: (x: .4em, y: .25em),
|
||||||
|
table.header[*#i18n("week")*][*#i18n("objectives")*],
|
||||||
|
[*1*], i18n("current-week1"),
|
||||||
|
[*2*], i18n("current-week2"),
|
||||||
|
[*3*], i18n("current-week3"),
|
||||||
|
[*4*#wah], i18n("current-week4"),
|
||||||
|
[*5*], i18n("current-week5"),
|
||||||
|
[*6*], i18n("current-week6"),
|
||||||
|
[*7*], table.cell(rowspan: 3, i18n("current-week7-9")),
|
||||||
|
[*8*],
|
||||||
|
[*9*],
|
||||||
|
)
|
||||||
|
|
||||||
|
#focus-slide(
|
||||||
|
theme: "neon",
|
||||||
|
show-counter: false
|
||||||
|
)[#i18n("demo")]
|
||||||
|
|
||||||
|
== #i18n("demo")
|
||||||
|
|
||||||
|
=== #i18n("def-custom-types")
|
||||||
|
|
||||||
|
#[
|
||||||
|
#set text(size: .8em)
|
||||||
|
```midas
|
||||||
|
type Meter = float
|
||||||
|
type Second = float
|
||||||
|
type MeterPerSecond = float
|
||||||
|
extend Meter {
|
||||||
|
op __add__(Meter) -> Meter
|
||||||
|
op __truediv__(Second) -> MeterPerSecond
|
||||||
|
}
|
||||||
|
extend Second {
|
||||||
|
op __add__(Second) -> Second
|
||||||
|
}
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
=== #i18n("write-program")
|
||||||
|
|
||||||
|
#[
|
||||||
|
#set text(size: .8em)
|
||||||
|
```python
|
||||||
|
distance: Meter = 123.45
|
||||||
|
time: Second = 6.7
|
||||||
|
time += time # [[valid]]
|
||||||
|
|
||||||
|
speed = distance / time # speed: MeterPerSecond
|
||||||
|
speed += time # [[invalid]]
|
||||||
|
```
|
||||||
|
]
|
||||||
|
|
||||||
|
#focus-slide(
|
||||||
|
theme: "mandarine",
|
||||||
|
show-counter: false,
|
||||||
|
)[
|
||||||
|
Questions ?
|
||||||
|
]
|
||||||
15
halfway-presentation/midas.sublime-syntax
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
name: Midas
|
||||||
|
file_extensions: [midas]
|
||||||
|
scope: source.midas
|
||||||
|
|
||||||
|
contexts:
|
||||||
|
main:
|
||||||
|
- match: \b(type|extend|op|predicate)\b
|
||||||
|
scope: keyword.control.midas
|
||||||
|
- match: //
|
||||||
|
scope: punctuation.definition.comment.midas
|
||||||
|
push:
|
||||||
|
- meta_scope: comment.line.midas
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
117
halfway-presentation/midas.svg
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="128"
|
||||||
|
height="128"
|
||||||
|
viewBox="0 0 128 128"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:export-filename="logo.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
inkscape:version="1.4.4 (1:1.4.4+202605061436+dcaf3e7d9e)"
|
||||||
|
sodipodi:docname="logo.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#000000"
|
||||||
|
borderopacity="0.25"
|
||||||
|
inkscape:showpageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="1.9332778"
|
||||||
|
inkscape:cx="-8.2760999"
|
||||||
|
inkscape:cy="112.2446"
|
||||||
|
inkscape:window-width="2584"
|
||||||
|
inkscape:window-height="1028"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="24"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1">
|
||||||
|
<inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="px"
|
||||||
|
originx="0"
|
||||||
|
originy="0"
|
||||||
|
spacingx="4"
|
||||||
|
spacingy="4"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="4"
|
||||||
|
enabled="true"
|
||||||
|
visible="true" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4689"
|
||||||
|
id="linearGradient1478"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
|
||||||
|
x1="26.648937"
|
||||||
|
y1="20.603781"
|
||||||
|
x2="135.66525"
|
||||||
|
y2="114.39767" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4689">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#e1be1e;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4691" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffeb82;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4693" />
|
||||||
|
</linearGradient>
|
||||||
|
<linearGradient
|
||||||
|
inkscape:collect="always"
|
||||||
|
xlink:href="#linearGradient4671"
|
||||||
|
id="linearGradient1475"
|
||||||
|
gradientUnits="userSpaceOnUse"
|
||||||
|
gradientTransform="matrix(0.562541,0,0,0.567972,-9.399749,-5.305317)"
|
||||||
|
x1="150.96111"
|
||||||
|
y1="192.35176"
|
||||||
|
x2="112.03144"
|
||||||
|
y2="137.27299" />
|
||||||
|
<linearGradient
|
||||||
|
id="linearGradient4671">
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffdc21;stop-opacity:1;"
|
||||||
|
offset="0"
|
||||||
|
id="stop4673" />
|
||||||
|
<stop
|
||||||
|
style="stop-color:#ffeb82;stop-opacity:1;"
|
||||||
|
offset="1"
|
||||||
|
id="stop4675" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
inkscape:label="Calque 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1">
|
||||||
|
<g
|
||||||
|
id="g1"
|
||||||
|
transform="translate(2.911719,3.414527)">
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient1478);fill-opacity:1"
|
||||||
|
d="m 60.510156,6.3979729 c -4.583653,0.021298 -8.960939,0.4122177 -12.8125,1.09375 C 36.35144,9.4962267 34.291407,13.691825 34.291406,21.429223 v 10.21875 h 26.8125 v 3.40625 h -26.8125 -10.0625 c -7.792459,0 -14.6157592,4.683717 -16.7500002,13.59375 -2.46182,10.212966 -2.5710151,16.586023 0,27.25 1.9059283,7.937852 6.4575432,13.593748 14.2500002,13.59375 h 9.21875 v -12.25 c 0,-8.849902 7.657144,-16.656248 16.75,-16.65625 h 26.78125 c 7.454951,0 13.406253,-6.138164 13.40625,-13.625 v -25.53125 c 0,-7.266339 -6.12998,-12.7247775 -13.40625,-13.9375001 -4.605987,-0.7667253 -9.385097,-1.1150483 -13.96875,-1.09375 z m -14.5,8.2187501 c 2.769547,0 5.03125,2.298646 5.03125,5.125 -2e-6,2.816336 -2.261703,5.09375 -5.03125,5.09375 -2.779476,-1e-6 -5.03125,-2.277415 -5.03125,-5.09375 -1e-6,-2.826353 2.251774,-5.125 5.03125,-5.125 z"
|
||||||
|
id="path1948" />
|
||||||
|
<path
|
||||||
|
style="fill:url(#linearGradient1475);fill-opacity:1"
|
||||||
|
d="m 91.228906,35.054223 v 11.90625 c 0,9.230755 -7.825895,16.999999 -16.75,17 h -26.78125 c -7.335833,0 -13.406249,6.278483 -13.40625,13.625 v 25.531247 c 0,7.26634 6.318588,11.54032 13.40625,13.625 8.487331,2.49561 16.626237,2.94663 26.78125,0 6.750155,-1.95439 13.406253,-5.88761 13.40625,-13.625 V 92.897973 h -26.78125 v -3.40625 h 26.78125 13.406254 c 7.79246,0 10.69625,-5.435408 13.40624,-13.59375 2.79933,-8.398886 2.68022,-16.475776 0,-27.25 -1.92578,-7.757441 -5.60387,-13.59375 -13.40624,-13.59375 z m -15.0625,64.65625 c 2.779478,3e-6 5.03125,2.277417 5.03125,5.093747 -2e-6,2.82635 -2.251775,5.125 -5.03125,5.125 -2.76955,0 -5.03125,-2.29865 -5.03125,-5.125 2e-6,-2.81633 2.261697,-5.093747 5.03125,-5.093747 z"
|
||||||
|
id="path1950" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 4.7 KiB |
100
halfway-presentation/utils.typ
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
#import "@preview/touying:0.6.2": *
|
||||||
|
#import "@preview/touying-unistra-pristine:1.4.3": *
|
||||||
|
|
||||||
|
// Redefine to allow extra-body
|
||||||
|
#let title-slide(
|
||||||
|
title: "",
|
||||||
|
subtitle: "",
|
||||||
|
logo: "",
|
||||||
|
logos: (),
|
||||||
|
hide: (),
|
||||||
|
extra-body: [],
|
||||||
|
..args,
|
||||||
|
) = touying-slide-wrapper(self => {
|
||||||
|
let info = self.info + args.named()
|
||||||
|
|
||||||
|
let nb-logos = logos.len()
|
||||||
|
|
||||||
|
if logo != "" and nb-logos > 0 {
|
||||||
|
panic("'logo' and 'logos' cannot be set at the same time.")
|
||||||
|
}
|
||||||
|
|
||||||
|
let logo-body = none
|
||||||
|
if nb-logos == 0 {
|
||||||
|
logo-body = logo
|
||||||
|
} else {
|
||||||
|
logo-body = grid(
|
||||||
|
columns: if nb-logos > 0 {
|
||||||
|
nb-logos
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
},
|
||||||
|
..(logos).map(logo => logo),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let body = {
|
||||||
|
set text(fill: white)
|
||||||
|
set block(inset: 0mm, outset: 0mm, spacing: 0em)
|
||||||
|
set align(top + left)
|
||||||
|
_gradientize(
|
||||||
|
self,
|
||||||
|
block(
|
||||||
|
fill: none,
|
||||||
|
width: 100%,
|
||||||
|
height: 100%,
|
||||||
|
inset: (left: 2em, top: 1em),
|
||||||
|
grid(
|
||||||
|
columns: 1fr,
|
||||||
|
rows: (6em, 6em, 4em, 4em),
|
||||||
|
logo-body,
|
||||||
|
_cell([
|
||||||
|
#text(size: 2em, weight: "bold", if (title != "") {
|
||||||
|
title
|
||||||
|
} else {
|
||||||
|
info.title
|
||||||
|
})
|
||||||
|
#linebreak()
|
||||||
|
#text(size: 1.7em, weight: "regular", if (subtitle != "") {
|
||||||
|
subtitle
|
||||||
|
} else {
|
||||||
|
info.subtitle
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
|
||||||
|
_cell([
|
||||||
|
#if ((none, "").all(x => x != info.subtitle)) {
|
||||||
|
linebreak()
|
||||||
|
}
|
||||||
|
#set text(size: 1.5em, fill: self.colors.white)
|
||||||
|
#text(weight: "bold", info.author)
|
||||||
|
#if "email" in info {
|
||||||
|
linebreak()
|
||||||
|
text(info.email, size: 0.8em)
|
||||||
|
}
|
||||||
|
]),
|
||||||
|
if "date" not in hide {
|
||||||
|
_cell([
|
||||||
|
#set text(fill: self.colors.white.transparentize(25%))
|
||||||
|
#utils.display-info-date(self)
|
||||||
|
])
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
c1: self.colors.nblue.E,
|
||||||
|
c2: self.colors.cyan.E,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
self = utils.merge-dicts(
|
||||||
|
self,
|
||||||
|
config-common(freeze-slide-counter: true),
|
||||||
|
config-page(margin: 0em),
|
||||||
|
config-common(subslide-preamble: none),
|
||||||
|
)
|
||||||
|
|
||||||
|
touying-slide(
|
||||||
|
self: self,
|
||||||
|
body + extra-body,
|
||||||
|
)
|
||||||
|
})
|
||||||
@@ -14,3 +14,26 @@
|
|||||||
- Read TAPL (22)
|
- Read TAPL (22)
|
||||||
- Rework abstract types
|
- Rework abstract types
|
||||||
- Generalize syntax (more modularity for generics, unions, constraints, etc.)
|
- Generalize syntax (more modularity for generics, unions, constraints, etc.)
|
||||||
|
- Weekly meeting
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- Halfway presentations
|
||||||
|
- Define formal syntax and typing rules
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- Work on formal rules
|
||||||
|
- Update syntax definition (EBNF + railroad diagrams)
|
||||||
|
- Add usage documentation
|
||||||
|
- Implement subtyping
|
||||||
|
|
||||||
|
#day(6)
|
||||||
|
|
||||||
|
- Implement subtyping
|
||||||
|
|
||||||
|
#day(7)
|
||||||
|
|
||||||
|
- Implement subtyping
|
||||||
|
- Implement attribute reference and assignments
|
||||||
|
- Improve diagnostics in CLI
|
||||||
|
|||||||
44
journal/week5.typ
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#import "template.typ": week, day
|
||||||
|
|
||||||
|
#show: week.with(num: 5)
|
||||||
|
|
||||||
|
#day(1)
|
||||||
|
|
||||||
|
- Implement generics
|
||||||
|
- Refactor type checker
|
||||||
|
- Create demo program
|
||||||
|
|
||||||
|
#day(2)
|
||||||
|
|
||||||
|
- Define formal calculus rules
|
||||||
|
- Add type params to extend block
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- Rework extend block for methods
|
||||||
|
- Goal: allow defining any method on types
|
||||||
|
- Issues:
|
||||||
|
- `GetExpr` can reference either a property on a `ComplexType` or a method.
|
||||||
|
- A method (or function) can be overloaded, for example ```py list[T].__getitem__(int) -> T``` and ```py list[T].__getitem__(slice) -> list[T]```
|
||||||
|
|
||||||
|
#day(4)
|
||||||
|
|
||||||
|
- Rework complex types: extension type, combine properties and methods as members
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- Implement member lookup
|
||||||
|
- Adapt operations
|
||||||
|
- Handle generic members
|
||||||
|
|
||||||
|
#day(6)
|
||||||
|
|
||||||
|
- Redefine builtins with members
|
||||||
|
- Tidy up
|
||||||
|
- Add unary operations and subscripts
|
||||||
|
|
||||||
|
#day(7)
|
||||||
|
|
||||||
|
- Resolve overloaded functions
|
||||||
|
- Add slices
|
||||||
|
- Add simple code generator
|
||||||
40
journal/week6.typ
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#import "template.typ": week, day
|
||||||
|
|
||||||
|
#show: week.with(num: 6)
|
||||||
|
|
||||||
|
#day(1)
|
||||||
|
|
||||||
|
- Simple code generator
|
||||||
|
- Redesign CLI
|
||||||
|
- Split overloaded command into multiple simple commands
|
||||||
|
- Add some commands
|
||||||
|
- Add for loops
|
||||||
|
- Start implementing cast assertions
|
||||||
|
|
||||||
|
#day(2)
|
||||||
|
|
||||||
|
- Weekly meeting
|
||||||
|
- Forward raw unhandled Python statements and expressions
|
||||||
|
- Generate cast assertions (type)
|
||||||
|
- Add generator tests
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- Generate stubs from Midas definitions
|
||||||
|
|
||||||
|
#day(4)
|
||||||
|
|
||||||
|
- Generate predicate functions
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- Type check predicate body
|
||||||
|
|
||||||
|
#day(6)
|
||||||
|
|
||||||
|
- Add variance to type variables (infer, use in subtype check, integrate in generated stubs)
|
||||||
|
- Unify / match types in generic function calls
|
||||||
|
|
||||||
|
#day(7)
|
||||||
|
|
||||||
|
- Unify / match types in generic function calls
|
||||||
34
journal/week7.typ
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#import "template.typ": week, day
|
||||||
|
|
||||||
|
#show: week.with(num: 7)
|
||||||
|
|
||||||
|
#day(1)
|
||||||
|
|
||||||
|
- better handle type variables
|
||||||
|
- write simple demo script
|
||||||
|
- various fixes
|
||||||
|
|
||||||
|
#day(2)
|
||||||
|
|
||||||
|
- weekly meeting
|
||||||
|
- start implementing data-frame and column types
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- statically check cast expressions on literal values
|
||||||
|
- add unsafe cast
|
||||||
|
- setup user manual
|
||||||
|
- setup report
|
||||||
|
|
||||||
|
#day(4)
|
||||||
|
|
||||||
|
- work on data-frame and column types (method resolution, subtyping)
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- work on data-frame and column types (asserts, dunders)
|
||||||
|
- start writing user manual (quick start)
|
||||||
|
|
||||||
|
#day(7)
|
||||||
|
|
||||||
|
- work on user manual (Midas reference, supported Python syntax)
|
||||||
49
journal/week8.typ
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#import "template.typ": week, day
|
||||||
|
|
||||||
|
#show: week.with(num: 8)
|
||||||
|
|
||||||
|
#day(1)
|
||||||
|
|
||||||
|
- improvements and bugfixes
|
||||||
|
- unknown frame methods
|
||||||
|
- assertion on column values
|
||||||
|
- allow unknowns in more places
|
||||||
|
- parse empty calls
|
||||||
|
- tuple type instantiation
|
||||||
|
- `str` methods
|
||||||
|
- multi-parameter generic
|
||||||
|
- tuple expression
|
||||||
|
|
||||||
|
#day(2)
|
||||||
|
|
||||||
|
- weekly meeting
|
||||||
|
- generate stubs when compiling
|
||||||
|
- work on frames and columns (brainstorm / setup methods)
|
||||||
|
- start working on call dispatcher
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- finish call dispatcher
|
||||||
|
- add type aliases
|
||||||
|
- work on frame and columns method registry
|
||||||
|
|
||||||
|
#day(4)
|
||||||
|
|
||||||
|
- implement group-by on frames and columns
|
||||||
|
- implement some methods on frames and columns
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- implement arithmetic, comparison and aggregation methods, `head`/`tail` and some attributes on frames and columns
|
||||||
|
- refactor printers
|
||||||
|
- rename `Function.Argument` -> `Function.Parameter`
|
||||||
|
- update manual for frames and columns
|
||||||
|
- add some docstrings
|
||||||
|
|
||||||
|
#day(6)
|
||||||
|
|
||||||
|
- add more docstrings
|
||||||
|
|
||||||
|
#day(7)
|
||||||
|
|
||||||
|
- add more docstrings
|
||||||
43
journal/week9.typ
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#import "template.typ": week, day
|
||||||
|
|
||||||
|
#show: week.with(num: 9)
|
||||||
|
|
||||||
|
#day(1)
|
||||||
|
|
||||||
|
- add more docstrings
|
||||||
|
- handle column subscript
|
||||||
|
- handle `not` operator
|
||||||
|
- properly type check parameter default values
|
||||||
|
- handle import statements
|
||||||
|
- handle column type instantiation
|
||||||
|
|
||||||
|
#day(2)
|
||||||
|
|
||||||
|
- parse int literals as integers
|
||||||
|
- implement scalar ops on frames and columns
|
||||||
|
- add more docstrings
|
||||||
|
- fix some bugs, make some small improvements
|
||||||
|
- complete weather pipeline example with frame operations
|
||||||
|
- implement formulae to compute aggregation method return types
|
||||||
|
|
||||||
|
#day(3)
|
||||||
|
|
||||||
|
- weekly meeting
|
||||||
|
- update syntax definitions
|
||||||
|
- check variable assignment when referenced
|
||||||
|
- add CI to run tests
|
||||||
|
- remove complex type
|
||||||
|
- complete user manual, including CLI subcommands
|
||||||
|
- add variance manager
|
||||||
|
- minor improvements
|
||||||
|
|
||||||
|
#day(4)
|
||||||
|
|
||||||
|
- check, document and fix function subtyping logic
|
||||||
|
- add some tests
|
||||||
|
- cleanup repository
|
||||||
|
|
||||||
|
#day(5)
|
||||||
|
|
||||||
|
- remove some raised errors to use diagnostics
|
||||||
|
- code repository submission
|
||||||
38
justfile
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
# Local Variables:
|
||||||
|
# mode: makefile
|
||||||
|
# End:
|
||||||
|
set shell := ["bash", "-uc"]
|
||||||
|
|
||||||
|
outdir := "out"
|
||||||
|
report_out_path := outdir / "report.pdf"
|
||||||
|
summary_out_path := outdir / "summary.pdf"
|
||||||
|
|
||||||
|
default: all
|
||||||
|
|
||||||
|
_setup:
|
||||||
|
mkdir -p {{outdir}}
|
||||||
|
|
||||||
|
check-links document:
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
import re
|
||||||
|
import requests
|
||||||
|
import sys
|
||||||
|
print("Checking links in {{document}}...")
|
||||||
|
with open("{{document}}", "rb") as f:
|
||||||
|
r = rb"</Type/Action/S/URI/URI\((.*?)\)"
|
||||||
|
matches = set(re.findall(r, f.read(), re.S))
|
||||||
|
print(f"Found {len(matches)} links")
|
||||||
|
for url in matches:
|
||||||
|
print(f"Testing {url.decode('utf-8')}")
|
||||||
|
res = requests.head(url, headers={"User-Agent": "BrokenURLChecker 1.0"})
|
||||||
|
if not (200 <= res.status_code <= 399):
|
||||||
|
print(f"{url} is broken: {res.status_code} {res.reason}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
report: _setup
|
||||||
|
typst c --root . report/bachelor_thesis.typ {{report_out_path}}
|
||||||
|
|
||||||
|
summary: _setup
|
||||||
|
typst c --root . summary/exec_summary.typ {{summary_out_path}}
|
||||||
|
|
||||||
|
all: report summary
|
||||||
25
meta.typ
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#let title = "Midas"
|
||||||
|
#let subtitle = none
|
||||||
|
#let authors = "Louis Heredero"
|
||||||
|
|
||||||
|
#let thesis-supervisor = "Prof. Dr Dimi Racordon"
|
||||||
|
#let thesis-co-supervisor = none
|
||||||
|
#let thesis-expert = "Dr Sébastien Doeraene"
|
||||||
|
#let thesis-id = "ISC-ID-26-8"
|
||||||
|
#let project-repos = "https://git.kb28.ch/HEL/midas"
|
||||||
|
#let mirror-repo = "https://github.com/LordBaryhobal/midas"
|
||||||
|
|
||||||
|
#let school = "Haute École d'Ingénierie de Sion"
|
||||||
|
#let programme = "Informatique et systèmes de communication (ISC)"
|
||||||
|
|
||||||
|
#let keywords = ("engineering", "type systems", "gradual typing")
|
||||||
|
#let major = "Data engineering"
|
||||||
|
#let date = datetime(year: 2026, month: 7, day: 10) // Date of the thesis & the declaration (or datetime.today())
|
||||||
|
|
||||||
|
#let permanent-email = "louis@heredero.org"
|
||||||
|
#let video-url = none
|
||||||
|
|
||||||
|
#let picture-web-opt-out = false // set to true to keep your picture off the web
|
||||||
|
#let email-web-opt-out = false // set to true to keep your email off the web
|
||||||
|
|
||||||
|
#let academic-year = "2025-2026"
|
||||||
211
midas.sublime-syntax
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
name: Midas
|
||||||
|
file_extensions:
|
||||||
|
- midas
|
||||||
|
scope: source.midas
|
||||||
|
|
||||||
|
variables:
|
||||||
|
identifier: "[a-zA-Z_][a-zA-Z0-9_]*"
|
||||||
|
|
||||||
|
contexts:
|
||||||
|
prototype:
|
||||||
|
- include: comments
|
||||||
|
|
||||||
|
main:
|
||||||
|
- include: keywords
|
||||||
|
- include: types
|
||||||
|
|
||||||
|
comments:
|
||||||
|
- match: "//"
|
||||||
|
scope: punctuation.definition.comment.midas
|
||||||
|
push:
|
||||||
|
- meta_scope: comment.line.midas
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
- match: /\*
|
||||||
|
scope: punctuation.definition.comment.midas
|
||||||
|
push:
|
||||||
|
- meta_scope: comment.block.midas
|
||||||
|
- match: \*/
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
string:
|
||||||
|
- meta_include_prototype: false
|
||||||
|
- meta_scope: string.quoted.double.c
|
||||||
|
- match: '"'
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
keywords:
|
||||||
|
- match: \balias\b
|
||||||
|
scope: keyword.declaration.midas
|
||||||
|
push: alias-stmt
|
||||||
|
- match: \btype\b
|
||||||
|
scope: keyword.declaration.midas
|
||||||
|
push: type-stmt
|
||||||
|
- match: \bextend\b
|
||||||
|
scope: keyword.declaration.midas
|
||||||
|
push: extend-stmt
|
||||||
|
- match: \bpredicate\b
|
||||||
|
scope: keyword.declaration.midas
|
||||||
|
push: predicate-stmt
|
||||||
|
|
||||||
|
alias-stmt:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: entity.name.type
|
||||||
|
- match: "="
|
||||||
|
scope: keyword.operator.equal.midas
|
||||||
|
push: type-expr
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
type-stmt:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: entity.name.type
|
||||||
|
- match: \[
|
||||||
|
push: type-params
|
||||||
|
- match: "="
|
||||||
|
scope: keyword.operator.equal.midas
|
||||||
|
push: type-expr
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
type-expr:
|
||||||
|
- match: \b(fn)\s*(\()
|
||||||
|
captures:
|
||||||
|
1: keyword.other.midas
|
||||||
|
2: punctuation.section.group.begin
|
||||||
|
push: fn-params
|
||||||
|
- match: \b(where)\b
|
||||||
|
scope: keyword.other.midas
|
||||||
|
set: constraint
|
||||||
|
- match: "Frame"
|
||||||
|
scope: entity.name.type
|
||||||
|
push:
|
||||||
|
- match: \[
|
||||||
|
push: frame-schema
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: entity.name.type
|
||||||
|
- match: $
|
||||||
|
pop: 2
|
||||||
|
|
||||||
|
fn-params:
|
||||||
|
- match: "({{identifier}})(:)"
|
||||||
|
captures:
|
||||||
|
1: variable.parameter.midas
|
||||||
|
2: punctuation.separator.annotation.midas
|
||||||
|
push:
|
||||||
|
- include: type-expr
|
||||||
|
- match: \?
|
||||||
|
scope: keyword.operator.qmark.midas
|
||||||
|
- match: "(?=,)"
|
||||||
|
scope: punctuation.separator.midas
|
||||||
|
pop: true
|
||||||
|
- match: '(?=\))'
|
||||||
|
pop: true
|
||||||
|
- include: type-expr
|
||||||
|
- match: '\)'
|
||||||
|
set:
|
||||||
|
- match: "->"
|
||||||
|
scope: keyword.operator.arrow.midas
|
||||||
|
set: type-expr
|
||||||
|
|
||||||
|
constraint:
|
||||||
|
- match: $
|
||||||
|
pop: 2
|
||||||
|
|
||||||
|
- match: \d+(\.\d+)?
|
||||||
|
scope: constant.numeric.midas
|
||||||
|
|
||||||
|
- match: \b(true|false|none)\b
|
||||||
|
scope: constant.language.midas
|
||||||
|
|
||||||
|
- match: '"'
|
||||||
|
push: string
|
||||||
|
|
||||||
|
- match: (<=|>=|<|>|==|!=|&)
|
||||||
|
scope: keyword.operator
|
||||||
|
|
||||||
|
- match: _
|
||||||
|
scope: variable.language.midas
|
||||||
|
|
||||||
|
- match: '{{identifier}}(?=\s*\()'
|
||||||
|
scope: variable.function.midas
|
||||||
|
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: variable.other.readwrite.midas
|
||||||
|
|
||||||
|
type-params:
|
||||||
|
- match: "<:"
|
||||||
|
scope: keyword.operator.subtype.midas
|
||||||
|
- match: "[a-zA-Z][a-zA-Z_0-9]*"
|
||||||
|
scope: entity.name.type
|
||||||
|
- match: "]"
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
extend-stmt:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: entity.name.type
|
||||||
|
- match: \[
|
||||||
|
push: type-params
|
||||||
|
- match: \{
|
||||||
|
scope: punctuation.section.block.begin
|
||||||
|
set: extend-body
|
||||||
|
|
||||||
|
extend-body:
|
||||||
|
- include: member-stmt
|
||||||
|
- match: \}
|
||||||
|
scope: punctuation.section.block.end
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
member-stmt:
|
||||||
|
- match: \b(prop|def)\b
|
||||||
|
scope: keyword.other.midas
|
||||||
|
push:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: variable.other.member
|
||||||
|
- match: ":"
|
||||||
|
push: type-expr
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
predicate-stmt:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: entity.name.function.midas
|
||||||
|
- match: '\('
|
||||||
|
push: predicate-params
|
||||||
|
- match: "="
|
||||||
|
scope: keyword.operator.equal.midas
|
||||||
|
set: constraint
|
||||||
|
- match: $
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
predicate-params:
|
||||||
|
- match: "({{identifier}})(:)"
|
||||||
|
captures:
|
||||||
|
1: variable.parameter.midas
|
||||||
|
2: punctuation.separator.annotation.midas
|
||||||
|
push:
|
||||||
|
- include: type-expr
|
||||||
|
- match: "(?=,)"
|
||||||
|
scope: punctuation.separator.midas
|
||||||
|
pop: true
|
||||||
|
- match: '(?=\))'
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
- match: '\)'
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
frame-schema:
|
||||||
|
- include: frame-column
|
||||||
|
- match: \]
|
||||||
|
# scope: punctuation.section.block.end
|
||||||
|
pop: true
|
||||||
|
|
||||||
|
frame-column:
|
||||||
|
- match: "{{identifier}}"
|
||||||
|
scope: variable.other.member
|
||||||
|
- match: ":"
|
||||||
|
push: type-expr
|
||||||
10
report/acronyms.typ
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#import "@preview/acrostiche:0.7.0": *
|
||||||
|
|
||||||
|
#let acronyms = (
|
||||||
|
"TaPL": ([Types and Progamming Languages@tapl],),
|
||||||
|
"LSP": (link("https://en.wikipedia.org/wiki/Liskov_substitution_principle")[Liskov substitution principle],),
|
||||||
|
"AST": ([Abstract Syntax Tree],),
|
||||||
|
"LUB": ([Least Upper Bound],),
|
||||||
|
)
|
||||||
|
|
||||||
|
#init-acronyms(acronyms)
|
||||||
13
report/appendices/call_dispatcher.typ
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: code
|
||||||
|
|
||||||
|
#let call-dispatcher-code = raw(
|
||||||
|
read("../code/call_dispatcher.py"),
|
||||||
|
lang: "python",
|
||||||
|
block: true
|
||||||
|
)
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(call-dispatcher-code),
|
||||||
|
caption: [Some call dispatcher methods]
|
||||||
|
) <fig:call-dispatcher>
|
||||||
88
report/appendices/function_subtyping.typ
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#import "@preview/curryst:0.6.0": prooftree, rule, rule-set
|
||||||
|
#import "@preview/gentle-clues:1.3.1" as gc
|
||||||
|
#import "@preview/lovelace:0.3.1": pseudocode-list
|
||||||
|
|
||||||
|
#let req = math.op("req")
|
||||||
|
|
||||||
|
This document formalizes the logic used when checking whether a function is a subtype of another.
|
||||||
|
|
||||||
|
= Definitions
|
||||||
|
|
||||||
|
A *Parameter specification* has a list of positional-only parameters $P$, mixed parameters $M$ and keyword-only parameters $K$:
|
||||||
|
$ S = (P, M, K) $
|
||||||
|
|
||||||
|
A *Parameter* has an index $i$, a name $n$ and a required flag $r$:
|
||||||
|
$ p = (i, n, r) $
|
||||||
|
|
||||||
|
A *Function* has a param spec $S$ and a return type $R$:
|
||||||
|
$ F = (S, R) $
|
||||||
|
|
||||||
|
= Main rules
|
||||||
|
|
||||||
|
We want to define a rule for checking structural subtyping of functions, i.e. to check when $F_1 <: F_2$
|
||||||
|
|
||||||
|
There are two conditions to check:
|
||||||
|
#align(center, prooftree(
|
||||||
|
rule(
|
||||||
|
$Gamma tack S_2 <: S_1$,
|
||||||
|
$Gamma tack R_1 <: R_2$,
|
||||||
|
$Gamma tack F_1 <: F_2$,
|
||||||
|
),
|
||||||
|
))
|
||||||
|
|
||||||
|
The second condition is trivial to check.
|
||||||
|
The first condition is a bit more tricky.
|
||||||
|
|
||||||
|
For a parameter specification $S_2$ to be a subtype of another $S_1$, the latter needs to be fully compatible with any usages of the former. What this means is that #link(<cond-1>)[(1)] any argument that can be passed to $S_2$ must be accepted by $S_1$, and #link(<cond-2>)[(2)] $S_1$ must not have additional required arguments that are not in $S_2$. However, $S_1$ can have additional optional parameters not present in $S_2$.
|
||||||
|
|
||||||
|
After mapping parameters of $S_1$ and $S_2$, types must be checked such that if a parameter $p_i: T in S_1$ is mapped to a parameter $q_j: U in S_2$, $U <: T$.
|
||||||
|
|
||||||
|
= Detailed rules for *ParamSpec* subtyping
|
||||||
|
|
||||||
|
#gc.info(title: [Notation])[
|
||||||
|
In the following equations:
|
||||||
|
- the notation $S in.rev a^i: T$ will be used to denote that a parameter spec $S$ accepts an argument named $a$ at index $i$ of type $T$
|
||||||
|
- the special name $alpha$ will be used to denote any argument without a specific name
|
||||||
|
- the special name $phi$ will be used to denote any parameter without a specific name
|
||||||
|
- $AA$ denotes the group of all arguments, i.e. $alpha in AA$
|
||||||
|
- $PP$ denotes the group of all parameters, i.e. $p in PP$
|
||||||
|
- $req(S, alpha)$ is a predicate checking whether $alpha$ is required in $S$
|
||||||
|
]
|
||||||
|
|
||||||
|
== Arguments of $S_2$ are compatible with $S_1$ <cond-1>
|
||||||
|
|
||||||
|
Formally, the condition is:
|
||||||
|
$
|
||||||
|
forall alpha in AA, S_2 in.rev alpha => S_1 in.rev alpha
|
||||||
|
$
|
||||||
|
|
||||||
|
Let $S_1 = (P_1, M_1, K_1)$ and $S_2 = (P_2, M_2, K_2)$.
|
||||||
|
|
||||||
|
For each positional-only parameter $phi_i in P_2$, $phi_i in P_1 or phi_i in M_1$. A positional-only parameter of $S_2$ can either be positional-only or mixed in $S_1$. Additionally, $not req(S_2, phi_i) => not req(S_1, phi_i)$. If $phi_i$ is optional in $S_2$, it must also be optional in $S_1$ so that a call omitting it is valid.
|
||||||
|
|
||||||
|
Similarly, for each keyword-only parameter $p in K_2$, $p in K_1 or p in M_1$. A keyword-only parameter of $S_2$ can either be keyword-only or mixed in $S_1$. Additionally, $not req(S_2, p) => not req(S_1, p)$. If $p$ is optional in $S_2$, it must also be optional in $S_1$ so that a call omitting it is valid.
|
||||||
|
|
||||||
|
Finally, for mixed parameters, the rule is slightly more complex. Either there is a corresponding mixed parameter in $S_1$, or the parameter is covered by both a positional/mixed and a keyword/mixed parameter. In the second case, we must keep in mind that only one of the match will made at runtime, or maybe even none if the parameter is optional in $S_2$, meaning the parameters in $S_1$ _must_ be optional.
|
||||||
|
|
||||||
|
We can thus split the rule in two. $forall p_i in M_2$:
|
||||||
|
$
|
||||||
|
cases(
|
||||||
|
p_i in M_1 and not req(S_2, p_i) => not req(S_1, p_i),
|
||||||
|
"or",
|
||||||
|
underbrace((phi_i in P_1 or phi_i in M_1), "Positional") and
|
||||||
|
underbrace((p in K_1 or p in M_1), "Keyword") and
|
||||||
|
underbrace((not req(S_1, phi_i) and not req(S_1, p)), "Optional")
|
||||||
|
)
|
||||||
|
$
|
||||||
|
|
||||||
|
== No additional required arguments in $S_1$ <cond-2>
|
||||||
|
|
||||||
|
Formally, the condition is:
|
||||||
|
$
|
||||||
|
forall alpha in AA, S_1 in.rev alpha and req(S_1, alpha) => S_2 in.rev alpha and req(S_2, alpha)
|
||||||
|
$
|
||||||
|
|
||||||
|
Each parameter in $S_1$ that is not matched by a parameter in $S_2$ must be optional:
|
||||||
|
$
|
||||||
|
forall p_i in S_1, p_i in.not S_2 => not req(S_1, p_i)
|
||||||
|
$
|
||||||
24
report/appendices/is_subtype.typ
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: code
|
||||||
|
#import "../utils.typ": code-ref
|
||||||
|
|
||||||
|
#let is-subtype-code = raw(
|
||||||
|
read("../code/is_subtype.py"),
|
||||||
|
lang: "python",
|
||||||
|
block: true
|
||||||
|
)
|
||||||
|
#let is-func-subtype-code = raw(
|
||||||
|
read("../code/is_func_subtype.py"),
|
||||||
|
lang: "python",
|
||||||
|
block: true
|
||||||
|
)
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(is-subtype-code),
|
||||||
|
caption: [Implementation of `TypesRegistry.is_subtype` (#code-ref(<is_subtype>, "midas/checker/registry.py"))#footnote[The order of cases is slightly different from the real implementation for grouped presentation purposes]]
|
||||||
|
) <fig:is_subtype>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(is-func-subtype-code),
|
||||||
|
caption: [Implementation of `TypesRegistry.is_func_subtype` (#code-ref(<is_func_subtype>, "midas/checker/registry.py"))]
|
||||||
|
) <fig:is_func_subtype>
|
||||||
216
report/appendices/midas_parsing.typ
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "utils.typ": format-ast-nodes
|
||||||
|
|
||||||
|
#let token-types = (
|
||||||
|
"Punctuation": (
|
||||||
|
"LEFT_PAREN",
|
||||||
|
"RIGHT_PAREN",
|
||||||
|
"LEFT_BRACKET",
|
||||||
|
"RIGHT_BRACKET",
|
||||||
|
"LEFT_BRACE",
|
||||||
|
"RIGHT_BRACE",
|
||||||
|
"COLON",
|
||||||
|
"COMMA",
|
||||||
|
"UNDERSCORE",
|
||||||
|
"ARROW",
|
||||||
|
"AND",
|
||||||
|
"QMARK",
|
||||||
|
"DOT",
|
||||||
|
),
|
||||||
|
|
||||||
|
"Operators": (
|
||||||
|
"PLUS",
|
||||||
|
"MINUS",
|
||||||
|
"STAR",
|
||||||
|
"SLASH",
|
||||||
|
"GREATER",
|
||||||
|
"GREATER_EQUAL",
|
||||||
|
"LESS",
|
||||||
|
"LESS_EQUAL",
|
||||||
|
"EQUAL",
|
||||||
|
"EQUAL_EQUAL",
|
||||||
|
"BANG_EQUAL",
|
||||||
|
"BANG",
|
||||||
|
),
|
||||||
|
|
||||||
|
"Literals": (
|
||||||
|
"IDENTIFIER",
|
||||||
|
"NUMBER",
|
||||||
|
"TRUE",
|
||||||
|
"FALSE",
|
||||||
|
"NONE",
|
||||||
|
"STRING",
|
||||||
|
),
|
||||||
|
|
||||||
|
"Keywords": (
|
||||||
|
"TYPE",
|
||||||
|
"ALIAS",
|
||||||
|
"PREDICATE",
|
||||||
|
"EXTEND",
|
||||||
|
"WHERE",
|
||||||
|
"PROP",
|
||||||
|
"DEF",
|
||||||
|
"FUNC",
|
||||||
|
),
|
||||||
|
|
||||||
|
"Misc": (
|
||||||
|
"COMMENT",
|
||||||
|
"WHITESPACE",
|
||||||
|
"EOF",
|
||||||
|
"NEWLINE",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let token-types-cells = {
|
||||||
|
let cells = ()
|
||||||
|
for (category, types) in token-types.pairs() {
|
||||||
|
cells.push([*#category*])
|
||||||
|
cells += types
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transpose
|
||||||
|
let per-col = calc.ceil(cells.len() / 4)
|
||||||
|
let total = per-col * 4
|
||||||
|
|
||||||
|
cells = (cells + (none,) * (total - cells.len())).chunks(per-col)
|
||||||
|
cells = cells.first().zip(..cells.slice(1)).flatten()
|
||||||
|
|
||||||
|
cells
|
||||||
|
}
|
||||||
|
|
||||||
|
#let ast-nodes = (
|
||||||
|
("Other classes", none, ```python
|
||||||
|
class TypeParam:
|
||||||
|
location: Location
|
||||||
|
name: Token
|
||||||
|
bound: Optional[Type]
|
||||||
|
|
||||||
|
class MemberKind(Enum):
|
||||||
|
PROPERTY = auto()
|
||||||
|
METHOD = auto()
|
||||||
|
|
||||||
|
class ParamSpec:
|
||||||
|
l_paren: Token
|
||||||
|
pos: list[FunctionType.Parameter]
|
||||||
|
mixed: list[FunctionType.Parameter]
|
||||||
|
kw: list[FunctionType.Parameter]
|
||||||
|
```),
|
||||||
|
("Statements", `Stmt`, ```python
|
||||||
|
class TypeStmt:
|
||||||
|
name: Token
|
||||||
|
params: list[TypeParam]
|
||||||
|
type: Type
|
||||||
|
|
||||||
|
class AliasStmt:
|
||||||
|
name: Token
|
||||||
|
type: Type
|
||||||
|
|
||||||
|
class MemberStmt:
|
||||||
|
name: Token
|
||||||
|
type: Type
|
||||||
|
kind: MemberKind
|
||||||
|
|
||||||
|
class ExtendStmt:
|
||||||
|
name: Token
|
||||||
|
params: list[TypeParam]
|
||||||
|
members: list[MemberStmt]
|
||||||
|
|
||||||
|
class PredicateStmt:
|
||||||
|
name: Token
|
||||||
|
params: list[ParamSpec]
|
||||||
|
body: Expr
|
||||||
|
```),
|
||||||
|
("Expressions", `Expr`, ```python
|
||||||
|
class LogicalExpr:
|
||||||
|
left: Expr
|
||||||
|
operator: Token
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class BinaryExpr:
|
||||||
|
left: Expr
|
||||||
|
operator: Token
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class UnaryExpr:
|
||||||
|
operator: Token
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class CallExpr:
|
||||||
|
callee: Expr
|
||||||
|
arguments: list[Expr]
|
||||||
|
keywords: dict[str, Expr]
|
||||||
|
|
||||||
|
class GetExpr:
|
||||||
|
expr: Expr
|
||||||
|
name: Token
|
||||||
|
|
||||||
|
class VariableExpr:
|
||||||
|
name: Token
|
||||||
|
|
||||||
|
class GroupingExpr:
|
||||||
|
expr: Expr
|
||||||
|
|
||||||
|
class LiteralExpr:
|
||||||
|
value: Any
|
||||||
|
|
||||||
|
class WildcardExpr:
|
||||||
|
token: Token
|
||||||
|
```),
|
||||||
|
("Types", `Type`, ```python
|
||||||
|
class NamedType:
|
||||||
|
name: Token
|
||||||
|
|
||||||
|
class GenericType:
|
||||||
|
type: Type
|
||||||
|
args: list[Type]
|
||||||
|
|
||||||
|
class ConstraintType:
|
||||||
|
type: Type
|
||||||
|
constraint: Expr
|
||||||
|
|
||||||
|
class FunctionType:
|
||||||
|
params: ParamSpec
|
||||||
|
returns: Type
|
||||||
|
|
||||||
|
class Parameter:
|
||||||
|
location: Optional[Location] = None
|
||||||
|
name: Optional[Token]
|
||||||
|
type: Type
|
||||||
|
required: bool
|
||||||
|
|
||||||
|
class FrameType:
|
||||||
|
columns: list[Column]
|
||||||
|
|
||||||
|
class Column:
|
||||||
|
location: Optional[Location] = None
|
||||||
|
name: Token
|
||||||
|
type: Type
|
||||||
|
```),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let midas-ast-nodes = table(
|
||||||
|
inset: .5em,
|
||||||
|
row-gutter: 2em,
|
||||||
|
stroke: gray,
|
||||||
|
..ast-nodes.map(nodes => format-ast-nodes(..nodes))
|
||||||
|
)
|
||||||
|
|
||||||
|
#show figure: set block(breakable: true)
|
||||||
|
#figure(
|
||||||
|
grid(
|
||||||
|
columns: 4,
|
||||||
|
column-gutter: 3em,
|
||||||
|
inset: .5em,
|
||||||
|
..token-types-cells,
|
||||||
|
),
|
||||||
|
caption: [Midas Token Types],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:token-types>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
midas-ast-nodes,
|
||||||
|
caption: [Midas #acr("AST") Nodes],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:midas-ast-nodes>
|
||||||
243
report/appendices/midas_railway.typ
Normal file
@@ -0,0 +1,243 @@
|
|||||||
|
#import "@preview/fervojo:0.1.1": default-css, render
|
||||||
|
|
||||||
|
#let extra-css = ```css
|
||||||
|
svg.railroad .terminal rect {
|
||||||
|
fill: #F7DCD4;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
#let css = default-css() + bytes(extra-css.text)
|
||||||
|
|
||||||
|
#let literal = ```
|
||||||
|
{[`literal` <
|
||||||
|
[`number` 'digit' * ! <!, ["." 'digit' * !]>],
|
||||||
|
[`boolean` <"False", "True">],
|
||||||
|
[`string` <["\"" 'char'*! "\""], ["'" 'char'*! "'"]>],
|
||||||
|
[`none` "None"]
|
||||||
|
>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let grouping = ```
|
||||||
|
{[`grouping` "(" 'expression' ")"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let primary = ```
|
||||||
|
{[`primary` <"_", 'literal', 'identifier', 'grouping'>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let reference = ```
|
||||||
|
{[`reference` 'primary' <!, ["." 'identifier']*!>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let call-args = ```
|
||||||
|
{[`call-args` "(" <!, <'expression', ['identifier' "=" 'expression']>*","#`Same rules as Python`> ")"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let call = ```
|
||||||
|
{[`call` 'reference' <!, 'call-args'*!>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let unary = ```
|
||||||
|
{[`unary` <[<"+", "-", "!"> 'unary'], 'call'>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let factor = ```
|
||||||
|
{[`factor` 'unary'*<"*", "/">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let term = ```
|
||||||
|
{[`term` 'factor'*<"+", "-">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let comparison = ```
|
||||||
|
{[`comparison` 'term'*<">", "<", ">=", "<=">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let equality = ```
|
||||||
|
{[`equality` 'comparison'*<"==", "!=">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let expression = ```
|
||||||
|
{[`expression` 'equality'*"&"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let constraint = ```
|
||||||
|
{[`constraint` 'expression']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let template-param = ```
|
||||||
|
{[`template-param` 'identifier' <!, ["<:" 'type']>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let template = ```
|
||||||
|
{[`template` "[" <!, 'template-param'*","> "]"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let named-type = ```
|
||||||
|
{[`named-type` 'identifier']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let type-args = ```
|
||||||
|
{[`type-args` "[" <!, 'type'*","> "]"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let frame-schema = ```
|
||||||
|
{[`frame-schema` "[" <!, ['TOKEN' ":" 'type']*","> "]"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let generic-type = ```
|
||||||
|
{[`generic-type` <["Frame" 'frame-schema'], ['named-type' <!, 'type-args'>]>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let grouped-type = ```
|
||||||
|
{[`grouped-type` "(" 'type' ")"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let base-type = ```
|
||||||
|
{[`base-type` <'grouped-type', 'generic-type'>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let constraint-type = ```
|
||||||
|
{[`constraint-type` 'base-type' <!, ["where" 'constraint']>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let pos-param = ```
|
||||||
|
{[`pos-param` <!, ['identifier' ":"]> 'type' <!, "?">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let kw-param = ```
|
||||||
|
{[`kw-param` 'identifier' ":" 'type' <!, "?">]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let param-spec = ```
|
||||||
|
{[`param-spec` "(" <!, <'pos-param', "/", "*", 'kw-param'>*",">#`Same rules as Python` ")"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let func-type = ```
|
||||||
|
{[`func-type` "fn" 'param-spec' "->" 'type']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let type = ```
|
||||||
|
{[`type` <'func-type', 'constraint-type'>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let alias-statement = ```
|
||||||
|
{[`alias-statement` "alias" 'identifier' "=" 'type']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let type-statement = ```
|
||||||
|
{[`type-statement` "type" 'identifier' <!, 'template'> "=" 'type']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let member-stmt = ```
|
||||||
|
{[`member-stmt` <"prop", "def"> 'identifier' ":" 'type']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let extend-statement = ```
|
||||||
|
{[`extend-statement` "extend" 'type' "{" <!, 'member-stmt'*!> "}"]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let predicate-statement = ```
|
||||||
|
{[`predicate-statement` "predicate" 'identifier' <!, 'param-spec'*!> "=" 'constraint']}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let statement = ```
|
||||||
|
{[`statement` <'alias-statement', 'type-statement', 'extend-statement', 'predicate-statement'>]}
|
||||||
|
```
|
||||||
|
|
||||||
|
#let rules = (
|
||||||
|
literal: literal,
|
||||||
|
grouping: grouping,
|
||||||
|
primary: primary,
|
||||||
|
reference: reference,
|
||||||
|
call-args: call-args,
|
||||||
|
call: call,
|
||||||
|
unary: unary,
|
||||||
|
factor: factor,
|
||||||
|
term: term,
|
||||||
|
comparison: comparison,
|
||||||
|
equality: equality,
|
||||||
|
expression: expression,
|
||||||
|
constraint: constraint,
|
||||||
|
template-param: template-param,
|
||||||
|
template: template,
|
||||||
|
named-type: named-type,
|
||||||
|
type-args: type-args,
|
||||||
|
generic-type: generic-type,
|
||||||
|
grouped-type: grouped-type,
|
||||||
|
base-type: base-type,
|
||||||
|
constraint-type: constraint-type,
|
||||||
|
pos-param: pos-param,
|
||||||
|
kw-param: kw-param,
|
||||||
|
param-spec: param-spec,
|
||||||
|
func-type: func-type,
|
||||||
|
type: type,
|
||||||
|
alias-statement: alias-statement,
|
||||||
|
type-statement: type-statement,
|
||||||
|
member-stmt: member-stmt,
|
||||||
|
extend-statement: extend-statement,
|
||||||
|
predicate-statement: predicate-statement,
|
||||||
|
statement: statement,
|
||||||
|
)
|
||||||
|
|
||||||
|
#let inline = (
|
||||||
|
"grouping",
|
||||||
|
"literal",
|
||||||
|
"template-param",
|
||||||
|
"template",
|
||||||
|
"call-args",
|
||||||
|
"type-args",
|
||||||
|
"named-type",
|
||||||
|
"grouped-type",
|
||||||
|
"generic-type",
|
||||||
|
"base-type",
|
||||||
|
"constraint-type",
|
||||||
|
"pos-param",
|
||||||
|
"kw-param",
|
||||||
|
"func-type",
|
||||||
|
"member-stmt",
|
||||||
|
"alias-statement",
|
||||||
|
"type-statement",
|
||||||
|
"extend-statement",
|
||||||
|
"predicate-statement",
|
||||||
|
)
|
||||||
|
|
||||||
|
= Statements and expressions
|
||||||
|
|
||||||
|
#let all-rules = for (name, rule) in rules.pairs().rev() {
|
||||||
|
[== #name]
|
||||||
|
render(rule, css: css)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let substitute(base-rule) = {
|
||||||
|
let new-rule = base-rule
|
||||||
|
for name in inline {
|
||||||
|
let rule = rules.at(name)
|
||||||
|
let replacement = rule.text.slice(1, -1).replace(regex("\[`.*?`"), "[")
|
||||||
|
replacement = "[" + replacement + "#`" + name + "`]"
|
||||||
|
new-rule = new-rule.replace(
|
||||||
|
"'" + name + "'",
|
||||||
|
replacement,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if new-rule != base-rule {
|
||||||
|
new-rule = substitute(new-rule)
|
||||||
|
}
|
||||||
|
return new-rule
|
||||||
|
}
|
||||||
|
|
||||||
|
#let capitalize(word) = {
|
||||||
|
return upper(word.slice(0, 1)) + word.slice(1)
|
||||||
|
}
|
||||||
|
#let display-name(name) = {
|
||||||
|
let words = name.split("-").map(capitalize)
|
||||||
|
return [#words.join(" ") (#raw(name))]
|
||||||
|
}
|
||||||
|
|
||||||
|
#let all-combined = for (name, rule) in rules.pairs() {
|
||||||
|
if not name in inline {
|
||||||
|
[== #display-name(name)]
|
||||||
|
let combined = substitute(rule.text)
|
||||||
|
render(raw(combined), css: css)
|
||||||
|
//raw(block: true, combined)
|
||||||
|
}
|
||||||
|
}
|
||||||
13
report/appendices/midas_typer_skeleton.typ
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: code
|
||||||
|
|
||||||
|
#let midas-typer-members-code = raw(
|
||||||
|
read("../code/midas_typer_skeleton.py"),
|
||||||
|
lang: "python",
|
||||||
|
block: true
|
||||||
|
)
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(midas-typer-members-code),
|
||||||
|
caption: [Midas Typer Members]
|
||||||
|
) <fig:midas-typer-members>
|
||||||
172
report/appendices/python_parsing.typ
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "utils.typ": format-ast-nodes
|
||||||
|
|
||||||
|
#let ast-nodes = (
|
||||||
|
("Other classes", none, ```python
|
||||||
|
class ParamSpec:
|
||||||
|
pos: list[Function.Parameter]
|
||||||
|
mixed: list[Function.Parameter]
|
||||||
|
kw: list[Function.Parameter]
|
||||||
|
@property
|
||||||
|
def all(self) -> list[Function.Parameter]:
|
||||||
|
return self.pos + self.mixed + self.kw
|
||||||
|
|
||||||
|
|
||||||
|
class ImportAlias:
|
||||||
|
location: Location
|
||||||
|
name: str
|
||||||
|
alias: Optional[str] = None
|
||||||
|
@property
|
||||||
|
def imported_name(self) -> str:
|
||||||
|
return (
|
||||||
|
self.alias
|
||||||
|
if self.alias is not None else
|
||||||
|
self.name
|
||||||
|
)
|
||||||
|
```),
|
||||||
|
|
||||||
|
("Type annotations", `MidasType`, ```python
|
||||||
|
class BaseType:
|
||||||
|
base: str
|
||||||
|
args: tuple[MidasType,...]
|
||||||
|
|
||||||
|
class FrameColumn:
|
||||||
|
name: Optional[str]
|
||||||
|
type: Optional[MidasType]
|
||||||
|
|
||||||
|
class FrameType:
|
||||||
|
columns: list[FrameColumn]
|
||||||
|
```),
|
||||||
|
|
||||||
|
("Statements", `Stmt`, ```python
|
||||||
|
class ExpressionStmt:
|
||||||
|
expr: Expr
|
||||||
|
|
||||||
|
class Function:
|
||||||
|
name: str
|
||||||
|
params: ParamSpec
|
||||||
|
returns: Optional[MidasType]
|
||||||
|
body: list[Stmt]
|
||||||
|
|
||||||
|
class Parameter:
|
||||||
|
location: Optional[Location] = None
|
||||||
|
name: str
|
||||||
|
type: Optional[MidasType]
|
||||||
|
default: Optional[Expr]
|
||||||
|
|
||||||
|
class TypeAssign:
|
||||||
|
name: str
|
||||||
|
type: MidasType
|
||||||
|
|
||||||
|
class AssignStmt:
|
||||||
|
targets: list[Expr]
|
||||||
|
value: Expr
|
||||||
|
|
||||||
|
class ReturnStmt:
|
||||||
|
value: Optional[Expr]
|
||||||
|
|
||||||
|
class IfStmt:
|
||||||
|
test: Expr
|
||||||
|
body: list[Stmt]
|
||||||
|
orelse: list[Stmt]
|
||||||
|
|
||||||
|
class Pass: ...
|
||||||
|
|
||||||
|
class ForStmt:
|
||||||
|
target: Expr
|
||||||
|
iterator: Expr
|
||||||
|
body: list[Stmt]
|
||||||
|
|
||||||
|
class ImportStmt:
|
||||||
|
imports: list[ImportAlias]
|
||||||
|
|
||||||
|
class FromImportStmt:
|
||||||
|
module: Optional[str]
|
||||||
|
imports: list[ImportAlias]
|
||||||
|
level: int
|
||||||
|
|
||||||
|
class RawStmt:
|
||||||
|
stmt: ast.stmt
|
||||||
|
```),
|
||||||
|
|
||||||
|
("Expressions", `Expr`, ```python
|
||||||
|
class BinaryExpr:
|
||||||
|
left: Expr
|
||||||
|
operator: ast.operator
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class CompareExpr:
|
||||||
|
left: Expr
|
||||||
|
operator: ast.cmpop
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class UnaryExpr:
|
||||||
|
operator: ast.unaryop
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class CallExpr:
|
||||||
|
callee: Expr
|
||||||
|
arguments: list[Expr]
|
||||||
|
keywords: dict[str, Expr]
|
||||||
|
|
||||||
|
class GetExpr:
|
||||||
|
object: Expr
|
||||||
|
name: str
|
||||||
|
|
||||||
|
class LiteralExpr:
|
||||||
|
value: Any
|
||||||
|
|
||||||
|
class VariableExpr:
|
||||||
|
name: str
|
||||||
|
|
||||||
|
class LogicalExpr:
|
||||||
|
left: Expr
|
||||||
|
operator: ast.boolop
|
||||||
|
right: Expr
|
||||||
|
|
||||||
|
class CastExpr:
|
||||||
|
type: MidasType
|
||||||
|
expr: Expr
|
||||||
|
unsafe: bool
|
||||||
|
|
||||||
|
class TernaryExpr:
|
||||||
|
test: Expr
|
||||||
|
if_true: Expr
|
||||||
|
if_false: Expr
|
||||||
|
|
||||||
|
class ListExpr:
|
||||||
|
items: list[Expr]
|
||||||
|
|
||||||
|
class DictExpr:
|
||||||
|
keys: list[Optional[Expr]]
|
||||||
|
values: list[Expr]
|
||||||
|
|
||||||
|
class SubscriptExpr:
|
||||||
|
object: Expr
|
||||||
|
index: Expr
|
||||||
|
|
||||||
|
class SliceExpr:
|
||||||
|
lower: Optional[Expr]
|
||||||
|
upper: Optional[Expr]
|
||||||
|
step: Optional[Expr]
|
||||||
|
|
||||||
|
class TupleExpr:
|
||||||
|
items: tuple[Expr, ...]
|
||||||
|
|
||||||
|
class RawExpr:
|
||||||
|
expr: ast.expr
|
||||||
|
```),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let python-ast-nodes = table(
|
||||||
|
inset: .5em,
|
||||||
|
stroke: gray,
|
||||||
|
row-gutter: 2em,
|
||||||
|
..ast-nodes.map(nodes => format-ast-nodes(..nodes))
|
||||||
|
)
|
||||||
|
|
||||||
|
#show figure: set block(breakable: true)
|
||||||
|
#figure(
|
||||||
|
python-ast-nodes,
|
||||||
|
caption: [Python #acr("AST") Nodes],
|
||||||
|
) <tab:python-ast-nodes>
|
||||||
13
report/appendices/python_typer.typ
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: code
|
||||||
|
|
||||||
|
#let python-typer-function-code = raw(
|
||||||
|
read("../code/python_check_function.py"),
|
||||||
|
lang: "python",
|
||||||
|
block: true
|
||||||
|
)
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(python-typer-function-code),
|
||||||
|
caption: [Implementation of `PythonTyper.visit_function`]
|
||||||
|
) <fig:python-visit_function>
|
||||||
37
report/appendices/utils.typ
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#import "@preview/codly:1.3.0": codly-disable, codly-enable
|
||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
|
||||||
|
#let format-ast-nodes(name, base-cls, code) = {
|
||||||
|
let nodes = code.text.split(regex(`\n\nclass`.text)).map(n => if n.starts-with("class") {n} else {"class" + n})
|
||||||
|
|
||||||
|
let cells = nodes.map(n => raw(n, block: true, lang: "python"))
|
||||||
|
|
||||||
|
if calc.rem(cells.len(), 3) == 2 {
|
||||||
|
let last-two = cells.slice(-2)
|
||||||
|
cells = cells.slice(0, -2)
|
||||||
|
let last = grid.cell(
|
||||||
|
colspan: 3,
|
||||||
|
stack(
|
||||||
|
dir: ltr,
|
||||||
|
spacing: 1fr,
|
||||||
|
none,
|
||||||
|
..last-two,
|
||||||
|
none
|
||||||
|
)
|
||||||
|
)
|
||||||
|
cells.push(last)
|
||||||
|
}
|
||||||
|
|
||||||
|
align(center)[*#name*]
|
||||||
|
if base-cls != none [Base class: #base-cls]
|
||||||
|
|
||||||
|
codly-disable()
|
||||||
|
grid(
|
||||||
|
columns: 3,
|
||||||
|
column-gutter: 1fr,
|
||||||
|
row-gutter: 2em,
|
||||||
|
align: left + top,
|
||||||
|
..cells
|
||||||
|
)
|
||||||
|
codly-enable()
|
||||||
|
}
|
||||||
29
report/appendices/variance.typ
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: code
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(raw(
|
||||||
|
block: true,
|
||||||
|
lang: "python",
|
||||||
|
read("../code/variance_tracker.py")
|
||||||
|
)),
|
||||||
|
caption: [Implementation of variance `Tracker`]
|
||||||
|
) <fig:midas-variance-tracker>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(raw(
|
||||||
|
block: true,
|
||||||
|
lang: "python",
|
||||||
|
read("../code/variance_inferrer.py")
|
||||||
|
)),
|
||||||
|
caption: [Implementation of variance `VarianceInferrer`]
|
||||||
|
) <fig:midas-variance-inferrer>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
code(raw(
|
||||||
|
block: true,
|
||||||
|
lang: "python",
|
||||||
|
read("../code/variance_manager.py")
|
||||||
|
)),
|
||||||
|
caption: [Implementation of variance `VarianceManager`]
|
||||||
|
) <fig:midas-variance-manager>
|
||||||
192
report/bachelor_thesis.typ
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
// ___ ____ ____ _ _ _____ ___
|
||||||
|
// |_ _/ ___| / ___| | | | | ____|_ _| Informatique et
|
||||||
|
// | |\___ \| | ___ | |_| | _| | | systèmes de communication
|
||||||
|
// | | ___) | |__|___| | _ | |___ | | HEI Sion · HES-SO Valais / mui 24-26
|
||||||
|
// |___|____/ \____| |_| |_|_____|___|
|
||||||
|
//
|
||||||
|
// 52 65 61 64 69 6e 67 20 68 65 78 20 66 6f 72 20 66 75 6e 3f 20 49 53 43 20 66 6f 72 65 76 65 72
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: *
|
||||||
|
#import "@preview/codly:1.3.0": codly-init, codly
|
||||||
|
#import "@preview/codly-languages:0.1.10": codly-languages
|
||||||
|
#import "../meta.typ"
|
||||||
|
#import "utils.typ": include-offset
|
||||||
|
|
||||||
|
#let doc_language = "en"
|
||||||
|
|
||||||
|
#show: codly-init
|
||||||
|
#codly(
|
||||||
|
languages: codly-languages
|
||||||
|
+ (
|
||||||
|
midas: (
|
||||||
|
name: "Midas",
|
||||||
|
color: rgb("#eedd47"),
|
||||||
|
icon: box(
|
||||||
|
image(
|
||||||
|
"../assets/icon.svg",
|
||||||
|
height: 130%,
|
||||||
|
fit: "contain",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#set raw(
|
||||||
|
syntaxes: path("../midas.sublime-syntax")
|
||||||
|
)
|
||||||
|
|
||||||
|
#show: thesis.with(
|
||||||
|
title: meta.title,
|
||||||
|
subtitle: meta.subtitle,
|
||||||
|
authors: meta.authors,
|
||||||
|
language: doc_language,
|
||||||
|
|
||||||
|
thesis-supervisor: meta.thesis-supervisor,
|
||||||
|
thesis-co-supervisor: meta.thesis-co-supervisor,
|
||||||
|
thesis-expert: meta.thesis-expert,
|
||||||
|
thesis-id: meta.thesis-id,
|
||||||
|
project-repos: meta.project-repos,
|
||||||
|
|
||||||
|
school: meta.school,
|
||||||
|
programme: meta.programme,
|
||||||
|
|
||||||
|
keywords: meta.keywords,
|
||||||
|
major : meta.major,
|
||||||
|
date: meta.date,
|
||||||
|
|
||||||
|
// Declaration of honour signature
|
||||||
|
signature: image("figs/signature_placeholder.svg", width: 4.5cm), // A scan/photo of your handwritten signature
|
||||||
|
|
||||||
|
revision: "1.0",
|
||||||
|
code-theme: "bluloco-light",
|
||||||
|
|
||||||
|
// The cover might show a red "ATTENTION REQUISE" box listing required fields still
|
||||||
|
// left at their placeholder values (and warns if the title/subtitle is too long).
|
||||||
|
// Uncomment to hide it, but only do this if you know what you are doing.
|
||||||
|
|
||||||
|
// hide-completeness-warning: true,
|
||||||
|
)
|
||||||
|
|
||||||
|
// If using acronyms
|
||||||
|
#import "@preview/acrostiche:0.7.0": *
|
||||||
|
#include "acronyms.typ"
|
||||||
|
|
||||||
|
// A tidy acronym table for the appendix, using the acronyms declared above.
|
||||||
|
// (Kept here, not in the package, so acrostiche stays an example-only dependency.)
|
||||||
|
#let acronym-table() = print-index(
|
||||||
|
title: page-title(i18n(doc_language, "acronym-table-title"), mult: 1, top: 1em, bottom: 1em),
|
||||||
|
sorted: "up",
|
||||||
|
delimiter: " : ",
|
||||||
|
row-gutter: 0.7em,
|
||||||
|
outlined: false,
|
||||||
|
)
|
||||||
|
|
||||||
|
////////////////////////////
|
||||||
|
// Let's get started folks!
|
||||||
|
////////////////////////////
|
||||||
|
|
||||||
|
#cleardoublepage()
|
||||||
|
#include "pages/abstract.typ"
|
||||||
|
|
||||||
|
#cleardoublepage()
|
||||||
|
#include "pages/résumé.typ"
|
||||||
|
|
||||||
|
#cleardoublepage()
|
||||||
|
#declaration-of-honour()
|
||||||
|
|
||||||
|
#cleardoublepage()
|
||||||
|
#include "pages/acknowledgements.typ"
|
||||||
|
|
||||||
|
/*
|
||||||
|
== The content of a thesis
|
||||||
|
|
||||||
|
The general structure of a bachelor thesis typically includes the following sections:
|
||||||
|
|
||||||
|
1. *Abstract*: A concise summary of the thesis, including the research question, methodology, results, and conclusions.
|
||||||
|
2. *Résumé*: A summary of the thesis in French.
|
||||||
|
3. *Acknowledgements*: [Optional] A section to thank those who supported your work.
|
||||||
|
4. *Table of Contents*: An organized list of chapters and sections.
|
||||||
|
5. *Introduction*: Presents the background/context, motivation, objectives, and scope and plan of the thesis.
|
||||||
|
6. *State of the Art / Literature Review*: Reviews existing research and situates the thesis within the academic context, if relevant to your work.
|
||||||
|
7. *Development and Methodology*: Describes the methods, materials, and procedures used in the research/thesis.
|
||||||
|
8. *Results*: Presents the findings of the research, often with tables, figures, and analysis.
|
||||||
|
9. *Discussion*: Interprets the results, discusses implications, and relates findings to the research question.
|
||||||
|
10. *Conclusion*: Summarizes the main findings and contributions, and suggests future work.
|
||||||
|
11. *References / Bibliography*: Lists all sources cited in the thesis.
|
||||||
|
12. *Appendices*: (Optional) Contains supplementary material such as raw data, code, or additional explanations.
|
||||||
|
|
||||||
|
This structure may vary depending on the field of study, but these elements are commonly found in most bachelor theses. They are recommended for the _ISC Bachelor thesis_ and should be adapted to the specific requirements of your thesis (e.g., if you have a state of the art section or not).
|
||||||
|
|
||||||
|
You can also change the order or the names of the sections, for instance, if you want to put the state of the art before the introduction, or if you want to add a section on methodology before the results.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "chapters/01_introduction.typ"
|
||||||
|
#include "chapters/02_state_of_the_art.typ"
|
||||||
|
#include "chapters/03_theory.typ"
|
||||||
|
#include "chapters/04_implementation.typ"
|
||||||
|
#include "chapters/05_results_discussion.typ"
|
||||||
|
#include "chapters/06_conclusion.typ"
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
#the-bibliography(
|
||||||
|
bib-file: read("bibliography.bib", encoding: none),
|
||||||
|
full: true,
|
||||||
|
style: "ieee"
|
||||||
|
)
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
// Appendices
|
||||||
|
//////////////
|
||||||
|
#cleardoublepage()
|
||||||
|
#appendix-page()
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
#set heading(numbering: "A.1", supplement: [Appendix])
|
||||||
|
|
||||||
|
#set figure(numbering: (..nums) => counter(heading).display("A.1") + "." + numbering("1", ..nums))
|
||||||
|
|
||||||
|
// Table of acronyms (optional). Defined near the acronyms above.
|
||||||
|
#acronym-table()
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
// Table of listings
|
||||||
|
#table-of-figures()
|
||||||
|
|
||||||
|
// Code inclusion
|
||||||
|
#pagebreak()
|
||||||
|
#code-samples()
|
||||||
|
|
||||||
|
#include "appendices/is_subtype.typ"
|
||||||
|
|
||||||
|
#include "appendices/midas_typer_skeleton.typ"
|
||||||
|
|
||||||
|
#include "appendices/variance.typ"
|
||||||
|
|
||||||
|
#include "appendices/python_typer.typ"
|
||||||
|
|
||||||
|
#include "appendices/call_dispatcher.typ"
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
= Midas Language Definition <app:midas-syntax>
|
||||||
|
|
||||||
|
#import "appendices/midas_railway.typ": all-combined
|
||||||
|
|
||||||
|
#all-combined
|
||||||
|
|
||||||
|
= Function Subtyping Rules <app:function-subtyping>
|
||||||
|
|
||||||
|
#include-offset("appendices/function_subtyping.typ")
|
||||||
|
|
||||||
|
= Midas Language Objects
|
||||||
|
|
||||||
|
#include-offset("appendices/midas_parsing.typ")
|
||||||
|
|
||||||
|
= Python Language Objects
|
||||||
|
|
||||||
|
#include-offset("appendices/python_parsing.typ")
|
||||||
118
report/bibliography.bib
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
% Encoding: UTF-8
|
||||||
|
@book{tapl,
|
||||||
|
author = {Pierce, Benjamin C.},
|
||||||
|
title = {Types and Programming Languages},
|
||||||
|
year = {2002},
|
||||||
|
isbn = {0262162091},
|
||||||
|
publisher = {The MIT Press},
|
||||||
|
edition = {1st},
|
||||||
|
abstract = {A type system is a syntactic method for automatically checking the absence of certain erroneous behaviors by classifying program phrases according to the kinds of values they compute. The study of type systems -- and of programming languages from a type-theoretic perspective -- has important applications in software engineering, language design, high-performance compilers, and security.This text provides a comprehensive introduction both to type systems in computer science and to the basic theory of programming languages. The approach is pragmatic and operational; each new concept is motivated by programming examples and the more theoretical sections are driven by the needs of implementations. Each chapter is accompanied by numerous exercises and solutions, as well as a running implementation, available via the Web. Dependencies between chapters are explicitly identified, allowing readers to choose a variety of paths through the material.The core topics include the untyped lambda-calculus, simple type systems, type reconstruction, universal and existential polymorphism, subtyping, bounded quantification, recursive types, kinds, and type operators. Extended case studies develop a variety of approaches to modeling the features of object-oriented languages.}
|
||||||
|
}
|
||||||
|
|
||||||
|
@article{gator,
|
||||||
|
author = {Geisler, Dietrich and Yoon, Irene and Kabra, Aditi and He, Horace and Sanders, Yinnon and Sampson, Adrian},
|
||||||
|
title = {Geometry types for graphics programming},
|
||||||
|
year = {2020},
|
||||||
|
issue_date = {November 2020},
|
||||||
|
publisher = {Association for Computing Machinery},
|
||||||
|
address = {New York, NY, USA},
|
||||||
|
volume = {4},
|
||||||
|
number = {OOPSLA},
|
||||||
|
url = {https://doi.org/10.1145/3428241},
|
||||||
|
doi = {10.1145/3428241},
|
||||||
|
abstract = {In domains that deal with physical space and geometry, programmers need to track the coordinate systems that underpin a computation. We identify a class of geometry bugs that arise from confusing which coordinate system a vector belongs to. These bugs are not ruled out by current languages for vector-oriented computing, are difficult to check for at run time, and can generate subtly incorrect output that can be hard to test for. We introduce a type system and language that prevents geometry bugs by reflecting the coordinate system for each geometric object. A value's geometry type encodes its reference frame, the kind of geometric object (such as a point or a direction), and the coordinate representation (such as Cartesian or spherical coordinates). We show how these types can rule out geometrically incorrect operations, and we show how to use them to automatically generate correct-by-construction code to transform vectors between coordinate systems. We implement a language for graphics programming, Gator, that checks geometry types and compiles to OpenGL's shading language, GLSL. Using case studies, we demonstrate that Gator can raise the level of abstraction for shader programming and prevent common errors without inducing significant annotation overhead or performance cost.},
|
||||||
|
journal = {Proc. ACM Program. Lang.},
|
||||||
|
month = nov,
|
||||||
|
articleno = {173},
|
||||||
|
numpages = {25},
|
||||||
|
keywords = {computer graphics, geometry, language design, type systems}
|
||||||
|
}
|
||||||
|
|
||||||
|
@inproceedings{Siek2006GradualTF,
|
||||||
|
title={Gradual Typing for Functional Languages},
|
||||||
|
author={Jeremy G. Siek and Walid Taha},
|
||||||
|
year={2006},
|
||||||
|
url={https://api.semanticscholar.org/CorpusID:1398902}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Book{Nystrom2021,
|
||||||
|
author = {Nystrom, Robert},
|
||||||
|
title = {{Crafting Interpreters}},
|
||||||
|
year = {2021},
|
||||||
|
publisher = {Genever Benning},
|
||||||
|
isbn = {978-0990582946},
|
||||||
|
pagetotal = {640},
|
||||||
|
url = {https://craftinginterpreters.com/},
|
||||||
|
added-at = {2025-04-07T18:48:41.000+0200},
|
||||||
|
biburl = {https://www.bibsonomy.org/bibtex/277c8c518a2426a59a8e4c3a720e60d23/gron},
|
||||||
|
interhash = {98f889463df208a828c08042cd116e94},
|
||||||
|
intrahash = {77c8c518a2426a59a8e4c3a720e60d23},
|
||||||
|
keywords = {AST Book Bytecode Interpreters Visitor},
|
||||||
|
month = {July},
|
||||||
|
timestamp = {2025-04-07T18:49:46.000+0200},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Book{Householder1951,
|
||||||
|
author = {Householder, Alston S.},
|
||||||
|
title = {Monte Carlo Method},
|
||||||
|
year = {1951},
|
||||||
|
series = {Applied Mathematics Series},
|
||||||
|
number = {12},
|
||||||
|
note = {Proceedings of a symposium held June 29, 30, and July 1, 1949},
|
||||||
|
publisher = {U.S. Department of Commerce, National Bureau of Standards},
|
||||||
|
pages = {36},
|
||||||
|
address = {Washington, D.C.},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Online{HOPL,
|
||||||
|
author = {Diarmuid Pigott},
|
||||||
|
title = {Online Historical Encyclopaedia of Programming Languages},
|
||||||
|
url = {https://hopl.info/},
|
||||||
|
language = {en},
|
||||||
|
urldate = {2026-07-13},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Online{SO2025Survey,
|
||||||
|
title = {2025 Stack Overflow Developer Survey},
|
||||||
|
year = {2025},
|
||||||
|
url = {https://survey.stackoverflow.co/2025/technology#most-popular-technologies-language-language},
|
||||||
|
language = {en},
|
||||||
|
organization = {Stack Overflow},
|
||||||
|
urldate = {2026-07-13},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Online{PythonGlossary,
|
||||||
|
title = {Python Glossary},
|
||||||
|
url = {https://docs.python.org/3/glossary.html#term-duck-typing},
|
||||||
|
language = {en},
|
||||||
|
urldate = {2026-07-13},
|
||||||
|
}
|
||||||
|
|
||||||
|
@TechReport{MCOReport,
|
||||||
|
author = {{{National Aeronautics and Space Administration}}},
|
||||||
|
title = {Mars Climate Orbiter Mishap Investigation Board - Phase I Report},
|
||||||
|
institution = {NASA Lessons Learned Information System},
|
||||||
|
year = {1999},
|
||||||
|
language = {en},
|
||||||
|
number = {641},
|
||||||
|
month = {11},
|
||||||
|
url = {https://llis.nasa.gov/lesson/641},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Online{Pebble,
|
||||||
|
author = {Louis Heredero},
|
||||||
|
title = {Pebble},
|
||||||
|
year = {2026},
|
||||||
|
url = {https://git.kb28.ch/HEL/pebble},
|
||||||
|
language = {en},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Misc{enwiki:1326872870,
|
||||||
|
author = {{Wikipedia contributors}},
|
||||||
|
title = {Definite assignment analysis --- {Wikipedia}{,} The Free Encyclopedia},
|
||||||
|
year = {2025},
|
||||||
|
note = {[Online; accessed 19-July-2026]},
|
||||||
|
url = {https://en.wikipedia.org/w/index.php?title=Definite_assignment_analysis&oldid=1326872870},
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment{jabref-meta: databaseType:biblatex;}
|
||||||
44
report/chapters/01_introduction.typ
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "../utils.typ": quote-block
|
||||||
|
|
||||||
|
= Introduction <chap:intro>
|
||||||
|
|
||||||
|
#quote-block[J. von Neumann @Householder1951][
|
||||||
|
Any one who considers arithmetical methods of producing random digits is, of course, in a state of sin
|
||||||
|
]
|
||||||
|
|
||||||
|
Dogs are often said to be man's best friend for their unwavering loyalty. As human beings, we thrive on patterns and predictability. On the other hand, our little animal friends can sometimes be irrational and surprise us with their unpredictable behavior. Computers however, these thought-less automatic machines made of metal, would be much better companions.
|
||||||
|
|
||||||
|
By their fundamental essence, computers and other similar machines are deterministic. As developers, we simply give them series of instructions, algorithms, functions and other scripts. Their one and only job is to execute our commands, one after the other, sometimes at the same time. An addition is always an addition, a byte is always a byte, and most importantly, a dog is always a dog.
|
||||||
|
|
||||||
|
When programming, developers use formal languages to instruct their devices to do particular tasks. Theses languages are designed to be unambiguous and generally explicit about what they describe. To the machine interpreting that written text, only one meaning is possible. "But", you may say, "sometimes there are bugs when I run my program". Of course, bugs are an inherent part of programming, but not because the machine might not understand you, because you explained it wrongly.
|
||||||
|
Errors and bugs are always caused by the human factor of computer science.#footnote[Notable exceptions are of course hardware failures which are a totally separate kind of issue]
|
||||||
|
|
||||||
|
Over the years, we have created a terrifyingly large number of programming languages#footnote[At least 8945 in 2005 according to the Historical Encyclopaedia of Programming Languages@HOPL] and developed countless tools to help developers avoid errors. Some are more famous than others, some are short-lived, and some remained obscure research projects which never made it out to the public.
|
||||||
|
While programming languages such as C and Java have long been some of the most popular among developers, another language seemed to have taken the lead in recent years. According to Stack Overflow's 2025 Developer Survey, Python is the most popular programming language among respondents, from beginners to professional developers.@SO2025Survey
|
||||||
|
|
||||||
|
Python is a very flexible scripting language, used in many fields, from small games, one-off data processing scripts and personal tooling to desktop applications and data processing pipelines. It is simple enough for beginners to easily learn it and play with it but highly expressive and with a rich ecosystem to build complex projects and production software.
|
||||||
|
|
||||||
|
One feature of Python that can be both a great benefit for lazy programmers or fast iteration, and a curse for safety and predictability is its use of duck typing. Duck typing is defined as "A programming style which does not look at an object’s type to determine if it has the right interface; instead, the method or attribute is simply called or used"@PythonGlossary, applying the principle "If it looks like a duck and quacks like a duck, it must be a duck.", also known as the duck test.
|
||||||
|
Additionally, the Python language uses dynamic typing, a design principle allowing users to selectively type values, for example through type hints. These annotations are entirely optional in Python and have no direct runtime effect.#footnote[The only runtime consequence of adding annotations may be additional attributes to access them as strings at runtime] Their goal is to be interpreted by type checkers, like MyPy or Pyright, to verify a program's validity statically.
|
||||||
|
|
||||||
|
== Motivation
|
||||||
|
|
||||||
|
As explained above, Python is a very flexible language, sometimes too flexible. For beginners trying to learn programming, this can be a double-edged sword. One the one hand, the language is quite lenient and allows mixing data types, reusing variables with different types and passing values that are not at all what was expected by a function but still have the correct attributes or methods. On the other hand, it can lead to confusing behavior, when a parameter does not fit the developer's expectation or a variable is changed in some part of the code to a completely different kind of value. At the professional level, this can also prove dangerous. Mixing medical measurements or having a production service crash because of a type error can become an expensive mistake with real-world impact.
|
||||||
|
|
||||||
|
Secondly, as every Java developer can tell you, runtime errors are the worst. The dreaded `NullPointerException` continues to haunt many developers. Although some runtime errors like this are quite loud and can crash an hour-long computation process, others are much more subtle and tricky to catch. A famous example of this is the historical crash of NASA's Mars Climate Orbiter in 1999, which failed its orbital insertion due to a unit error mixing metric and imperial measurements.@MCOReport
|
||||||
|
|
||||||
|
Lastly, designing a safe code base and including tests to check that values conform to what is expected can be a tedious and often unrewarding process. Simplifying this process for user is one of the motivation for the famous Python library Pydantic, allowing users to define data structures that can validate inputs when instantiated.
|
||||||
|
|
||||||
|
== Objectives
|
||||||
|
|
||||||
|
In light of the various points exposed in the previous section, I set out to create a potential solution, a tool to help Python developers code more safely and avoid runtime type errors.
|
||||||
|
|
||||||
|
The general goal of this bachelor project is to create a type system on top of Python, using type hints, which can help detect non-trivial type errors (i.e. not necessarily structurally wrong, and also on complex types like dataframes), and produce runtime assertions to check type conformity where static checking is not possible.
|
||||||
|
|
||||||
|
The system should not impede on Python's dynamic typing philosophy. It should ensure soundness where types are annotated or inferred, while leaving the user free to omit some and perform unsafe operations.
|
||||||
|
|
||||||
|
It system must be flexible to allow checking various kinds of constraints (e.g. value domain, geometric shape, distribution, etc.) and allow extension to add support for more Python features and packages.
|
||||||
|
|
||||||
|
Finally, the system must be simple to use for average Python developers, and be able to seamlessly integrate into existing Python code.
|
||||||
21
report/chapters/02_state_of_the_art.typ
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
|
||||||
|
= State of the Art <chap:state-of-the-art>
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Python type hints (https://peps.python.org/pep-0484/):
|
||||||
|
- base types
|
||||||
|
- type aliases
|
||||||
|
- structural subtyping with Protocols -> matches duck-typing (https://peps.python.org/pep-0544/)
|
||||||
|
|
||||||
|
- Existing type checkers
|
||||||
|
- MyPy / Pyright
|
||||||
|
|
||||||
|
- Existing libraries
|
||||||
|
- Pandera: runtime only, syntax heavy, but quite complete
|
||||||
|
|
||||||
|
- Similar ideas
|
||||||
|
- Gator system (https://capra.cs.cornell.edu/research/gator/)
|
||||||
|
*/
|
||||||
244
report/chapters/03_theory.typ
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "@preview/gentle-clues:1.3.1" as gc
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "@preview/curryst:0.6.0": prooftree, rule
|
||||||
|
#import "03_theory/python_syntax.typ": python-syntax
|
||||||
|
#import "03_theory/midas_syntax.typ": midas-syntax
|
||||||
|
#import "03_theory/typing.typ"
|
||||||
|
|
||||||
|
= Underlying Theory and Typing Rules <chap:theory>
|
||||||
|
|
||||||
|
#gc.info[
|
||||||
|
This chapter presents some type theory notions that form the basis of a type checker and establishes some typing rules we would wish to implement for Python. The reader may skip this more theoretical chapter to the implementation in @chap:impl. These notions are only explained to justify some implementation decisions and provide a solid basis on which to build the type checker but are not strictly necessary to understand the concrete development.
|
||||||
|
]
|
||||||
|
|
||||||
|
The first step to build a useful type checker for Python is to identify the concrete requirements. By identifying what kind of expressions and relationships we are dealing with, we can then select the rules we need to define and handle, and implement appropriate solutions. The concepts and ideas covered in this chapter are mainly derived from the wonderful #acr("TaPL") by Benjamin C. Pierce. This books serves as a reference for all type theory notions presented in this report. This report does not intend to become the new #acr("TaPL").
|
||||||
|
|
||||||
|
== Principles <sec:theory-principles>
|
||||||
|
|
||||||
|
To talk about type theory and typing rules, we must first define some concepts. B. C. Pierce suggests one definition for type systems:
|
||||||
|
|
||||||
|
#quote(block: true)[
|
||||||
|
A type system is a tractable syntactic method for proving the absence of certain program behaviors by classifying phrases according to the kinds of values they compute.@tapl
|
||||||
|
]
|
||||||
|
|
||||||
|
At its core, a type system provides techniques to ensure the absence of unwanted behavior due to incompatibilities between value types. Although often associated with computer science and programming languages, the fundamental concept of a type system is a mathematical construct.
|
||||||
|
In the following sections, we will define both syntax rules, to lay out legal constructs in the languages, and typing rules, to build relationships and theorems in our type system.
|
||||||
|
|
||||||
|
Syntactically, we will use different kinds of elements, as described in @tab:calculus-elmts.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
table(
|
||||||
|
columns: 3,
|
||||||
|
table.header[*Element*][*Meta-variable*][*Description*],
|
||||||
|
[Terms], $"t"$, [Building blocks of the language, expressions which can be evaluated],
|
||||||
|
[Values], $"v"$, [Subset of terms, possible final results of evaluation],
|
||||||
|
[Statements], $"s"$, [Language constructs that do not evaluate to a value and may have side-effects],
|
||||||
|
[Types], $"T"$, [Category of values of the same kind],
|
||||||
|
),
|
||||||
|
caption: [Calculus elements]
|
||||||
|
) <tab:calculus-elmts>
|
||||||
|
|
||||||
|
A term $"t"$ is said to be of type $"T"$, written $"t": "T"$ if it can be statically proven that it evaluates to a value belonging to type $"T"$.
|
||||||
|
|
||||||
|
Additionally, we will need to define rules that link different types together in a compatibility relationship. For example, we can say that a car is a kind of vehicle. In this case, the type `Car` is said to be a "subtype" of `Vehicle`. This relationship is asymmetric and transitive, and is written $"S" <: "T"$ (read "S is a subtype of T").
|
||||||
|
|
||||||
|
Finally, because we are dealing with a complex programming language such as Python, we need to introduce the concept of a context. In Python, as in most other languages, users can define variables and functions taking named parameters. This fact means that evaluating an expression, or even typing it, requires knowing some things about the context of what comes before. Taking the example of @fig:example-context, we can see that evaluating or typing the expression `a + a` on line 2 requires knowing the type (or value) of `a`, which was set in a different statement on line 1.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
a: float = 3
|
||||||
|
b = a + a
|
||||||
|
```,
|
||||||
|
caption: [Example Python expression requiring context]
|
||||||
|
) <fig:example-context>
|
||||||
|
|
||||||
|
The notations for context are as follows:
|
||||||
|
#align(center, grid(
|
||||||
|
columns: 2,
|
||||||
|
gutter: 1em,
|
||||||
|
align: (center, left),
|
||||||
|
$Gamma$,
|
||||||
|
[the context, a list of bindings, mapping terms to types],
|
||||||
|
$Gamma, "t": "T"$,
|
||||||
|
[the context extended with the binding of $"t"$ to the type $"T"$],
|
||||||
|
))
|
||||||
|
|
||||||
|
Finally, the rules expressed in @sec:theory-syntax are written in the form of theorems using the following mathematical syntaxes:
|
||||||
|
|
||||||
|
#align(center, grid(
|
||||||
|
columns: 2,
|
||||||
|
gutter: 1em,
|
||||||
|
align: (center, left),
|
||||||
|
prooftree(rule($P_1$, $...$, $P_n$, $C$)),
|
||||||
|
[Given premises $P_1, ..., P_n$, conclusion $C$ is true],
|
||||||
|
$Gamma tack P$,
|
||||||
|
[$Gamma$ "judges" that $P$ is true, i.e. $P$ is true given context $Gamma$],
|
||||||
|
$P tack.l Gamma'$,
|
||||||
|
[Evaluating $P$ produces the new context $Gamma'$]
|
||||||
|
))
|
||||||
|
|
||||||
|
== Syntax rules <sec:theory-syntax>
|
||||||
|
|
||||||
|
In this section, we define syntax rules for both Python and our type definition language Midas. Obviously, Python already has syntax rules defining what is or is not valid code. What is defined in @sec:theory-syntax-python are a subset of constructs which our type checker will be able to process.
|
||||||
|
|
||||||
|
=== Python syntax <sec:theory-syntax-python>
|
||||||
|
|
||||||
|
@tab:python-syntax-rules lists mosts Python constructs we want to support with our type checker (notable exceptions are listed below). This subset of the Python language is sufficient to express a wide range of programs, including data processing pipelines and moderately complex scripts.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
python-syntax,
|
||||||
|
caption: [Python syntax rules],
|
||||||
|
supplement: [Table],
|
||||||
|
kind: table,
|
||||||
|
) <tab:python-syntax-rules>
|
||||||
|
|
||||||
|
Some syntaxes are simplified or omitted from @tab:python-syntax-rules for the sake of conciseness, readability and scope. Indeed, this work's primary focus is not on the theoretical and formal approach to type checking but rather on the concrete application of it to produce a useful tool for developers. For example, function signature in Python are rather complex and flexible, allowing positional-only, keyword-only and mixed parameters, argument sinks, and default values. Expressing this level of flexibility in a formal definition as those presented above is tricky and not necessarily pertinent to this work.
|
||||||
|
|
||||||
|
Other syntaxes not referenced in this report are voluntarily left out because they either fall out of the scope of this work or are either not fundamental to the language or not necessary to most developers. Such constructs include classes, match statements, while loops, `for`/`else` blocks and the walrus operator~(`:=`).
|
||||||
|
|
||||||
|
=== Midas syntax <sec:theory-syntax-midas>
|
||||||
|
|
||||||
|
Our type system includes a dedicated language to define custom types that can be used in Python code. This language is hereafter referred to as the Midas language, or simply Midas. Its goal is to allow users to concisely define types, aliases, subtypes and the like in a simple and intuitive language. All syntax rules are listed in @tab:midas-syntax-rules.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
midas-syntax,
|
||||||
|
caption: [Midas syntax rules],
|
||||||
|
supplement: [Table],
|
||||||
|
kind: table,
|
||||||
|
) <tab:midas-syntax-rules>
|
||||||
|
|
||||||
|
Parameter specifications in function types and predicates are simplified here for conciseness. In actuality, the supported syntax is similar to Python's regarding positional-only, keyword-only and mixed arguments, with the following notable differences:
|
||||||
|
- the name of positional-only parameters is optional, i.e. `fn(float, /) -> bool` is valid
|
||||||
|
|
||||||
|
- default values are not supported but optional parameters may be indicated with a question mark (`?`) after the type, e.g. `fn(a: float?) -> bool`
|
||||||
|
|
||||||
|
A more detailed definition of the syntax is available in @app:midas-syntax.
|
||||||
|
|
||||||
|
Some elements are worth explaining here. Midas offers four base statements through four keywords: `alias`, `type`, `extend` and `predicate`.\
|
||||||
|
The first is rather straightforward: ```midas alias X = T``` defines an alias named `X` for the type `T`.\
|
||||||
|
The second is a simple subtype definition. ```midas type X = T``` is similar to an alias, but it creates a subtype relationship instead of an equivalence. `X` is thus a subtype of `T`. This also allows defining generic types using type parameters, bounded or not, which can be referenced in the right-hand side of the definition. For example ```midas type Foo[T <: U] = list[T]``` defines a type generic `Foo` with one parameter `T` subtype of `U`, which is a subtype of `list[T]`.\
|
||||||
|
The third, `extend`, is linked to a subtype definition. It allows users to define members on a type, such as properties/attributes (`prop`) and methods (`def`). Methods may be overloaded to combine multiple signatures under the same name. The type specific after `extend` must obviously be defined.\
|
||||||
|
The last kind of statement provides user with a way to define named constraint expressions and reuse them as functions in other constraint expressions. Predicates are defined like functions, with a list of parameters. This list may be split into multiple parameter specifications, for example ```midas predicate foo(a: float)(b: int) = a < b``` to allow partial application.
|
||||||
|
|
||||||
|
A particularity of Midas are its constraint types. A constraint type `T where e` is built from a base type `T` and a constraint expression `e`. It allows binding a constraint on the values belonging to this type, which will be materialized by assertions at runtime.
|
||||||
|
|
||||||
|
== Typing rules <sec:theory-typing>
|
||||||
|
|
||||||
|
Now that we have defined what Python syntax we will support and our own definition language, we need to define how our type checker will be able to bind types to Python expressions. This section is heavily inspired by the _Pure simply typed lambda-calculus~($lambda_->$)_, _Simply typed lambda-calculus with subtyping~($lambda_(<:)$)_, _Polymorphic lambda-calculus (System F)_ and _Bounded quantification (kernel $F_(<:)$)_ presented in Chapters 9, 15, 23 and 26 of #acr("TaPL")@tapl.
|
||||||
|
|
||||||
|
=== Literals <sec:typing-literals>
|
||||||
|
|
||||||
|
First and foremost, we can define elementary typing rules for all literal values. These rules having no premises, they are simple axioms. @tab:typing-literals lists all literal typing rules.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.literals,
|
||||||
|
caption: [Typing rules: literals],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-literals>
|
||||||
|
|
||||||
|
Other constructs, although not constants, directly map to builtin types. These include literal lists, tuples and dictionaries. Each of these has a corresponding `list[T]`, `tuple` and `dict[K, V]` type. We will not define formal rules in this section regarding these elements, but a more in depth explanation will be given in the implementation of the type checker, in @sec:python-check-literals.
|
||||||
|
|
||||||
|
=== Expressions <sec:typing-expressions>
|
||||||
|
|
||||||
|
Apart from literals, developers also need some building blocks to express their programs. These expressions include variables, function calls, operations, etc. and need their own typing rules. The rules listed in @tab:typing-expressions cover most expressions we will handle, as defined in @sec:theory-syntax-python. Some syntaxes are omitted to keep this chapter short and because they don't necessarily bring new theoretical concepts.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.expressions,
|
||||||
|
caption: [Typing rules: expressions],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-expressions>
|
||||||
|
|
||||||
|
#smallcaps[T-Var] simply states that a variable can be typed iff it is in the context.
|
||||||
|
|
||||||
|
#smallcaps[T-Call] is a simplified rule of the concrete behavior. Taking into account all call forms with positional and keyword arguments is a rather tedious process which is left as an exercise to the reader.
|
||||||
|
|
||||||
|
#smallcaps[T-Tern] is worth a few more words too. Typing rules used by Midas are, by design, stricter than what Python allows. In this case, because we have chosen not to include union types, an expression can only have at most one type, thus the branches must belong to a common type. The specific types of each branch may differ thanks to #smallcaps[T-Sub], defined in @tab:typing-subtyping-base. Additionally, the test expression must be of type $"bool"$, whereas Python can evaluate any object to a boolean.
|
||||||
|
|
||||||
|
#smallcaps[T-Op] is used for all binary operations. In Python, these are implemented in _dunder-methods_, such as `__add__` for the `+` operator. A similar rule could be defined for unary operations but is omitted here for brevity.
|
||||||
|
|
||||||
|
=== Statements <sec:typing-statements>
|
||||||
|
|
||||||
|
Finally, expressions can be used in statements, which are special constructs that can have side-effects. We listed in @sec:theory-syntax-python the particular statements that Midas should support, and @tab:typing-statements provides rules to type check their components and effects.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.statements,
|
||||||
|
caption: [Typing rules: statements],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-statements>
|
||||||
|
|
||||||
|
#smallcaps[T-Annot] is a rule which handles Python type annotations. It states that the type checker must take note of type hints in the context.
|
||||||
|
|
||||||
|
#smallcaps[T-Assign] handles assignments to variables. For an assignment to be valid, the value must be of the same type as the variable's type (modulo subsumption, #smallcaps[T-Sub]).
|
||||||
|
|
||||||
|
#smallcaps[T-Seq] allows sequences of statements.
|
||||||
|
|
||||||
|
#smallcaps[T-IfElse], like #smallcaps[T-Tern] is a stricter version of how Python processes `if` statements. Indeed, Midas will not allow leaking context from inside the bodies of any branch. If a variable is declared inside an `if` statement, Midas will not allow references outside of it.
|
||||||
|
|
||||||
|
#gc.info[
|
||||||
|
You may be familiar with the walrus operator `:=` which is often used in `if` statements to simultaneously declare a variable and use it as an expression. It it thus a mix between a simple expression, which may be used everywhere, and a statement, with the side-effect of declaring a variable.
|
||||||
|
]
|
||||||
|
|
||||||
|
#smallcaps[T-Def] is a gross simplification of how functions can be defined. It does not cover multiple parameters, positional-only and keyword-only parameters, complex bodies with multiple and implicit returns, etc. Again, for the sake of simplicity and readability, we will not define a complete rule to handle all forms and features, but the implementation will go into more details in @sec:python-functions.
|
||||||
|
|
||||||
|
=== Subtyping <sec:typing-subtyping>
|
||||||
|
|
||||||
|
Similarly to some calculi described in #acr("TaPL")@tapl and to allow flexibility, we must equip our type system with a subtyping relationship. This relationship allows using some types in place of others where it is sound to do so. The subtyping rules presented in @tab:typing-subtyping-base cover the base cases of subtyping.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.subtyping,
|
||||||
|
caption: [Typing rules: subtyping base],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-subtyping-base>
|
||||||
|
|
||||||
|
The subtyping relationship is by definition both reflective (#smallcaps[S-Refl]) and transitive (#smallcaps[S-Trans]).
|
||||||
|
|
||||||
|
#smallcaps[T-Sub] is a consequence of the #acr("LSP"). A term $"t"$ of type $"S"$ can be used anywhere a term of type $"T"$ is expected if $"S"$ is a subtype of $"T"$.
|
||||||
|
|
||||||
|
In addition to these base rules, we need to define how functions, constraint types and generic types are handled.
|
||||||
|
For constraint types, we will take the simple approach of considering only the base type for the subtype relationship. A more complete and interesting implementation could implement subtyping of constraint expression, where a condition such as `_ < 10` is a subtype of `_ < 100`, but the added complexity was deemed out of scope for this particular project. We do nonetheless define #smallcaps[S-Constr] in @tab:typing-subtyping-constraint to handle the base case.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.subtyping-constraint,
|
||||||
|
caption: [Typing rules: subtyping constraint type],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-subtyping-constraint>
|
||||||
|
|
||||||
|
Generics are handled using similar rules to the _Bounded quantification (kernel $F_(<:)$)_ calculus presented in #acr("TaPL") Chapter 26@tapl. Additionally, Midas supports implicit variance, which is inferred from the locations in which type parameters are used, and is used when checking subtypes of applied generic types. A detailed explanation of variance inference is provided in the corresponding implementation section, @sec:variance-inference.
|
||||||
|
|
||||||
|
Finally, functions in Python are complex types. The general subtyping rule is given in @tab:typing-subtyping-function, but the complete set of rules for checking parameter specifications is too complex to include here. It is however detailed in @app:function-subtyping.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.subtyping-function,
|
||||||
|
caption: [Typing rules: subtyping functions],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-subtyping-function>
|
||||||
|
|
||||||
|
=== Special types <sec:theory-special-types>
|
||||||
|
|
||||||
|
Two special types can be added to our type system for practical purposes. The first is a regular top type, as represented by `Any` in Python. Every type is a subtype of `Any`, as stated by #smallcaps[S-Any] in @tab:typing-subtyping-top.
|
||||||
|
|
||||||
|
In addition to `Any`, we will add a second top type to represent unknowns. When a user omits an annotation, the type checker can use this type as a placeholder to track that a particular expression was indeed processed but its type could not be determined. This has many practical benefits, among which avoiding early exits and propagating unknowns. Additionally, this allows the type checker to differentiate a variable which has specifically been typed as `Any`, and can contain _any_ kind of value, from a variable whose type the checker does not know.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
typing.subtyping-top,
|
||||||
|
caption: [Typing rules: subtyping top types],
|
||||||
|
kind: table,
|
||||||
|
supplement: [Table],
|
||||||
|
) <tab:typing-subtyping-top>
|
||||||
|
|
||||||
|
The special type `None`, also later referred to as `UnitType`, is used in Midas as a unit type, mapping Python functions' behavior regarding implicit returns.
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Identify requirements
|
||||||
|
- Introduction to TAPL
|
||||||
|
- Grammar and typing rules for Midas, paralleled with TAPL
|
||||||
|
- Omitted rules, simplifications, mechanisms not implemented
|
||||||
|
*/
|
||||||
61
report/chapters/03_theory/midas_syntax.typ
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#import "utils.typ": *
|
||||||
|
|
||||||
|
#let types = (
|
||||||
|
($"X"$, [_named type_]),
|
||||||
|
($"T" ["T"^(i in 1..n)]$, [_type application_]),
|
||||||
|
($"T" #syntax[where] "e"$, [_constraint type_]),
|
||||||
|
($#syntax[fn] (attach("a"_i: "T"_i, tr: i in 1..n)) -> "T"$, [_function type_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let statements = (
|
||||||
|
($#syntax[alias] "X" = "T"$, [_alias definition_]),
|
||||||
|
($#syntax[type] "X" = "T"$, [_type definition_]),
|
||||||
|
($#syntax[type] "X"["P"^(i in 1..n)] = "T"$, [_generic definition_]),
|
||||||
|
($ cases(
|
||||||
|
#syntax[extend] "X"["P"^(i in 1..n)] space \{,
|
||||||
|
quad m^(j in 1..M),
|
||||||
|
\},
|
||||||
|
delim: "["
|
||||||
|
) $, [_generic definition_]),
|
||||||
|
($#syntax[predicate] "p" = "e"$, [_predicate alias_]),
|
||||||
|
($#syntax[predicate] "p" (attach("a"_i: "T"_i, tr: i in 1..n))^(j in 1..m) = "e"$, none),
|
||||||
|
($$, [_predicate definition_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let type-parameters = (
|
||||||
|
($X$, [_type variable_]),
|
||||||
|
($X <: T$, [_bounded type\ variable_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let member-statements = (
|
||||||
|
($#syntax[prop] x: T$, [_property_]),
|
||||||
|
($#syntax[def] x: T$, [_method_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let expressions = (
|
||||||
|
($x$, [_variable_]),
|
||||||
|
($"i"$, [_integer literal_]),
|
||||||
|
($"f"$, [_float literal_]),
|
||||||
|
($"z"$, [_string literal_]),
|
||||||
|
($"True"$, [_constant true_]),
|
||||||
|
($"False"$, [_constant false_]),
|
||||||
|
($"None"$, [_constant none_]),
|
||||||
|
($f("t")$, [_call_]),
|
||||||
|
($"t"_1 "op" "t"_2$, [_operation_]),
|
||||||
|
($"t"."x"$, [_attribute_]),
|
||||||
|
($\_$, [_self reference_])
|
||||||
|
)
|
||||||
|
|
||||||
|
#let midas-syntax = grid(
|
||||||
|
columns: (1fr, 1fr),
|
||||||
|
gutter: 2em,
|
||||||
|
syntax-grid(
|
||||||
|
("T", "types", types),
|
||||||
|
("e", "expressions", expressions),
|
||||||
|
),
|
||||||
|
syntax-grid(
|
||||||
|
("s", "statements", statements),
|
||||||
|
("P", "type parameters", type-parameters),
|
||||||
|
("m", "member statements", member-statements),
|
||||||
|
),
|
||||||
|
)
|
||||||
68
report/chapters/03_theory/python_syntax.typ
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
#import "utils.typ": *
|
||||||
|
|
||||||
|
#let terms = (
|
||||||
|
($"x"$, [_variable_]),
|
||||||
|
($"i"$, [_integer literal_]),
|
||||||
|
($"f"$, [_float literal_]),
|
||||||
|
($"z"$, [_string literal_]),
|
||||||
|
($"True"$, [_constant true_]),
|
||||||
|
($"False"$, [_constant false_]),
|
||||||
|
($"None"$, [_constant none_]),
|
||||||
|
($f("t")$, [_call_]),
|
||||||
|
($"t"_21 #syntax[if] "t"_1 #syntax[else] "t"_22$, [_ternary_]),
|
||||||
|
($"t"_1 "op" "t"_2$, [_operation_]),
|
||||||
|
($"t" [ "t" ]$, [_subscript_]),
|
||||||
|
($"t"."x"$, [_attribute_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let values = (
|
||||||
|
($"i"$, [_integer literal_]),
|
||||||
|
($"f"$, [_float literal_]),
|
||||||
|
($"z"$, [_string literal_]),
|
||||||
|
($"True"$, [_constant true_]),
|
||||||
|
($"False"$, [_constant false_]),
|
||||||
|
($"None"$, [_constant none_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let statements = (
|
||||||
|
($"t"$, [_expression_]),
|
||||||
|
($"s"; "t"$, [_inline sequence_]),
|
||||||
|
($ cases(
|
||||||
|
"s" #nl,
|
||||||
|
"s",
|
||||||
|
delim: "["
|
||||||
|
) $, [_multiline sequence_]),
|
||||||
|
($"x" = "t"$, [_assignment_]),
|
||||||
|
($"x": "T"$, [_variable declaration_]),
|
||||||
|
($ cases(
|
||||||
|
#syntax[def] f("x": "T") -> "T": #nl,
|
||||||
|
#tab "t" #nl,
|
||||||
|
delim: "["
|
||||||
|
) $, [_def_]),
|
||||||
|
($ cases(
|
||||||
|
#syntax[if] "t": #nl,
|
||||||
|
tab "s" #nl,
|
||||||
|
#syntax[else]: #nl,
|
||||||
|
tab "s" #nl,
|
||||||
|
delim: "["
|
||||||
|
) $, [_if / else_]),
|
||||||
|
($ cases(
|
||||||
|
#syntax[for] "x" #syntax[in] "t":#nl,
|
||||||
|
#tab "s",
|
||||||
|
delim: "["
|
||||||
|
) $, [_for loop_]),
|
||||||
|
($#syntax[return]$, [_bare return_]),
|
||||||
|
($#syntax[return] "t"$, [_value return_]),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let python-syntax = grid(
|
||||||
|
columns: (1fr, 1fr),
|
||||||
|
gutter: 2em,
|
||||||
|
syntax-grid(
|
||||||
|
("t", "terms", terms),
|
||||||
|
("v", "values", values),
|
||||||
|
),
|
||||||
|
syntax-grid(
|
||||||
|
("s", "statements", statements),
|
||||||
|
),
|
||||||
|
)
|
||||||
206
report/chapters/03_theory/typing.typ
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
#import "@preview/curryst:0.6.0"
|
||||||
|
#import "utils.typ": *
|
||||||
|
|
||||||
|
#let rule(
|
||||||
|
name,
|
||||||
|
..premises,
|
||||||
|
conclusion,
|
||||||
|
python,
|
||||||
|
) = (
|
||||||
|
return (
|
||||||
|
name: name,
|
||||||
|
rule: curryst.prooftree(
|
||||||
|
curryst.rule(
|
||||||
|
..premises.pos(),
|
||||||
|
conclusion,
|
||||||
|
name: smallcaps[(#name)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
python: python,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
#let literals-rules = (
|
||||||
|
rule(
|
||||||
|
"T-Int",
|
||||||
|
$Gamma tack "i": "int"$,
|
||||||
|
```py 12: int```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Float",
|
||||||
|
$Gamma tack "f": "float"$,
|
||||||
|
```py 12.34: float```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Str",
|
||||||
|
$Gamma tack "z": "str"$,
|
||||||
|
```py "foo": str```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-True",
|
||||||
|
$Gamma tack "True": "bool"$,
|
||||||
|
```py True: bool```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-False",
|
||||||
|
$Gamma tack "False": "bool"$,
|
||||||
|
```py False: bool```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-None",
|
||||||
|
$Gamma tack "None": "None"$,
|
||||||
|
```py None: None```
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let expressions-rules = (
|
||||||
|
rule(
|
||||||
|
"T-Var",
|
||||||
|
$"x": "T" in Gamma$,
|
||||||
|
$Gamma tack "x": "T"$,
|
||||||
|
```py x```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Call",
|
||||||
|
$Gamma tack f: "T"_1 -> "T"_2$,
|
||||||
|
$Gamma tack "t": "T"_1$,
|
||||||
|
$Gamma tack f("t"): "T"_2$,
|
||||||
|
```py
|
||||||
|
def func(a: S) -> T: ...
|
||||||
|
...
|
||||||
|
func(a): T
|
||||||
|
```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Tern",
|
||||||
|
$Gamma tack "t"_1: "bool"$,
|
||||||
|
$Gamma tack "t"_21: "T"$,
|
||||||
|
$Gamma tack "t"_22: "T"$,
|
||||||
|
$Gamma tack "t"_21 #syntax[if] "t"_1 #syntax[else] "t"_22: "T"$,
|
||||||
|
```py (true if cond else false): T ```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Op",
|
||||||
|
$Gamma tack "t"_1: "T"_1$,
|
||||||
|
$Gamma tack "t"_2: "T"_2$,
|
||||||
|
$"op": "T"_1 -> "T"_2 -> "T"_3 in Gamma$,
|
||||||
|
$Gamma tack "t"_1 "op" "t"_2: "T"_3$,
|
||||||
|
```py (a + b): T```,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let statements-rules = (
|
||||||
|
rule(
|
||||||
|
"T-Annot",
|
||||||
|
$Gamma tack "x": "T" tack.l Gamma, "x": "T"$,
|
||||||
|
```py x: T```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Assign",
|
||||||
|
$Gamma tack "x": "T"$,
|
||||||
|
$Gamma tack "t": "T"$,
|
||||||
|
$Gamma tack "x" = "t" tack.l Gamma$,
|
||||||
|
```py x = t```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Seq",
|
||||||
|
$Gamma tack "s"_1 tack.l Gamma'$,
|
||||||
|
$Gamma' tack "s"_2 tack.l Gamma''$,
|
||||||
|
$Gamma tack "s"_1; "s"_2 tack.l Gamma''$,
|
||||||
|
```py a = 3; a: int```
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-IfElse",
|
||||||
|
$Gamma tack "t": "bool"$,
|
||||||
|
$Gamma tack "s"_1 tack.l Gamma'$,
|
||||||
|
$Gamma tack "s"_2 tack.l Gamma''$,
|
||||||
|
$Gamma tack #syntax[if] "t": "s"_1 #syntax[else]: "s"_2 tack.l Gamma$,
|
||||||
|
```py
|
||||||
|
if cond:
|
||||||
|
...
|
||||||
|
else:
|
||||||
|
...
|
||||||
|
```,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Def",
|
||||||
|
$Gamma, f: "T"_1 -> "T"_2, "x": "T"_1 tack "t": "T"_2$,
|
||||||
|
$ Gamma tack cases(delim: #none, #syntax[def] &f("x": "T"_1) -> "T"_2:, &#syntax[return] "t") space tack.l space Gamma, f: "T"_1 -> "T"_2 $,
|
||||||
|
```py
|
||||||
|
def func(a: S) -> T:
|
||||||
|
return ...: T
|
||||||
|
```,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let subtyping-rules = (
|
||||||
|
rule(
|
||||||
|
"S-Refl",
|
||||||
|
$"S" <: "S"$,
|
||||||
|
none,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"S-Trans",
|
||||||
|
$"S" <: "U"$,
|
||||||
|
$"U" <: "T"$,
|
||||||
|
$"S" <: "T"$,
|
||||||
|
none,
|
||||||
|
),
|
||||||
|
rule(
|
||||||
|
"T-Sub",
|
||||||
|
$Gamma tack "t": "S"$,
|
||||||
|
$"S" <: "T"$,
|
||||||
|
$Gamma tack "t": "T"$,
|
||||||
|
none,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
#let rules-grid(rules, columns: 1, large: false) = {
|
||||||
|
let cells = rules.map(
|
||||||
|
r => (r.rule, r.python)
|
||||||
|
).chunks(columns).flatten()
|
||||||
|
let header = ([*Rule*], [*Python example*]) * columns
|
||||||
|
grid(
|
||||||
|
columns: (auto, if large {1fr} else {auto}) * columns,
|
||||||
|
//row-gutter: 2em,
|
||||||
|
//column-gutter: 1em,
|
||||||
|
column-gutter: (0pt, 3em) * columns,
|
||||||
|
inset: (x:.5em, y: 1em),
|
||||||
|
align: (center+horizon, right+horizon),
|
||||||
|
//stroke: (x, _) => if calc.rem(x, 2) == 0 and x != 0 {(left: black)},
|
||||||
|
grid.header(..header),
|
||||||
|
..cells,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let literals = rules-grid(literals-rules, columns: 2)
|
||||||
|
#let expressions = rules-grid(expressions-rules)
|
||||||
|
#let statements = rules-grid(statements-rules, large: true)
|
||||||
|
#let subtyping = curryst.rule-set(
|
||||||
|
..subtyping-rules.map(r => r.rule)
|
||||||
|
)
|
||||||
|
#let subtyping-constraint = curryst.prooftree(
|
||||||
|
curryst.rule(
|
||||||
|
$"S" <: "T"$,
|
||||||
|
$"S" #syntax[where] "e" <: "T"$,
|
||||||
|
name: smallcaps[(S-Constr)],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
#let subtyping-function = curryst.prooftree(
|
||||||
|
curryst.rule(
|
||||||
|
$"S"_2 <: "S"_1$,
|
||||||
|
$"R"_1 <: "R"_2$,
|
||||||
|
$#syntax[fn] ("S"_1) -> "R"_1 <: #syntax[fn] ("S"_2) -> "R"_2$,
|
||||||
|
name: smallcaps[(S-Func)],
|
||||||
|
)
|
||||||
|
)
|
||||||
|
#let subtyping-top = curryst.rule-set(
|
||||||
|
curryst.prooftree(curryst.rule(
|
||||||
|
$"T" <: "Any"$,
|
||||||
|
name: smallcaps[(S-Any)],
|
||||||
|
)),
|
||||||
|
curryst.prooftree(curryst.rule(
|
||||||
|
$"T" <: "Unknown"$,
|
||||||
|
name: smallcaps[(S-Unknown)],
|
||||||
|
)),
|
||||||
|
)
|
||||||
48
report/chapters/03_theory/utils.typ
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
#let syntax(body) = {
|
||||||
|
set text(weight: "bold", fill: rgb(100, 50, 0))
|
||||||
|
body
|
||||||
|
}
|
||||||
|
#let blank(r, c) = grid.cell(
|
||||||
|
rowspan: r,
|
||||||
|
colspan: c
|
||||||
|
)[]
|
||||||
|
|
||||||
|
#let tab = sym.arrow.r.stop
|
||||||
|
#let nl = move(dx: -2pt, dy: 2pt, sym.arrow.curve.l)
|
||||||
|
#let syntax-preamble = doc => {
|
||||||
|
show tab: set text(fill: gray.darken(20%))
|
||||||
|
show sym.arrow.curve.l: set text(fill: gray.darken(20%))
|
||||||
|
set math.cases(gap: 4pt)
|
||||||
|
|
||||||
|
show math.equation: set align(left)
|
||||||
|
|
||||||
|
doc
|
||||||
|
}
|
||||||
|
|
||||||
|
#let syntax-grid(..sections) = {
|
||||||
|
let cells = ()
|
||||||
|
|
||||||
|
for (i, (meta-var, name, elements)) in sections.pos().enumerate() {
|
||||||
|
if i != 0 {
|
||||||
|
cells.push(grid.cell(colspan: 4)[])
|
||||||
|
}
|
||||||
|
cells += ($#meta-var$, $::=$, none, [_#{name}_])
|
||||||
|
cells.push(blank(elements.len(), 2))
|
||||||
|
cells += elements.map(
|
||||||
|
e => if e.last() == none {
|
||||||
|
grid.cell(colspan: 2, e.first())
|
||||||
|
} else {
|
||||||
|
e
|
||||||
|
}
|
||||||
|
).flatten()
|
||||||
|
}
|
||||||
|
|
||||||
|
show: syntax-preamble
|
||||||
|
grid(
|
||||||
|
columns: (auto, auto, 1fr, auto),
|
||||||
|
align: (left, left, left, right).map(a => a + horizon),
|
||||||
|
column-gutter: .4em,
|
||||||
|
row-gutter: 1.2em,
|
||||||
|
..cells,
|
||||||
|
)
|
||||||
|
}
|
||||||
39
report/chapters/04_implementation.typ
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "../utils.typ": include-offset
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "@preview/gentle-clues:1.3.1" as gc
|
||||||
|
#import "../../meta.typ"
|
||||||
|
|
||||||
|
= Implementation <chap:impl>
|
||||||
|
|
||||||
|
Now that we have chosen a subset of Python to support and some type checking rules, we may start implementing the type checker itself. We will split the implementation into three relatively independent parts: the Midas language (parsing and registering types), type checking Python and the generator (to output runnable code with runtime assertions).
|
||||||
|
|
||||||
|
The Python language has been chosen for implementing the type checker for several reasons. First, the student was already greatly familiar with that language and its environment. Secondly, as stated in the introduction, Python is a highly versatile tool which is particularly good at manipulating data, and is easy to iterate with. Then, the student had already implemented a simple interpreter which could be reused and adapted for Midas, as explained in @sec:impl-midas. Finally, Python already provides an `ast` module in its standard library to parse and unparse Python source code, and manipulate its #acr("AST") nodes.
|
||||||
|
|
||||||
|
In @sec:impl-overview, we will first look at the whole system from a top-down perspective to locate its components and get a feel of how they connect to each other.
|
||||||
|
|
||||||
|
#gc.info[
|
||||||
|
This chapter contains many references to the project's source code, which is available in the repository at #link(meta.project-repos).\
|
||||||
|
Additionally, a mirror is also available on GitHub at #link(meta.mirror-repo).
|
||||||
|
]
|
||||||
|
|
||||||
|
#pagebreak()
|
||||||
|
|
||||||
|
#include-offset(path("04_implementation/01_overview.typ"))
|
||||||
|
#include-offset(path("04_implementation/02_types.typ"))
|
||||||
|
#include-offset(path("04_implementation/03_registry.typ"))
|
||||||
|
#include-offset(path("04_implementation/04_midas_language.typ"))
|
||||||
|
#include-offset(path("04_implementation/05_python_checking.typ"))
|
||||||
|
#include-offset(path("04_implementation/06_generation.typ"))
|
||||||
|
|
||||||
|
/*
|
||||||
|
Subjects:
|
||||||
|
- Variance inference
|
||||||
|
- Environment
|
||||||
|
- Resolver
|
||||||
|
- Evaluator
|
||||||
|
- CallDispatcher
|
||||||
|
- Registry (`is_subtype`)
|
||||||
|
- MethodRegistry (frames and columns)
|
||||||
|
*/
|
||||||
33
report/chapters/04_implementation/01_overview.typ
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#import "../../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "../../figs/architecture.typ"
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
|
||||||
|
= Architecture Overview <sec:impl-overview>
|
||||||
|
|
||||||
|
Our type checker is composed of several interdependent elements shown in @fig:architecture. At its core, there is a type registry which holds a list of all registered types. This registry is initialized with builtin types, like `float` and `str`, and can be further populated by user definitions written in the Midas language. Finally, it is used when type checking the Python source code based on the type checking rules we defined in @sec:theory-typing.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
architecture.overview,
|
||||||
|
caption: [Implementation Architecture Overview],
|
||||||
|
kind: image,
|
||||||
|
supplement: [Figure],
|
||||||
|
) <fig:architecture>
|
||||||
|
|
||||||
|
The different components have the following responsibilities:
|
||||||
|
/ Midas Typer: Take in a Midas definition file or some source code, parse it, process each statement and register new types in the registry. It must also check references between types and provide users with diagnostics in case of errors.
|
||||||
|
/ Python Typer: Take in a Python file or some source code, parse it, walk through each statement and expression, take note of type hints and otherwise infer types if possible, detect any incompatibilities, i.e. type errors and report them to the user.
|
||||||
|
/ Types Registry: Hold a registry of existing types (builtin or user-defined) and predicates, provide a method to check subtyping according to our rules (i.e. `is_subtype(type1, type2)`) and provide some methods to register, lookup and manipulate types.
|
||||||
|
/ Generator: Take in a Python #acr("AST"), type judgments (i.e. conclusions of the type checker) and the registry to produce new Python code with assertions that check types at runtime where necessary as well as constraint predicates.
|
||||||
|
|
||||||
|
Apart from the types registry, another component will be used across the whole system which is not shown in @fig:architecture: the reporter. The reporter is a simple object that will collect all diagnostics produced at different steps of the process. That includes syntax errors in Midas files, unknown references, type errors and more.
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Main elements
|
||||||
|
- Definition language
|
||||||
|
- Supported Python syntax (cf. grammar and typing rules)
|
||||||
|
- Parse and type check
|
||||||
|
- Produce user-facing diagnostics
|
||||||
|
- Generate runtime assertions
|
||||||
|
- Architecture overview
|
||||||
|
*/
|
||||||
151
report/chapters/04_implementation/02_types.typ
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
#import "../../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "../../utils.typ": fn-link, code-ref
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
|
||||||
|
= Internal Type Representations <sec:impl-types>
|
||||||
|
|
||||||
|
Before we can parse type definitions or type check Python code, we need to define structures to represent our types.
|
||||||
|
|
||||||
|
In our type system, we will indeed have different kinds of types with different properties. All types described in this section are grouped under a union type named `Type` for easier references in annotations. Additionally, we will later need to define some basic functions to manipulate types, for example to substitute parameters in a generic type. These functions will be introduced where needed in later sections. The source code for internal type representations and these basic functions is available in the repository in #code-ref(<types>, "midas/checker/types.py").
|
||||||
|
|
||||||
|
== Base Types
|
||||||
|
|
||||||
|
The simplest types are those at the root of the type lattice with no or few properties. These include top-types like `Any`, `UnknownType` and `UnitType`/`None`, as described in @sec:theory-special-types, which can be represented as simple empty classes like in @fig:types-base-types. Builtin types also have a dedicated `BaseType` kind which holds the type's name.
|
||||||
|
For the special `tuple` type, we can define a more specific class which can hold the each item's type. This will allow nice type checking of subscript expressions for example.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class TopType: ...
|
||||||
|
class UnknownType: ...
|
||||||
|
class UnitType: ...
|
||||||
|
class BaseType:
|
||||||
|
name: str
|
||||||
|
class TupleType:
|
||||||
|
items: tuple[Type, ...]
|
||||||
|
```,
|
||||||
|
caption: [Type kinds: base types]
|
||||||
|
) <fig:types-base-types>
|
||||||
|
|
||||||
|
== Derived Types
|
||||||
|
|
||||||
|
When defining subtypes in Midas, we will need to store that link in the registry. There are multiple approaches to subtyping, which can either be nominal or structural. In the case of Midas, we will generally stick to nominal subtyping, i.e. subtypes are explicitly defined, with some exceptions like constraint types and function types, as described in @sec:typing-subtyping.
|
||||||
|
|
||||||
|
Instead of storing the subtype relationship in a separate registry, we will embed it in the type itself by using a `DerivedType` class containing the type's name and super-type. This allows easy pattern matching without additional queries to the registry, and keeps the type hierarchy clear and explicit.
|
||||||
|
A similar approach is used for constraint types, by embedding the base type and the constraint expression in the same `ConstraintType` object, as shown in @fig:types-derived-types.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class DerivedType:
|
||||||
|
name: str
|
||||||
|
type: Type
|
||||||
|
class ConstraintType:
|
||||||
|
type: Type
|
||||||
|
constraint: m.Expr
|
||||||
|
```,
|
||||||
|
caption: [Type kinds: derived types]
|
||||||
|
) <fig:types-derived-types>
|
||||||
|
|
||||||
|
== Generic Types
|
||||||
|
|
||||||
|
To define generic types, we first need type variables, which are kinds of placeholder types. These type variables have a name, an optional bounding type and a variance. The latter can be represented as a simple enum. As explained in @sec:typing-subtyping, variance is inferred rather than explicitly annotated by the user. This inference process is described in @sec:variance-inference.
|
||||||
|
Once type variables are defined, generic types are simply a kind of derived type with a list of parameters.
|
||||||
|
We also need to define an application counterpart to represent a generic type that has been instantiated with some concrete type arguments. Here, the choice of having this `AppliedType` kind instead of simply using the generic's body with its parameters substituted has been made for multiple reasons. Most importantly, it allows diagnostics to be more specific and informative and eases some comparisons between different applied types.
|
||||||
|
|
||||||
|
These types are implemented by the classes in @fig:types-generics.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class Variance(StrEnum):
|
||||||
|
INVARIANT = "INVARIANT"
|
||||||
|
COVARIANT = "COVARIANT"
|
||||||
|
CONTRAVARIANT = "CONTRAVARIANT"
|
||||||
|
class TypeVar:
|
||||||
|
name: str
|
||||||
|
bound: Optional[Type]
|
||||||
|
variance: Variance = Variance.INVARIANT
|
||||||
|
class GenericType:
|
||||||
|
name: str
|
||||||
|
params: list[TypeVar]
|
||||||
|
body: Type
|
||||||
|
class AppliedType:
|
||||||
|
name: str
|
||||||
|
args: list[Type]
|
||||||
|
body: Type
|
||||||
|
```,
|
||||||
|
caption: [Type kinds: generic types]
|
||||||
|
) <fig:types-generics>
|
||||||
|
|
||||||
|
== Function Types
|
||||||
|
|
||||||
|
As noted in the theory chapter (@chap:theory), functions in Python are complex and highly flexible.
|
||||||
|
A function type thus have a parameter specification and a return type. That parameter specification contains three kinds of parameters: positional-only (`pos`), keyword-only (`kw`) and mixed (`mixed`).
|
||||||
|
@fig:types-functions shows the implemented structures to handle function types and their parameters.
|
||||||
|
For simplicity, each parameter will store both its position and name, as well as its type and a flag indicating whether it is required or not (e.g. parameters with default values are optional). You may notice an additional `unsupported` flag in @fig:types-functions:10, which is added for some dataframe-related methods. More information shall be given in @sec:impl-python #todo[replace ref].
|
||||||
|
|
||||||
|
Finally, we will also define a structure to hold multiple signature of an overloaded function because it cannot be represented as a single `Function`. You may also notice that `OverloadedFunction.overloads` does not store a list of `Function` but simply a list of `Type`, in @fig:types-functions:16. This allows the use of generic functions, which are `Function` types wrapped inside a `GenericType`.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class Function:
|
||||||
|
params: ParamSpec
|
||||||
|
returns: Type
|
||||||
|
|
||||||
|
class Parameter:
|
||||||
|
pos: int
|
||||||
|
name: str
|
||||||
|
type: Type
|
||||||
|
required: bool
|
||||||
|
unsupported: bool = False
|
||||||
|
class ParamSpec:
|
||||||
|
pos: list[Function.Parameter] = field(default_factory=list)
|
||||||
|
mixed: list[Function.Parameter] = field(default_factory=list)
|
||||||
|
kw: list[Function.Parameter] = field(default_factory=list)
|
||||||
|
class OverloadedFunction:
|
||||||
|
overloads: list[Type]
|
||||||
|
```,
|
||||||
|
caption: [Type kinds: function types]
|
||||||
|
) <fig:types-functions>
|
||||||
|
|
||||||
|
== Dataframe types
|
||||||
|
|
||||||
|
Because Midas has been designed with data scientists in mind, it will also try and type check some common dataframe operations. To do so, we want the user to be able to define dataframe schemas and use their columns. We thus define `ColumnType` and `DataFrameType` in @fig:types-dataframes, which can be thought of as more abstract representations of Pandas' `Series` and `DataFrame`. Additionally, we define special objects to handle group-by entities which are intermediary values used when computing aggregations. These group-by types are necessary to distinguish them from the base dataframe or column because they provide different methods.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class ColumnType:
|
||||||
|
type: Type
|
||||||
|
class DataFrameType:
|
||||||
|
columns: list[Column]
|
||||||
|
|
||||||
|
class Column:
|
||||||
|
index: int
|
||||||
|
name: Optional[str]
|
||||||
|
type: ColumnType
|
||||||
|
class FrameGroupBy:
|
||||||
|
frame: DataFrameType
|
||||||
|
class ColumnGroupBy:
|
||||||
|
column: ColumnType
|
||||||
|
```,
|
||||||
|
caption: [Type kinds: dataframe types]
|
||||||
|
) <fig:types-dataframes>
|
||||||
|
|
||||||
|
== Predicates
|
||||||
|
|
||||||
|
Although not types, predicates will also be represented by similar dataclasses in the types registry, as defined in @fig:types-predicate.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class Predicate:
|
||||||
|
type: Type
|
||||||
|
body: m.Expr
|
||||||
|
alias: bool
|
||||||
|
```,
|
||||||
|
caption: [Predicate Dataclass]
|
||||||
|
) <fig:types-predicate>
|
||||||
|
|
||||||
|
This class holds three properties of predicates:
|
||||||
|
- `type`: the function signature of the predicate.\
|
||||||
|
For example, ```midas predicate less_than(max: float)(v: float) = v < max``` has the signature ```midas fn(max: float) -> fn(v: float) -> bool```
|
||||||
|
- `body`: the raw predicate expression. This will be used to generate equivalent Python code and perform static checks against literal values
|
||||||
|
- `alias`: a flag indicating whether a predicate is a simple alias of another, used for example with partially applied predicates (see @sec:midas-predicate-stmt)
|
||||||
340
report/chapters/04_implementation/03_registry.typ
Normal file
@@ -0,0 +1,340 @@
|
|||||||
|
#import "../../utils.typ": code-ref
|
||||||
|
#import "@preview/codly:1.3.0": codly
|
||||||
|
#import "../../appendices/is_subtype.typ": is-subtype-code, is-func-subtype-code
|
||||||
|
|
||||||
|
= Types Registry <sec:impl-registry>
|
||||||
|
|
||||||
|
With structures to represent our types, we now need to implement the registry which hold all builtin and user-defined types, as well as named predicates. As a reminder of requirements given in @sec:impl-overview, the registry must also provide a method `is_subtype` to check whether according to our subtyping rules one type is subtype of another, a method to register a type with a name, a method to lookup a type given a name, and some methods to manipulate types, such as instantiating a generic type given some arguments. We will also registration and lookup methods for predicates, as well as for type members (defined in `extend` statements).
|
||||||
|
|
||||||
|
@fig:registry-contract shows the minimal contract our registry must satisfy.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class TypesRegistry:
|
||||||
|
def get_type(self, name: str) -> Type: ...
|
||||||
|
def define_type(self, name: str, type: Type): ...
|
||||||
|
def define_member(
|
||||||
|
self,
|
||||||
|
type_name: str,
|
||||||
|
member_name: str,
|
||||||
|
member_type: Type,
|
||||||
|
kind: MemberKind,
|
||||||
|
): ...
|
||||||
|
def define_predicate(self, name: str, predicate: Predicate): ...
|
||||||
|
def is_subtype(self, type1: Type, type2: Type) -> bool: ...
|
||||||
|
def apply_generic(self, type: Type, args: list[Type]) -> Type: ...
|
||||||
|
def lookup_member(self, type: Type, member_name: str) -> Optional[Type]: ...
|
||||||
|
def lookup_predicate(self, name: str) -> Optional[Predicate]: ...
|
||||||
|
```,
|
||||||
|
caption: [Minimal Registry Contract]
|
||||||
|
) <fig:registry-contract>
|
||||||
|
|
||||||
|
The `define_*` and `lookup_*`/`get_*` methods are quite straightforward, inserting and querying an internal dictionary with some added safeguards and errors to prevent redefining an entity or handle undefined references. Additionally, `define_member` handles overriding methods by wrapping multiple method definitions with the same member name inside an `OverloadedFunction` type. This process is detailed in @sec:define_member hereafter. The complete implementation of `TypesRegistry` is available in the repository in #code-ref(<types-registry>, "midas/checker/registry.py")
|
||||||
|
|
||||||
|
== `define_member` <sec:define_member>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def define_member(
|
||||||
|
self,
|
||||||
|
type_name: str,
|
||||||
|
member_name: str,
|
||||||
|
member_type: Type,
|
||||||
|
kind: MemberKind,
|
||||||
|
):
|
||||||
|
members: dict[str, Member] = self._members.setdefault(type_name, {})
|
||||||
|
if member_name in members:
|
||||||
|
current: Member = members[member_name]
|
||||||
|
if current.kind != kind:
|
||||||
|
self.logger.error(
|
||||||
|
f"Member '{member_name}' is already defined as a {current.kind},"
|
||||||
|
+ f" cannot define a {kind} with the same name"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
if kind != MemberKind.METHOD:
|
||||||
|
self.logger.error(
|
||||||
|
f"Member '{member_name}' already defined for type {type_name},"
|
||||||
|
+ " only methods can be overloaded"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
combined: Type
|
||||||
|
match current.type:
|
||||||
|
case OverloadedFunction(overloads=overloads):
|
||||||
|
combined = OverloadedFunction(overloads=overloads + [member_type])
|
||||||
|
case _:
|
||||||
|
combined = OverloadedFunction(overloads=[current.type, member_type])
|
||||||
|
members[member_name] = Member(kind=current.kind, type=combined)
|
||||||
|
|
||||||
|
else:
|
||||||
|
members[member_name] = Member(kind=kind, type=member_type)
|
||||||
|
```,
|
||||||
|
caption: [Implementation of `TypesRegistry.define_member`]
|
||||||
|
) <fig:define_member>
|
||||||
|
|
||||||
|
First in @fig:define_member:8, we retrieve the dictionary of all members defined for the given type, and check wether a member is already defined with the given name in @fig:define_member:9. If that is the case, we check whether the kind is equal; we avoid registering a method with the same name as a property and vice-versa. The current implementation simply ignores such definitions but an error could also be raised to be more explicit to the user.
|
||||||
|
A second check in @fig:define_member:17 avoid redefining a member which is not a method (i.e. a property). If we are redefining a method, an `OverloadedFunction` is then built to combine already defined signatures with the new one, as implemented in @fig:define_member:24 to @fig:define_member:29.
|
||||||
|
|
||||||
|
== `lookup_member`
|
||||||
|
|
||||||
|
`lookup_member` also needs some logic to handle each kind ot types. Indeed, looking up a member on a type (e.g. when processing an attribute reference expression like `foo.bar`), it may be defined in any of the type's supertypes too. Thus the method needs to recurse in the hierarchy if the member cannot be found directly on the requested type.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def lookup_member(self, type: Type, member_name: str) -> Optional[Type]:
|
||||||
|
match type:
|
||||||
|
case BaseType(name=name):
|
||||||
|
if name in self._members:
|
||||||
|
if member_name in self._members[name]:
|
||||||
|
return self._members[name][member_name].type
|
||||||
|
return None
|
||||||
|
|
||||||
|
case DerivedType(name=name, type=base):
|
||||||
|
if name in self._members:
|
||||||
|
if member_name in self._members[name]:
|
||||||
|
return self._members[name][member_name].type
|
||||||
|
return self.lookup_member(base, member_name)
|
||||||
|
|
||||||
|
case AppliedType(name=name, body=body, args=args):
|
||||||
|
generic: Type = self.get_type(name)
|
||||||
|
|
||||||
|
if not isinstance(generic, GenericType):
|
||||||
|
raise ValueError("AppliedType not derived from a GenericType")
|
||||||
|
|
||||||
|
substitutions = {
|
||||||
|
type_var.name: arg for arg, type_var in zip(args, generic.params)
|
||||||
|
}
|
||||||
|
if name in self._members:
|
||||||
|
if member_name in self._members[name]:
|
||||||
|
member_type: Type = self._members[name][member_name].type
|
||||||
|
return substitute_typevars(member_type, substitutions)
|
||||||
|
|
||||||
|
member_type2: Optional[Type] = self.lookup_member(body, member_name)
|
||||||
|
if member_type2 is not None:
|
||||||
|
member_type2 = substitute_typevars(member_type2, substitutions)
|
||||||
|
return member_type2
|
||||||
|
|
||||||
|
case ConstraintType(type=base):
|
||||||
|
return self.lookup_member(base, member_name)
|
||||||
|
|
||||||
|
case TypeVar(bound=bound) if bound is not None:
|
||||||
|
return self.lookup_member(bound, member_name)
|
||||||
|
|
||||||
|
case UnknownType():
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
|
case _:
|
||||||
|
self.logger.debug(f"Can't get member on {type}")
|
||||||
|
return None
|
||||||
|
```
|
||||||
|
) <fig:lookup_member>
|
||||||
|
|
||||||
|
Because we defined our internal type representations with dataclasses, we can easily leverage Python's pattern-matching capabilities to handle each case, as shown in @fig:lookup_member. The method is also quite straightforward though two things can be noted. The first is that looking up a member on `UnknownType` returns `UnknownType`. This basically tells the registry to go along with any references to unknown types, trusting the user that what they are doing is correct. It also allows gracefully propagating errors to avoid early returns that could be caused by raising an exception. The second important part of `lookup_member` is how `AppliedType` is handled. Since this type is derived from a generic type, its members may contain type variables. These are substituted lazily when referenced, i.e. in this method. `substitute_typevars` is a method which performs this substitution recursively given a mapping of type parameters to concrete type arguments. Its implementation is available in the repository in #code-ref(<substitute_typevars>, "midas/checker/types.py").
|
||||||
|
|
||||||
|
== `apply_generic`
|
||||||
|
|
||||||
|
`apply_generic` is a simple method which builds an `AppliedType` from a `GenericType` and a list of type arguments. This method is used when processing expressions such as `Foo[Bar]` and is implemented using the aforementioned `substitute_typevars`. Moreover, it checks potential bounds of type parameters. It is also used for the special `TupleType` which is constructed as `tuple[Type1, Type2, ...]`, as shown in @fig:apply_generic.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def apply_generic(self, type: Type, args: list[Type]) -> Type:
|
||||||
|
match type:
|
||||||
|
case DerivedType(name=name, type=base):
|
||||||
|
return DerivedType(name=name, type=self.apply_generic(base, args))
|
||||||
|
|
||||||
|
case GenericType(name=name, params=type_vars, body=body):
|
||||||
|
n_args: int = len(args)
|
||||||
|
n_type_vars: int = len(type_vars)
|
||||||
|
if n_args < n_type_vars:
|
||||||
|
raise ValueError(
|
||||||
|
f"Missing type arguments, expected {n_type_vars} but only {n_args} provided"
|
||||||
|
)
|
||||||
|
if n_args > n_type_vars:
|
||||||
|
raise ValueError(
|
||||||
|
f"Too many type arguments, expected {n_type_vars} but {n_args} provided"
|
||||||
|
)
|
||||||
|
substitutions: dict[str, Type] = {}
|
||||||
|
for arg, type_var in zip(args, type_vars):
|
||||||
|
if type_var.bound is not None and not self.is_subtype(
|
||||||
|
arg, type_var.bound
|
||||||
|
):
|
||||||
|
raise ValueError(
|
||||||
|
f"Type argument {arg} is not a subtype of {type_var.bound}"
|
||||||
|
)
|
||||||
|
substitutions[type_var.name] = arg
|
||||||
|
return AppliedType(
|
||||||
|
name=name,
|
||||||
|
args=args,
|
||||||
|
body=substitute_typevars(body, substitutions),
|
||||||
|
)
|
||||||
|
|
||||||
|
case BaseType(name="tuple"):
|
||||||
|
return TupleType(items=tuple(args))
|
||||||
|
|
||||||
|
case _:
|
||||||
|
raise ValueError(f"{type} is not a generic type")
|
||||||
|
```,
|
||||||
|
caption: [Implementation of `TypesRegistry.apply_generic`]
|
||||||
|
) <fig:apply_generic>
|
||||||
|
|
||||||
|
The first case handling `DerivedType`, @fig:apply_generic:3 to @fig:apply_generic:4, is a kind of syntactic sugar to define subtypes of generic types without redefining and forwarding type parameters, as demonstrated in @fig:generic-subtype.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```midas
|
||||||
|
type Foo[T] = T
|
||||||
|
type Bar1[T] = Foo[T]
|
||||||
|
// is functionally equivalent to
|
||||||
|
type Bar2 = Foo
|
||||||
|
```,
|
||||||
|
caption: [Generic subtype syntactic sugar]
|
||||||
|
) <fig:generic-subtype>
|
||||||
|
|
||||||
|
== `is_subtype` <sec:is_subtype>
|
||||||
|
|
||||||
|
This method is one of the central parts of our type system. Its role is simple: judge, according to the rules we defined in @sec:typing-subtyping (and some we skipped), whether a given type (`type1`) should be considered a subtype of another (`type2`).
|
||||||
|
|
||||||
|
We will first look at the simplest cases and work our way up to the more complex ones. The complete implementation of `is_subtype` is given in @fig:is_subtype#footnote[The order of cases is slightly different from the real implementation for grouped presentation purposes].
|
||||||
|
|
||||||
|
The trivial case where `type1` is the same as `type2` can be handled with a simple equality check, which is implemented by the `dataclasses` module (#smallcaps[S-Refl] in @tab:typing-subtyping-base). This is the first check in the method, as shown in @fig:is_subtype-equal.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (1, 3),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtype`: equal types]
|
||||||
|
) <fig:is_subtype-equal>
|
||||||
|
|
||||||
|
Even if the types differ, some cases such as top types are still trivially handled. If `type2` is a top type, `type1` is by definition a subtype (#smallcaps[S-Any] and #smallcaps[S-Unknown] in @tab:typing-subtyping-top).
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
ranges: ((5, 10), (71, 71)),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtype`: top types]
|
||||||
|
) <fig:is_subtype-top>
|
||||||
|
|
||||||
|
For builtin types, we define some hardcoded subtype relationships, which are checked if both types are instances of `BaseType`. It may happen one or both of the types are type variables. If that is the case and the type variable has a bound, we may recursively check the subtype relationship against the bound. If not, we cannot make any assumption about the type of the variable and must return `False`. @fig:is_subtype-base-vars shows how both these cases are handled.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (12, 23),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtype`: builtins and type variables]
|
||||||
|
) <fig:is_subtype-base-vars>
|
||||||
|
|
||||||
|
Then we have two similar kinds of types. First, `DerivedType` which encode an explicit subtype relationship, and `ConstraintType` which contain a base type and a constraint. To check these, we simply call `is_subtype` on the base type recursively. The latter corresponds to #smallcaps[S-Constr] in @tab:typing-subtyping-constraint. Note that we only consider `type1`, and not `type2`. The reason we only recurse on the potential subtype is that we are checking whether `type2` is in the hierarchy _above_ `type1`, i.e. a supertype. Because we don't allow multiple inheritance, the type lattice is basically a tree (in the graph theory sense) and a supertype must be in the same branch. This recursion process is an application of #smallcaps[S-Trans] (see @tab:typing-subtyping-base), which should either converge at one of the simpler cases described above or converge at a negative result if the subtype relationship cannot be verified (i.e. not subtyping rule was matched).
|
||||||
|
The implementation shown in @fig:is_subtype-derived-constr is a straightforward application of these rules.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (25, 29),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtpye`: derived and constraint types]
|
||||||
|
) <fig:is_subtype-derived-constr>
|
||||||
|
|
||||||
|
Special care must be taken when comparing two `AppliedType`, that is, instances of generic types.
|
||||||
|
For $"T"_1["A"_11, "A"_12, ...] <: "T"_2["A"_21, "A"_22, ...]$ to be true, $"T"_1$ and $"T"_2$ must first refer to the same generic type. If they are, we must then check that each pair of arguments $("A"_11, "A"_21), ("A"_12, "A"_22), ..$ respect the variance of corresponding type parameters. This means that for a given triplet $("A"_1, "A"_2, "P")$, where $"A"_1$ and $"A"_2$ are paired arguments of `type1` and `type2`, and $"P"$ is the matching type parameter of the generic type:
|
||||||
|
- if $"P"$ is _covariant_, we must check that $"A"_1 <: "A"_2$
|
||||||
|
- if $"P"$ is _contravariant_, we must check that $"A"_2 <: "A"_1$
|
||||||
|
- if $"P"$ is _invariant_, we must check both conditions
|
||||||
|
|
||||||
|
This verification is implemented as in @fig:is_subtype-applied-type.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (31, 50),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtype`: applied types]
|
||||||
|
) <fig:is_subtype-applied-type>
|
||||||
|
|
||||||
|
The second case simply handles other situations where `type1` is an `AppliedType`, recursively checking its body against `type2` similarly to derived types.
|
||||||
|
|
||||||
|
Only three rules remain to check for dataframes, columns and most importantly functions.
|
||||||
|
Columns are simply regarded as invariant generic types. They are not implement using a regular `GenericType`/`AppliedType` because it makes many mechanisms much simpler to implement and reason about, especially regarding attributes and methods, which is worth making them a special construct.
|
||||||
|
|
||||||
|
For dataframes, another approach is taken: structural subtyping. What this means in our type checker is that a dataframe is considered a subtype of another if it has at least the same columns (by name) as the supertype, and they are compatible (i.e. columns of `type1` are subtypes of `type2`'s). This idea has some benefits and drawbacks.
|
||||||
|
Starting with the negative, allowing `type1` to have more columns than `type2` could have a runtime impact. For example, if a function iterates over the columns or applies an operation which is not compatible with one of the extra columns, runtime behavior would not match the type checker's expectations. On the other hand, this allows much more flexibility for users who can pass whole dataframe to function which only need a subset of columns.
|
||||||
|
A potential solution not explored in this work could be to add a dedicated type, construct or syntax for explicit structural subtyping.
|
||||||
|
|
||||||
|
Finally, as shown in @fig:is_subtype-df-cols-funcs, functions are checked separately. Indeed, the algorithm as described in @tab:typing-subtyping-function and @app:function-subtyping is too complex to inline in this method. The implementation is discussed in @sec:is_func_subtype.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (51, 69),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-subtype-code,
|
||||||
|
caption: [`is_subtype`: dataframes, columns and functions]
|
||||||
|
) <fig:is_subtype-df-cols-funcs>
|
||||||
|
|
||||||
|
== `is_func_subtype` <sec:is_func_subtype>
|
||||||
|
|
||||||
|
This section describes the implementation of the function subtyping verification algorithm. Please refer to @app:function-subtyping for more information on the underlying theory and formal rules.
|
||||||
|
|
||||||
|
The complete implementation of `is_func_subtype` is given in @fig:is_func_subtype.
|
||||||
|
|
||||||
|
The first thing `is_func_subtype` must check is whether the return types of the given functions are subtypes of one another (see #smallcaps[S-Func] in @tab:typing-subtyping-function). A simple early return can be added right at the beginning of the method, as shown in @fig:is_func_subtype-returns.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (1, 3),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-func-subtype-code,
|
||||||
|
caption: [`is_func_subtype`: check return types]
|
||||||
|
) <fig:is_func_subtype-returns>
|
||||||
|
|
||||||
|
As we will need to get parameters of each function by kind, name and position, we will first extract the different lists and dictionaries in short variables as outlined in @fig:is_func_subtype-extract-params. These correspond to $(P_1, M_1, K_1)$ and $(P_2, M_2, K_2)$ in the theoretical description.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (5, 22),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-func-subtype-code,
|
||||||
|
caption: [`is_func_subtype`: extracting parameters]
|
||||||
|
) <fig:is_func_subtype-extract-params>
|
||||||
|
|
||||||
|
We first check that `func2`'s positional- and keyword-only parameters are appropriately covered by `func1`. We also record parameter matches to later check subtyping between them and additional parameters of `func1`.
|
||||||
|
@fig:is_func_subtype-pos-kw shows how this is implemented with simple loops.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (24, 52),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-func-subtype-code,
|
||||||
|
caption: [`is_func_subtype`: checking positional- and keyword-only parameters]
|
||||||
|
) <fig:is_func_subtype-pos-kw>
|
||||||
|
|
||||||
|
Verifying proper coverage of mixed arguments is slightly more complicated but a similar method can be used to implement the theoretical algorithm, such as in @fig:is_func_subtype-mixed.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (54, 80),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-func-subtype-code,
|
||||||
|
caption: [`is_func_subtype`: checking mixed parameters]
|
||||||
|
) <fig:is_func_subtype-mixed>
|
||||||
|
|
||||||
|
Finally in @fig:is_func_subtype-extra-subtypes, we check that `func1` does not introduce new required parameters and that matching parameters respect contravariance.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (82, 98),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
is-func-subtype-code,
|
||||||
|
caption: [`is_func_subtype`: check extra parameters and subtypes]
|
||||||
|
) <fig:is_func_subtype-extra-subtypes>
|
||||||
437
report/chapters/04_implementation/04_midas_language.typ
Normal file
@@ -0,0 +1,437 @@
|
|||||||
|
#import "../../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "../../utils.typ": fn-link, code-ref
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "../../appendices/midas_typer_skeleton.typ": midas-typer-members-code
|
||||||
|
#import "@preview/codly:1.3.0": codly
|
||||||
|
|
||||||
|
= Midas Definition Processing <sec:impl-midas>
|
||||||
|
|
||||||
|
For maximum flexibility and control over the whole process, it has been chosen to implement a custom parser for the Midas language from scratch. Moreover, the student already had some experience in implementing a parser and interpreter. Thus, most of the lexer and parser logic implemented in this section has been adapted from the student's previous #fn-link(<pebble-fn>, "https://git.kb28.ch/HEL/pebble")[pebble] project, which is itself based on the wonderful _Crafting Interpreters_ by Robert Nystrom@Nystrom2021.
|
||||||
|
|
||||||
|
Processing a Midas definitions file is done in 3 steps:
|
||||||
|
+ lexing, i.e. turning raw text bytes into tokens
|
||||||
|
+ parsing, i.e. assembling tokens into an #acr("AST") according to syntax rules defined in @sec:theory-syntax-midas (and @app:midas-syntax)
|
||||||
|
+ typing, i.e. processing each statement, registering types and predicates in the registry
|
||||||
|
|
||||||
|
Each of these steps map to a dedicated class, respectively `MidasLexer`, `MidasParser` and `MidasTyper`.
|
||||||
|
|
||||||
|
== Lexing and parsing <sec:midas-lexing-parsing>
|
||||||
|
|
||||||
|
The lexer and parser follow the structure presented by Nystrom@Nystrom2021 and implemented in #fn-link(<pebble-fn>, "https://git.kb28.ch/HEL/pebble")[pebble]@Pebble.
|
||||||
|
|
||||||
|
Concretely, the lexer scans the source code character by character and produces tokens. Several token types are defined to cover all needs in Midas, such as operators, identifiers, keywords and punctuation. The full list of token types is included in @tab:token-types. Whitespace and comments are also converted to tokens but are ignored by the parser. Each token, as represented by the class shown in @fig:token-class, has a token type, a lexeme (i.e. the raw characters making up that token) and a position. That position is crucial for reporting diagnostics as it allows precisely showing the user where an error is in the source file. Tokens representing literals also contain their literal value, like strings, numbers and constants.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class Token:
|
||||||
|
type: TokenType
|
||||||
|
lexeme: str
|
||||||
|
value: Any
|
||||||
|
position: Position
|
||||||
|
|
||||||
|
class Position:
|
||||||
|
file: Optional[str]
|
||||||
|
line: int
|
||||||
|
column: int
|
||||||
|
```,
|
||||||
|
caption: [`Token` and `Position` classes]
|
||||||
|
) <fig:token-class>
|
||||||
|
|
||||||
|
`MidasLexer` has a simple constructor taking in a source code string and optional file path, and a concise `process` method returning a list of tokens, as shown in @fig:lexer-signatures.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class MidasLexer:
|
||||||
|
def __init__(self, source: str, file: Optional[str] = None) -> None: ...
|
||||||
|
def process(self) -> list[Token]: ...
|
||||||
|
```,
|
||||||
|
caption: [Constructor and main method signatures of `MidasLexer`]
|
||||||
|
) <fig:lexer-signatures>
|
||||||
|
|
||||||
|
The parser receives this list of tokens and produces a sequence of statements. All #acr("AST") nodes are defined using frozen dataclasses, which are similar to Java's records. Like Nystrom's implementation, #acr("AST") classes are generated from a template using a script. This script also generates a visitor interface including methods for each node type. The script is available in the repository in #code-ref(<gen-script>, "gen/gen.py").
|
||||||
|
|
||||||
|
The Midas language uses three kinds of nodes:
|
||||||
|
- Statements (`Stmt`): top-level constructs introduced by keywords, have side-effects in the registry
|
||||||
|
- Expressions (`Expr`): composable building blocks for constraint expressions
|
||||||
|
- Types (`Type`): type constructors and references
|
||||||
|
|
||||||
|
The full list of #acr("AST") nodes used for Midas is available in @tab:midas-ast-nodes and their concrete implementation in the repository in #code-ref(<midas-ast>, "midas/ast/midas.py").
|
||||||
|
|
||||||
|
Like tokens, each node also keeps track of its location. The location object contains a starting position and an optional ending position, given by the starting and end token covered by the node. @fig:node-location shows the simple dataclass that is used to hold this information.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class Location:
|
||||||
|
lineno: int
|
||||||
|
col_offset: int
|
||||||
|
end_lineno: Optional[int]
|
||||||
|
end_col_offset: Optional[int]
|
||||||
|
```,
|
||||||
|
caption: [#acr("AST") node location class]
|
||||||
|
) <fig:node-location>
|
||||||
|
|
||||||
|
The complete implementations of `MidasLexer` and `MidasParser` are available in the project's repository in the following files:
|
||||||
|
- `MidasLexer`: #code-ref(<midas-lexer>, "midas/lexer/midas.py")
|
||||||
|
- `Lexer` (base class): #code-ref(<lexer>, "midas/lexer/base.py")
|
||||||
|
- `MidasParser`: #code-ref(<midas-parser>, "midas/parser/midas.py")
|
||||||
|
- `Parser` (base class): #code-ref(<parser>, "midas/parser/base.py")
|
||||||
|
|
||||||
|
Let's take a simple example of some Midas source code to highlight the different steps of the process:
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```midas
|
||||||
|
type Kelvin = float where _ >= 0
|
||||||
|
```,
|
||||||
|
caption: [Midas Example: source code]
|
||||||
|
) <fig:example-midas-src>
|
||||||
|
|
||||||
|
@fig:example-midas-src is first passed through the lexer which outputs a sequence of tokens, as shown in @fig:example-midas-tokens.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
[
|
||||||
|
Token(type=TokenType.TYPE, lexeme='type', value=None,position="L1:1"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:5"),
|
||||||
|
Token(type=TokenType.IDENTIFIER, lexeme='Kelvin',value=None,position="L1:6"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:12"),
|
||||||
|
Token(type=TokenType.EQUAL, lexeme='=', value=None,position="L1:13"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:14"),
|
||||||
|
Token(type=TokenType.IDENTIFIER, lexeme='float', value=None,position="L1:15"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:20"),
|
||||||
|
Token(type=TokenType.WHERE, lexeme='where', value=None,position="L1:21"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:26"),
|
||||||
|
Token(type=TokenType.UNDERSCORE, lexeme='_', value=None,position="L1:27"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:28"),
|
||||||
|
Token(type=TokenType.GREATER_EQUAL,lexeme='>=', value=None,position="L1:29"),
|
||||||
|
Token(type=TokenType.WHITESPACE, lexeme=' ', value=None,position="L1:31"),
|
||||||
|
Token(type=TokenType.NUMBER, lexeme='0', value=0, position="L1:32"),
|
||||||
|
Token(type=TokenType.EOF, lexeme='', value=None,position="L1:33")
|
||||||
|
]
|
||||||
|
```,
|
||||||
|
caption: [Midas Example: tokens]
|
||||||
|
) <fig:example-midas-tokens>
|
||||||
|
|
||||||
|
These tokens are then passed through the parser which builds an #acr("AST") shown in @fig:example-midas-ast. This representation is produced by the `MidasASTPrinter` class which can be used via a dedicated command: ```sh midas parse file.midas```. More information about available commands are given in the dedicated #fn-link(<manual>, "https://git.kb28.ch/HEL/midas/src/branch/main/docs/manual.pdf")[manual].
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```AST
|
||||||
|
TypeStmt
|
||||||
|
├── name: "Kelvin"
|
||||||
|
├── params
|
||||||
|
└── type
|
||||||
|
└── ConstraintType
|
||||||
|
├── type
|
||||||
|
│ └── NamedType
|
||||||
|
│ └── name: "float"
|
||||||
|
└── constraint
|
||||||
|
└── BinaryExpr
|
||||||
|
├── left
|
||||||
|
│ └── WildcardExpr
|
||||||
|
├── operator: >=
|
||||||
|
└── right
|
||||||
|
└── LiteralExpr
|
||||||
|
└── value: 0
|
||||||
|
```,
|
||||||
|
caption: [Midas Example: #acr("AST")]
|
||||||
|
) <fig:example-midas-ast>
|
||||||
|
|
||||||
|
After passing through `MidasParser`, we thus obtain a stable and explicit structure that can be given to `MidasTyper` and interpreted (as far as a definition language can be interpreted).
|
||||||
|
|
||||||
|
== Processing statements <sec:midas-interpretation>
|
||||||
|
|
||||||
|
Each statement is processed in order. In the following sections we will get in more details for each kind of statements, and look at how we can implement their effects on the types registry.
|
||||||
|
|
||||||
|
The complete implementation of `MidasTyper` is available in the project's repository in #code-ref(<midas-typer>, "midas/checker/midas.py").
|
||||||
|
|
||||||
|
The basic members and methods referenced in implementations of this section are listed in @fig:midas-typer-members.
|
||||||
|
|
||||||
|
=== Building types <sec:midas-building-types>
|
||||||
|
|
||||||
|
Before we can register a new type or an alias, we must be able to convert an #acr("AST") representation of a type into our internal type representation structures. For this we leverage the visitor pattern by implementing the visitor class of `Type` #acr("AST") nodes, as generated in @sec:midas-lexing-parsing. We thus make `MidasTyper` extend ```python m.Type.Visitor[Type]```#footnote[To avoid confusion between Midas and Python AST nodes, their namespaces are imported as `m` and `p` respectively. A standalone reference to `Type` relates to the union of internal type representations mentioned in @sec:impl-types.]<fn:types-ref>, indicating that it must handle visiting any `m.Type` node and return a `Type` object.
|
||||||
|
|
||||||
|
As an example, visiting a `m.NamedType` node simply looks up the name in the registry to retrieve the definition for that type. If it cannot be found, an error is reported to the user and `UnknownType` is returned. This is the standard behavior we will implement whenever the type checker cannot make a definite judgement about something. As you may notice in @fig:midas-visit_named_type, the implementation checks `self._current_name` to detect cyclic references. In @fig:midas-visit_named_type:4, `self.get_type` is used instead of directly calling the registry's method to handle type variables, as explained in @sec:midas-type-stmt.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_named_type(self, type: m.NamedType) -> Type:
|
||||||
|
name: str = type.name.lexeme
|
||||||
|
try:
|
||||||
|
return self.get_type(name)
|
||||||
|
except NameError:
|
||||||
|
msg: str = f"Undefined type {name}"
|
||||||
|
if self._current_name == name:
|
||||||
|
msg += ". Recursive types are not supported, use an extend block"
|
||||||
|
self.reporter.error(type.name.get_location(), msg)
|
||||||
|
return UnknownType()
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_named_type`]
|
||||||
|
) <fig:midas-visit_named_type>
|
||||||
|
|
||||||
|
Applied generics are built by looking up the type by its name, processing all arguments to build types and call `TypesRegistry.apply_generic`. The implementation shown in @fig:midas-visit_generic_type also handles the special `Column` type separately, as discussed in @sec:is_subtype.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_generic_type(self, type: m.GenericType) -> Type:
|
||||||
|
match type.type:
|
||||||
|
case m.NamedType(name=Token(lexeme="Column")):
|
||||||
|
if len(type.args) != 1:
|
||||||
|
self.reporter.error(
|
||||||
|
type.location,
|
||||||
|
f"Column requires 1 type argument, {len(type.args)} provided",
|
||||||
|
)
|
||||||
|
return ColumnType(type=UnknownType())
|
||||||
|
return ColumnType(type=type.args[0].accept(self))
|
||||||
|
|
||||||
|
type_: Type = type.type.accept(self)
|
||||||
|
args: list[Type] = [arg.accept(self) for arg in type.args]
|
||||||
|
try:
|
||||||
|
return self.types.apply_generic(type_, args)
|
||||||
|
except Exception as e:
|
||||||
|
self.reporter.error(type.location, f"Cannot apply generic type: {e}")
|
||||||
|
return UnknownType()
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_generic_type`]
|
||||||
|
) <fig:midas-visit_generic_type>
|
||||||
|
|
||||||
|
Constraint types also need some special handling because they include an `m.Expr` node for the constraint expression. This expression is type checked, like Python code will, ensuring that operations are coherent and that the resulting type is a boolean. For more information, please refer to @sec:midas-checking-expr.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_constraint_type(self, type: m.ConstraintType) -> Type:
|
||||||
|
base_type: Type = type.type.accept(self)
|
||||||
|
self._predicate_params["_"] = base_type
|
||||||
|
constraint_type: Type = self.type_of(type.constraint)
|
||||||
|
self._predicate_params = {}
|
||||||
|
if not self.types.is_subtype(constraint_type, self._bool):
|
||||||
|
self.reporter.error(
|
||||||
|
type.constraint.location,
|
||||||
|
f"Constraint must evaluate to a boolean, got {constraint_type}",
|
||||||
|
)
|
||||||
|
|
||||||
|
return ConstraintType(
|
||||||
|
type=base_type,
|
||||||
|
constraint=type.constraint,
|
||||||
|
)
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_constraint_type`]
|
||||||
|
) <fig:midas-visit_constraint_type>
|
||||||
|
|
||||||
|
As you can see in the implementation above, in @fig:midas-visit_constraint_type, we insert the base type as `"_"` in an internal `_predicate_params` dictionary. This will be used later when type checking expression (@sec:midas-checking-expr) to retrieve the "current" type when using a `m.WildcardExpr`.
|
||||||
|
|
||||||
|
Processing functions and dataframe types is naturally implemented by processing their internal types (e.g. parameters, columns) and building the corresponding internal representations.
|
||||||
|
|
||||||
|
=== Type checking expressions <sec:midas-checking-expr>
|
||||||
|
|
||||||
|
The process of type checking constraint expressions (`m.Expr`) is nearly identical to type checking a Python expression. Thus, the implementation is quite similar. This will be covered in the section concerning `PythonTyper`, i.e. @sec:python-check-expr.
|
||||||
|
For now, we only look at `visit_variable_expr` and `visit_wildcard_expr` which call `get_variable` to return the type of the referenced variable. This method is detailed in @fig:midas-typer-members and in essence does the following:
|
||||||
|
+ Look up the variable in the list of predicate parameters (including `_`)
|
||||||
|
+ Look up any predicate with the given name
|
||||||
|
+ Look up in the global environment or preamble for a builtin with the given name (e.g. `float`, `len`, etc.)
|
||||||
|
|
||||||
|
If all three lookups fail, `UnknownType` is returned and an error is reported.
|
||||||
|
|
||||||
|
=== Alias statement <sec:midas-alias-stmt>
|
||||||
|
|
||||||
|
Now that we can build types we must implement a way to register them for future reference.
|
||||||
|
The first and simplest statement is the alias statement (`m.AliasStmt`). Its effect is to bind the given name to the type defined on the right-hand side. The implementation is quite straightforward, as demonstrated in @fig:midas-visit_alias_stmt. Do note that `self._current_name` is set before processing the `m.Type` node, and cleared afterwards, so that cyclic references can be caught. The exception raised by the registry is also caught and reported through an error diagnostic to continue processing remaining statements.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_alias_stmt(self, stmt: m.AliasStmt) -> None:
|
||||||
|
name: str = stmt.name.lexeme
|
||||||
|
self._current_name = name
|
||||||
|
type: Type = stmt.type.accept(self)
|
||||||
|
try:
|
||||||
|
self.types.define_type(name, type)
|
||||||
|
except ValueError:
|
||||||
|
self.reporter.error(stmt.location, f"Type {name} already defined")
|
||||||
|
self._current_name = None
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_alias_stmt`]
|
||||||
|
) <fig:midas-visit_alias_stmt>
|
||||||
|
|
||||||
|
=== Type statement <sec:midas-type-stmt>
|
||||||
|
|
||||||
|
Type statements work similarly to alias statements, though they wrap the defined type in a `DerivedType` or `GenericType` depending on whether there are parameters.
|
||||||
|
Additionally, if parameters are given, they are processed and transformed into `TypeVar` instances, and registered in an internal `_local_variables` dictionary. This internal registry is used by `TypesRegistry.get_type` to resolve references to type variables inside generic types and `extend` statements.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_type_stmt(self, stmt: m.TypeStmt) -> None:
|
||||||
|
name: str = stmt.name.lexeme
|
||||||
|
self._current_name = name
|
||||||
|
params: list[TypeVar] = self._resolve_type_params(stmt.params)
|
||||||
|
|
||||||
|
type: Type = stmt.type.accept(self)
|
||||||
|
if len(params) != 0:
|
||||||
|
type = GenericType(name=name, params=params, body=type)
|
||||||
|
else:
|
||||||
|
type = DerivedType(name=name, type=type)
|
||||||
|
try:
|
||||||
|
self.types.define_type(name, type)
|
||||||
|
except ValueError:
|
||||||
|
self.reporter.error(stmt.location, f"Type {name} already defined")
|
||||||
|
self._local_variables.clear()
|
||||||
|
self._current_name = None
|
||||||
|
def _resolve_type_params(self, params: list[m.TypeParam]):
|
||||||
|
vars: list[TypeVar] = []
|
||||||
|
for param in params:
|
||||||
|
name: str = param.name.lexeme
|
||||||
|
bound: Optional[Type] = None
|
||||||
|
if param.bound is not None:
|
||||||
|
bound = param.bound.accept(self)
|
||||||
|
var = TypeVar(name=name, bound=bound)
|
||||||
|
self._local_variables[name] = var
|
||||||
|
vars.append(var)
|
||||||
|
return vars
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_type_stmt`]
|
||||||
|
) <fig:midas-visit_type_stmt>
|
||||||
|
|
||||||
|
=== Predicate statement <sec:midas-predicate-stmt>
|
||||||
|
|
||||||
|
When processing a predicate definition, we first need to gather all parameters and register them internally in `self._predicate_params`. Then we type check the predicate body, i.e. a constraint expression (`m.Expr`). After this we process all parameter specifications using the same method as for function types. Before defining the predicate, we also check that the body's type is valid, i.e. a subtype of `bool` or a function which returns a valid predicate (in case of a partially applied predicate). Lastly, we build a complete function signature for the predicate, combining curried parameter specifications into functions returning functions, and insert it in the registry. If the predicate definition does not include any parameter specification, we mark it as an alias. This whole procedure is implemented as shown in @fig:midas-visit_predicate_stmt.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_predicate_stmt(self, stmt: m.PredicateStmt) -> None:
|
||||||
|
name: str = stmt.name.lexeme
|
||||||
|
for spec in stmt.params:
|
||||||
|
for param in spec.mixed:
|
||||||
|
assert param.name is not None
|
||||||
|
self._predicate_params[param.name.lexeme] = param.type.accept(self)
|
||||||
|
type: Type = self.type_of(stmt.body)
|
||||||
|
params: list[ParamSpec] = [self._visit_param_spec(spec) for spec in stmt.params]
|
||||||
|
|
||||||
|
if not self._is_valid_predicate(type):
|
||||||
|
self.reporter.error(
|
||||||
|
stmt.body.location,
|
||||||
|
f"Predicate function body must evaluate to a boolean, got {type}",
|
||||||
|
)
|
||||||
|
if len(params) != 0:
|
||||||
|
type = self._bool
|
||||||
|
for spec in reversed(params):
|
||||||
|
type = Function(
|
||||||
|
params=spec,
|
||||||
|
returns=type,
|
||||||
|
)
|
||||||
|
self._predicate_params = {}
|
||||||
|
try:
|
||||||
|
self.types.define_predicate(
|
||||||
|
name,
|
||||||
|
Predicate(
|
||||||
|
type=type,
|
||||||
|
body=stmt.body,
|
||||||
|
alias=len(params) == 0,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
except ValueError:
|
||||||
|
self.reporter.error(stmt.location, f"Predicate {name} already defined")
|
||||||
|
|
||||||
|
def _is_valid_predicate(self, body: Type) -> bool:
|
||||||
|
match body:
|
||||||
|
case Function(returns=returns):
|
||||||
|
return self._is_valid_predicate(returns)
|
||||||
|
case _ if self.types.is_subtype(body, self._bool):
|
||||||
|
return True
|
||||||
|
case _:
|
||||||
|
return False
|
||||||
|
```,
|
||||||
|
caption: [Midas Typer: implementation of `visit_predicate_stmt`]
|
||||||
|
) <fig:midas-visit_predicate_stmt>
|
||||||
|
|
||||||
|
=== Extend statement <sec:midas-extend-stmt>
|
||||||
|
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
=== Example
|
||||||
|
|
||||||
|
Continuing with our example from @fig:example-midas-ast, the type statement would register a new type named `Kelvin` with internal representation given in
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
DerivedType(
|
||||||
|
name='Kelvin',
|
||||||
|
type=ConstraintType(
|
||||||
|
type=BaseType(name='float'),
|
||||||
|
constraint=BinaryExpr(
|
||||||
|
left=WildcardExpr(
|
||||||
|
token=Token(type=TokenType.UNDERSCORE, lexeme='_', value=None)
|
||||||
|
),
|
||||||
|
operator=Token(type=TokenType.GREATER_EQUAL, lexeme='>=', value=None),
|
||||||
|
right=LiteralExpr(value=0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
```,
|
||||||
|
caption: [Midas Example: registered type#footnote[Location and position objects are omitted for readability]]
|
||||||
|
) <fig:example-midas-type>
|
||||||
|
|
||||||
|
== Variance inference <sec:variance-inference>
|
||||||
|
|
||||||
|
The main `resolve` method of `MidasTyper`, as shown in @fig:midas-typer-resolve and @fig:midas-typer-members, first processes all statements, and then summons a `VarianceManager` to infer variance of all types.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (68, 78),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
midas-typer-members-code,
|
||||||
|
caption: [Midas Typer: `resolve` method]
|
||||||
|
) <fig:midas-typer-resolve>
|
||||||
|
|
||||||
|
|
||||||
|
The inference process is actually not very complicated but rigorous. The objective is, for all type variables in all generic types, to walk through all their usages and record their polarity.
|
||||||
|
By polarity, we mean that:
|
||||||
|
- any _producer_ position, such as a function return type, is considered *positive*
|
||||||
|
- any _consumer_ position, such as a function parameter, is considered *negative*
|
||||||
|
|
||||||
|
Algorithmically, when inferring the variance of a variable, we start at the root generic type with a positive polarity. The inference function identifies all possible positions (type body and members) and recurses with the current polarity multiplied by the position's polarity. For example, if the current polarity is positive and a variable is used in a producer position, the resulting polarity used when recursing is $+ times + = +$. If however the variable is used in a consumer position, the polarity becomes $+ times - = -$. A consumer or negative position basically _flips_ the current polarity. When the recursion reaches the bottom usage, i.e. a simple `TypeVar`, the polarity is recorded.
|
||||||
|
This algorithm is implemented by the `VarianceInferrer` class in @fig:midas-variance-inferrer-walk.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
ranges: (
|
||||||
|
(1, 2),
|
||||||
|
(11, 66),
|
||||||
|
),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
raw(block: true, lang: "python", read("../../code/variance_inferrer.py")),
|
||||||
|
caption: [Implementation of `VarianceInferrer.infer` and `VarianceInferrer.walk`]
|
||||||
|
) <fig:midas-variance-inferrer-walk>
|
||||||
|
|
||||||
|
A `Tracker` helper class is responsible for keeping a record of all occurrences of each type variable, with a list of observed polarities.
|
||||||
|
When the generic type has been full walked, the tracker returns the list of type variables with their variance fixed, according to the following rule:
|
||||||
|
- if the variable only appears with positive polarity, it is *covariant*
|
||||||
|
- if the variable only appears with negative polarity, it is *contravariant*
|
||||||
|
- otherwise it is *invariant*
|
||||||
|
Its implementation is given in @fig:midas-variance-tracker.
|
||||||
|
|
||||||
|
It should be noted that we also use a `VarianceManager` to orchestrate how all the types are processed. The naive approach is to simply iterate over each type and infer their variance. However, this breaks down when a type is referenced before it is processed, or even inside itself. To counter such situations, we introduce a queue of types currently being processed. When walking through a type, if we encounter an `AppliedType`, we first check whether it is in the queue. If not, we ask the manager to infer its variance before continuing, as highlighted in @fig:midas-variance-inferrer-walk:42 to @fig:midas-variance-inferrer-walk:47.
|
||||||
|
|
||||||
|
`VarianceManager` is a simple helper class. Its main method, `infer`, is shown in @fig:midas-variance-manager-infer.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (12, 21),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
raw(block: true, lang: "python", read("../../code/variance_manager.py")),
|
||||||
|
caption: [Implementation of `VarianceManager.infer`]
|
||||||
|
) <fig:midas-variance-manager-infer>
|
||||||
|
|
||||||
|
The complete implementation of all classes mentioned in this section is available in the repository in #code-ref(<midas-variance>, "midas/checker/variance.py").
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Midas definition language
|
||||||
|
- Lexer + parser (Crafting Interpreters, Pebble)
|
||||||
|
- reference theory for grammar rules
|
||||||
|
- token location -> necessary later for diagnostics
|
||||||
|
- AST node generation, similar to CI (3 kinds, Stmt/Expr/Type)
|
||||||
|
- Typer
|
||||||
|
- reference theory for typing rules
|
||||||
|
- type structures
|
||||||
|
- types registry
|
||||||
|
*/
|
||||||
503
report/chapters/04_implementation/05_python_checking.typ
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
#import "../../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
#import "@preview/acrostiche:0.7.0": acr
|
||||||
|
#import "../../utils.typ": code-ref, fn-link
|
||||||
|
#import "@preview/codly:1.3.0": codly
|
||||||
|
#import "@preview/lovelace:0.3.1": pseudocode-list
|
||||||
|
#import "../../appendices/python_typer.typ": python-typer-function-code
|
||||||
|
#import "../../appendices/call_dispatcher.typ": call-dispatcher-code
|
||||||
|
|
||||||
|
= Python Type Checking <sec:impl-python>
|
||||||
|
|
||||||
|
We have now built a type definition language and registry, but it is of no use if we cannot type-check our Python code. In a similar fashion to `MidasTyper`, we must now implement a `PythonTyper`. Its role is to take in some Python source code and the types registry, walk through each statement and expression, infer the type of each term and verify the program's soundness. We will need several tools to concretize this process, such as a resolver to keep track of which value each variable references, and an environment to store the inferred types of local variables.
|
||||||
|
|
||||||
|
For the sake of readability and conciseness, many parts of the implementation will be omitted from the following sections, focusing instead on the basic principles and most interesting methods. As always, the full source code is available in the repository, mainly in #code-ref(<checker>, "midas/checker").
|
||||||
|
|
||||||
|
== Parsing Python <sec:python-parsing>
|
||||||
|
|
||||||
|
For consistency and resource sharing, we will mirror a number of structures and methods used for the Midas language. However, we do not need to implement a lexer and parser for Python as it already provides an `ast` module just for this purpose. Nonetheless, we will implement our own #acr("AST") nodes similar to those discussed in @sec:midas-lexing-parsing. This allows having the same structure as the Midas #acr("AST") and explicitly only implement supported Python constructs. Additionally, it will make some node namings and internal structures clearer.
|
||||||
|
|
||||||
|
The same generation script is used to create dataclasses for each node type (see @sec:midas-lexing-parsing).
|
||||||
|
|
||||||
|
For Python, we will also use three kinds of nodes:
|
||||||
|
- Statements (`Stmt`): top-level constructs which can have side-effects in the environment
|
||||||
|
- Expressions (`Expr`): composable building blocks with an inferrable type
|
||||||
|
- Types (`MidasType`): type expressions used in annotations
|
||||||
|
|
||||||
|
The full list of #acr("AST") nodes used for Python is available in @tab:python-ast-nodes and their concrete implementation in the repository in #code-ref(<python-ast>, "midas/ast/python.py").
|
||||||
|
|
||||||
|
We implement a `PythonParser` class which takes in an #acr("AST") module node generated from Python's own `ast` library, and produces an equivalent tree with our nodes, skipping unsupported constructs and simplifying some elements. Because `ast` also uses statement (`ast.stmt`) and expression (`ast.expr`) nodes, we must implement two methods `parse_expr(node: ast.expr) -> Expr` and `parse_stmt(node: ast.stmt) -> None | Stmt | list[Stmt]`. The latter does not simply return a `Stmt` object to allow single Python statements to be split into multiple nodes (e.g. `ast.AnnAssign` is split into a type assignment and a value assignment) or even not produce any node (e.g. `ast.Pass` nodes are skipped). We leverage again Python's `match` statement for pattern matching.
|
||||||
|
|
||||||
|
This section will not go into details about the parser's implementation because it is not particularly interesting and quite repetitive. The source code is still available in the repository in #code-ref(<python-parser>, "midas/parser/python.py").
|
||||||
|
|
||||||
|
== Resolving References <sec:python-resolver>
|
||||||
|
|
||||||
|
Although we will not _evaluate_ Python expressions, we will need to know what bindings refer to. Following chapter 11 of _Crafting Interpreters_@Nystrom2021, we will implement a resolver class. Its goal is to identify binding declarations, keep a record of which scope that declaration appears in and mark each reference with the binding it actually refers to. For example in @fig:example-scoping, the variable `foo` on @fig:example-scoping:4 refers to the inner variable, not the global one.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
foo = 3
|
||||||
|
def bar():
|
||||||
|
foo = ""
|
||||||
|
print(foo)
|
||||||
|
```,
|
||||||
|
caption: [Example of variable scoping in Python]
|
||||||
|
) <fig:example-scoping>
|
||||||
|
|
||||||
|
The implementation is mostly adapted from a previous project, #fn-link(<pebble-fn>, "https://git.kb28.ch/HEL/pebble")[pebble] and based on Nystrom's@Nystrom2021 tutorial-like approach. We will not describe the whole implementation of our `Resolver`, which is available in the repository in #code-ref(<resolver>, "midas/checker/resolver.py"), but only mention two points of interest.
|
||||||
|
|
||||||
|
The first point is that this resolver will also perform a form of definite assignment analysis, which is "a data-flow analysis used by compilers to conservatively ensure that a variable or location is always assigned before it is used"@enwiki:1326872870. This is distinguishing variable declaration and definition, which is not explicit in Python's syntax. It allows producing useful error diagnostics such as in @fig:resolver-visit_variable_expr.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_variable_expr(self, expr: p.VariableExpr) -> None:
|
||||||
|
if self.is_declared(expr.name) and not self.is_defined(expr.name):
|
||||||
|
self.reporter.error(
|
||||||
|
expr.location,
|
||||||
|
f"Variable '{expr.name}' is declared but may not be defined",
|
||||||
|
)
|
||||||
|
self.resolve_local(expr, expr.name)
|
||||||
|
```,
|
||||||
|
caption: [Implementation of `Resolver.visit_variable_expr`]
|
||||||
|
) <fig:resolver-visit_variable_expr>
|
||||||
|
|
||||||
|
Secondly, as stated in #smallcaps[T-IfElse] in @sec:typing-statements, our type checker will not allow leaking variables from inner scopes such as in `if`/`else` statements. Using scopes we can trivially isolate branches and discard inner declarations after such statements. However, we still want to perform assignment analysis. Taking the situation exhibited in @fig:example-if-else-assignment, the resolver can know that `foo` is definitely assigned when reaching @fig:example-if-else-assignment:6 even though no assignment is made outside of the conditional.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
foo: str
|
||||||
|
if ...:
|
||||||
|
foo = "true"
|
||||||
|
else:
|
||||||
|
foo = "false"
|
||||||
|
print(foo)
|
||||||
|
```,
|
||||||
|
caption: [Example of fully assigned variable in `if` statement]
|
||||||
|
) <fig:example-if-else-assignment>
|
||||||
|
|
||||||
|
More generally, if all sub-branches assign to a variable, we can consider it defined in the parent scope. This is implemented as shown in @fig:resolver-visit_if_stmt. Here, `self.end_scope` returns the inner scope containing declarations and assignments made inside each branch. We then check which variable is defined in both branches and forward the definition.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_if_stmt(self, stmt: p.IfStmt) -> None:
|
||||||
|
self.resolve(stmt.test)
|
||||||
|
|
||||||
|
self.begin_scope()
|
||||||
|
self.resolve(*stmt.body)
|
||||||
|
body: dict[str, bool] = self.end_scope()
|
||||||
|
|
||||||
|
self.begin_scope()
|
||||||
|
self.resolve(*stmt.orelse)
|
||||||
|
else_: dict[str, bool] = self.end_scope()
|
||||||
|
|
||||||
|
for name, is_defined in body.items():
|
||||||
|
if is_defined and else_.get(name, False):
|
||||||
|
self.define(name)
|
||||||
|
```,
|
||||||
|
caption: [Implementation of `Resolver.visit_if_stmt`]
|
||||||
|
) <fig:resolver-visit_if_stmt>
|
||||||
|
|
||||||
|
== Environments <sec:python-env>
|
||||||
|
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
== Type Checking Statements <sec:python-check-stmt>
|
||||||
|
|
||||||
|
We now have the tools to start type checking our Python code.
|
||||||
|
The input given to `PythonTyper` is basically a sequence of statements (`p.Stmt`). Using the visitor pattern, we make `PythonTyper` extend ```python p.Stmt.Visitor[None]``` and implement all `visit_*_stmt` methods.
|
||||||
|
|
||||||
|
=== Variable assignment <sec:python-var-assign>
|
||||||
|
|
||||||
|
One of the main mechanics manipulating the environment is variable declaration and assignment.
|
||||||
|
During parsing, a statement such as ```python foo: int = 3```, represented in Python as a single `ast.AnnAssign` node, is split into two #acr("AST") nodes. The first is a type assignment (`p.TypeAssign`), which declares a new variable with the given type. The second is a variable assignment (`p.AssignStmt`). Implementing `visit_type_assign` is straightforward: we first resolve the type annotation expression and then define a new variable in the current environment, as demonstrated in @fig:python-visit_type_assign.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_type_assign(self, stmt: p.TypeAssign) -> None:
|
||||||
|
type: Type = self.resolve_type_expr(stmt.type)
|
||||||
|
self.env.define(stmt.name, type)
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_type_assign`]
|
||||||
|
) <fig:python-visit_type_assign>
|
||||||
|
|
||||||
|
This method basically materializes #smallcaps[T-Annot] from @tab:typing-statements.
|
||||||
|
|
||||||
|
Handling the variable assignment part is a bit more involved, because Python (and our type checker) allows both assigning to multiple targets simultaneously (@fig:python-visit_assign_stmt:3) and assigning to attributes and subscripts (not only variables). This is the reason we use a `match` statement in @fig:python-visit_assign_stmt. This function embodies #smallcaps[T-Assign].
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
ranges: (
|
||||||
|
(1, 9),
|
||||||
|
(19, 30)
|
||||||
|
),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_assign_stmt(self, stmt: p.AssignStmt) -> None:
|
||||||
|
value_type: Type = self.type_of(stmt.value)
|
||||||
|
for target in stmt.targets:
|
||||||
|
self._assign(stmt.location, target, value_type)
|
||||||
|
|
||||||
|
def _assign(self, location: Location, target: p.Expr, value_type: Type):
|
||||||
|
match target:
|
||||||
|
case p.VariableExpr():
|
||||||
|
self._assign_var(location, target, value_type)
|
||||||
|
case p.GetExpr(object=object, name=name):
|
||||||
|
self._assign_attr(location, object, name, value_type)
|
||||||
|
case p.SubscriptExpr(object=p.VariableExpr() as var, index=index):
|
||||||
|
self._assign_sub(location, var, index, value_type)
|
||||||
|
case _:
|
||||||
|
self.reporter.warning(
|
||||||
|
target.location, f"Unsupported assignment to {target}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def _assign_var(self, location: Location, target: p.VariableExpr, value_type: Type):
|
||||||
|
name: str = target.name
|
||||||
|
var_type: Optional[Type] = self.look_up_variable(name, target)
|
||||||
|
|
||||||
|
if var_type is None:
|
||||||
|
self.env.define(name, value_type)
|
||||||
|
else:
|
||||||
|
if not self.is_subtype(value_type, var_type):
|
||||||
|
self.reporter.error(
|
||||||
|
location,
|
||||||
|
f"Cannot assign {value_type} to variable '{name}' of type {var_type}",
|
||||||
|
)
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_assign_stmt` (variable target)]
|
||||||
|
) <fig:python-visit_assign_stmt>
|
||||||
|
|
||||||
|
This is also one of the places our subtyping rules come into play. When assigning to an already defined variable, we check that the value's type is a subtype of the variable's type.#footnote[`PythonTyper.is_subtype` is simply a shortcut for calling `is_subtype` on the types registry], emitting an error diagnostics in case of incompatibility.
|
||||||
|
|
||||||
|
=== Returns <sec:python-returns>
|
||||||
|
|
||||||
|
One special control flow statement is the ```py return``` keyword.
|
||||||
|
Its effect is twofold. First, it cuts a branch short and any further statement in that branch is skipped. Secondly, it provides a possible return type for the parent function. The latter implies that return statements must appear inside functions.
|
||||||
|
|
||||||
|
To easily implement the first effect, we will take advantage of exceptions and raise one inside `visit_return_stmt` (named `ReturnException`). We must then catch this exception at the closest branching point, i.e. the entry point of a block. In our case, in addition to a method type checking a single statement (`process_stmt`), we can implement a method to type check a whole block (`process_block`). Inside the latter we can then wrap calls `process_stmt` in a `try`/`except` statement. If a `ReturnException` is caught while processing a block and some statements remain to be processed, we can emit a warning to the user indicating that they will be skipped at runtime.
|
||||||
|
|
||||||
|
@fig:python-visit_return_stmt shows how the exception is raised while @fig:python-process_block shows how the exception is caught.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_return_stmt(self, stmt: p.ReturnStmt) -> None:
|
||||||
|
type: Type = self.type_of(stmt.value) if stmt.value is not None else UnitType()
|
||||||
|
self.env.return_types.append(type)
|
||||||
|
raise ReturnException(stmt)
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_return_stmt`]
|
||||||
|
) <fig:python-visit_return_stmt>
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def process_block(self, block: list[p.Stmt], env: Environment) -> bool:
|
||||||
|
previous_env: Environment = self.env
|
||||||
|
self.env = env
|
||||||
|
returned: bool = False
|
||||||
|
for i, stmt in enumerate(block):
|
||||||
|
try:
|
||||||
|
self.process_stmt(stmt)
|
||||||
|
except ReturnException:
|
||||||
|
returned = True
|
||||||
|
if i < len(block) - 1:
|
||||||
|
self.reporter.warning(
|
||||||
|
block[i + 1].location, "Unreachable statement"
|
||||||
|
)
|
||||||
|
break
|
||||||
|
self.env = previous_env
|
||||||
|
return returned
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `process_block`]
|
||||||
|
) <fig:python-process_block>
|
||||||
|
|
||||||
|
The second effect of return statements is executed by @fig:python-visit_return_stmt:3 by recording the return value's type in a list of all return types for the current function.
|
||||||
|
|
||||||
|
Similarly to how we handled variable assignments in `if` branches (see @fig:resolver-visit_if_stmt), if all sub-branches return, then the parent scope must also return, thus the implementation in @fig:python-visit_if_stmt.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_if_stmt(self, stmt: p.IfStmt) -> None:
|
||||||
|
test_type: Type = self.type_of(stmt.test)
|
||||||
|
|
||||||
|
if (
|
||||||
|
not self.is_subtype(test_type, self.types.get_type("bool"))
|
||||||
|
and test_type != UnknownType()
|
||||||
|
):
|
||||||
|
self.reporter.error(
|
||||||
|
stmt.test.location, f"If test must be a boolean, got {test_type}"
|
||||||
|
)
|
||||||
|
|
||||||
|
env: Environment = Environment(self.env)
|
||||||
|
body_returned: bool = self.process_block(stmt.body, env)
|
||||||
|
else_returned: bool = self.process_block(stmt.orelse, env)
|
||||||
|
self.env.return_types.extend(env.return_types)
|
||||||
|
if body_returned and else_returned:
|
||||||
|
raise ReturnException(stmt)
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_if_stmt`]
|
||||||
|
) <fig:python-visit_if_stmt>
|
||||||
|
|
||||||
|
=== Function definitions <sec:python-functions>
|
||||||
|
|
||||||
|
Function definitions include many components from all kinds of parameters, default values return type hints and their bodies. One particular property is the optionality of return type hints and the potential multiplicity of return statements inside a function body.
|
||||||
|
What we want for our type checker is to ensure soundness of return types while helping the user by giving them as much freedom as possible by inferring types where not explicitly given.
|
||||||
|
|
||||||
|
In the case of functions, this means that the user should be allowed to omit the return type hint and let the type checker infer it from return statements inside the body. To do so, we will implement the following method:
|
||||||
|
|
||||||
|
#[
|
||||||
|
+ Type check the function's body, collecting return types in the environment
|
||||||
|
+ If no return statement appears in the body, default to `UnitType`
|
||||||
|
+ Try and find a #acr("LUB") of all return types, only in this list of types#footnote[We check whether one of the types in the list is a supertype of all the others ($exists t_r in TT : forall t in TT, t <: t_r$)]
|
||||||
|
+ Unique return supertype?
|
||||||
|
- *Yes*: use it as the inferred return type
|
||||||
|
- *No*: report an error and use `UnknownType` as the inferred return type
|
||||||
|
+ Return type hint ?
|
||||||
|
- *Yes*: check that the inferred return type is a subtype of the annotated one, use the type hint as the function's return type
|
||||||
|
- *No*: use the inferred return type for the function
|
||||||
|
]
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (77, 105),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
python-typer-function-code,
|
||||||
|
caption: [Python Typer: function return type inference]
|
||||||
|
) <fig:python-function-return-type>
|
||||||
|
|
||||||
|
The complete implementation of `PythonTyper.visit_function` is listed in @fig:python-visit_function.
|
||||||
|
|
||||||
|
== Type Checking Expressions <sec:python-check-expr>
|
||||||
|
|
||||||
|
We extend `PythonTyper` to also type check expressions by inheriting ```python p.Expr.Visitor[Type]``` and implementing `visit_*_expr` methods. We thus make all expression visitor methods return a `Type` instance. Indeed, each Python expression is a typeable element composed into other expressions or statements. Some expressions such as literal value are trivial to type check whilst others can be much more complex. The latter are detailed in separate sections.
|
||||||
|
|
||||||
|
=== Literals <sec:python-check-literals>
|
||||||
|
|
||||||
|
Applying typing rules for literals (@tab:typing-literals) is only a matter of matching each value type to the corresponding builtin type representation, as shown in @fig:python-visit_literal_expr.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_literal_expr(self, expr: p.LiteralExpr) -> Type:
|
||||||
|
match expr.value:
|
||||||
|
case bool(): return self.types.get_type("bool")
|
||||||
|
case int(): return self.types.get_type("int")
|
||||||
|
case float(): return self.types.get_type("float")
|
||||||
|
case str(): return self.types.get_type("str")
|
||||||
|
case None: return self.types.get_type("None")
|
||||||
|
case _:
|
||||||
|
self.reporter.warning(expr.location, f"Unknown literal {expr}")
|
||||||
|
return UnknownType()
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_literal_expr`]
|
||||||
|
) <fig:python-visit_literal_expr>
|
||||||
|
|
||||||
|
For literal list expressions, we will reuse `TypesRegistry.reduce_types` method used in @fig:python-function-return-type to try and find a supertype of all item types.
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
def visit_list_expr(self, expr: p.ListExpr) -> Type:
|
||||||
|
list_type: Type = self.types.get_type("list")
|
||||||
|
item_types: list[Type] = [self.type_of(item) for item in expr.items]
|
||||||
|
item_types = self.types.reduce_types(item_types)
|
||||||
|
|
||||||
|
if len(item_types) == 0:
|
||||||
|
return list_type
|
||||||
|
if len(item_types) == 1:
|
||||||
|
item_type: Type = item_types[0]
|
||||||
|
return self.types.apply_generic(list_type, [item_type])
|
||||||
|
self.reporter.warning(
|
||||||
|
expr.location,
|
||||||
|
f"Heterogeneous list items: [{', '.join(map(str, item_types))}]",
|
||||||
|
)
|
||||||
|
return self.types.apply_generic(list_type, [UnknownType()])
|
||||||
|
```,
|
||||||
|
caption: [Python Typer: implementation of `visit_list_expr`]
|
||||||
|
) <fig:python-visit_list_expr>
|
||||||
|
|
||||||
|
Literal dictionaries are handled in the same manner, finding a supertype for keys and for values.
|
||||||
|
|
||||||
|
=== Operations
|
||||||
|
|
||||||
|
In Python, builtin operators are implemented through _dunder-methods_, i.e. methods on the operands. To the eyes of the type checker, an operation is thus equivalent to a function call. We can implement this idea by following these steps:
|
||||||
|
+ Get the dunder-method name corresponding to the operator
|
||||||
|
+ Type-check all operands (two for binary operators, one for unary operators)
|
||||||
|
+ Lookup the method on the left operand#footnote[Reverse operations (e.g. `__radd__`) have not been implemented in Midas yet]
|
||||||
|
+ Type check a call to the method with the given operand(s)
|
||||||
|
|
||||||
|
Step 1 is a simple lookup in a dictionary.\
|
||||||
|
Step 2 is a recursive call to type check the operand expressions.\
|
||||||
|
Step 3 calls `TypesRegistry.lookup_member`.\
|
||||||
|
Step 4 is delegated to a common `call_method` function, also used for call expressions (see @sec:python-check-calls).
|
||||||
|
|
||||||
|
Similarly, subscripts are de-sugared into calls to `__getitem__`.
|
||||||
|
|
||||||
|
== Type Checking Calls <sec:python-check-calls>
|
||||||
|
|
||||||
|
Function calls are not always as straightforward as matching arguments with parameters and getting the return type. For a start, the callee is not necessary a direct `Function`. It may be a `DerivedType` or an `AppliedType`, in which case we must _unfold_ the type hierarchy to get the actual function type. It may also be an `OverloadedFunction`, in which case we must resolve which overload to call. It can also be a `GenericType`, in which case we must try and resolve the actual type arguments based on usage. To keep the type checker tidy, we introduce a separate `CallDispatcher` class, which we can reuse in `MidasTyper` for call expressions too.
|
||||||
|
|
||||||
|
This dispatcher has one main entrypoint: `get_result`. This method, shown in @fig:dispatcher-get_result-signature, takes in a callee type, positional and keyword arguments, and returns a `CallResult` object. This object bundles information about the result type and potential error should the dispatcher fail to resolve the call. The complete methods discusses hereafter are included in @fig:call-dispatcher. Their implementations are available in the repository in #code-ref(<call-dispatcher>, "midas/checker/dispatcher.py").
|
||||||
|
|
||||||
|
#figure(
|
||||||
|
```python
|
||||||
|
class CallResult:
|
||||||
|
error: Optional[CallError] = None
|
||||||
|
result: Type = UnknownType()
|
||||||
|
message: Optional[str] = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_valid(self) -> bool: return self.error is None
|
||||||
|
@property
|
||||||
|
def error_message(self) -> str:
|
||||||
|
if self.message is not None:
|
||||||
|
return self.message
|
||||||
|
if self.error is not None:
|
||||||
|
return str(self.error)
|
||||||
|
return ""
|
||||||
|
|
||||||
|
class CallDispatcher(Generic[E]):
|
||||||
|
def get_result(
|
||||||
|
self,
|
||||||
|
location: Location,
|
||||||
|
callee: Type,
|
||||||
|
positional: list[TypedExpr[E]],
|
||||||
|
keywords: dict[str, TypedExpr[E]],
|
||||||
|
report_errors: bool = True,
|
||||||
|
) -> CallResult: ...
|
||||||
|
```,
|
||||||
|
caption: [Call Dispatcher: signature of `get_result` and `CallResult`]
|
||||||
|
) <fig:dispatcher-get_result-signature>
|
||||||
|
|
||||||
|
`CallDispatcher` is generic in `E`, which represents an expression base class. This allows instantiating it both for `m.Expr` and `p.Expr`.
|
||||||
|
|
||||||
|
The simple case where the callee is a `Function` involves matching call-site arguments with parameters in the function's specification. Then, if a match is possible each pair is check for correct typing. Similar to variable assignment (#smallcaps[T-Assign], see @sec:python-var-assign), an argument must be of the same type as the parameter it matches with (module subsumption). Pragmatically, this corresponds to @fig:dispatcher-match-func.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (14, 24),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Call Dispatcher: call to `Function`]
|
||||||
|
) <fig:dispatcher-match-func>
|
||||||
|
|
||||||
|
Some other simple cases mentioned above can be handled with recursion. Calls to `UnknownType` are also allowed by the type checker, only resulting in an `UnknownType` too. These form the three simple match-cases in @fig:dispatcher-match-simple.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (25, 34),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Call Dispatcher: call to `UnknownType`, `DerivedType` and `AppliedType`]
|
||||||
|
) <fig:dispatcher-match-simple>
|
||||||
|
|
||||||
|
For `OverloadedFunction`, we must first resolve which overload the calls should use. We defer this process to a `_match_overload` method which we will build now.
|
||||||
|
|
||||||
|
=== Matching Overload
|
||||||
|
|
||||||
|
This method receives the list of overloads and all call arguments. Its goal is to:
|
||||||
|
1. identify which overload is compatible
|
||||||
|
2. choose the most specific overload candidate if multiple are plausible
|
||||||
|
|
||||||
|
Regarding the first point, we simply iterate over the overload types and check whether a call with the given arguments is valid. As shown in @fig:overloads-filter-candidates, we first call a method named `_unwrap_function`. This is a simplified form of `get_result`, only to get the actual `Function`. You may find its implementation in @fig:call-dispatcher.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (104, 135),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Matching Overload: filtering candidates]
|
||||||
|
) <fig:overloads-filter-candidates>
|
||||||
|
|
||||||
|
After having filtered the overload candidates, if only one remains we can use it as the actual function. If no overload matches the arguments, we directly return an error, as implemented in @fig:overloads-1-0-candidate.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (143, 154),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Matching Overload: unique or no candidate]
|
||||||
|
) <fig:overloads-1-0-candidate>
|
||||||
|
|
||||||
|
Finally, if there are multiple candidates, we can try one last thing. If one of the candidates is more specific than all others, it is chosen as the actual function signature. By more specific, we mean that for each argument mapping in one overload, corresponding mappings in all other candidates have supertype parameters. Formally, if $CC$ is the list of valid candidates, $C_"spec"$ the potential most specific candidate and $C_"rest"$ another candidate ($a$ are arguments mapped to parameters $p$):
|
||||||
|
$
|
||||||
|
&exists C_"spec" ({(a_i, p_"spec"_i)^(i in 1..n)}) in CC :\
|
||||||
|
&forall C_"rest" ({(a_j, p_"rest"_j)^(j in 1..n)}) in CC,\
|
||||||
|
&forall i in 1..n, space p_"spec"_i <: p_"rest"_i
|
||||||
|
$
|
||||||
|
|
||||||
|
In Python, this translates to @fig:overloads-candidate-subtype.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (156, 168),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Matching Overload: most specific overload]
|
||||||
|
) <fig:overloads-candidate-subtype>
|
||||||
|
|
||||||
|
Ultimately, if this also fails to find a unique, unambiguous candidate, an error is returned, as seen in @fig:overloads-error.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (170, 176),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Matching Overload: default error]
|
||||||
|
) <fig:overloads-error>
|
||||||
|
|
||||||
|
Now that we have a method to choose an overload given some arguments, we can add the case in @fig:dispatcher-match-overloaded to `get_result`.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (35, 44),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Call Dispatcher: call to `OverloadedFunction`]
|
||||||
|
) <fig:dispatcher-match-overloaded>
|
||||||
|
|
||||||
|
=== Generic function
|
||||||
|
|
||||||
|
Generic functions are useful for defining some kind of template behavior while allowing different types to be used. However, when it comes to a call to such a function, things get a bit more complicated. Indeed, type parameters must be mapped to concrete types and unified depending on the actual call-site arguments before getting the return type. Taking the example of a simple generic doubling function ```py def double(value: T) -> T```, the return type depends on the type of the argument. Furthermore, in a more complex case like ```py def add(v1: T, v2: T) -> T```, the type variable `T` must be mapped to the same type for both `v1` and `v2`.
|
||||||
|
|
||||||
|
This process is covered more in depth in chapter 22 of #acr("TaPL")@tapl.
|
||||||
|
|
||||||
|
For this purpose, we can implement a dedicated `Unifier` class whose role is to find appropriate substitutions for type variables in a generic call. Its source code is available in the repository in #code-ref(<unifier>, "midas/checker/unifier.py").
|
||||||
|
|
||||||
|
Using this class, we can complete `get_result` with the last case handling calls to a `GenericType`, as shown in @fig:dispatcher-match-generic.
|
||||||
|
|
||||||
|
#codly(
|
||||||
|
range: (45, 68),
|
||||||
|
smart-skip: true
|
||||||
|
)
|
||||||
|
#figure(
|
||||||
|
call-dispatcher-code,
|
||||||
|
caption: [Call Dispatcher: call to `GenericType`]
|
||||||
|
) <fig:dispatcher-match-generic>
|
||||||
|
|
||||||
|
== Casts and Static Evaluation <sec:python-check-casts>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
== Frames and Columns <sec:python-df-cols>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
== Output <sec:python-output>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Python type checking
|
||||||
|
- Parsing (short paragraph about AST nodes)
|
||||||
|
- Resolver
|
||||||
|
- Cf. CI
|
||||||
|
- Assignment analysis
|
||||||
|
- Typer
|
||||||
|
- Returns / if-else
|
||||||
|
- Environment
|
||||||
|
- Static constraint evaluation
|
||||||
|
*/
|
||||||
20
report/chapters/04_implementation/06_generation.typ
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#import "../../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
|
||||||
|
= Code Generation <sec:impl-generation>
|
||||||
|
|
||||||
|
== Stubs <sec:gen-stubs>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
== Output Code <sec:gen-code>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
== Assertions <sec:gen-assertions>
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
- Code generation
|
||||||
|
- Stubs
|
||||||
|
- Assertions
|
||||||
|
*/
|
||||||
4
report/chapters/05_results_discussion.typ
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
|
||||||
|
= Results and Discussion <chap:results>
|
||||||
4
report/chapters/06_conclusion.typ
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#import "../requirements.typ": isc-hei-bthesis
|
||||||
|
#import isc-hei-bthesis: todo
|
||||||
|
|
||||||
|
= Conclusion <chap:conclusion>
|
||||||
190
report/code/call_dispatcher.py
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
class OverloadCandidate:
|
||||||
|
function: Function
|
||||||
|
mapped: list[MappedArgument]
|
||||||
|
|
||||||
|
class CallDispatcher(Generic[E]):
|
||||||
|
def get_result(
|
||||||
|
self,
|
||||||
|
location: Location,
|
||||||
|
callee: Type,
|
||||||
|
positional: list[TypedExpr[E]],
|
||||||
|
keywords: dict[str, TypedExpr[E]],
|
||||||
|
report_errors: bool = True,
|
||||||
|
) -> CallResult:
|
||||||
|
match callee:
|
||||||
|
case Function() as function:
|
||||||
|
valid: bool
|
||||||
|
mapped: list[MappedArgument[E]]
|
||||||
|
valid, mapped = self.map_call_arguments(
|
||||||
|
function, location, positional, keywords
|
||||||
|
)
|
||||||
|
valid = valid and self._are_arguments_valid(mapped, report_errors)
|
||||||
|
if not valid:
|
||||||
|
return CallResult(error=CallError.INVALID_ARGS)
|
||||||
|
return CallResult(result=function.returns)
|
||||||
|
case UnknownType():
|
||||||
|
return CallResult(result=UnknownType())
|
||||||
|
case DerivedType(type=base):
|
||||||
|
return self.get_result(
|
||||||
|
location, base, positional, keywords, report_errors
|
||||||
|
)
|
||||||
|
case AppliedType(body=body):
|
||||||
|
return self.get_result(
|
||||||
|
location, body, positional, keywords, report_errors
|
||||||
|
)
|
||||||
|
case OverloadedFunction(overloads=overloads):
|
||||||
|
res = self._match_overload(
|
||||||
|
overloads, location, positional, keywords, report_errors
|
||||||
|
)
|
||||||
|
if res[0] is None:
|
||||||
|
return CallResult(
|
||||||
|
error=CallError.NO_MATCHING_OVERLOAD,
|
||||||
|
message=res[1],
|
||||||
|
)
|
||||||
|
return CallResult(result=res[0].returns)
|
||||||
|
case GenericType():
|
||||||
|
unifier: Unifier = Unifier(self.types)
|
||||||
|
pos: list[Type] = [a[1] for a in positional]
|
||||||
|
kw: dict[str, Type] = {k: v[1] for k, v in keywords.items()}
|
||||||
|
unified: Optional[Type] = unifier.unify_call(callee, pos, kw)
|
||||||
|
if unified is None:
|
||||||
|
pos_str: str = ", ".join(str(t) for t in pos)
|
||||||
|
kw_str: str = ", ".join(f"{k}: {v}" for k, v in kw.items())
|
||||||
|
message: str = (
|
||||||
|
f"Could not unify {callee}={callee.body} with pos=[{pos_str}] and kw={{{kw_str}}}"
|
||||||
|
)
|
||||||
|
if report_errors:
|
||||||
|
self.reporter.error(location, message)
|
||||||
|
return CallResult(
|
||||||
|
error=CallError.IMPOSSIBLE_UNIFICATION,
|
||||||
|
message=message,
|
||||||
|
)
|
||||||
|
return self.get_result(
|
||||||
|
location,
|
||||||
|
unified,
|
||||||
|
positional,
|
||||||
|
keywords,
|
||||||
|
report_errors,
|
||||||
|
)
|
||||||
|
case _:
|
||||||
|
message: str = f"{callee} ({callee.__class__.__name__}) is not callable"
|
||||||
|
if report_errors:
|
||||||
|
self.reporter.error(location, message)
|
||||||
|
return CallResult(
|
||||||
|
error=CallError.NOT_CALLABLE,
|
||||||
|
message=message,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _unwrap_function(
|
||||||
|
self,
|
||||||
|
callee: Type,
|
||||||
|
positional: list[TypedExpr[E]],
|
||||||
|
keywords: dict[str, TypedExpr[E]],
|
||||||
|
) -> Union[tuple[Function, None], tuple[None, CallError]]:
|
||||||
|
match callee:
|
||||||
|
case Function():
|
||||||
|
return callee, None
|
||||||
|
case DerivedType(type=base):
|
||||||
|
return self._unwrap_function(base, positional, keywords)
|
||||||
|
case AppliedType(body=body):
|
||||||
|
return self._unwrap_function(body, positional, keywords)
|
||||||
|
case GenericType():
|
||||||
|
unifier: Unifier = Unifier(self.types)
|
||||||
|
unified: Optional[Type] = unifier.unify_call(
|
||||||
|
callee,
|
||||||
|
[a[1] for a in positional],
|
||||||
|
{k: v[1] for k, v in keywords.items()},
|
||||||
|
)
|
||||||
|
if unified is None:
|
||||||
|
return None, CallError.IMPOSSIBLE_UNIFICATION
|
||||||
|
return self._unwrap_function(unified, positional, keywords)
|
||||||
|
case _:
|
||||||
|
return None, CallError.NOT_CALLABLE
|
||||||
|
|
||||||
|
def _match_overload(
|
||||||
|
self,
|
||||||
|
overloads: list[Type],
|
||||||
|
location: Location,
|
||||||
|
positional: list[TypedExpr[E]],
|
||||||
|
keywords: dict[str, TypedExpr[E]],
|
||||||
|
report_errors: bool = True,
|
||||||
|
) -> Union[tuple[Function, None], tuple[None, str]]:
|
||||||
|
candidates: list[OverloadCandidate] = []
|
||||||
|
errors: list[CallError] = []
|
||||||
|
for overload in overloads:
|
||||||
|
function, unwrap_error = self._unwrap_function(
|
||||||
|
overload, positional, keywords
|
||||||
|
)
|
||||||
|
if function is None:
|
||||||
|
errors.append(unwrap_error)
|
||||||
|
continue
|
||||||
|
|
||||||
|
valid, mapped = self.map_call_arguments(
|
||||||
|
function=function,
|
||||||
|
location=location,
|
||||||
|
positional=positional,
|
||||||
|
keywords=keywords,
|
||||||
|
report_errors=False,
|
||||||
|
)
|
||||||
|
if valid and self._are_arguments_valid(mapped, report_errors=False):
|
||||||
|
candidates.append(
|
||||||
|
OverloadCandidate(
|
||||||
|
function=function,
|
||||||
|
mapped=mapped,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
pos_types: str = ", ".join(str(type) for _, type in positional)
|
||||||
|
kw_types: str = ", ".join(
|
||||||
|
f"{name}: {type}" for name, (_, type) in keywords.items()
|
||||||
|
)
|
||||||
|
for_args: str = f"for arguments pos=[{pos_types}] and kw={{{kw_types}}}"
|
||||||
|
|
||||||
|
n_candidates: int = len(candidates)
|
||||||
|
if n_candidates == 1:
|
||||||
|
return candidates[0].function, None
|
||||||
|
if n_candidates == 0:
|
||||||
|
overloads_str: str = ", ".join(map(str, overloads))
|
||||||
|
errors_str: str = ", ".join(errors)
|
||||||
|
message: str = (
|
||||||
|
f"No matching overload in [{overloads_str}] {for_args} (errors: {errors_str})"
|
||||||
|
)
|
||||||
|
if report_errors:
|
||||||
|
self.reporter.error(location, message)
|
||||||
|
return None, message
|
||||||
|
|
||||||
|
for i1, c1 in enumerate(candidates):
|
||||||
|
mapped1: list[MappedArgument[E]] = c1.mapped
|
||||||
|
best_match: bool = True
|
||||||
|
for i2, c2 in enumerate(candidates):
|
||||||
|
if i1 == i2:
|
||||||
|
continue
|
||||||
|
mapped2: list[MappedArgument[E]] = c2.mapped
|
||||||
|
if not self._are_mapped_subtypes(mapped1, mapped2):
|
||||||
|
best_match = False
|
||||||
|
break
|
||||||
|
self.logger.debug(f"{c1.function} is a full overload of {c2.function}")
|
||||||
|
if best_match:
|
||||||
|
return c1.function, None
|
||||||
|
|
||||||
|
candidates_str: str = ", ".join(
|
||||||
|
str(candidate.function) for candidate in candidates
|
||||||
|
)
|
||||||
|
message: str = f"Multiple matching overloads {for_args}: {candidates_str}"
|
||||||
|
if report_errors:
|
||||||
|
self.reporter.error(location, message)
|
||||||
|
return None, message
|
||||||
|
|
||||||
|
def _are_mapped_subtypes(
|
||||||
|
self, mapped1: list[MappedArgument[E]], mapped2: list[MappedArgument[E]]
|
||||||
|
) -> bool:
|
||||||
|
by_expr: dict[E, Type] = {}
|
||||||
|
for arg in mapped1:
|
||||||
|
by_expr[arg.arg_expr] = arg.parameter.type
|
||||||
|
|
||||||
|
for arg in mapped2:
|
||||||
|
type2: Type = arg.parameter.type
|
||||||
|
type1: Type = by_expr[arg.arg_expr]
|
||||||
|
if not self.types.is_subtype(type1, type2):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
98
report/code/is_func_subtype.py
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
def is_func_subtype(self, func1: Function, func2: Function) -> bool:
|
||||||
|
if not self.is_subtype(func1.returns, func2.returns):
|
||||||
|
return False
|
||||||
|
|
||||||
|
pos1: list[Function.Parameter] = func1.params.pos
|
||||||
|
mixed1: list[Function.Parameter] = func1.params.mixed
|
||||||
|
kw1: dict[str, Function.Parameter] = {
|
||||||
|
param.name: param for param in func1.params.kw
|
||||||
|
}
|
||||||
|
|
||||||
|
pos2: list[Function.Parameter] = func2.params.pos
|
||||||
|
mixed2: list[Function.Parameter] = func2.params.mixed
|
||||||
|
kw2: dict[str, Function.Parameter] = {
|
||||||
|
param.name: param for param in func2.params.kw
|
||||||
|
}
|
||||||
|
|
||||||
|
mixed_by_pos: dict[int, Function.Parameter] = {
|
||||||
|
param.pos: param for param in mixed1
|
||||||
|
}
|
||||||
|
mixed_by_name: dict[str, Function.Parameter] = {
|
||||||
|
param.name: param for param in mixed1
|
||||||
|
}
|
||||||
|
|
||||||
|
matches: list[Match] = []
|
||||||
|
|
||||||
|
for param2 in pos2:
|
||||||
|
param1: Function.Parameter
|
||||||
|
|
||||||
|
if param2.pos < len(pos1):
|
||||||
|
param1 = pos1[param2.pos]
|
||||||
|
elif param2.pos in mixed_by_pos:
|
||||||
|
param1 = mixed_by_pos[param2.pos]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not param2.required and param1.required:
|
||||||
|
return False
|
||||||
|
matches.append((param1, param2))
|
||||||
|
|
||||||
|
for name, param2 in kw2.items():
|
||||||
|
param1: Function.Parameter
|
||||||
|
|
||||||
|
if name in kw1:
|
||||||
|
param1 = kw1[name]
|
||||||
|
elif name in mixed_by_name:
|
||||||
|
param1 = mixed_by_name[name]
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if not param2.required and param1.required:
|
||||||
|
return False
|
||||||
|
matches.append((param1, param2))
|
||||||
|
|
||||||
|
for param2 in mixed2:
|
||||||
|
pos_param1: Optional[Function.Parameter] = None
|
||||||
|
kw_param1: Optional[Function.Parameter] = None
|
||||||
|
|
||||||
|
if param2.name in kw1:
|
||||||
|
kw_param1 = kw1[param2.name]
|
||||||
|
elif param2.name in mixed_by_name:
|
||||||
|
kw_param1 = mixed_by_name[param2.name]
|
||||||
|
|
||||||
|
if param2.pos < len(pos1):
|
||||||
|
pos_param1 = pos1[param2.pos]
|
||||||
|
elif param2.pos in mixed_by_pos:
|
||||||
|
pos_param1 = mixed_by_pos[param2.pos]
|
||||||
|
|
||||||
|
if pos_param1 is None or kw_param1 is None:
|
||||||
|
return False
|
||||||
|
|
||||||
|
if pos_param1 == kw_param1:
|
||||||
|
param1: Function.Parameter = pos_param1
|
||||||
|
if not param2.required and param1.required:
|
||||||
|
return False
|
||||||
|
matches.append((param1, param2))
|
||||||
|
else:
|
||||||
|
if pos_param1.required or kw_param1.required:
|
||||||
|
return False
|
||||||
|
matches.append((pos_param1, param2))
|
||||||
|
matches.append((kw_param1, param2))
|
||||||
|
|
||||||
|
def is_matched(param: Function.Parameter) -> bool:
|
||||||
|
for p1, _ in matches:
|
||||||
|
if p1 == param:
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
all_params1: list[Function.Parameter] = pos1 + mixed1 + list(kw1.values())
|
||||||
|
|
||||||
|
for param1 in all_params1:
|
||||||
|
if not is_matched(param1) and param1.required:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for param1, param2 in matches:
|
||||||
|
if not self.is_subtype(param2.type, param1.type):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
71
report/code/is_subtype.py
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
def is_subtype(self, type1: Type, type2: Type) -> bool:
|
||||||
|
if type1 == type2:
|
||||||
|
return True
|
||||||
|
|
||||||
|
match (type1, type2):
|
||||||
|
case (_, TopType()):
|
||||||
|
return True
|
||||||
|
|
||||||
|
case (_, UnknownType()):
|
||||||
|
return True
|
||||||
|
|
||||||
|
case (BaseType(name=name1), BaseType(name=name2)):
|
||||||
|
return self.is_builtin_subtype(name1, name2)
|
||||||
|
|
||||||
|
case (TypeVar(bound=bound), _):
|
||||||
|
if bound is None:
|
||||||
|
return False
|
||||||
|
return self.is_subtype(bound, type2)
|
||||||
|
|
||||||
|
case (_, TypeVar(bound=bound)):
|
||||||
|
if bound is None:
|
||||||
|
return True
|
||||||
|
return self.is_subtype(type1, bound)
|
||||||
|
|
||||||
|
case (DerivedType(type=base1), _):
|
||||||
|
return self.is_subtype(base1, type2)
|
||||||
|
|
||||||
|
case (ConstraintType(type=base1), _):
|
||||||
|
return self.is_subtype(base1, type2)
|
||||||
|
|
||||||
|
case (
|
||||||
|
AppliedType(name=name1, args=args1),
|
||||||
|
AppliedType(name=name2, args=args2),
|
||||||
|
) if (
|
||||||
|
name1 == name2
|
||||||
|
):
|
||||||
|
generic: Type = self.get_type(name1)
|
||||||
|
assert isinstance(generic, GenericType)
|
||||||
|
for param, arg1, arg2 in zip(generic.params, args1, args2):
|
||||||
|
variance: Variance = param.variance
|
||||||
|
if variance in {Variance.INVARIANT, Variance.COVARIANT}:
|
||||||
|
if not self.is_subtype(arg1, arg2):
|
||||||
|
return False
|
||||||
|
if variance in {Variance.INVARIANT, Variance.CONTRAVARIANT}:
|
||||||
|
if not self.is_subtype(arg2, arg1):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
case (AppliedType(body=body), _):
|
||||||
|
return self.is_subtype(body, type2)
|
||||||
|
|
||||||
|
case (DataFrameType(columns=columns1), DataFrameType(columns=columns2)):
|
||||||
|
by_name1: dict[str, DataFrameType.Column] = {
|
||||||
|
col.name: col for col in columns1 if col.name is not None
|
||||||
|
}
|
||||||
|
for col2 in columns2:
|
||||||
|
if col2.name not in by_name1:
|
||||||
|
return False
|
||||||
|
if not self.is_subtype(by_name1[col2.name].type, col2.type):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
case (ColumnType(type=inner1), ColumnType(type=inner2)):
|
||||||
|
if not self.are_equivalent(inner1, inner2):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
case (Function(), Function()):
|
||||||
|
return self.is_func_subtype(type1, type2)
|
||||||
|
|
||||||
|
return False
|
||||||
88
report/code/midas_typer_skeleton.py
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
class MidasTyper(m.Stmt.Visitor[None], m.Expr.Visitor[Type], m.Type.Visitor[Type]):
|
||||||
|
logger: logging.Logger
|
||||||
|
reporter: FileReporter
|
||||||
|
types: TypesRegistry
|
||||||
|
dispatcher: CallDispatcher[m.Expr]
|
||||||
|
|
||||||
|
_local_variables: dict[str, TypeVar]
|
||||||
|
_predicate_params: dict[str, Type]
|
||||||
|
_current_name: Optional[str]
|
||||||
|
|
||||||
|
_preamble: Environment
|
||||||
|
|
||||||
|
def type_of(self, expr: m.Expr) -> Type:
|
||||||
|
"""Compute the type of the given expression
|
||||||
|
|
||||||
|
Args:
|
||||||
|
expr (m.Expr): the expression to type
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Type: the type of the expression
|
||||||
|
"""
|
||||||
|
type: Type = expr.accept(self)
|
||||||
|
return type
|
||||||
|
|
||||||
|
def get_type(self, name: str) -> Type:
|
||||||
|
"""Get a type from its name
|
||||||
|
|
||||||
|
Args:
|
||||||
|
name (str): the name of the type
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
NameError: if the type is not defined
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Type: the type
|
||||||
|
"""
|
||||||
|
if name in self._local_variables:
|
||||||
|
return self._local_variables[name]
|
||||||
|
return self.types.get_type(name)
|
||||||
|
|
||||||
|
def get_variable(self, location: Location, name: str) -> Type:
|
||||||
|
"""Get the type of a variable
|
||||||
|
|
||||||
|
This function will first look into the current predicate's parameters if
|
||||||
|
we are in a predicate definition.
|
||||||
|
The the variable is looked up in the preamble (i.e. global environment)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
location (Location): the location of the variable reference
|
||||||
|
name (str): the name of the variable
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Type: the type of the variable
|
||||||
|
"""
|
||||||
|
if name in self._predicate_params:
|
||||||
|
return self._predicate_params[name]
|
||||||
|
predicate: Optional[Predicate] = self.types.lookup_predicate(name)
|
||||||
|
if predicate is not None:
|
||||||
|
return predicate.type
|
||||||
|
|
||||||
|
global_: Optional[Type] = self._preamble.get(name)
|
||||||
|
if global_ is not None:
|
||||||
|
return global_
|
||||||
|
|
||||||
|
self.reporter.error(location, f"Unknown variable '{name}'")
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
|
def resolve(self, stmts: list[m.Stmt]):
|
||||||
|
"""Process a sequence of statements
|
||||||
|
|
||||||
|
Args:
|
||||||
|
stmts (list[m.Stmt]): the statements
|
||||||
|
"""
|
||||||
|
for stmt in stmts:
|
||||||
|
stmt.accept(self)
|
||||||
|
|
||||||
|
manager: VarianceManager = VarianceManager(self.types)
|
||||||
|
manager.infer_all()
|
||||||
|
|
||||||
|
def assert_bool(self, expr: m.Expr):
|
||||||
|
"""Check that the given expression is a subtype of `bool` or report an error
|
||||||
|
|
||||||
|
Args:
|
||||||
|
expr (m.Expr): the expression to check
|
||||||
|
"""
|
||||||
|
type: Type = self.type_of(expr)
|
||||||
|
if not self.types.is_subtype(type, self._bool):
|
||||||
|
self.reporter.error(expr.location, f"Must be a boolean but is {type}")
|
||||||
119
report/code/python_check_function.py
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
def visit_function(self, stmt: p.Function) -> None:
|
||||||
|
env: Environment = Environment(self.env)
|
||||||
|
pos: list[Function.Parameter] = []
|
||||||
|
mixed: list[Function.Parameter] = []
|
||||||
|
kw: list[Function.Parameter] = []
|
||||||
|
|
||||||
|
def eval_param_type(param: p.Function.Parameter) -> Type:
|
||||||
|
default_type: Optional[Type] = None
|
||||||
|
if param.default is not None:
|
||||||
|
default_type = self.type_of(param.default)
|
||||||
|
|
||||||
|
if param.type is not None:
|
||||||
|
param_type: Type = self.resolve_type_expr(param.type)
|
||||||
|
if default_type is not None:
|
||||||
|
if not self.types.is_subtype(default_type, param_type):
|
||||||
|
self.reporter.error(
|
||||||
|
param.location or stmt.location,
|
||||||
|
f"Cannot use default value of type {default_type} for parameter of type {param_type}",
|
||||||
|
)
|
||||||
|
return param_type
|
||||||
|
|
||||||
|
if default_type is not None:
|
||||||
|
return default_type
|
||||||
|
|
||||||
|
return UnknownType()
|
||||||
|
|
||||||
|
position: int = 0
|
||||||
|
for param in stmt.params.pos:
|
||||||
|
pos.append(
|
||||||
|
Function.Parameter(
|
||||||
|
pos=position,
|
||||||
|
name=param.name,
|
||||||
|
type=eval_param_type(param),
|
||||||
|
required=param.default is None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
position += 1
|
||||||
|
for param in stmt.params.mixed:
|
||||||
|
mixed.append(
|
||||||
|
Function.Parameter(
|
||||||
|
pos=position,
|
||||||
|
name=param.name,
|
||||||
|
type=eval_param_type(param),
|
||||||
|
required=param.default is None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
position += 1
|
||||||
|
for param in stmt.params.kw:
|
||||||
|
kw.append(
|
||||||
|
Function.Parameter(
|
||||||
|
pos=position,
|
||||||
|
name=param.name,
|
||||||
|
type=eval_param_type(param),
|
||||||
|
required=param.default is None,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
position += 1
|
||||||
|
|
||||||
|
param_spec: ParamSpec = ParamSpec(
|
||||||
|
pos=pos,
|
||||||
|
mixed=mixed,
|
||||||
|
kw=kw,
|
||||||
|
)
|
||||||
|
all_params: list[Function.Parameter] = pos + mixed + kw
|
||||||
|
for param in all_params:
|
||||||
|
env.define(param.name, param.type)
|
||||||
|
|
||||||
|
returns_hint: Optional[Type] = None
|
||||||
|
if stmt.returns is not None:
|
||||||
|
returns_hint = self.resolve_type_expr(stmt.returns)
|
||||||
|
inside_function: Function = Function(
|
||||||
|
params=param_spec,
|
||||||
|
returns=returns_hint,
|
||||||
|
)
|
||||||
|
self.env.define(stmt.name, inside_function)
|
||||||
|
|
||||||
|
returned: bool = self.process_block(stmt.body, env)
|
||||||
|
inferred_return: Type = UnknownType()
|
||||||
|
if not returned:
|
||||||
|
env.return_types.append(UnitType())
|
||||||
|
return_types: list[Type] = self.types.reduce_types(env.return_types)
|
||||||
|
if len(return_types) == 1:
|
||||||
|
inferred_return = return_types[0]
|
||||||
|
elif len(return_types) > 1:
|
||||||
|
self.reporter.error(
|
||||||
|
stmt.location,
|
||||||
|
f"Mixed return types: {return_types}",
|
||||||
|
)
|
||||||
|
|
||||||
|
returns: Type = UnknownType()
|
||||||
|
if returns_hint is not None:
|
||||||
|
assert stmt.returns is not None
|
||||||
|
returns = returns_hint
|
||||||
|
if not self.is_subtype(inferred_return, returns):
|
||||||
|
self.reporter.error(
|
||||||
|
stmt.returns.location,
|
||||||
|
f"Return type mismatch, annotated {returns} but returns {inferred_return}",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
returns = inferred_return
|
||||||
|
|
||||||
|
function: Type = Function(
|
||||||
|
params=param_spec,
|
||||||
|
returns=returns,
|
||||||
|
)
|
||||||
|
generic_params: list[TypeVar] = []
|
||||||
|
all_types: list[Type] = [param.type for param in all_params] + [returns]
|
||||||
|
for type in all_types:
|
||||||
|
if isinstance(type, TypeVar):
|
||||||
|
if type not in generic_params:
|
||||||
|
generic_params.append(type)
|
||||||
|
|
||||||
|
if len(generic_params) != 0:
|
||||||
|
function = GenericType(
|
||||||
|
name=stmt.name,
|
||||||
|
params=generic_params,
|
||||||
|
body=function,
|
||||||
|
)
|
||||||
|
self.env.define(stmt.name, function)
|
||||||
66
report/code/variance_inferrer.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
Polarity = Literal[-1, 0, 1]
|
||||||
|
class VarianceInferrer:
|
||||||
|
def __init__(self, manager: VarianceManager) -> None:
|
||||||
|
self.manager: VarianceManager = manager
|
||||||
|
self.tracker: Tracker = Tracker([])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def types(self) -> TypesRegistry:
|
||||||
|
return self.manager.types
|
||||||
|
|
||||||
|
def infer(self, type: GenericType) -> GenericType:
|
||||||
|
self.tracker = Tracker(type.params)
|
||||||
|
self.walk(type.body, 1, type.name)
|
||||||
|
members: dict[str, Member] = self.types._members.get(type.name, {})
|
||||||
|
for name, member in members.items():
|
||||||
|
self.walk(member.type, 1, type.name)
|
||||||
|
return GenericType(
|
||||||
|
name=type.name,
|
||||||
|
params=self.tracker.get_updated_vars(),
|
||||||
|
body=type.body,
|
||||||
|
)
|
||||||
|
def walk(
|
||||||
|
self,
|
||||||
|
type: Type,
|
||||||
|
polarity: Polarity,
|
||||||
|
base_name: str,
|
||||||
|
):
|
||||||
|
match type:
|
||||||
|
case Function(params=spec):
|
||||||
|
all_params: list[Function.Parameter] = spec.pos + spec.mixed + spec.kw
|
||||||
|
for param in all_params:
|
||||||
|
self.walk(
|
||||||
|
param.type,
|
||||||
|
-polarity,
|
||||||
|
base_name,
|
||||||
|
)
|
||||||
|
self.walk(type.returns, polarity, base_name)
|
||||||
|
case OverloadedFunction(overloads=overloads):
|
||||||
|
for overload in overloads:
|
||||||
|
self.walk(overload, polarity, base_name)
|
||||||
|
case AppliedType(name=name, args=args):
|
||||||
|
if self.manager.is_in_queue(name):
|
||||||
|
return
|
||||||
|
|
||||||
|
generic: Type = self.types.get_type(name)
|
||||||
|
assert isinstance(generic, GenericType)
|
||||||
|
generic = self.manager.infer(name, generic)
|
||||||
|
|
||||||
|
params: list[TypeVar] = generic.params
|
||||||
|
polarities: dict[Variance, Polarity] = {
|
||||||
|
Variance.INVARIANT: 0,
|
||||||
|
Variance.COVARIANT: 1,
|
||||||
|
Variance.CONTRAVARIANT: -1,
|
||||||
|
}
|
||||||
|
for arg, param in zip(args, params):
|
||||||
|
param_polarity: Polarity = polarities[param.variance]
|
||||||
|
self.walk(
|
||||||
|
arg,
|
||||||
|
cast(Polarity, polarity * param_polarity),
|
||||||
|
base_name,
|
||||||
|
)
|
||||||
|
case ConstraintType(type=base):
|
||||||
|
self.walk(base, polarity, base_name)
|
||||||
|
case TypeVar():
|
||||||
|
if type in self.tracker:
|
||||||
|
self.tracker.record(type, polarity)
|
||||||
27
report/code/variance_manager.py
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
class VarianceManager:
|
||||||
|
def __init__(self, types: TypesRegistry) -> None:
|
||||||
|
self.types: TypesRegistry = types
|
||||||
|
self._queue: list[str] = []
|
||||||
|
self._inferred: set[str] = set()
|
||||||
|
|
||||||
|
def infer_all(self):
|
||||||
|
for name, type in self.types._types.items():
|
||||||
|
if isinstance(type, GenericType):
|
||||||
|
self.infer(name, type)
|
||||||
|
|
||||||
|
def infer(self, name: str, type: GenericType) -> GenericType:
|
||||||
|
if self.is_inferred(name):
|
||||||
|
return type
|
||||||
|
self._queue.append(name)
|
||||||
|
inferrer: VarianceInferrer = VarianceInferrer(self)
|
||||||
|
inferred: GenericType = inferrer.infer(type)
|
||||||
|
self.types._types[name] = inferred
|
||||||
|
self._queue.pop()
|
||||||
|
self._inferred.add(name)
|
||||||
|
return inferred
|
||||||
|
|
||||||
|
def is_in_queue(self, name: str) -> bool:
|
||||||
|
return name in self._queue
|
||||||
|
|
||||||
|
def is_inferred(self, name: str) -> bool:
|
||||||
|
return name in self._inferred
|
||||||
28
report/code/variance_tracker.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
class Tracker:
|
||||||
|
def __init__(self, vars: list[TypeVar]) -> None:
|
||||||
|
self.vars: list[TypeVar] = vars
|
||||||
|
self.refs: dict[str, set[Polarity]] = {var.name: set() for var in self.vars}
|
||||||
|
|
||||||
|
def record(self, var: TypeVar, polarity: Polarity):
|
||||||
|
self.refs[var.name].add(polarity)
|
||||||
|
|
||||||
|
def get_updated_vars(self) -> list[TypeVar]:
|
||||||
|
return [
|
||||||
|
TypeVar(
|
||||||
|
name=var.name, bound=var.bound, variance=self.get_variance(var.name)
|
||||||
|
)
|
||||||
|
for var in self.vars
|
||||||
|
]
|
||||||
|
|
||||||
|
def get_variance(self, name: str) -> Variance:
|
||||||
|
refs: set[Polarity] = self.refs[name]
|
||||||
|
if refs == {-1}:
|
||||||
|
return Variance.CONTRAVARIANT
|
||||||
|
if refs == {1}:
|
||||||
|
return Variance.COVARIANT
|
||||||
|
return Variance.INVARIANT
|
||||||
|
|
||||||
|
def __contains__(self, item: TypeVar | str):
|
||||||
|
if isinstance(item, TypeVar):
|
||||||
|
return item.name in self
|
||||||
|
return item in self.refs
|
||||||
70
report/figs/architecture.typ
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
#import "@preview/cetz:0.5.2": canvas, draw
|
||||||
|
#import "@preview/fletcher:0.5.8" as fletcher: diagram, node, edge
|
||||||
|
|
||||||
|
#let overview = diagram(
|
||||||
|
node-stroke: .6pt,
|
||||||
|
node-fill: white,
|
||||||
|
node((0, 0), [Midas Typer], name: <midas>),
|
||||||
|
node((1, 0), [Python Typer], name: <python>),
|
||||||
|
node((0.5, 1), [Types Registry], name: <reg>),
|
||||||
|
node((1, 2), [Generator], name: <gen>),
|
||||||
|
edge(<midas>, "d", <reg>, "<|-|>"),
|
||||||
|
edge(<python>, "d", <reg>, "<|-"),
|
||||||
|
edge((<python.south>, 50%, <python.south-east>), "d", <gen>, "-|>"),
|
||||||
|
edge(<reg>, "d", <gen>, "-|>"),
|
||||||
|
node(align(bottom + left)[*Type Checker*], enclose: (<midas>, <python>, <reg>, <gen>), fill: teal.lighten(80%)),
|
||||||
|
|
||||||
|
node((-1, 0), [Midas File], name: <midas-file>),
|
||||||
|
node((-1, 1), [Python File], name: <python-file>),
|
||||||
|
edge(
|
||||||
|
<midas-file.south>,
|
||||||
|
((), "|-", (-1, 0.4)),
|
||||||
|
((), "-|", (<midas.south-west>, 50%, <midas.south>)),
|
||||||
|
((), "|-", <midas.south>),
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%
|
||||||
|
),
|
||||||
|
edge(
|
||||||
|
<python-file.north>,
|
||||||
|
((), "|-", (-1, 0.6)),
|
||||||
|
((), "-|", (<python.south-west>, 50%, <python.south>)),
|
||||||
|
((), "|-", <python.south>),
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%
|
||||||
|
),
|
||||||
|
/*node((-1, .5), [
|
||||||
|
types.midas\
|
||||||
|
source.py
|
||||||
|
], name: <files>),*/
|
||||||
|
/*edge(
|
||||||
|
(<files.north-east>, 80%, <files.east>),
|
||||||
|
((), "-|", (<midas.south-west>, 50%, <midas.south>)),
|
||||||
|
((), "|-", <midas.south>),
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%,
|
||||||
|
),
|
||||||
|
edge(
|
||||||
|
(<files.south-east>, 80%, <files.east>),
|
||||||
|
((), "-|", (<python.south-west>, 50%, <python.south>)),
|
||||||
|
((), "|-", <python.south>),
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%,
|
||||||
|
)*/
|
||||||
|
|
||||||
|
node((3, 1.5), [Stubs], name: <stubs>, width: 5.5em),
|
||||||
|
node((3, 2), [Generated Python], name: <output>, width: 5.5em),
|
||||||
|
edge(
|
||||||
|
<gen>,
|
||||||
|
<output>,
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%
|
||||||
|
),
|
||||||
|
edge(
|
||||||
|
<gen>,
|
||||||
|
"r",
|
||||||
|
((), "|-", <stubs>),
|
||||||
|
<stubs>,
|
||||||
|
"=|>",
|
||||||
|
mark-scale: 150%
|
||||||
|
)
|
||||||
|
)
|
||||||
6
report/figs/signature_placeholder.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="70" viewBox="0 0 220 70">
|
||||||
|
<!-- Placeholder handwritten-style signature for the template example. -->
|
||||||
|
<path d="M8 50 C 30 10, 45 60, 60 35 S 85 5, 100 40 C 110 60, 120 20, 135 38 S 165 55, 185 25 C 195 12, 205 30, 212 22"
|
||||||
|
fill="none" stroke="#1a2b6b" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M70 55 C 110 48, 150 58, 200 50" fill="none" stroke="#1a2b6b" stroke-width="1.2" stroke-linecap="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 514 B |
16
report/fonts/README.md
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# License
|
||||||
|
|
||||||
|
All the fonts downloaded by this script for the layout of the documents are licensed under the [SIL Open Font License](https://openfontlicense.org/) which is included in [here](ofl.md).
|
||||||
|
|
||||||
|
## Installing fonts
|
||||||
|
|
||||||
|
This report template uses several fonts packaged in this repository. To install the fonts in a Linux environment, simply type:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
source install_fonts.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
from within the `fonts` directory and voilà!
|
||||||
|
|
||||||
|
The installer also creates a local fontconfig alias so Linux maps `Source Sans Pro` to `Source Sans 3`.
|
||||||
|
This keeps Typst/web template naming compatibility while avoiding missing-font warnings on Linux.
|
||||||
59
report/fonts/install_fonts.sh
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
VU="${GREEN}✔${NC}"
|
||||||
|
|
||||||
|
# v2: ships both "Source Sans 3" and "Source Sans Pro" (v2 name used by the
|
||||||
|
# Typst web editor) so templates compile without font warnings on both CLI and web.
|
||||||
|
FONTS_URL="https://files.isc-vs.ch/typst/modern-isc-fonts-v2.tar.gz"
|
||||||
|
FONTS_ARCHIVE="modern-isc-fonts-v2.tar.gz"
|
||||||
|
FONTS_DIR="modern-isc-fonts-v2"
|
||||||
|
|
||||||
|
echo -e "Downloading and installing fonts locally..."
|
||||||
|
|
||||||
|
fonts_dir="${HOME}/.local/share/fonts"
|
||||||
|
|
||||||
|
if [ ! -d "${fonts_dir}" ]; then
|
||||||
|
mkdir -p "${fonts_dir}"
|
||||||
|
echo -e "Created fonts directory $fonts_dir $VU"
|
||||||
|
else
|
||||||
|
echo -e "Found fonts directory $fonts_dir $VU"
|
||||||
|
fi
|
||||||
|
|
||||||
|
wget -q --show-progress "${FONTS_URL}"
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo -e "${RED}Error: Failed to download ${FONTS_ARCHIVE}.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "Font bundle downloaded $VU"
|
||||||
|
tar -zxf "${FONTS_ARCHIVE}"
|
||||||
|
|
||||||
|
cp "${FONTS_DIR}"/*.ttf "${fonts_dir}/"
|
||||||
|
cp "${FONTS_DIR}"/*.otf "${fonts_dir}/"
|
||||||
|
echo -e "Fonts installed $VU"
|
||||||
|
|
||||||
|
echo -e "Rebuilding font cache..."
|
||||||
|
fc-cache -f
|
||||||
|
echo -e "Font cache rebuilt $VU"
|
||||||
|
|
||||||
|
rm -f "${FONTS_ARCHIVE}"
|
||||||
|
rm -rf "${FONTS_DIR}/"
|
||||||
|
|
||||||
|
# Verify all required fonts are visible to Typst
|
||||||
|
missing_fonts=()
|
||||||
|
for font in "Source Sans Pro" "Source Sans 3" "Inria Sans" "Fira Code"; do
|
||||||
|
if ! typst fonts | grep -q "^${font}$"; then
|
||||||
|
missing_fonts+=("$font")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ${#missing_fonts[@]} -eq 0 ]; then
|
||||||
|
echo -e "${VU} All required fonts found in Typst. Install successful!"
|
||||||
|
else
|
||||||
|
echo -e "${RED}The following fonts were not found by Typst: ${missing_fonts[*]}${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
113
report/fonts/ofl.md
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
Copyright (c) ``<dates>``, ``<Copyright Holder>`` (``<URL|email>``),
|
||||||
|
with Reserved Font Name ``<Reserved Font Name>``.
|
||||||
|
Copyright (c) ``<dates>``, ``<additional Copyright Holder>`` (``<URL|email>``),
|
||||||
|
with Reserved Font Name ``<additional Reserved Font Name>``.
|
||||||
|
Copyright (c) ``<dates>``, ``<additional Copyright Holder>`` (``<URL|email>``).
|
||||||
|
|
||||||
|
|
||||||
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
<https://openfontlicense.org>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
# SIL OPEN FONT LICENSE
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
##### *Version 1.1 - 26 February 2007*
|
||||||
|
|
||||||
|
|
||||||
|
PREAMBLE
|
||||||
|
----------
|
||||||
|
|
||||||
|
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||||
|
development of collaborative font projects, to support the font creation
|
||||||
|
efforts of academic and linguistic communities, and to provide a free and
|
||||||
|
open framework in which fonts may be shared and improved in partnership
|
||||||
|
with others.
|
||||||
|
|
||||||
|
The OFL allows the licensed fonts to be used, studied, modified and
|
||||||
|
redistributed freely as long as they are not sold by themselves. The
|
||||||
|
fonts, including any derivative works, can be bundled, embedded,
|
||||||
|
redistributed and/or sold with any software provided that any reserved
|
||||||
|
names are not used by derivative works. The fonts and derivatives,
|
||||||
|
however, cannot be released under any other type of license. The
|
||||||
|
requirement for fonts to remain under this license does not apply
|
||||||
|
to any document created using the fonts or their derivatives.
|
||||||
|
|
||||||
|
DEFINITIONS
|
||||||
|
-------------
|
||||||
|
|
||||||
|
***Font Software*** refers to the set of files released by the Copyright
|
||||||
|
Holder(s) under this license and clearly marked as such. This may
|
||||||
|
include source files, build scripts and documentation.
|
||||||
|
|
||||||
|
***Reserved Font Name*** refers to any names specified as such after the
|
||||||
|
copyright statement(s).
|
||||||
|
|
||||||
|
***Original Version*** refers to the collection of Font Software components as
|
||||||
|
distributed by the Copyright Holder(s).
|
||||||
|
|
||||||
|
***Modified Version*** refers to any derivative made by adding to, deleting,
|
||||||
|
or substituting -- in part or in whole -- any of the components of the
|
||||||
|
Original Version, by changing formats or by porting the Font Software to a
|
||||||
|
new environment.
|
||||||
|
|
||||||
|
***Author*** refers to any designer, engineer, programmer, technical
|
||||||
|
writer or other person who contributed to the Font Software.
|
||||||
|
|
||||||
|
PERMISSION & CONDITIONS
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of the ***Font Software***, to use, study, copy, merge, embed, modify,
|
||||||
|
redistribute, and sell modified and unmodified copies of the ***Font
|
||||||
|
Software***, subject to the following conditions:
|
||||||
|
|
||||||
|
1) Neither the ***Font Software*** nor any of its individual components,
|
||||||
|
in ***Original*** or ***Modified Versions***, may be sold by itself.
|
||||||
|
|
||||||
|
2) ***Original*** or ***Modified Versions*** of the ***Font Software*** may be bundled,
|
||||||
|
redistributed and/or sold with any software, provided that each copy
|
||||||
|
contains the above copyright notice and this license. These can be
|
||||||
|
included either as stand-alone text files, human-readable headers or
|
||||||
|
in the appropriate machine-readable metadata fields within text or
|
||||||
|
binary files as long as those fields can be easily viewed by the user.
|
||||||
|
|
||||||
|
3) No ***Modified Version*** of the ***Font Software*** may use the ***Reserved Font
|
||||||
|
Name(s)*** unless explicit written permission is granted by the corresponding
|
||||||
|
Copyright Holder. This restriction only applies to the primary font name as
|
||||||
|
presented to the users.
|
||||||
|
|
||||||
|
4) The name(s) of the Copyright Holder(s) or the ***Author(s)*** of the ***Font
|
||||||
|
Software*** shall not be used to promote, endorse or advertise any
|
||||||
|
***Modified Version***, except to acknowledge the contribution(s) of the
|
||||||
|
Copyright Holder(s) and the ***Author(s)*** or with their explicit written
|
||||||
|
permission.
|
||||||
|
|
||||||
|
5) The ***Font Software***, modified or unmodified, in part or in whole,
|
||||||
|
must be distributed entirely under this license, and must not be
|
||||||
|
distributed under any other license. The requirement for fonts to
|
||||||
|
remain under this license does not apply to any document created
|
||||||
|
using the ***Font Software***.
|
||||||
|
|
||||||
|
TERMINATION
|
||||||
|
-----------
|
||||||
|
|
||||||
|
This license becomes null and void if any of the above conditions are
|
||||||
|
not met.
|
||||||
|
|
||||||
|
|
||||||
|
DISCLAIMER
|
||||||
|
-----------
|
||||||
|
|
||||||
|
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||||
|
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||||
|
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||||
|
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||||
|
OTHER DEALINGS IN THE FONT SOFTWARE.
|
||||||
21
report/pages/abstract.typ
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#import "@preview/isc-hei-bthesis:0.8.1" : *
|
||||||
|
|
||||||
|
#page-title("Abstract")
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
|
|
||||||
|
The abstract of a bachelor thesis should provide a concise summary of the entire work. It typically includes:
|
||||||
|
|
||||||
|
- The context and motivation for the research.
|
||||||
|
- The main objective or research question.
|
||||||
|
- A brief description of the methodology or approach used.
|
||||||
|
- The key results or findings.
|
||||||
|
- The main conclusion or implications of the work.
|
||||||
|
|
||||||
|
The abstract should be self-contained, clear, and usually does not exceed 250–300 words. It allows readers to quickly understand the purpose and outcomes of the thesis without reading the full document.
|
||||||
|
|
||||||
|
The abstract *must* be written in both French and English.
|
||||||
|
|
||||||
|
#lorem(150)
|
||||||
|
|
||||||
|
#abstract-footer("en")
|
||||||
18
report/pages/acknowledgements.typ
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#import "@preview/isc-hei-bthesis:0.8.1" : *
|
||||||
|
|
||||||
|
// Get the proper title for acknowledgements if not written in English
|
||||||
|
#page-title(context i18n(inc.global-language.get(), "acknowledgements"))
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
|
|
||||||
|
The *Acknowledgements* section of a bachelor thesis is where you express gratitude to those who supported you during your research and writing process. It is an *OPTIONAL* section. It may include:
|
||||||
|
|
||||||
|
- Academic supervisors or advisors who provided guidance.
|
||||||
|
- Professors or instructors who offered feedback or resources.
|
||||||
|
- Family and friends for emotional or practical support.
|
||||||
|
- Institutions or organizations that provided funding, facilities, or data.
|
||||||
|
- Anyone else who contributed significantly to your work.
|
||||||
|
|
||||||
|
Keep this section concise and sincere. It is typically placed after the abstract and before the main content of your thesis.
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
21
report/pages/résumé.typ
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#import "@preview/isc-hei-bthesis:0.8.1" : *
|
||||||
|
|
||||||
|
#page-title("Résumé")
|
||||||
|
|
||||||
|
#v(1fr)
|
||||||
|
|
||||||
|
Le résumé d’un mémoire de bachelor doit fournir un aperçu concis de l’ensemble du travail. Il inclut généralement :
|
||||||
|
|
||||||
|
- Le contexte et la motivation de la recherche.
|
||||||
|
- L’objectif principal ou la question de recherche.
|
||||||
|
- Une brève description de la méthodologie ou de l’approche utilisée.
|
||||||
|
- Les principaux résultats ou découvertes.
|
||||||
|
- La conclusion principale ou les implications du travail.
|
||||||
|
|
||||||
|
Le résumé doit être autonome, clair et ne pas dépasser habituellement 250 à 300 mots. Il permet aux lecteurs de comprendre rapidement le but et les résultats du mémoire sans lire l’intégralité du document.
|
||||||
|
|
||||||
|
Le résumé doit être rédigé en français *et* en anglais.
|
||||||
|
|
||||||
|
#lorem(150)
|
||||||
|
|
||||||
|
#abstract-footer("fr")
|
||||||
159
report/plan.typ
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
= General Plan
|
||||||
|
1. *Abstract*: concise summary, includes: research question, methodology, results, conclusions
|
||||||
|
2. *Résumé*: summary in French
|
||||||
|
3. *Acknowledgements*: [Optional] thank those who supported your work
|
||||||
|
4. *Table of Contents*
|
||||||
|
5. *Introduction*: background/context, motivation, objectives, scope and plan
|
||||||
|
6. *State of the Art / Literature Review*: existing research and situates thesis within academic context, if relevant to the work
|
||||||
|
7. *Development and Methodology*: methods, materials, and procedures
|
||||||
|
8. *Results*: findings, often with tables, figures, and analysis
|
||||||
|
9. *Discussion*: Interpret results, discuss implications, and relate findings to research question
|
||||||
|
10. *Conclusion*: Summarize main findings and contributions, suggest future work
|
||||||
|
11. *References / Bibliography*: List all sources cited
|
||||||
|
12. *Appendices*: (Optional) Contains supplementary material such as raw data, code, or additional explanations
|
||||||
|
|
||||||
|
|
||||||
|
= Introduction
|
||||||
|
|
||||||
|
== Background / context
|
||||||
|
- Programming
|
||||||
|
- Deterministic -> ask the machine to do something, does it
|
||||||
|
- Ambiguities come from developer
|
||||||
|
- Python
|
||||||
|
- Duck typing
|
||||||
|
- (Highly) Dynamic
|
||||||
|
- Very popular, especially in data science
|
||||||
|
- Type hints
|
||||||
|
- Type theory introduction
|
||||||
|
- Why does the IDE know that float + str not valid, but not that EUR + USD is also invalid
|
||||||
|
|
||||||
|
== Motivation
|
||||||
|
|
||||||
|
- Python is often too flexible
|
||||||
|
- Can be good but also confusing for beginners
|
||||||
|
- Dangerous for production use
|
||||||
|
- Even type-checkers can be too lenient
|
||||||
|
- Runtime errors are the worst
|
||||||
|
- Hour-long pipeline process crashing in the middle can be costly
|
||||||
|
- Silent errors producing the wrong results are close to impossible to locate
|
||||||
|
- Manually checking things can be tedious and unrewarding
|
||||||
|
|
||||||
|
== Objectives
|
||||||
|
|
||||||
|
Create a type system on top of Python, using type hints, which can help detect non-trivial type errors (i.e. not necessarily structurally wrong, and also on complex types like dataframes), and produces runtime assertions to check type conformity where static checking is not possible.
|
||||||
|
|
||||||
|
This system should ensure soundness where types are annotated or inferred, while leaving the user free to omit some and perform unsafe operations.
|
||||||
|
|
||||||
|
The system must be flexible to allow checking various kinds of constraints (e.g. value domain, geometric shape, distribution, etc.) and allow extension.
|
||||||
|
|
||||||
|
Finally, the system must be simple to use for average Python developers, and be able to seamlessly integrate into existing Python code.
|
||||||
|
|
||||||
|
== Scope and plan
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
= State of the art
|
||||||
|
|
||||||
|
- Python type hints (https://peps.python.org/pep-0484/):
|
||||||
|
- base types
|
||||||
|
- type aliases
|
||||||
|
- structural subtyping with Protocols -> matches duck-typing (https://peps.python.org/pep-0544/)
|
||||||
|
|
||||||
|
- Existing type checkers
|
||||||
|
- MyPy / Pyright
|
||||||
|
|
||||||
|
- Existing libraries
|
||||||
|
- Pandera: runtime only, syntax heavy, but quite complete
|
||||||
|
|
||||||
|
- Similar ideas
|
||||||
|
- Gator system (https://capra.cs.cornell.edu/research/gator/)
|
||||||
|
|
||||||
|
= Development and methodology
|
||||||
|
|
||||||
|
2 sections:
|
||||||
|
1. theory
|
||||||
|
2. implementation
|
||||||
|
|
||||||
|
== Theory
|
||||||
|
|
||||||
|
- Identify requirements
|
||||||
|
- Introduction to TAPL
|
||||||
|
- Grammar and typing rules for Midas, paralleled with TAPL
|
||||||
|
- Omitted rules, simplifications, mechanisms not implemented
|
||||||
|
|
||||||
|
== Implementation
|
||||||
|
|
||||||
|
- Main elements
|
||||||
|
- Definition language
|
||||||
|
- Supported Python syntax (cf. grammar and typing rules)
|
||||||
|
- Parse and type check
|
||||||
|
- Produce user-facing diagnostics
|
||||||
|
- Generate runtime assertions
|
||||||
|
- Architecture overview
|
||||||
|
|
||||||
|
- Midas definition language
|
||||||
|
- Lexer + parser (Crafting Interpreters, Pebble)
|
||||||
|
- reference theory for grammar rules
|
||||||
|
- token location -> necessary later for diagnostics
|
||||||
|
- AST node generation, similar to CI (3 kinds, Stmt/Expr/Type)
|
||||||
|
- Typer
|
||||||
|
- reference theory for typing rules
|
||||||
|
- type structures
|
||||||
|
- types registry
|
||||||
|
|
||||||
|
- Python type checking
|
||||||
|
- Parsing (short paragraph about AST nodes)
|
||||||
|
- Resolver
|
||||||
|
- Cf. CI
|
||||||
|
- Assignment analysis
|
||||||
|
- Typer
|
||||||
|
- Returns / if-else
|
||||||
|
- Environment
|
||||||
|
- Static constraint evaluation
|
||||||
|
|
||||||
|
- Code generation
|
||||||
|
- Stubs
|
||||||
|
- Assertions
|
||||||
|
|
||||||
|
/*
|
||||||
|
Subjects:
|
||||||
|
- Variance inference
|
||||||
|
- Environment
|
||||||
|
- Resolver
|
||||||
|
- Evaluator
|
||||||
|
- CallDispatcher
|
||||||
|
- Registry (`is_subtype`)
|
||||||
|
- MethodRegistry (frames and columns)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
= Results
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
= Discussion
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
= Conclusion
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
== Future work
|
||||||
|
|
||||||
|
=== Python features
|
||||||
|
- support for more common structures and methods (e.g. numpy array, more methods on dataframes)
|
||||||
|
- support for more builtin types: Iterator, Sequence, etc.
|
||||||
|
- argument sinks
|
||||||
|
- while loops, lambdas, classes
|
||||||
|
- multi-file project and imports
|
||||||
|
|
||||||
|
=== Typing features
|
||||||
|
- expected type
|
||||||
|
- literal value propagation
|
||||||
|
|
||||||
|
=== Improvements
|
||||||
|
- more control on assertion type, for example to avoid expensive checks
|
||||||
|
- less redundant check for know part of type (e.g. a dataframe is still a dataframe if only the columns have changed)
|
||||||
|
- better integration with VSCode (e.g. inline diagnostics)
|
||||||
|
- generate checks for members (does the object being cast have the given properties and methods?)
|
||||||
1
report/requirements.typ
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#import "@preview/isc-hei-bthesis:0.8.1"
|
||||||
511
report/themes/3024_Day.tmTheme
Normal file
@@ -0,0 +1,511 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Name: 3024 day
|
||||||
|
Author: Jan T. Sott
|
||||||
|
License: Public Domain Mark 1.0
|
||||||
|
URL: https://github.com/idleberg/3024.tmTheme
|
||||||
|
|
||||||
|
Base16 template for TextMate by Chris Kempson (https://github.com/chriskempson)
|
||||||
|
|
||||||
|
-->
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>Jan T. Sott</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>3024 day</string>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>https://github.com/idleberg/3024.tmTheme</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.3024</string>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>gutterSettings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
<key>divider</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
<key>selectionBackground</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
<key>selectionForeground</key>
|
||||||
|
<string>#a5a2a2</string>
|
||||||
|
</dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#d6d5d4</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#d6d5d4</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#d6d5d4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Text</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comments</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment, punctuation.definition.comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#807d7c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Delimiters</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operators</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keywords</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword, keyword.control</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a16a94</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variables</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Functions</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function, meta.require, support.function.any-method</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a0e4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Classes</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.class, support.class, entity.name.class, entity.name.type.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Methods</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.special-method</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a0e4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a16a94</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b5e4f4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Strings, Inherited Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string, constant.other.symbol, entity.other.inherited-class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a252</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Integers</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Floats</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constants</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tags</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Attributes</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Attribute IDs</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name.id, punctuation.definition.entity</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a0e4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.selector</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a16a94</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Values</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Headings</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.heading punctuation.definition.heading, entity.name.section</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a0e4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Units</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.unit</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bold</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.bold, punctuation.definition.bold</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Italic</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.italic, punctuation.definition.italic</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a16a94</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Code</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.raw.inline</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a252</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link Text</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.other.link</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link Url</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.link</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Lists</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.list</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Quotes</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.quote</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ed0c8c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Separator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.separator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#d6d5d4</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#4a4543</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inserted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#01a252</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Deleted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Changed</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.changed</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a16a94</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Colors</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.other.color</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b5e4f4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Regular Expressions</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b5e4f4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Escape Characters</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character.escape</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b5e4f4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Embedded</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.section.embedded, variable.interpolation</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#cdab53</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.illegal</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#db2d20</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>14875ac8-6a02-493d-9cfa-1701c764e24b</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
948
report/themes/Angular-io-Code.tmTheme
Normal file
@@ -0,0 +1,948 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<!-- Generated by: TmTheme-Editor -->
|
||||||
|
<!-- ============================================ -->
|
||||||
|
<!-- app: http://tmtheme-editor.herokuapp.com -->
|
||||||
|
<!-- code: https://github.com/aziz/tmTheme-Editor -->
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Angular-io-Code</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#F5F6F7</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
<key>gutter</key>
|
||||||
|
<string>#F5F6F7</string>
|
||||||
|
<key>gutterForeground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
<key>guide</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>stackGuide</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>activeGuide</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#FFFFFF00</string>
|
||||||
|
<key>findHighlight</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>findHighlightForeground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>selectionBorder</key>
|
||||||
|
<string>#ffffff</string>
|
||||||
|
<key>bracketsForeground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
<key>bracketsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
<key>bracketContentsForeground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
<key>bracketContentsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
<key>tagsForeground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
<key>tagsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>RegExp Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>regexp-operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>RegExp Character Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp.characterclass punctuation.definition.string.begin, string.regexp.characterclass punctuation.definition.string.end</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Built-in Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>User-defined Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character, constant.other, variable.other.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bitwise</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>bitwise-operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage Type</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Class Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inherited Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.inherited-class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Argument</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library Function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.type, support.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.other.variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid, invalid.illegal, invalid.deprecated</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#f5f5f5</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Find-in-files Filename</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.filename.find-in-files</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Find-in-files Line Numbers</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric.line-number.find-in-files, constant.numeric.line-number.match.find-in-files</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Header</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ffffff</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Header</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header punctuation.definition.from-file.diff</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ffecec</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic </string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Header</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header punctuation.definition.to-file.diff</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#eaffea</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic </string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Range</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.range</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic </string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Deleted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ffecec</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Deleted Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted punctuation.definition.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Inserted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#eaffea</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Diff Inserted Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted punctuation.definition.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitGutter Deleted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted.git_gutter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitGutter Inserted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted.git_gutter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitGutter Modified</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.changed.git_gutter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitGutter Ignored</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.ignored.git_gutter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b3b3b3</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitGutter Untracked</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.untracked.git_gutter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b3b3b3</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Entity Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.css punctuation.definition.entity</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Pseudo Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.css entity.other.attribute-name.pseudo-class, source.css entity.other.attribute-name.pseudo-element</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Property Value</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.css meta.value, source.css support.constant, source.css support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Color</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.css constant.other.color</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Entity Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.scss punctuation.definition.entity</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Pseudo Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.scss entity.other.attribute-name.pseudo-class, source.scss entity.other.attribute-name.pseudo-element</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Color</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.scss support.constant.property-value, source.scss support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.scss variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>this</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.language.this.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.js entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>regular</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Definition</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.js meta.function entity.name.function, source.js entity.name.function meta.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>New Function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type.new.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Prototype</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.language.prototype.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support Function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.js support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Prototype</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.type.object.console.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>JSON Property</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.structure.dictionary.json string.quoted.double.json</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>JSON Value</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.structure.dictionary.json meta.structure.dictionary.value.json string.quoted.double.json</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>regular</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.python keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.python storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage Type</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.python storage.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.python entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.php entity.name.type.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Language Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.language.ruby</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Module Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type.module.ruby</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Class Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type.class.ruby</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inherited Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.inherited-class.ruby</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.heading.markdown, punctuation.definition.italic.markdown, punctuation.definition.bold.markdown, punctuation.definition.string.begin.markdown, punctuation.definition.string.end.markdown, punctuation.definition.metadata.markdown, punctuation.definition.link.markdown, punctuation.definition.blockquote.markdown, punctuation.definition.raw.markdown</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Separator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown meta.separator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Heading</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.heading</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Code Block</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.raw.block</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inline Code</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.raw.inline</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5C707A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link and Image</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown meta.link, text.html.markdown meta.image</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link URL</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.underline.link, text.html.markdown constant.other.reference</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>List</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.list</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bold</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.bold</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Italic</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.italic</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bold Italic</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.bold markup.italic</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> italic bold</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Italic Bold</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text.html.markdown markup.italic markup.bold</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic bold</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Decorators</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>tag.decorator.js entity.name.tag.js, tag.decorator.js punctuation.definition.tag.js, tag.decorator.ts entity.name.tag.ts, tag.decorator.ts punctuation.definition.tag.ts</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#647F11</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Type</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.return.type, meta.return-type, meta.cast, meta.type.annotation, support.type, entity.name.class, entity.name.type, storage.type.cs, storage.type.java</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D43669</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.angular-io-code</string>
|
||||||
|
<key>author</key>
|
||||||
|
<string>NoHomey</string>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>Angular.io inspired theme</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
294
report/themes/Chrome_DevTools.tmTheme
Normal file
@@ -0,0 +1,294 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>Austin Cummings</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Chrome DevTools</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#B3B3B3F4</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#0000001A</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#BAD6FD</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C41A16</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#1C00CF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Identifier</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Exception</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class.exception</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#990000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>italic</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Type name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Arguments</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>italic</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#007400</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>background</key>
|
||||||
|
<string>#E71A114D</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF0000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Trailing whitespace</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.deprecated.trailing-whitespace</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#E71A1100</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Embedded source</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text source</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FAFAFAFC</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag, declaration.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- <dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant, support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict> -->
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>bold</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Section name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.section</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Frame title</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function.frame</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<!-- <string>#881280</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>XML Declaration</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag.preprocessor.xml</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#333333</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<!-- <string>#3366CC</string> -->
|
||||||
|
<string>#994500</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#881280</string>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>bold</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>4FCFA210-B247-11D9-9D00-000D93347A42</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
436
report/themes/EditPlus.tmTheme
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>Kobzarev Mikhail</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>EditPlus</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#B3B3B3F4</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#00808060</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#BAD6FD</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF00FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800080</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Regular expression</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF0080</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0000FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Identifier</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0000FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Exception</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class.exception</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#990000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Type name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Arguments</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#008000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#E71A114D</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF0000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Trailing whitespace</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.deprecated.trailing-whitespace</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#E71A1100</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Embedded source</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text source</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Functions Alt</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function.construct</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0000FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag, declaration.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0033CC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant, support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#3333FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#3333FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation Alt</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF00FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Object Ref</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.function-call</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Var Alt</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Var Alt 2</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.other.php</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#008080</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation Alt</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.section.embedded</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operators Alt</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator.assignment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operators Alt 2</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operators Alt 3</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage.modifier</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#800000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>SQL</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.string.begin</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF00FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#3333FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Section name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.section</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Frame title</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function.frame</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0000FF</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>XML Declaration</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag.preprocessor.xml</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#333333</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF0000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag Name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>SublimeLinter Error</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.mark.error</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#D02000</string>
|
||||||
|
</dict>
|
||||||
|
</dict><dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>SublimeLinter Warning</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.mark.warning</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#DDB700</string>
|
||||||
|
</dict>
|
||||||
|
</dict><dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>SublimeLinter Gutter Mark</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.gutter-mark</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
</dict>
|
||||||
|
</dict></array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>4FCFA210-B247-11D9-9D00-000D93347A42</string>
|
||||||
|
</dict>
|
||||||
|
|
||||||
|
</plist>
|
||||||
374
report/themes/GitHubCleanWhite.tmTheme
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>Ankur Gupta</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitHub Clean White</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#B3B3B3F4</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#0000001A</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#BAD6FD</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C41A16</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0086B3</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#A71D5D</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Built-in constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0086B3</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Exception</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class.exception</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#990000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>italic</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Type name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Arguments</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>italic</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#969896</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>background</key>
|
||||||
|
<string>#E71A114D</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF0000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Trailing whitespace</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.deprecated.trailing-whitespace</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#E71A1100</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Embedded source</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>text source</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FAFAFAFC</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag, declaration.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- <dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant, support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict> -->
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>bold</string> -->
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#AA0D91</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Section name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.section</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Frame title</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function.frame</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<!-- <string>#881280</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>XML Declaration</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.tag.preprocessor.xml</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#333333</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>html attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<!-- <string>#3366CC</string> -->
|
||||||
|
<string>#0A8585</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>html tag punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#121289</string>
|
||||||
|
<!-- <key>fontStyle</key>
|
||||||
|
<string>bold</string> -->
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- Adding stuff for diff. This works in ST3 -->
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>diff header from</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header.from-file</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFDDDD</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>diff header to</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header.to-file</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#DDFFDD</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>diff inserted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted.diff</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#DDFFDD</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>diff deleted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted.diff</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFDDDD</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<!-- BracketHighlighter colors -->
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>BH Color</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>brackethighlighter.default</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#FF992244</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>26786979-843B-4FE2-BCB6-4FCEC6F8FB58</string>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.git_hub_clean_white</string>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>v1.0 Feb 1, 2015
|
||||||
|
Made to look as close to GitHub as possible.</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
643
report/themes/GitHub_Light.tmTheme
Normal file
@@ -0,0 +1,643 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>GitHub</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#c8c8fa</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#fff</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#959da5</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
<key>diffRenamed</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
<key>diffModified</key>
|
||||||
|
<string>#f9c513</string>
|
||||||
|
<key>diffDeleted</key>
|
||||||
|
<string>#d73a49</string>
|
||||||
|
<key>diffAdded</key>
|
||||||
|
<string>#34d058</string>
|
||||||
|
<key>markdown</key>
|
||||||
|
<string>#f7f7f7</string>
|
||||||
|
<key>inactiveSelection</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
<key>selectionBorder</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
<key>findHighlight</key>
|
||||||
|
<string>#e36209</string>
|
||||||
|
<key>findHighlightForeground</key>
|
||||||
|
<string>#fff8f2</string>
|
||||||
|
<key>guide</key>
|
||||||
|
<string>#959da5</string>
|
||||||
|
<key>activeGuide</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
<key>stackGuide</key>
|
||||||
|
<string>#959da5</string>
|
||||||
|
<key>highlight</key>
|
||||||
|
<string>#444d56</string>
|
||||||
|
<key>popupCss</key>
|
||||||
|
<string><![CDATA[html { background-color: #e0e0e0; } h1, h2, h3, h4, h5, h6 { color: #005cc5; margin-top: 0.2em; margin-bottom: 0.2em; } h1 { font-size: 1.5em; } h2 { font-size: 1.4em; } h3 { font-size: 1.3em; } h4 { font-size: 1.2em; } h5 { font-size: 1.1em; } h6 { font-size: 1em; } blockquote { color: #22863a; display: block; font-style: italic; } pre { display: block; } a { color: #032f62; font-style: underline; } body { color: #24292e; background-color: #fff; margin: 1px; font-size: 1em; padding: 0.2em; } .danger { color: #b31d28; } .important, .attention { color: #6f42c1; } .caution, .warning { color: #e36209; } .note { color: #735c0f; }]]></string>
|
||||||
|
<key>highlightForeground</key>
|
||||||
|
<string>#444d56</string>
|
||||||
|
<key>tagsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
<key>bracketContentsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
<key>bracketContentsForeground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
<key>bracketsOptions</key>
|
||||||
|
<string>underline</string>
|
||||||
|
<key>bracketsForeground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
<key>gutterForeground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment, punctuation.definition.comment, string.comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#6a737d</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant, entity.name.constant, variable.other.constant, variable.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constant</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator.symbole, keyword.other.mark</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Clojure workaround; don't highlight these separately from their enclosing scope</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity, entity.name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#6f42c1</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Entity</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#22863a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d73a49</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage, storage.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d73a49</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage.modifier.package, storage.modifier.import, storage.type.java</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string, punctuation.definition.string, string punctuation.section.embedded source</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#032f62</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Ada workaround; don't highlight imports as strings</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.unquoted.import.ada</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict/>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.property-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#e36209</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.broken</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold italic underline</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid - Broken</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.deprecated</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold italic underline</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid – Deprecated</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.illegal</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic underline</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid – Illegal</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>carriage-return</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic underline</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#d73a49</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#fafbfc</string>
|
||||||
|
<key>content</key>
|
||||||
|
<string>^M</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Carriage Return</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid.unimplemented</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold italic underline</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid - Unimplemented</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>message.error</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string source</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String embedded-source</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String variable</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>source.regexp, string.regexp</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#032f62</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String.regexp</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp.character-class, string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#032f62</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String.regexp.«special»</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp constant.character.escape</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#22863a</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String.regexp constant.character.escape</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support.constant</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support.variable</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.module-reference</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>meta module-reference</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.list</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#735c0f</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.list</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.heading, markup.heading entity.name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.heading</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.quote</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#22863a</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.quote</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.italic</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>italic</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.italic</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.bold</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#24292e</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.bold</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.raw</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string/>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.raw</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted, meta.diff.header.from-file, punctuation.definition.deleted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ffeef0</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.deleted</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted, meta.diff.header.to-file, punctuation.definition.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#f0fff4</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#22863a</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup.inserted</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.changed, punctuation.definition.changed</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ffebda</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#e36209</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.ignored, markup.untracked</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#f6f8fa</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.range</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#6f42c1</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.diff.header</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.separator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Meta.separator</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Output</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.output</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#005cc5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>brackethighlighter.tag, brackethighlighter.curly, brackethighlighter.round, brackethighlighter.square, brackethighlighter.angle, brackethighlighter.quote</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#586069</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>brackethighlighter.unmatched</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.mark.error</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#b31d28</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.mark.warning</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#e36209</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>sublimelinter.gutter-mark</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#959da5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.other.reference.link, string.other.link</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#032f62</string>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>underline</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>GitHub Light syntax theme</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>GitHub Light</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.github</string>
|
||||||
|
<key>filename</key>
|
||||||
|
<string>github-light</string>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>A1C4DFA0-7031-11E4-9803-0800200C9A66</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
369
report/themes/ILM.tmTheme
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<!-- Created by: ilm techno solutions -->
|
||||||
|
<!-- ============================================ -->
|
||||||
|
<!-- code: https://github.com/codex8/Colorsublime-Themes -->
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>ILM</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#BFBFBF</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#FFFBD1</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#BDD5FC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#BCC8BA</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5D90CD</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#46A609</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Built-in constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#39946A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>User-defined constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character, constant.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.language, variable.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#2b991b</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword, support.constant.property-value, constant.other.color</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ef5a19</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> Unit</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.unit</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#96DC5F</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#655465</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C52727</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Class name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#27a6b4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inherited class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.inherited-class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#858585</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5319b5</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function argument</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>HTML Entity</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character.entity</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#BF78CC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>JS Support Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#BF78CC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>CSS Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.selector.css, entity.name.tag.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C52727</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>CSS Property</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.property-name.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#484848</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C52727</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library class/type</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.type, support.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.other.variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FF002A</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation/Widgets</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.section.embedded</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#C52727</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation (Tags)</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> CSS</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.other.color.rgb-value.css, support.constant.property-value.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#BF78CC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>47536290-6FC1-4B09-A08F-B219909E1A69</string>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.ILM</string>
|
||||||
|
<key>author</key>
|
||||||
|
<string>sameer</string>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>https://github.com/codex8/Colorsublime-Themes</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
369
report/themes/ILMLight.tmTheme
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<!-- Created by: ilm techno solutions -->
|
||||||
|
<!-- ============================================ -->
|
||||||
|
<!-- code: https://github.com/codex8/Colorsublime-Themes -->
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>ILM 2</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#FFFFFF</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#000000</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#BFBFBF</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#FFFBD1</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#BDD5FC</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comment</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5c8baff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>String</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5dcdbfff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Number</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a69d09ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Built-in constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#459439ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>User-defined constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character, constant.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.language, variable.other</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#7f991bff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword, support.constant.property-value, constant.other.color</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ef1967ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> Unit</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.unit</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#dccf5fff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#5a5465ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c52790ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Class name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#27b464ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inherited class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.inherited-class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#858585ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string> bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#1947b5ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function argument</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag name</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>HTML Entity</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character.entity</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#8778ccff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>JS Support Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#8778ccff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tag attribute</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>CSS Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.selector.css, entity.name.tag.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c52790ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>CSS Property</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.property-name.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#484848ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library function</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c52790ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library class/type</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.type, support.class</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Library variable</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.other.variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Invalid</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#ff00d4ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation/Widgets</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.section.embedded</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c52790ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation (Tags)</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#606060ff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keyword -> CSS</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.other.color.rgb-value.css, support.constant.property-value.css</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#8778ccff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>47536290-6FC1-4B09-A08F-B219909E1A69</string>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.ILM light</string>
|
||||||
|
<key>author</key>
|
||||||
|
<string>sameer</string>
|
||||||
|
<key>comment</key>
|
||||||
|
<string>sam0hack</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
619
report/themes/bluloco-light.tmTheme
Normal file
@@ -0,0 +1,619 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<!-- Generated by: TmTheme-Editor -->
|
||||||
|
<!-- ============================================ -->
|
||||||
|
<!-- app: http://tmtheme-editor.herokuapp.com -->
|
||||||
|
<!-- code: https://github.com/aziz/tmTheme-Editor -->
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>author</key>
|
||||||
|
<string>Umut Topuzoğlu</string>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bluloco Light</string>
|
||||||
|
<key>semanticClass</key>
|
||||||
|
<string>theme.light.bluloco_light</string>
|
||||||
|
<key>colorSpaceName</key>
|
||||||
|
<string>sRGB</string>
|
||||||
|
<key>gutterSettings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#353b45</string>
|
||||||
|
<key>divider</key>
|
||||||
|
<string>#353b45</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a0a1a7</string>
|
||||||
|
<key>selectionBackground</key>
|
||||||
|
<string>#d2ecff</string>
|
||||||
|
<key>selectionForeground</key>
|
||||||
|
<string>#565c64</string>
|
||||||
|
</dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#f9f9f9</string>
|
||||||
|
<key>caret</key>
|
||||||
|
<string>#f31459</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
<key>invisibles</key>
|
||||||
|
<string>#a0a1a7</string>
|
||||||
|
<key>lineHighlight</key>
|
||||||
|
<string>#f1f1f1</string>
|
||||||
|
<key>selection</key>
|
||||||
|
<string>#d2ecff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Text</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Comments</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>comment, punctuation.definition.comment, string.comment</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a0a1a7</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Punctuation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.variable, punctuation.definition.parameters, punctuation.definition.array, punctuation.definition.function, meta.brace, punctuation.terminator.statement, meta.delimiter.object.comma, punctuation.definition.entity, punctuation.definition,punctuation.definition.string.begin.markdown, punctuation.definition.string.end.markdown, punctuation.separator.key-value, punctuation.separator.dictionary, punctuation.terminator, meta.delimiter.comma, punctuation.separator.comma,punctuation.accessor,punctuation.separator.array,punctuation.section.property-list.begin.bracket.curly, punctuation.section.property-list.end.bracket.curly, punctuation.separator.statement</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#7a82da</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Delimiters</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Operators</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#7a82da</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Keywords</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword, variable.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variables</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Functions</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.function, meta.require, support.function.any-method, meta.function-call</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#23974a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Classes</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.class, entity.name.class, entity.name.type.class,meta.class.instance,meta.class.inheritance, entity.other.inherited-class, entity.name.type</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d52753</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Methods</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.special-method</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#23974a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Storage</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>storage,constant.language</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.function</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#23974a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Strings, Inherited Class</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string, constant.other.symbol, punctuation.definition.string,support.constant.property-value, string.quoted.double.shell</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5a332</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Integers</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.numeric</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ce33c0</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Floats</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ce33c0</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Boolean</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Constants</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#823ff1</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Tags</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.name.tag, punctuation.definition.tag</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#275fe4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Attribute IDs</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#df631c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Selector</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.selector</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#7a82da</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Values</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>none</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ce33c0</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Headings</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.heading, punctuation.definition.heading, entity.name.section, markup.heading.setext</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string></string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5a332</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Units</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.other.unit</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5a332</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Bold</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.bold, punctuation.definition.bold</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>fontStyle</key>
|
||||||
|
<string>bold</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d52753</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Italic</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.italic, punctuation.definition.italic</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#df631c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Code</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.raw.inline</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5a332</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link Text</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.other.link</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#275fe4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Link Url</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.link</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Lists</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>beginning.punctuation.definition.list</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a05a48</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Quotes</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.quote</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#823ff1</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Separator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.separator</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#d2ecff</string>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Inserted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inserted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#23974a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Deleted</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.deleted</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d52753</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Changed</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.changed</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Colors</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.other.color, support.constant.color</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#c5a332</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Regular Expressions</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.regexp</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a05a48</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Escape Characters</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>constant.character.escape</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#df631c</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Embedded</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.section.embedded, variable.interpolation</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Illegal</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>invalid</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#ff0000</string>
|
||||||
|
<key>background</key>
|
||||||
|
<string>#d2ecff</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Support Constant</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.constant</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a05a48</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>New Operator</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>keyword.operator.new</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Css ID</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>entity.other.attribute-name.id</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d52753</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Function Parameters</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.function-call.arguments</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#383a42</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Object Properties</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>meta.object-literal.key, meta.object.member, support.type.property-name, entity.name.tag.yaml, constant.other.key,constant.other.object.key.js,string.unquoted.label.js</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a05a48</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup Code</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.inline.raw, markup.fenced_code.block, markup.raw.block</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#a05a48</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Markup Link Image</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>markup.underline.link.image</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#23974a</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Variable Parameter</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>variable.parameter</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict></dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>Type Primitive</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>support.type.primitive</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#0098dd</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>BASH: Command Substitution</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.interpolated.dollar.shell</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#d52753</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>BASH: Math Operation</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>string.other.math.shell</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#275fe4</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>name</key>
|
||||||
|
<string>BASH: Substitution</string>
|
||||||
|
<key>scope</key>
|
||||||
|
<string>punctuation.definition.string.begin.shell, punctuation.definition.string.end.shell</string>
|
||||||
|
<key>settings</key>
|
||||||
|
<dict>
|
||||||
|
<key>foreground</key>
|
||||||
|
<string>#7a82da</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>uuid</key>
|
||||||
|
<string>uuid</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
43
report/utils.typ
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#let include-offset(what) = context {
|
||||||
|
let current-offset = heading.offset
|
||||||
|
set heading(offset: current-offset + 1)
|
||||||
|
include what
|
||||||
|
}
|
||||||
|
|
||||||
|
#let quote-block(width: 10cm, who, what) = {
|
||||||
|
set par(justify: false)
|
||||||
|
align(
|
||||||
|
right,
|
||||||
|
block(
|
||||||
|
width: width,
|
||||||
|
inset: (bottom: 1cm),
|
||||||
|
quote(
|
||||||
|
attribution: who,
|
||||||
|
block: true,
|
||||||
|
what
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#let _fn-links = state("_fn-links", ())
|
||||||
|
|
||||||
|
#let fn-link(lbl, url, body) = context {
|
||||||
|
link(url, body)
|
||||||
|
let links = _fn-links.get()
|
||||||
|
let name = str(lbl)
|
||||||
|
if name in links {
|
||||||
|
footnote(lbl)
|
||||||
|
} else {
|
||||||
|
[#footnote(link(url)) #lbl]
|
||||||
|
_fn-links.update(links => links + (name,))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#let code-ref(lbl, path, body: auto) = {
|
||||||
|
if body == auto {
|
||||||
|
body = path
|
||||||
|
}
|
||||||
|
let url = "https://git.kb28.ch/HEL/midas/src/branch/main/" + path
|
||||||
|
fn-link(lbl, url, body)
|
||||||
|
}
|
||||||
58
summary/exec_summary.typ
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// ___ ____ ____ _ _ _____ ___
|
||||||
|
// |_ _/ ___| / ___| | | | | ____|_ _| Informatique et
|
||||||
|
// | |\___ \| | ___ | |_| | _| | | systèmes de communication
|
||||||
|
// | | ___) | |__|___| | _ | |___ | | HEI Sion · HES-SO Valais / mui 24-26
|
||||||
|
// |___|____/ \____| |_| |_|_____|___|
|
||||||
|
//
|
||||||
|
// 52 65 61 64 69 6e 67 20 68 65 78 20 66 6f 72 20 66 75 6e 3f 20 49 53 43 20 66 6f 72 65 76 65 72
|
||||||
|
//
|
||||||
|
// Adapted from the BFH year book idea at https://www.bfh.ch/dam/jcr:e512ae31-a3ed-4b65-b589-870383d794b0/abschlussarbeiten-bsc-informatik.pdf
|
||||||
|
|
||||||
|
#import "@preview/isc-hei-exec-summary:0.8.1" : *
|
||||||
|
#import "../meta.typ"
|
||||||
|
|
||||||
|
// Must be <= 365 characters long.
|
||||||
|
#let summary = "Midas is cool!" // TODO
|
||||||
|
|
||||||
|
#assert(
|
||||||
|
summary.len() <= 365,
|
||||||
|
message: "Summary too long: len() > 365"
|
||||||
|
)
|
||||||
|
|
||||||
|
#let content = [
|
||||||
|
#todo[]
|
||||||
|
|
||||||
|
#lorem-pars(500)
|
||||||
|
#colbreak()
|
||||||
|
#lorem-pars(500)
|
||||||
|
]
|
||||||
|
|
||||||
|
#show: exec-summary.with(
|
||||||
|
title: meta.title,
|
||||||
|
subtitle: meta.subtitle,
|
||||||
|
language: "en",
|
||||||
|
authors: meta.authors,
|
||||||
|
student-picture: image("figs/me.jpg"), // TODO: replace
|
||||||
|
permanent-email: meta.permanent-email,
|
||||||
|
video-url: meta.video-url,
|
||||||
|
|
||||||
|
picture-web-opt-out: meta.picture-web-opt-out,
|
||||||
|
email-web-opt-out: meta.email-web-opt-out,
|
||||||
|
|
||||||
|
summary: summary,
|
||||||
|
content: content,
|
||||||
|
|
||||||
|
thesis-supervisor: meta.thesis-supervisor,
|
||||||
|
thesis-co-supervisor: meta.thesis-co-supervisor,
|
||||||
|
thesis-expert: meta.thesis-expert,
|
||||||
|
academic-year: meta.academic-year,
|
||||||
|
|
||||||
|
school: meta.school,
|
||||||
|
programme: meta.programme,
|
||||||
|
|
||||||
|
keywords: meta.keywords,
|
||||||
|
major : meta.major,
|
||||||
|
|
||||||
|
bind: right, // Bind the left side of the page
|
||||||
|
footer: none, //align(right, text(0.9em)[This is some content for the footer])
|
||||||
|
)
|
||||||
BIN
summary/figs/me.jpg
Normal file
|
After Width: | Height: | Size: 752 KiB |