Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
B
baas-ide
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
guxukai
baas-ide
Commits
b08b0204
Commit
b08b0204
authored
Sep 09, 2015
by
chriseth
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #7 from d11e9/usability
Usability features and UI polish
parents
1d460e89
8b1eca91
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
695 additions
and
462 deletions
+695
-462
ballot.sol.js
ballot.sol.js
+69
-0
index.html
index.html
+598
-396
solidity.svg
solidity.svg
+28
-64
styles.css
stylesheets/styles.css
+0
-2
No files found.
ballot.sol.js
0 → 100644
View file @
b08b0204
var
multi
=
function
(
func
)
{
return
func
.
toString
().
match
(
/
[^]
*
\/\*([^]
*
)\*\/\}
$/
)[
1
];
}
var
BALLOT_EXAMPLE
=
multi
(
function
(){
/*contract Ballot {
struct Voter {
uint weight;
bool voted;
uint8 vote;
address delegate;
}
struct Proposal {
uint voteCount;
}
address chairperson;
mapping(address => Voter) voters;
Proposal[] proposals;
// Create a new ballot with $(_numProposals) different proposals.
function Ballot(uint8 _numProposals) {
chairperson = msg.sender;
voters[chairperson].weight = 1;
proposals.length = _numProposals;
}
// Give $(voter) the right to vote on this ballot.
// May only be called by $(chairperson).
function giveRightToVote(address voter) {
if (msg.sender != chairperson || voters[voter].voted) return;
voters[voter].weight = 1;
}
// Delegate your vote to the voter $(to).
function delegate(address to) {
Voter sender = voters[msg.sender]; // assigns reference
if (sender.voted) return;
while (voters[to].delegate != address(0) && voters[to].delegate != msg.sender)
to = voters[to].delegate;
if (to == msg.sender) return;
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[to];
if (delegate.voted)
proposals[delegate.vote].voteCount += sender.weight;
else
delegate.weight += sender.weight;
}
// Give a single vote to proposal $(proposal).
function vote(uint8 proposal) {
Voter sender = voters[msg.sender];
if (sender.voted || proposal >= proposals.length) return;
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount += sender.weight;
}
function winningProposal() constant returns (uint8 winningProposal) {
uint256 winningVoteCount = 0;
for (uint8 proposal = 0; proposal < proposals.length; proposal++) {
if (proposals[proposal].voteCount > winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount;
winningProposal = proposal;
}
++proposal;
}
}
}
*/
});
\ No newline at end of file
index.html
View file @
b08b0204
...
...
@@ -12,67 +12,206 @@ body {
font-size
:
12px
;
color
:
#111111
;
}
#solIcon
{
right
:
10px
;
top
:
10px
;
#editor
{
position
:
absolute
;
height
:
100px
;
width
:
100px
;
overflow
:
hidden
;
}
#solIcon
img
{
top
:
-20px
;
right
:
-10px
;
position
:
absolute
;
height
:
100px
;
}
#optimizeBox
{
position
:
absolute
;
top
:
30px
;
left
:
720px
;
font-size
:
14px
;
}
#input
{
position
:
absolute
;
top
:
120px
;
top
:
0
;
left
:
0px
;
width
:
700px
;
width
:
auto
;
bottom
:
0px
;
right
:
37em
;
}
#input
{
font-size
:
15px
;
position
:
absolute
;
top
:
0
;
left
:
0
;
right
:
0
;
bottom
:
0
;
min-width
:
20vw
;
}
#output
{
#righthand-panel
{
position
:
absolute
;
top
:
120px
;
left
:
720px
;
right
:
10px
;
top
:
0
;
width
:
37em
;
max-width
:
80vw
;
right
:
0
;
bottom
:
0px
;
font-size
:
14px
;
overflow
:
auto
;
border-left
:
1px
dotted
black
;
box-sizing
:
border-box
;
}
#output
{
border-top
:
1px
dotted
black
;
display
:
block
;
}
#header
{
margin-bottom
:
4px
;
font-size
:
14px
;
padding
:
1em
;
font-size
:
12px
;
}
#header
h1
{
margin-top
:
0
;
}
#header
.info
{
clear
:
left
;
}
#header
#solIcon
{
float
:
left
;
height
:
5em
;
}
.col1
{
width
:
18ex
;
display
:
inline-block
;
width
:
30%
;
float
:
left
;
}
.col2
{
width
:
60ex
;
display
:
inline-block
;
width
:
70%
;
float
:
left
;
}
.row
{
overflow
:
auto
;
}
.gethDeployText
{
border-color
:
#bebebe
;
height
:
2.5ex
;
height
:
2.5em
;
width
:
100%
;
display
:
block
;
}
.contractInstance
{
background-color
:
#ccc
;
margin-bottom
:
1em
;
padding
:
0.6em
;
}
.runButton
{
width
:
30ex
;
.contractInstance.hide
>
*
:not
(
.title
)
{
display
:
none
;
}
.contractInstance
.contractProperty
input
,
.contractInstance
.contractProperty
button
{
text-align
:
left
;
overflow
:
hidden
;
padding
:
0.3em
;
width
:
50%
;
margin
:
0
;
}
.contractInstance
{
margin-left
:
2ex
;
margin-bottom
:
20px
;
.contractOutput
.contractInstance
.contractProperty
{
margin-bottom
:
0
;
}
.contractOutput
.contractInstance
.contractProperty
.output
{
padding
:
0.4em
;
background-color
:
#333
;
color
:
white
;
margin-bottom
:
1em
;
display
:
block
;
}
.contractInstance
.contractProperty
.output
:empty
{
display
:
none
;
}
.contractOutput
{
border-bottom
:
1px
dotted
black
;
padding
:
0.6em
;
box-sizing
:
border-box
;
}
.contractOutput
.contractProperty
{
margin-bottom
:
0.6em
;
}
.contractOutput
.contractProperty
.output
{
display
:
inline
;
}
.contractOutput
.body
{
margin-top
:
10px
;
}
.contractOutput.hide
{
background-color
:
#4C4C67
;
color
:
white
;
}
.contractOutput.hide
>
*
:not
(
.title
)
{
display
:
none
;
}
.title
{
margin
:
0
;
cursor
:
pointer
;
font-family
:
monospace
;
font-weight
:
bold
;
}
.title
:before
{
content
:
"\25BC"
;
opacity
:
0.5
;
margin-right
:
0.4em
;
font-size
:
10px
;
}
.hide
>
.title
:before
{
content
:
"\25B6"
;
}
.contractOutput
>
.title
{
border-bottom
:
#4C4C67
;
}
.title
.size
{
font-weight
:
normal
;
float
:
right
;
}
.solError
{
position
:
absolute
;
background-color
:
rgba
(
255
,
0
,
0
,
0.2
);
z-index
:
40
;
}
.error
{
background-color
:
rgba
(
255
,
0
,
0
,
0.5
);
border-radius
:
0
;
word-wrap
:
break-word
;
border
:
1px
solid
#D00909
;
}
#ghostbar
{
width
:
1px
;
background-color
:
red
;
opacity
:
0.5
;
position
:
absolute
;
cursor
:
col-resize
;
z-index
:
9999
;
top
:
0
;
bottom
:
0
;
}
#dragbar
{
background-color
:
transparent
;
position
:
absolute
;
width
:
5px
;
left
:
0
;
top
:
0
;
bottom
:
0
;
cursor
:
col-resize
;
z-index
:
999
;
}
input
[
readonly
]
{
padding
:
.4em
;
border
:
1px
solid
#ccc
;
box-sizing
:
border-box
;
display
:
block
;
width
:
100%
;
}
</style>
<script
src=
"libs/jquery-2.1.3.min.js"
></script>
<script
src=
"libs/ace.js"
></script>
...
...
@@ -80,369 +219,432 @@ body {
<script
src=
"soljson.js"
></script>
<script
src=
"ethereumjs-vm.js"
></script>
<script
src=
"web3.min.js"
></script>
<script
src=
"ballot.sol.js"
></script>
</head>
<body>
<div
id=
"solIcon"
><img
src=
"solidity.svg"
></div>
<h1
id=
"header"
>
Solidity realtime compiler and runtime
</h1>
Version:
<span
id=
"version"
>
(loading)
</span><br/>
Execution environment does not connect to any node, everyhing is in-memory only.
<br/>
<b>
Note:
</b>
If Chrome/Chromium reports
"
Uncaught JavaScript Exception
"
,
enable the debug console (Ctrl+Shift+i) and reload.
<div
id=
"optimizeBox"
>
<input
id=
"optimize"
type=
"checkbox"
><label
for=
"optimize"
>
optimize
</label>
</div>
<div
id=
"input"
>
contract Ballot {
struct Voter {
uint weight;
bool voted;
uint8 vote;
address delegate;
}
struct Proposal {
uint voteCount;
}
address chairperson;
mapping(address => Voter) voters;
Proposal[] proposals;
// Create a new ballot with $(_numProposals) different proposals.
function Ballot(uint8 _numProposals) {
chairperson = msg.sender;
voters[chairperson].weight = 1;
proposals.length = _numProposals;
}
// Give $(voter) the right to vote on this ballot.
// May only be called by $(chairperson).
function giveRightToVote(address voter) {
if (msg.sender != chairperson || voters[voter].voted) return;
voters[voter].weight = 1;
}
// Delegate your vote to the voter $(to).
function delegate(address to) {
Voter sender = voters[msg.sender]; // assigns reference
if (sender.voted) return;
while (voters[to].delegate != address(0)
&&
voters[to].delegate != msg.sender)
to = voters[to].delegate;
if (to == msg.sender) return;
sender.voted = true;
sender.delegate = to;
Voter delegate = voters[to];
if (delegate.voted)
proposals[delegate.vote].voteCount += sender.weight;
else
delegate.weight += sender.weight;
}
// Give a single vote to proposal $(proposal).
function vote(uint8 proposal) {
Voter sender = voters[msg.sender];
if (sender.voted || proposal >= proposals.length) return;
sender.voted = true;
sender.vote = proposal;
proposals[proposal].voteCount += sender.weight;
}
function winningProposal() constant returns (uint8 winningProposal) {
uint256 winningVoteCount = 0;
for (uint8 proposal = 0; proposal
<
proposals
.
length
;
proposal
++)
{
if
(
proposals
[
proposal
].
voteCount
>
winningVoteCount) {
winningVoteCount = proposals[proposal].voteCount;
winningProposal = proposal;
}
++proposal;
}
}
}
</div>
<div
id=
"output"
></div>
<div
style=
"height: 100px;"
></div>
<p><small>
Theme by
<a
href=
"https://github.com/orderedlist"
>
orderedlist
</a></small></p>
<script>
// ----------------- editor ----------------------
var
editor
=
ace
.
edit
(
"input"
);
editor
.
getSession
().
setMode
(
"ace/mode/javascript"
);
editor
.
getSession
().
setTabSize
(
4
);
editor
.
getSession
().
setUseSoftTabs
(
true
);
// ----------------- compiler ----------------------
var
compileJSON
=
Module
.
cwrap
(
"compileJSON"
,
"string"
,
[
"string"
,
"number"
]);
$
(
'#version'
).
text
(
Module
.
cwrap
(
"version"
,
"string"
,
[])());
var
previousInput
=
''
;
var
compile
=
function
()
{
var
input
=
editor
.
getValue
();
var
optimize
=
document
.
querySelector
(
'#optimize'
).
checked
;
try
{
var
data
=
$
.
parseJSON
(
compileJSON
(
input
,
optimize
?
1
:
0
));
}
catch
(
exception
)
{
renderError
(
"Uncaught JavaScript Exception:
\
n"
+
exception
);
return
;
}
if
(
data
[
'error'
]
!==
undefined
)
renderError
(
data
[
'error'
]);
else
renderContracts
(
data
,
input
);
}
var
compileTimeout
=
null
;
var
onChange
=
function
()
{
var
input
=
editor
.
getValue
();
if
(
input
==
previousInput
)
return
;
previousInput
=
input
;
if
(
compileTimeout
)
window
.
clearTimeout
(
compileTimeout
);
compileTimeout
=
window
.
setTimeout
(
compile
,
300
);
};
onChange
();
editor
.
getSession
().
on
(
'change'
,
onChange
);
document
.
querySelector
(
'#optimize'
).
addEventListener
(
'change'
,
compile
);
// ----------------- compiler output renderer ----------------------
var
detailsOpen
=
{};
var
renderError
=
function
(
message
)
{
$
(
'#output'
).
empty
().
append
(
$
(
'<pre></pre>'
).
text
(
message
));
};
var
gethDeploy
=
function
(
contractName
,
interface
,
bytecode
){
var
code
=
""
;
var
funABI
=
getConstructorInterface
(
$
.
parseJSON
(
interface
));
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"var "
+
inp
.
name
+
" = /* var of type "
+
inp
.
type
+
" here */ ;
\
n"
;
});
code
+=
"
\
nvar "
+
contractName
+
"Contract = web3.eth.contract("
+
interface
.
replace
(
"
\
n"
,
""
)
+
");"
+
"
\
nvar "
+
contractName
+
" = "
+
contractName
+
"Contract.new("
;
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"
\
n "
+
inp
.
name
+
","
;
});
code
+=
"
\
n {"
+
"
\
n from: web3.eth.accounts[0], "
+
"
\
n data: '"
+
bytecode
+
"', "
+
"
\
n gas: 1000000"
+
"
\
n }, function(e, contract){"
+
"
\
n if(!e) {"
+
"
\
n if(!contract.address) {"
+
"
\
n console.log('Contract transaction sent! TransactionHash: ' + contract.transactionHash + ' waiting to be mined...');"
+
"
\
n } else {"
+
"
\
n console.log('Contract mined! Address: ' + contract.address);"
+
"
\
n console.log(contract);"
+
"
\
n }"
+
"
\
n }})"
;
return
code
;
};
var
renderContracts
=
function
(
data
,
source
)
{
$
(
'#output'
).
empty
();
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
var
contractOutput
=
$
(
'<div class="contractOutput"/>'
)
.
append
(
$
(
'<h3/>'
).
text
(
contractName
));
if
(
contract
.
bytecode
.
length
>
0
)
contractOutput
.
append
(
$
(
'<div/>'
).
text
((
contract
.
bytecode
.
length
/
2
)
+
' bytes'
))
.
append
(
getExecuteInterface
(
contract
,
contractName
))
.
append
(
tableRow
(
'Bytecode'
,
contract
.
bytecode
));
contractOutput
.
append
(
tableRow
(
'Interface'
,
contract
[
'interface'
]))
.
append
(
textRow
(
'Console deploy'
,
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
)))
.
append
(
getDetails
(
contract
,
source
,
contractName
));
$
(
'#output'
).
append
(
contractOutput
);
}
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
}
);
};
var
tableRowItems
=
function
(
first
,
second
)
{
return
$
(
'<div/>'
)
.
append
(
$
(
'<div class="col1">'
).
append
(
first
))
.
append
(
$
(
'<div class="col2">'
).
append
(
second
));
};
var
tableRow
=
function
(
description
,
data
)
{
return
tableRowItems
(
$
(
'<span/>'
).
text
(
description
),
$
(
'<input readonly="readonly"/>'
).
val
(
data
));
};
var
textRow
=
function
(
description
,
data
)
{
return
tableRowItems
(
$
(
'<strong/>'
).
text
(
description
),
$
(
'<textarea readonly="readonly" class="gethDeployText"/>'
).
val
(
data
));
};
var
getDetails
=
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
))
.
append
(
tableRow
(
'Opcodes'
,
contract
.
opcodes
));
var
funHashes
=
''
;
for
(
var
fun
in
contract
.
functionHashes
)
funHashes
+=
contract
.
functionHashes
[
fun
]
+
' '
+
fun
+
'
\
n'
;
details
.
append
(
$
(
'<span class="col1">Functions</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
funHashes
));
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
formatGasEstimates
(
contract
.
gasEstimates
)));
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
button
.
click
(
function
()
{
detailsOpen
[
contractName
]
=
!
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
detailsOpen
[
contractName
])
details
.
show
();
return
$
(
'<div/>'
).
append
(
button
).
append
(
details
);
};
var
formatGasEstimates
=
function
(
data
)
{
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
}
var
text
=
''
;
if
(
'creation'
in
data
)
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
text
+=
'External:
\
n'
;
for
(
var
fun
in
data
.
external
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
text
+=
'Internal:
\
n'
;
for
(
var
fun
in
data
.
internal
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
return
text
;
};
var
formatAssemblyText
=
function
(
asm
,
prefix
,
source
)
{
if
(
typeof
(
asm
)
==
typeof
(
''
)
||
asm
===
null
||
asm
===
undefined
)
return
prefix
+
asm
+
'
\
n'
;
var
text
=
prefix
+
'.code
\
n'
;
$
.
each
(
asm
[
'.code'
],
function
(
i
,
item
)
{
var
v
=
item
.
value
===
undefined
?
''
:
item
.
value
;
var
src
=
''
;
if
(
item
.
begin
!==
undefined
&&
item
.
end
!=
undefined
)
src
=
source
.
slice
(
item
.
begin
,
item
.
end
).
replace
(
'
\
n'
,
'
\\
n'
,
'g'
);
if
(
src
.
length
>
30
)
src
=
src
.
slice
(
0
,
30
)
+
'...'
;
if
(
item
.
name
!=
'tag'
)
text
+=
' '
;
text
+=
prefix
+
item
.
name
+
' '
+
v
+
'
\
t
\
t
\
t'
+
src
+
'
\
n'
;
});
text
+=
prefix
+
'.data
\
n'
;
if
(
asm
[
'.data'
])
$
.
each
(
asm
[
'.data'
],
function
(
i
,
item
)
{
text
+=
' '
+
prefix
+
''
+
i
+
':
\
n'
;
text
+=
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
return
text
;
};
$
(
'.asmOutput button'
).
click
(
function
()
{
$
(
this
).
parent
().
find
(
'pre'
).
toggle
();
}
)
// ----------------- VM ----------------------
var
stateTrie
=
new
EthVm
.
Trie
();
var
vm
=
new
EthVm
.
VM
(
stateTrie
);
//@todo this does not calculate the gas costs correctly but gets the job done.
var
identityCode
=
'return { gasUsed: 1, return: opts.data, exception: 1 };'
;
var
identityAddr
=
ethUtil
.
pad
(
new
Buffer
(
'04'
,
'hex'
),
20
)
vm
.
loadPrecompiled
(
identityAddr
,
identityCode
);
var
secretKey
=
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
var
publicKey
=
'0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0'
var
address
=
ethUtil
.
pubToAddress
(
new
Buffer
(
publicKey
,
'hex'
));
var
account
=
new
EthVm
.
Account
();
account
.
balance
=
'f00000000000000001'
;
var
nonce
=
0
;
stateTrie
.
put
(
address
,
account
.
serialize
());
var
runTx
=
function
(
data
,
to
,
cb
)
{
var
tx
=
new
EthVm
.
Transaction
({
nonce
:
new
Buffer
([
nonce
++
]),
//@todo count beyond 255
gasPrice
:
'01'
,
gasLimit
:
'3000000'
,
to
:
to
,
data
:
data
});
tx
.
sign
(
new
Buffer
(
secretKey
,
'hex'
));
vm
.
runTx
({
tx
:
tx
},
cb
);
};
var
getConstructorInterface
=
function
(
abi
)
{
var
funABI
=
{
'name'
:
''
,
'inputs'
:[],
'type'
:
'constructor'
,
'outputs'
:[]};
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
if
(
abi
[
i
].
type
==
'constructor'
)
{
funABI
.
inputs
=
abi
[
i
].
inputs
||
[];
break
;
}
return
funABI
;
};
var
getCallButton
=
function
(
args
)
{
// args.abi, args.bytecode [constr only], args.address [fun only]
// args.appendFunctions [constr only]
var
isConstructor
=
args
.
bytecode
!==
undefined
;
var
fun
=
new
web3
.
eth
.
function
(
args
.
abi
);
var
inputs
=
''
;
$
.
each
(
args
.
abi
.
inputs
,
function
(
i
,
inp
)
{
if
(
inputs
!=
''
)
inputs
+=
', '
;
inputs
+=
inp
.
type
+
' '
+
inp
.
name
;
});
var
inputField
=
$
(
'<input/>'
).
attr
(
'placeholder'
,
inputs
);
var
outputSpan
=
$
(
'<div/>'
);
var
button
=
$
(
'<button/>'
)
.
text
(
args
.
bytecode
?
'Create'
:
fun
.
displayName
())
.
click
(
function
()
{
var
funArgs
=
$
.
parseJSON
(
'['
+
inputField
.
val
()
+
']'
);
var
data
=
fun
.
toPayload
(
funArgs
).
data
;
if
(
data
.
slice
(
0
,
2
)
==
'0x'
)
data
=
data
.
slice
(
2
);
if
(
isConstructor
)
data
=
args
.
bytecode
+
data
.
slice
(
8
);
outputSpan
.
text
(
' ...'
);
runTx
(
data
,
args
.
address
,
function
(
err
,
result
)
{
if
(
err
)
outputSpan
.
text
(
err
);
else
if
(
isConstructor
)
{
outputSpan
.
text
(
' Creation used '
+
result
.
vm
.
gasUsed
.
toString
(
10
)
+
' gas.'
);
args
.
appendFunctions
(
result
.
createdAddress
);
}
else
{
var
outputObj
=
fun
.
unpackOutput
(
'0x'
+
result
.
vm
.
return
.
toString
(
'hex'
));
outputSpan
.
text
(
' Returned: '
+
JSON
.
stringify
(
outputObj
));
<div
id=
"editor"
>
<div
id=
"input"
></div>
</div>
<div
id=
"righthand-panel"
>
<div
id=
"dragbar"
></div>
<div
id=
"header"
>
<img
id=
"solIcon"
src=
"solidity.svg"
>
<h1>
Solidity realtime
<br/>
compiler and runtime
</h1>
<div
class=
"info"
>
<p>
Version:
<span
id=
"version"
>
(loading)
</span><br/>
Execution environment does not connect to any node, everyhing is in-memory only.
<br/>
<strong>
Note:
</strong>
If Chrome/Chromium reports
"
Uncaught JavaScript Exception
"
,
enable the debug console (Ctrl+Shift+i) and reload.
</p>
</div>
<div
id=
"optimizeBox"
>
<input
id=
"editorWrap"
type=
"checkbox"
><label
for=
"editorWrap"
>
Text Wrap
</label>
<input
id=
"optimize"
type=
"checkbox"
><label
for=
"optimize"
>
Enable Optimization
</label>
</div>
</div>
<div
id=
"output"
></div>
</div>
<script>
// ----------------- editor ----------------------
var
SOL_CACHE_KEY
=
"sol-cache"
;
var
editor
=
ace
.
edit
(
"input"
);
var
session
=
editor
.
getSession
();
var
Range
=
ace
.
require
(
'ace/range'
).
Range
;
var
errMarkerId
=
null
;
var
solCache
=
window
.
localStorage
.
getItem
(
SOL_CACHE_KEY
);
editor
.
setValue
(
solCache
||
BALLOT_EXAMPLE
,
1
);
session
.
setMode
(
"ace/mode/javascript"
);
session
.
setTabSize
(
4
);
session
.
setUseSoftTabs
(
true
);
// ----------------- resizeable ui ---------------
var
EDITOR_SIZE_CACHE_KEY
=
"editor-size-cache"
;
var
dragging
=
false
;
$
(
'#dragbar'
).
mousedown
(
function
(
e
){
e
.
preventDefault
();
dragging
=
true
;
var
main
=
$
(
'#righthand-panel'
);
var
ghostbar
=
$
(
'<div id="ghostbar">'
,
{
css
:
{
top
:
main
.
offset
().
top
,
left
:
main
.
offset
().
left
}
}).
prependTo
(
'body'
);
$
(
document
).
mousemove
(
function
(
e
){
ghostbar
.
css
(
"left"
,
e
.
pageX
+
2
);
});
});
if
(
!
isConstructor
)
button
.
addClass
(
'runButton'
);
var
c
=
$
(
'<div/>'
)
.
append
(
button
);
if
(
args
.
abi
.
inputs
.
length
>
0
)
c
.
append
(
inputField
);
return
c
.
append
(
outputSpan
);
};
var
getExecuteInterface
=
function
(
contract
,
name
)
{
var
abi
=
$
.
parseJSON
(
contract
.
interface
);
var
execInter
=
$
(
'<div/>'
);
var
funABI
=
getConstructorInterface
(
abi
);
var
appendFunctions
=
function
(
address
)
{
var
instance
=
$
(
'<div class="contractInstance"/>'
);
instance
.
append
(
$
(
'<span/>'
).
text
(
'Contract at address '
+
address
.
toString
(
'hex'
)));
$
.
each
(
abi
,
function
(
i
,
funABI
)
{
if
(
funABI
.
type
!=
'function'
)
return
;
instance
.
append
(
getCallButton
({
abi
:
funABI
,
address
:
address
}));
var
$body
=
$
(
'body'
);
function
setEditorSize
(
delta
)
{
$
(
'#righthand-panel'
).
css
(
"width"
,
delta
);
$
(
'#editor'
).
css
(
"right"
,
delta
);
onResize
();
}
$
(
document
).
mouseup
(
function
(
e
){
if
(
dragging
)
{
var
delta
=
$body
.
width
()
-
e
.
pageX
+
2
;
$
(
'#ghostbar'
).
remove
();
$
(
document
).
unbind
(
'mousemove'
);
dragging
=
false
;
setEditorSize
(
delta
)
window
.
localStorage
.
setItem
(
EDITOR_SIZE_CACHE_KEY
,
delta
);
}
});
execInter
.
append
(
instance
);
};
execInter
.
append
(
getCallButton
({
abi
:
funABI
,
bytecode
:
contract
.
bytecode
,
appendFunctions
:
appendFunctions
}));
return
execInter
;
};
</script>
// set cached defaults
var
cachedSize
=
window
.
localStorage
.
getItem
(
EDITOR_SIZE_CACHE_KEY
);
if
(
cachedSize
)
setEditorSize
(
cachedSize
);
// ----------------- editor resize ---------------
function
onResize
()
{
editor
.
resize
();
session
.
setUseWrapMode
(
document
.
querySelector
(
'#editorWrap'
).
checked
);
if
(
session
.
getUseWrapMode
())
{
var
characterWidth
=
editor
.
renderer
.
characterWidth
;
var
contentWidth
=
editor
.
container
.
ownerDocument
.
getElementsByClassName
(
"ace_scroller"
)[
0
].
clientWidth
;
if
(
contentWidth
>
0
)
{
session
.
setWrapLimit
(
parseInt
(
contentWidth
/
characterWidth
,
10
));
}
}
}
window
.
onresize
=
onResize
;
onResize
();
document
.
querySelector
(
'#editor'
).
addEventListener
(
'change'
,
onResize
);
// ----------------- compiler ----------------------
var
compileJSON
=
Module
.
cwrap
(
"compileJSON"
,
"string"
,
[
"string"
,
"number"
]);
$
(
'#version'
).
text
(
Module
.
cwrap
(
"version"
,
"string"
,
[])());
var
previousInput
=
''
;
var
compile
=
function
()
{
editor
.
getSession
().
clearAnnotations
();
editor
.
getSession
().
removeMarker
(
errMarkerId
);
var
input
=
editor
.
getValue
();
var
optimize
=
document
.
querySelector
(
'#optimize'
).
checked
;
try
{
var
data
=
$
.
parseJSON
(
compileJSON
(
input
,
optimize
?
1
:
0
));
}
catch
(
exception
)
{
renderError
(
"Uncaught JavaScript Exception:
\
n"
+
exception
);
return
;
}
if
(
data
[
'error'
]
!==
undefined
)
renderError
(
data
[
'error'
]);
else
renderContracts
(
data
,
input
);
}
var
compileTimeout
=
null
;
var
onChange
=
function
()
{
var
input
=
editor
.
getValue
();
if
(
input
===
""
)
{
window
.
localStorage
.
setItem
(
SOL_CACHE_KEY
,
''
)
return
;
}
if
(
input
===
previousInput
)
return
;
previousInput
=
input
;
if
(
compileTimeout
)
window
.
clearTimeout
(
compileTimeout
);
compileTimeout
=
window
.
setTimeout
(
compile
,
300
);
};
onChange
();
editor
.
getSession
().
on
(
'change'
,
onChange
);
document
.
querySelector
(
'#optimize'
).
addEventListener
(
'change'
,
compile
);
// ----------------- compiler output renderer ----------------------
var
detailsOpen
=
{};
var
renderError
=
function
(
message
)
{
var
$output
=
$
(
'#output'
).
empty
()
var
err
=
message
.
match
(
/^:
([
0-9
]
*
)
:
([
0-9
]
*
)
/
)
if
(
err
&&
err
.
length
)
{
var
errLine
=
parseInt
(
err
[
1
],
10
)
-
1
;
var
errCol
=
err
[
2
]
?
parseInt
(
err
[
2
],
10
)
:
0
;
$output
.
append
(
$
(
'<pre class="error"></pre>'
).
text
(
message
));
editor
.
getSession
().
setAnnotations
([{
row
:
errLine
,
column
:
errCol
,
text
:
message
,
type
:
"error"
}]);
}
};
var
gethDeploy
=
function
(
contractName
,
interface
,
bytecode
){
var
code
=
""
;
var
funABI
=
getConstructorInterface
(
$
.
parseJSON
(
interface
));
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"var "
+
inp
.
name
+
" = /* var of type "
+
inp
.
type
+
" here */ ;
\
n"
;
});
code
+=
"
\
nvar "
+
contractName
+
"Contract = web3.eth.contract("
+
interface
.
replace
(
"
\
n"
,
""
)
+
");"
+
"
\
nvar "
+
contractName
+
" = "
+
contractName
+
"Contract.new("
;
$
.
each
(
funABI
.
inputs
,
function
(
i
,
inp
)
{
code
+=
"
\
n "
+
inp
.
name
+
","
;
});
code
+=
"
\
n {"
+
"
\
n from: web3.eth.accounts[0], "
+
"
\
n data: '"
+
bytecode
+
"', "
+
"
\
n gas: 1000000"
+
"
\
n }, function(e, contract){"
+
"
\
n if (typeof contract.address != 'undefined') {"
+
"
\
n console.log(e, contract);"
+
"
\
n console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);"
+
"
\
n }"
+
"
\
n })"
;
return
code
;
};
var
combined
=
function
(
contractName
,
interface
,
bytecode
){
return
JSON
.
stringify
(
[{
name
:
contractName
,
interface
:
interface
,
bytecode
:
bytecode
}]);
};
var
renderContracts
=
function
(
data
,
source
)
{
window
.
localStorage
.
setItem
(
SOL_CACHE_KEY
,
source
);
$
(
'#output'
).
empty
();
for
(
var
contractName
in
data
.
contracts
)
{
var
contract
=
data
.
contracts
[
contractName
];
var
title
=
$
(
'<h3 class="title"/>'
).
text
(
contractName
);
var
contractOutput
=
$
(
'<div class="contractOutput"/>'
)
.
append
(
title
);
var
body
=
$
(
'<div class="body" />'
)
contractOutput
.
append
(
body
);
if
(
contract
.
bytecode
.
length
>
0
)
title
.
append
(
$
(
'<div class="size"/>'
).
text
((
contract
.
bytecode
.
length
/
2
)
+
' bytes'
))
body
.
append
(
getExecuteInterface
(
contract
,
contractName
))
.
append
(
tableRow
(
'Bytecode'
,
contract
.
bytecode
));
body
.
append
(
tableRow
(
'Interface'
,
contract
[
'interface'
]))
.
append
(
textRow
(
'Web3 deploy'
,
gethDeploy
(
contractName
.
toLowerCase
(),
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
textRow
(
'uDApp'
,
combined
(
contractName
,
contract
[
'interface'
],
contract
.
bytecode
),
'deploy'
))
.
append
(
getDetails
(
contract
,
source
,
contractName
));
$
(
'#output'
).
append
(
contractOutput
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
}
$
(
'.col2 input,textarea'
).
click
(
function
()
{
this
.
select
();
}
);
};
var
tableRowItems
=
function
(
first
,
second
,
cls
)
{
return
$
(
'<div class="row"/>'
)
.
addClass
(
cls
)
.
append
(
$
(
'<div class="col1">'
).
append
(
first
))
.
append
(
$
(
'<div class="col2">'
).
append
(
second
));
};
var
tableRow
=
function
(
description
,
data
)
{
return
tableRowItems
(
$
(
'<span/>'
).
text
(
description
),
$
(
'<input readonly="readonly"/>'
).
val
(
data
));
};
var
textRow
=
function
(
description
,
data
,
cls
)
{
return
tableRowItems
(
$
(
'<strong/>'
).
text
(
description
),
$
(
'<textarea readonly="readonly" class="gethDeployText"/>'
).
val
(
data
),
cls
);
};
var
getDetails
=
function
(
contract
,
source
,
contractName
)
{
var
button
=
$
(
'<button>Details</button>'
);
var
details
=
$
(
'<div style="display: none;"/>'
)
.
append
(
tableRow
(
'Solidity Interface'
,
contract
.
solidity_interface
))
.
append
(
tableRow
(
'Opcodes'
,
contract
.
opcodes
));
var
funHashes
=
''
;
for
(
var
fun
in
contract
.
functionHashes
)
funHashes
+=
contract
.
functionHashes
[
fun
]
+
' '
+
fun
+
'
\
n'
;
details
.
append
(
$
(
'<span class="col1">Functions</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
funHashes
));
details
.
append
(
$
(
'<span class="col1">Gas Estimates</span>'
));
details
.
append
(
$
(
'<pre/>'
).
text
(
formatGasEstimates
(
contract
.
gasEstimates
)));
if
(
contract
.
assembly
!==
null
)
{
details
.
append
(
$
(
'<span class="col1">Assembly</span>'
));
var
assembly
=
$
(
'<pre/>'
).
text
(
formatAssemblyText
(
contract
.
assembly
,
''
,
source
));
details
.
append
(
assembly
);
}
button
.
click
(
function
()
{
detailsOpen
[
contractName
]
=
!
detailsOpen
[
contractName
];
details
.
toggle
();
});
if
(
detailsOpen
[
contractName
])
details
.
show
();
return
$
(
'<div/>'
).
append
(
button
).
append
(
details
);
};
var
formatGasEstimates
=
function
(
data
)
{
var
gasToText
=
function
(
g
)
{
return
g
===
null
?
'unknown'
:
g
;
}
var
text
=
''
;
if
(
'creation'
in
data
)
text
+=
'Creation: '
+
gasToText
(
data
.
creation
[
0
])
+
' + '
+
gasToText
(
data
.
creation
[
1
])
+
'
\
n'
;
text
+=
'External:
\
n'
;
for
(
var
fun
in
data
.
external
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
external
[
fun
])
+
'
\
n'
;
text
+=
'Internal:
\
n'
;
for
(
var
fun
in
data
.
internal
)
text
+=
' '
+
fun
+
': '
+
gasToText
(
data
.
internal
[
fun
])
+
'
\
n'
;
return
text
;
};
var
formatAssemblyText
=
function
(
asm
,
prefix
,
source
)
{
if
(
typeof
(
asm
)
==
typeof
(
''
)
||
asm
===
null
||
asm
===
undefined
)
return
prefix
+
asm
+
'
\
n'
;
var
text
=
prefix
+
'.code
\
n'
;
$
.
each
(
asm
[
'.code'
],
function
(
i
,
item
)
{
var
v
=
item
.
value
===
undefined
?
''
:
item
.
value
;
var
src
=
''
;
if
(
item
.
begin
!==
undefined
&&
item
.
end
!=
undefined
)
src
=
source
.
slice
(
item
.
begin
,
item
.
end
).
replace
(
'
\
n'
,
'
\\
n'
,
'g'
);
if
(
src
.
length
>
30
)
src
=
src
.
slice
(
0
,
30
)
+
'...'
;
if
(
item
.
name
!=
'tag'
)
text
+=
' '
;
text
+=
prefix
+
item
.
name
+
' '
+
v
+
'
\
t
\
t
\
t'
+
src
+
'
\
n'
;
});
text
+=
prefix
+
'.data
\
n'
;
if
(
asm
[
'.data'
])
$
.
each
(
asm
[
'.data'
],
function
(
i
,
item
)
{
text
+=
' '
+
prefix
+
''
+
i
+
':
\
n'
;
text
+=
formatAssemblyText
(
item
,
prefix
+
' '
,
source
);
});
return
text
;
};
$
(
'.asmOutput button'
).
click
(
function
()
{
$
(
this
).
parent
().
find
(
'pre'
).
toggle
();
}
)
// ----------------- VM ----------------------
var
stateTrie
=
new
EthVm
.
Trie
();
var
vm
=
new
EthVm
.
VM
(
stateTrie
);
//@todo this does not calculate the gas costs correctly but gets the job done.
var
identityCode
=
'return { gasUsed: 1, return: opts.data, exception: 1 };'
;
var
identityAddr
=
ethUtil
.
pad
(
new
Buffer
(
'04'
,
'hex'
),
20
)
vm
.
loadPrecompiled
(
identityAddr
,
identityCode
);
var
secretKey
=
'3cd7232cd6f3fc66a57a6bedc1a8ed6c228fff0a327e169c2bcc5e869ed49511'
var
publicKey
=
'0406cc661590d48ee972944b35ad13ff03c7876eae3fd191e8a2f77311b0a3c6613407b5005e63d7d8d76b89d5f900cde691497688bb281e07a5052ff61edebdc0'
var
address
=
ethUtil
.
pubToAddress
(
new
Buffer
(
publicKey
,
'hex'
));
var
account
=
new
EthVm
.
Account
();
account
.
balance
=
'f00000000000000001'
;
var
nonce
=
0
;
stateTrie
.
put
(
address
,
account
.
serialize
());
var
runTx
=
function
(
data
,
to
,
cb
)
{
var
tx
=
new
EthVm
.
Transaction
({
nonce
:
new
Buffer
([
nonce
++
]),
//@todo count beyond 255
gasPrice
:
'01'
,
gasLimit
:
'3000000'
,
to
:
to
,
data
:
data
});
tx
.
sign
(
new
Buffer
(
secretKey
,
'hex'
));
vm
.
runTx
({
tx
:
tx
},
cb
);
};
var
getConstructorInterface
=
function
(
abi
)
{
var
funABI
=
{
'name'
:
''
,
'inputs'
:[],
'type'
:
'constructor'
,
'outputs'
:[]};
for
(
var
i
=
0
;
i
<
abi
.
length
;
i
++
)
if
(
abi
[
i
].
type
==
'constructor'
)
{
funABI
.
inputs
=
abi
[
i
].
inputs
||
[];
break
;
}
return
funABI
;
};
var
getCallButton
=
function
(
args
)
{
// args.abi, args.bytecode [constr only], args.address [fun only]
// args.appendFunctions [constr only]
var
isConstructor
=
args
.
bytecode
!==
undefined
;
var
fun
=
new
web3
.
eth
.
function
(
args
.
abi
);
var
inputs
=
''
;
$
.
each
(
args
.
abi
.
inputs
,
function
(
i
,
inp
)
{
if
(
inputs
!=
''
)
inputs
+=
', '
;
inputs
+=
inp
.
type
+
' '
+
inp
.
name
;
});
var
inputField
=
$
(
'<input/>'
).
attr
(
'placeholder'
,
inputs
);
var
outputSpan
=
$
(
'<div class="output"/>'
);
var
button
=
$
(
'<button/>'
)
.
text
(
args
.
bytecode
?
'Create'
:
fun
.
displayName
())
.
click
(
function
()
{
var
funArgs
=
$
.
parseJSON
(
'['
+
inputField
.
val
()
+
']'
);
var
data
=
fun
.
toPayload
(
funArgs
).
data
;
if
(
data
.
slice
(
0
,
2
)
==
'0x'
)
data
=
data
.
slice
(
2
);
if
(
isConstructor
)
data
=
args
.
bytecode
+
data
.
slice
(
8
);
outputSpan
.
text
(
'...'
);
runTx
(
data
,
args
.
address
,
function
(
err
,
result
)
{
if
(
err
)
outputSpan
.
text
(
err
);
else
if
(
isConstructor
)
{
outputSpan
.
text
(
' Creation used '
+
result
.
vm
.
gasUsed
.
toString
(
10
)
+
' gas.'
);
args
.
appendFunctions
(
result
.
createdAddress
);
}
else
{
var
outputObj
=
fun
.
unpackOutput
(
'0x'
+
result
.
vm
.
return
.
toString
(
'hex'
));
outputSpan
.
text
(
' Returned: '
+
JSON
.
stringify
(
outputObj
));
}
});
});
if
(
!
isConstructor
)
button
.
addClass
(
'runButton'
);
var
c
=
$
(
'<div class="contractProperty"/>'
)
.
append
(
button
);
if
(
args
.
abi
.
inputs
.
length
>
0
)
c
.
append
(
inputField
);
return
c
.
append
(
outputSpan
);
};
var
getExecuteInterface
=
function
(
contract
,
name
)
{
var
abi
=
$
.
parseJSON
(
contract
.
interface
);
var
execInter
=
$
(
'<div/>'
);
var
funABI
=
getConstructorInterface
(
abi
);
var
appendFunctions
=
function
(
address
)
{
var
instance
=
$
(
'<div class="contractInstance"/>'
);
var
title
=
$
(
'<span class="title"/>'
).
text
(
'Contract at '
+
address
.
toString
(
'hex'
)
);
instance
.
append
(
title
);
$
.
each
(
abi
,
function
(
i
,
funABI
)
{
if
(
funABI
.
type
!=
'function'
)
return
;
instance
.
append
(
getCallButton
({
abi
:
funABI
,
address
:
address
}));
});
execInter
.
append
(
instance
);
title
.
click
(
function
(
ev
){
$
(
this
).
parent
().
toggleClass
(
'hide'
)
});
};
execInter
.
append
(
getCallButton
({
abi
:
funABI
,
bytecode
:
contract
.
bytecode
,
appendFunctions
:
appendFunctions
}));
return
execInter
;
};
</script>
</body>
</html>
solidity.svg
View file @
b08b0204
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"Layer_1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"0 0 3840 2160"
enable-background=
"new 0 0 3840 2160"
xml:space=
"preserve"
>
<g>
<polyline
opacity=
"0.45"
points=
"2063.6,490.6 1919,747.6 1630,747.6 1774.5,490.6 2063.6,490.6 "
/>
<polygon
opacity=
"0.6"
points=
"1919,747.6 2208.1,747.6 2063.6,490.6 1774.5,490.6 "
/>
<polygon
opacity=
"0.8"
points=
"1774.5,1004.5 1919,747.6 1774.5,490.6 1630,747.6 "
/>
<polyline
opacity=
"0.45"
points=
"1775.9,1390 1920.5,1133 2209.6,1133 2065,1390 1775.9,1390 "
/>
<polygon
opacity=
"0.6"
points=
"1920.5,1133 1631.4,1133 1775.9,1390 2065,1390 "
/>
<polygon
opacity=
"0.8"
points=
"2065,876.1 1920.5,1133 2065,1390 2209.6,1133 "
/>
<path
fill=
"#010101"
d=
"M1602.3,1636c0,4.1,1.7,7.1,5,9.1c3.3,2,7.4,3.7,12.3,5c4.9,1.3,10.3,2.5,16.1,3.5c5.8,1,11.2,2.5,16.1,4.4
c4.9,1.9,9,4.6,12.3,8c3.3,3.4,5,8.1,5,14c0,5-1.2,9.3-3.5,12.9c-2.3,3.6-5.3,6.6-8.9,8.9c-3.6,2.3-7.6,4.1-12.1,5.3
c-4.4,1.2-8.8,1.8-13,1.8c-4.6,0-9.2-0.5-13.7-1.5c-4.5-1-8.6-2.6-12.2-4.8c-3.6-2.2-6.6-5.1-8.9-8.7c-2.3-3.6-3.5-8.1-3.5-13.4
c0-1.8,0.2-3.4,0.7-4.6c0.5-1.2,1.8-1.8,4-1.8c1.1,0,1.9,0.5,2.4,1.5c0.5,1,0.7,2,0.7,2.9c0,4.6,0.8,8.4,2.5,11.4
c1.7,3,3.9,5.3,6.8,6.9c2.9,1.7,6.1,2.8,9.8,3.5c3.7,0.6,7.5,1,11.4,1c3.1,0,6.5-0.4,10-1.2c3.5-0.8,6.7-2.1,9.6-3.7
c2.9-1.7,5.3-3.8,7.2-6.5c1.9-2.7,2.9-5.9,2.9-9.6c0-4.6-1.7-8.2-5-10.7c-3.3-2.5-7.4-4.5-12.3-6c-4.9-1.5-10.3-2.7-16.1-3.6
c-5.8-0.9-11.2-2.3-16.1-4c-4.9-1.8-9-4.1-12.3-7.1c-3.3-3-5-7.1-5-12.5c0-4.6,1.2-8.5,3.5-11.5c2.3-3,5.2-5.4,8.7-7.2
c3.5-1.8,7.3-3,11.5-3.6c4.2-0.6,8.1-1,11.8-1c4.4,0,8.8,0.5,13.2,1.4c4.3,0.9,8.3,2.4,11.8,4.4c3.5,2,6.4,4.8,8.6,8.3
c2.2,3.5,3.3,7.9,3.3,13c0,1.1-0.5,2-1.4,2.6c-0.9,0.7-1.8,1-2.8,1c-1.3,0-2.2-0.5-2.8-1.4c-0.6-0.9-0.8-1.8-0.8-2.8
c-0.7-4.1-2.1-7.3-4-9.8c-1.9-2.5-4.3-4.4-6.9-5.7c-2.7-1.3-5.6-2.2-8.7-2.6c-3.1-0.5-6.3-0.7-9.4-0.7c-2.6,0-5.5,0.2-8.6,0.6
c-3.1,0.4-6.1,1.1-9,2.2c-2.9,1.1-5.3,2.6-7.2,4.6C1603.3,1630,1602.3,1632.7,1602.3,1636z"
/>
<path
fill=
"#010101"
d=
"M1748.3,1611.9c6.5,0,12.5,1.3,18,4c5.5,2.7,10.3,6.2,14.3,10.7c4,4.4,7.1,9.6,9.3,15.4
c2.2,5.8,3.3,11.9,3.3,18.2c0,6.3-1.1,12.3-3.3,18.2c-2.2,5.8-5.3,10.9-9.3,15.4c-4,4.4-8.7,8-14.3,10.7c-5.5,2.7-11.5,4-18,4
c-6.5,0-12.4-1.3-17.9-4c-5.5-2.7-10.2-6.2-14.1-10.7c-4-4.4-7.1-9.6-9.3-15.4c-2.2-5.8-3.3-11.9-3.3-18.2c0-6.3,1.1-12.3,3.3-18.2
c2.2-5.8,5.3-10.9,9.3-15.4c4-4.4,8.7-8,14.1-10.7C1735.9,1613.2,1741.8,1611.9,1748.3,1611.9z M1748.3,1700.5
c5.5,0,10.6-1.2,15.1-3.5c4.5-2.3,8.4-5.3,11.6-9c3.2-3.7,5.7-8,7.5-12.9c1.8-4.9,2.6-9.9,2.6-15.1c0-5.2-0.9-10.2-2.6-15
c-1.8-4.8-4.3-9-7.5-12.7c-3.2-3.7-7.1-6.7-11.6-9c-4.5-2.3-9.6-3.5-15.1-3.5c-5.4,0-10.3,1.2-14.8,3.5c-4.5,2.3-8.4,5.3-11.6,9
c-3.2,3.7-5.8,7.9-7.6,12.7c-1.8,4.8-2.8,9.8-2.8,15c0,5.2,0.9,10.2,2.8,15.1c1.8,4.9,4.4,9.2,7.6,12.9c3.2,3.7,7.1,6.7,11.6,9
C1738,1699.4,1742.9,1700.5,1748.3,1700.5z"
/>
<path
fill=
"#010101"
d=
"M1833.8,1536.8c1.1,0,2,0.4,2.8,1.2c0.7,0.8,1.1,1.7,1.1,2.6V1703c0,0.9-0.4,1.8-1.1,2.6
c-0.7,0.8-1.7,1.2-2.8,1.2c-1.1,0-2-0.4-2.8-1.2c-0.7-0.8-1.1-1.7-1.1-2.6v-162.4c0-0.9,0.4-1.8,1.1-2.6
C1831.7,1537.2,1832.7,1536.8,1833.8,1536.8z"
/>
<path
fill=
"#010101"
d=
"M1883.2,1587.5c0,1.7-0.6,3.1-1.9,4.3c-1.3,1.2-2.8,1.8-4.4,1.8c-1.8,0-3.4-0.6-4.6-1.8
c-1.2-1.2-1.8-2.6-1.8-4.3c0-1.8,0.6-3.4,1.8-4.6c1.2-1.2,2.7-1.8,4.6-1.8c1.7,0,3.1,0.6,4.4,1.8
C1882.6,1584.1,1883.2,1585.6,1883.2,1587.5z M1876.9,1614.6c0.9,0,1.8,0.4,2.6,1.2c0.8,0.8,1.2,1.7,1.2,2.6v84.2
c0,0.9-0.4,1.8-1.2,2.6c-0.8,0.8-1.7,1.2-2.6,1.2c-1.1,0-2-0.4-2.8-1.2c-0.7-0.8-1.1-1.7-1.1-2.6v-84.2c0-0.9,0.4-1.8,1.1-2.6
C1874.8,1615.1,1875.8,1614.6,1876.9,1614.6z"
/>
<path
fill=
"#010101"
d=
"M2003.2,1536.5c1.1,0,2,0.4,2.8,1.2c0.7,0.8,1.1,1.7,1.1,2.6v162.1c0,2.6-1.3,3.9-3.9,3.9
c-2.6,0-3.9-1.3-3.9-3.9v-17.7c-3.9,7.2-9.2,13-16.1,17.5c-6.8,4.4-14.4,6.7-22.7,6.7c-6.5,0-12.4-1.3-17.9-4
c-5.5-2.7-10.2-6.2-14.1-10.7c-4-4.4-7.1-9.6-9.3-15.4c-2.2-5.8-3.3-11.9-3.3-18.2c0-6.3,1.1-12.3,3.3-18.2
c2.2-5.8,5.3-10.9,9.3-15.4c4-4.4,8.7-8,14.1-10.7c5.4-2.7,11.4-4,17.9-4c8.3,0,15.9,2.3,22.7,6.8c6.8,4.5,12.2,10.4,16.1,17.6
v-96.4c0-0.9,0.4-1.8,1.1-2.6C2001.2,1536.9,2002.1,1536.5,2003.2,1536.5z M1960.5,1701.1c5.5,0,10.6-1.2,15.1-3.5
c4.5-2.3,8.4-5.3,11.6-9c3.2-3.7,5.7-8,7.5-12.9c1.8-4.9,2.6-9.9,2.6-15.1c0-5.2-0.9-10.2-2.6-15.1c-1.8-4.9-4.3-9.2-7.5-12.9
c-3.2-3.7-7.1-6.7-11.6-9c-4.5-2.3-9.6-3.5-15.1-3.5c-5.4,0-10.3,1.2-14.8,3.5c-4.5,2.3-8.4,5.3-11.6,9c-3.2,3.7-5.8,8-7.6,12.9
c-1.8,4.9-2.8,9.9-2.8,15.1c0,5.2,0.9,10.2,2.8,15.1c1.8,4.9,4.4,9.2,7.6,12.9c3.2,3.7,7.1,6.7,11.6,9
C1950.2,1699.9,1955.2,1701.1,1960.5,1701.1z"
/>
<path
fill=
"#010101"
d=
"M2054.1,1587.5c0,1.7-0.6,3.1-1.9,4.3c-1.3,1.2-2.8,1.8-4.4,1.8c-1.8,0-3.4-0.6-4.6-1.8
c-1.2-1.2-1.8-2.6-1.8-4.3c0-1.8,0.6-3.4,1.8-4.6c1.2-1.2,2.7-1.8,4.6-1.8c1.7,0,3.1,0.6,4.4,1.8
C2053.4,1584.1,2054.1,1585.6,2054.1,1587.5z M2047.7,1614.6c0.9,0,1.8,0.4,2.6,1.2c0.8,0.8,1.2,1.7,1.2,2.6v84.2
c0,0.9-0.4,1.8-1.2,2.6c-0.8,0.8-1.7,1.2-2.6,1.2c-1.1,0-2-0.4-2.8-1.2c-0.7-0.8-1.1-1.7-1.1-2.6v-84.2c0-0.9,0.4-1.8,1.1-2.6
C2045.7,1615.1,2046.6,1614.6,2047.7,1614.6z"
/>
<path
fill=
"#010101"
d=
"M2135.2,1614.1c1.1,0,2,0.4,2.8,1.2c0.7,0.8,1.1,1.7,1.1,2.6c0,2.6-1.3,3.9-3.9,3.9h-20.8v81.5
c0,0.9-0.4,1.8-1.1,2.6c-0.7,0.8-1.7,1.2-2.8,1.2c-1.1,0-2-0.4-2.8-1.2c-0.7-0.8-1.1-1.7-1.1-2.6v-81.5h-20c-2.6,0-3.9-1.3-3.9-3.9
c0-0.9,0.4-1.8,1.1-2.6c0.7-0.8,1.7-1.2,2.8-1.2h20v-29.9c0-2.6,1.3-3.9,3.9-3.9c2.6,0,3.9,1.3,3.9,3.9v29.9H2135.2z"
/>
<path
fill=
"#010101"
d=
"M2242.7,1613.8c2.6,0,3.9,1.3,3.9,3.9c0,0.2-0.7,2.2-2.2,6.1c-1.5,3.9-3.4,8.9-5.7,15.1
c-2.3,6.2-5,13.3-8,21.2c-3,7.9-6.2,16.1-9.6,24.5c-3.3,8.4-6.6,16.7-9.7,24.8c-3.1,8.1-6.1,15.6-8.7,22.3
c-2.7,6.7-4.9,12.5-6.8,17.2c-1.8,4.7-3,7.7-3.6,9c-0.9,1.7-2.1,2.5-3.6,2.5c-0.9,0-1.8-0.4-2.6-1.2c-0.8-0.8-1.2-1.7-1.2-2.6
c0-0.4,0.5-1.8,1.4-4.3c0.9-2.5,2-5.5,3.3-9c1.3-3.5,2.8-7.3,4.4-11.5c1.7-4.2,3.2-8.1,4.7-11.9c1.5-3.8,2.8-7.1,3.9-9.8
c1.1-2.8,1.8-4.6,2.2-5.5c-0.2-0.2-1.2-2.4-3-6.6c-1.8-4.2-4.1-9.6-6.8-15.9c-2.7-6.4-5.5-13.3-8.5-20.6c-3-7.4-5.7-14.3-8.3-20.6
c-2.6-6.4-4.8-11.7-6.5-16.1c-1.8-4.3-2.6-6.6-2.6-6.8c0-2.6,1.3-3.9,3.9-3.9c1.8,0,3,0.7,3.6,2.2l32.1,78.4l30.5-78.1
C2239.6,1614.6,2240.8,1613.8,2242.7,1613.8z"
/>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width=
"1472px"
height=
"1472px"
viewBox=
"0 0 1472 1472"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
xmlns:sketch=
"http://www.bohemiancoding.com/sketch/ns"
>
<!-- Generator: Sketch 3.1.1 (8761) - http://www.bohemiancoding.com/sketch -->
<title>
Vector 1
</title>
<desc>
Created with Sketch.
</desc>
<defs></defs>
<g
id=
"Page-1"
stroke=
"none"
stroke-width=
"1"
fill=
"none"
fill-rule=
"evenodd"
sketch:type=
"MSPage"
>
<g
id=
"solidity"
sketch:type=
"MSLayerGroup"
transform=
"translate(402.000000, 118.000000)"
>
<g
id=
"Group"
sketch:type=
"MSShapeGroup"
>
<path
d=
"M470.6,-0.4 L326,256.6 L37,256.6 L181.5,-0.4 L470.6,-0.4"
id=
"Shape"
opacity=
"0.45"
fill=
"#000000"
></path>
<path
d=
"M326,256.6 L615.1,256.6 L470.6,-0.4 L181.5,-0.4 L326,256.6 Z"
id=
"Shape"
opacity=
"0.6"
fill=
"#000000"
></path>
<path
d=
"M181.5,513.5 L326,256.6 L181.5,-0.4 L37,256.6 L181.5,513.5 Z"
id=
"Shape"
opacity=
"0.8"
fill=
"#000000"
></path>
<path
d=
"M182.9,899 L327.5,642 L616.6,642 L472,899 L182.9,899"
id=
"Shape"
opacity=
"0.45"
fill=
"#000000"
></path>
<path
d=
"M327.5,642 L38.4,642 L182.9,899 L472,899 L327.5,642 Z"
id=
"Shape"
opacity=
"0.6"
fill=
"#000000"
></path>
<path
d=
"M472,385.1 L327.5,642 L472,899 L616.6,642 L472,385.1 Z"
id=
"Shape"
opacity=
"0.8"
fill=
"#000000"
></path>
<path
d=
"M9.3,1145 C9.3,1149.1 11,1152.1 14.3,1154.1 C17.6,1156.1 21.7,1157.8 26.6,1159.1 C31.5,1160.4 36.9,1161.6 42.7,1162.6 C48.5,1163.6 53.9,1165.1 58.8,1167 C63.7,1168.9 67.8,1171.6 71.1,1175 C74.4,1178.4 76.1,1183.1 76.1,1189 C76.1,1194 74.9,1198.3 72.6,1201.9 C70.3,1205.5 67.3,1208.5 63.7,1210.8 C60.1,1213.1 56.1,1214.9 51.6,1216.1 C47.2,1217.3 42.8,1217.9 38.6,1217.9 C34,1217.9 29.4,1217.4 24.9,1216.4 C20.4,1215.4 16.3,1213.8 12.7,1211.6 C9.1,1209.4 6.1,1206.5 3.8,1202.9 C1.5,1199.3 0.3,1194.8 0.3,1189.5 C0.3,1187.7 0.5,1186.1 1,1184.9 C1.5,1183.7 2.8,1183.1 5,1183.1 C6.1,1183.1 6.9,1183.6 7.4,1184.6 C7.9,1185.6 8.1,1186.6 8.1,1187.5 C8.1,1192.1 8.9,1195.9 10.6,1198.9 C12.3,1201.9 14.5,1204.2 17.4,1205.8 C20.3,1207.5 23.5,1208.6 27.2,1209.3 C30.9,1209.9 34.7,1210.3 38.6,1210.3 C41.7,1210.3 45.1,1209.9 48.6,1209.1 C52.1,1208.3 55.3,1207 58.2,1205.4 C61.1,1203.7 63.5,1201.6 65.4,1198.9 C67.3,1196.2 68.3,1193 68.3,1189.3 C68.3,1184.7 66.6,1181.1 63.3,1178.6 C60,1176.1 55.9,1174.1 51,1172.6 C46.1,1171.1 40.7,1169.9 34.9,1169 C29.1,1168.1 23.7,1166.7 18.8,1165 C13.9,1163.2 9.8,1160.9 6.5,1157.9 C3.2,1154.9 1.5,1150.8 1.5,1145.4 C1.5,1140.8 2.7,1136.9 5,1133.9 C7.3,1130.9 10.2,1128.5 13.7,1126.7 C17.2,1124.9 21,1123.7 25.2,1123.1 C29.4,1122.5 33.3,1122.1 37,1122.1 C41.4,1122.1 45.8,1122.6 50.2,1123.5 C54.5,1124.4 58.5,1125.9 62,1127.9 C65.5,1129.9 68.4,1132.7 70.6,1136.2 C72.8,1139.7 73.9,1144.1 73.9,1149.2 C73.9,1150.3 73.4,1151.2 72.5,1151.8 C71.6,1152.5 70.7,1152.8 69.7,1152.8 C68.4,1152.8 67.5,1152.3 66.9,1151.4 C66.3,1150.5 66.1,1149.6 66.1,1148.6 C65.4,1144.5 64,1141.3 62.1,1138.8 C60.2,1136.3 57.8,1134.4 55.2,1133.1 C52.5,1131.8 49.6,1130.9 46.5,1130.5 C43.4,1130 40.2,1129.8 37.1,1129.8 C34.5,1129.8 31.6,1130 28.5,1130.4 C25.4,1130.8 22.4,1131.5 19.5,1132.6 C16.6,1133.7 14.2,1135.2 12.3,1137.2 C10.3,1139 9.3,1141.7 9.3,1145 L9.3,1145 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M155.3,1120.9 C161.8,1120.9 167.8,1122.2 173.3,1124.9 C178.8,1127.6 183.6,1131.1 187.6,1135.6 C191.6,1140 194.7,1145.2 196.9,1151 C199.1,1156.8 200.2,1162.9 200.2,1169.2 C200.2,1175.5 199.1,1181.5 196.9,1187.4 C194.7,1193.2 191.6,1198.3 187.6,1202.8 C183.6,1207.2 178.9,1210.8 173.3,1213.5 C167.8,1216.2 161.8,1217.5 155.3,1217.5 C148.8,1217.5 142.9,1216.2 137.4,1213.5 C131.9,1210.8 127.2,1207.3 123.3,1202.8 C119.3,1198.4 116.2,1193.2 114,1187.4 C111.8,1181.6 110.7,1175.5 110.7,1169.2 C110.7,1162.9 111.8,1156.9 114,1151 C116.2,1145.2 119.3,1140.1 123.3,1135.6 C127.3,1131.2 132,1127.6 137.4,1124.9 C142.9,1122.2 148.8,1120.9 155.3,1120.9 L155.3,1120.9 Z M155.3,1209.5 C160.8,1209.5 165.9,1208.3 170.4,1206 C174.9,1203.7 178.8,1200.7 182,1197 C185.2,1193.3 187.7,1189 189.5,1184.1 C191.3,1179.2 192.1,1174.2 192.1,1169 C192.1,1163.8 191.2,1158.8 189.5,1154 C187.7,1149.2 185.2,1145 182,1141.3 C178.8,1137.6 174.9,1134.6 170.4,1132.3 C165.9,1130 160.8,1128.8 155.3,1128.8 C149.9,1128.8 145,1130 140.5,1132.3 C136,1134.6 132.1,1137.6 128.9,1141.3 C125.7,1145 123.1,1149.2 121.3,1154 C119.5,1158.8 118.5,1163.8 118.5,1169 C118.5,1174.2 119.4,1179.2 121.3,1184.1 C123.1,1189 125.7,1193.3 128.9,1197 C132.1,1200.7 136,1203.7 140.5,1206 C145,1208.4 149.9,1209.5 155.3,1209.5 L155.3,1209.5 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M240.8,1045.8 C241.9,1045.8 242.8,1046.2 243.6,1047 C244.3,1047.8 244.7,1048.7 244.7,1049.6 L244.7,1212 C244.7,1212.9 244.3,1213.8 243.6,1214.6 C242.9,1215.4 241.9,1215.8 240.8,1215.8 C239.7,1215.8 238.8,1215.4 238,1214.6 C237.3,1213.8 236.9,1212.9 236.9,1212 L236.9,1049.6 C236.9,1048.7 237.3,1047.8 238,1047 C238.7,1046.2 239.7,1045.8 240.8,1045.8 L240.8,1045.8 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M290.2,1096.5 C290.2,1098.2 289.6,1099.6 288.3,1100.8 C287,1102 285.5,1102.6 283.9,1102.6 C282.1,1102.6 280.5,1102 279.3,1100.8 C278.1,1099.6 277.5,1098.2 277.5,1096.5 C277.5,1094.7 278.1,1093.1 279.3,1091.9 C280.5,1090.7 282,1090.1 283.9,1090.1 C285.6,1090.1 287,1090.7 288.3,1091.9 C289.6,1093.1 290.2,1094.6 290.2,1096.5 L290.2,1096.5 Z M283.9,1123.6 C284.8,1123.6 285.7,1124 286.5,1124.8 C287.3,1125.6 287.7,1126.5 287.7,1127.4 L287.7,1211.6 C287.7,1212.5 287.3,1213.4 286.5,1214.2 C285.7,1215 284.8,1215.4 283.9,1215.4 C282.8,1215.4 281.9,1215 281.1,1214.2 C280.4,1213.4 280,1212.5 280,1211.6 L280,1127.4 C280,1126.5 280.4,1125.6 281.1,1124.8 C281.8,1124.1 282.8,1123.6 283.9,1123.6 L283.9,1123.6 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M410.2,1045.5 C411.3,1045.5 412.2,1045.9 413,1046.7 C413.7,1047.5 414.1,1048.4 414.1,1049.3 L414.1,1211.4 C414.1,1214 412.8,1215.3 410.2,1215.3 C407.6,1215.3 406.3,1214 406.3,1211.4 L406.3,1193.7 C402.4,1200.9 397.1,1206.7 390.2,1211.2 C383.4,1215.6 375.8,1217.9 367.5,1217.9 C361,1217.9 355.1,1216.6 349.6,1213.9 C344.1,1211.2 339.4,1207.7 335.5,1203.2 C331.5,1198.8 328.4,1193.6 326.2,1187.8 C324,1182 322.9,1175.9 322.9,1169.6 C322.9,1163.3 324,1157.3 326.2,1151.4 C328.4,1145.6 331.5,1140.5 335.5,1136 C339.5,1131.6 344.2,1128 349.6,1125.3 C355,1122.6 361,1121.3 367.5,1121.3 C375.8,1121.3 383.4,1123.6 390.2,1128.1 C397,1132.6 402.4,1138.5 406.3,1145.7 L406.3,1049.3 C406.3,1048.4 406.7,1047.5 407.4,1046.7 C408.2,1045.9 409.1,1045.5 410.2,1045.5 L410.2,1045.5 Z M367.5,1210.1 C373,1210.1 378.1,1208.9 382.6,1206.6 C387.1,1204.3 391,1201.3 394.2,1197.6 C397.4,1193.9 399.9,1189.6 401.7,1184.7 C403.5,1179.8 404.3,1174.8 404.3,1169.6 C404.3,1164.4 403.4,1159.4 401.7,1154.5 C399.9,1149.6 397.4,1145.3 394.2,1141.6 C391,1137.9 387.1,1134.9 382.6,1132.6 C378.1,1130.3 373,1129.1 367.5,1129.1 C362.1,1129.1 357.2,1130.3 352.7,1132.6 C348.2,1134.9 344.3,1137.9 341.1,1141.6 C337.9,1145.3 335.3,1149.6 333.5,1154.5 C331.7,1159.4 330.7,1164.4 330.7,1169.6 C330.7,1174.8 331.6,1179.8 333.5,1184.7 C335.3,1189.6 337.9,1193.9 341.1,1197.6 C344.3,1201.3 348.2,1204.3 352.7,1206.6 C357.2,1208.9 362.2,1210.1 367.5,1210.1 L367.5,1210.1 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M461.1,1096.5 C461.1,1098.2 460.5,1099.6 459.2,1100.8 C457.9,1102 456.4,1102.6 454.8,1102.6 C453,1102.6 451.4,1102 450.2,1100.8 C449,1099.6 448.4,1098.2 448.4,1096.5 C448.4,1094.7 449,1093.1 450.2,1091.9 C451.4,1090.7 452.9,1090.1 454.8,1090.1 C456.5,1090.1 457.9,1090.7 459.2,1091.9 C460.4,1093.1 461.1,1094.6 461.1,1096.5 L461.1,1096.5 Z M454.7,1123.6 C455.6,1123.6 456.5,1124 457.3,1124.8 C458.1,1125.6 458.5,1126.5 458.5,1127.4 L458.5,1211.6 C458.5,1212.5 458.1,1213.4 457.3,1214.2 C456.5,1215 455.6,1215.4 454.7,1215.4 C453.6,1215.4 452.7,1215 451.9,1214.2 C451.2,1213.4 450.8,1212.5 450.8,1211.6 L450.8,1127.4 C450.8,1126.5 451.2,1125.6 451.9,1124.8 C452.7,1124.1 453.6,1123.6 454.7,1123.6 L454.7,1123.6 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M542.2,1123.1 C543.3,1123.1 544.2,1123.5 545,1124.3 C545.7,1125.1 546.1,1126 546.1,1126.9 C546.1,1129.5 544.8,1130.8 542.2,1130.8 L521.4,1130.8 L521.4,1212.3 C521.4,1213.2 521,1214.1 520.3,1214.9 C519.6,1215.7 518.6,1216.1 517.5,1216.1 C516.4,1216.1 515.5,1215.7 514.7,1214.9 C514,1214.1 513.6,1213.2 513.6,1212.3 L513.6,1130.8 L493.6,1130.8 C491,1130.8 489.7,1129.5 489.7,1126.9 C489.7,1126 490.1,1125.1 490.8,1124.3 C491.5,1123.5 492.5,1123.1 493.6,1123.1 L513.6,1123.1 L513.6,1093.2 C513.6,1090.6 514.9,1089.3 517.5,1089.3 C520.1,1089.3 521.4,1090.6 521.4,1093.2 L521.4,1123.1 L542.2,1123.1 L542.2,1123.1 Z"
id=
"Shape"
fill=
"#010101"
></path>
<path
d=
"M649.7,1122.8 C652.3,1122.8 653.6,1124.1 653.6,1126.7 C653.6,1126.9 652.9,1128.9 651.4,1132.8 C649.9,1136.7 648,1141.7 645.7,1147.9 C643.4,1154.1 640.7,1161.2 637.7,1169.1 C634.7,1177 631.5,1185.2 628.1,1193.6 C624.8,1202 621.5,1210.3 618.4,1218.4 C615.3,1226.5 612.3,1234 609.7,1240.7 C607,1247.4 604.8,1253.2 602.9,1257.9 C601.1,1262.6 599.9,1265.6 599.3,1266.9 C598.4,1268.6 597.2,1269.4 595.7,1269.4 C594.8,1269.4 593.9,1269 593.1,1268.2 C592.3,1267.4 591.9,1266.5 591.9,1265.6 C591.9,1265.2 592.4,1263.8 593.3,1261.3 C594.2,1258.8 595.3,1255.8 596.6,1252.3 C597.9,1248.8 599.4,1245 601,1240.8 C602.7,1236.6 604.2,1232.7 605.7,1228.9 C607.2,1225.1 608.5,1221.8 609.6,1219.1 C610.7,1216.3 611.4,1214.5 611.8,1213.6 C611.6,1213.4 610.6,1211.2 608.8,1207 C607,1202.8 604.7,1197.4 602,1191.1 C599.3,1184.7 596.5,1177.8 593.5,1170.5 C590.5,1163.1 587.8,1156.2 585.2,1149.9 C582.6,1143.5 580.4,1138.2 578.7,1133.8 C576.9,1129.5 576.1,1127.2 576.1,1127 C576.1,1124.4 577.4,1123.1 580,1123.1 C581.8,1123.1 583,1123.8 583.6,1125.3 L615.7,1203.7 L646.2,1125.6 C646.6,1123.6 647.8,1122.8 649.7,1122.8 L649.7,1122.8 Z"
id=
"Shape"
fill=
"#010101"
></path>
</g>
</g>
</g>
</svg>
\ No newline at end of file
stylesheets/styles.css
View file @
b08b0204
...
...
@@ -8,7 +8,6 @@ body {
}
h1
,
h2
,
h3
,
h4
,
h5
,
h6
{
color
:
#222
;
margin
:
20px
0
10px
;
}
...
...
@@ -29,7 +28,6 @@ h2 {
}
h3
,
h4
,
h5
,
h6
{
color
:
#494949
;
}
a
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment