Merge branch 'develop' into batch-emails

# Conflicts:
#	backend/grant/proposal/models.py
This commit is contained in:
Aaron 2019-03-12 20:14:51 -05:00
commit eb4767d4cc
No known key found for this signature in database
GPG Key ID: 3B5B7597106F0A0E
30 changed files with 776 additions and 1171 deletions

119
DISCLOSURE.md Normal file
View File

@ -0,0 +1,119 @@
# Responsible Disclosure Policy
We greatly appreciate any and all disclosures of bugs and vulnerabilities that are done in a responsible manner. We will engage responsible disclosures according to this policy and put forth our best effort to fix disclosed vulnerabilities as well as reaching out to numerous node operators to deploy fixes in a timely manner.
## Responsible Disclosure Guidelines
Non-critical bugs can be repoted by creating an issue on [GitHub](https://github.com/grant-project/zcash-grant-system). Do not disclose critical bug or vulnerability on public forums, message boards, mailing lists, etc. prior to responsibly disclosing to the Zcash Foundation / Grant.io teams and giving sufficient time for the issue to be fixed and deployed.
## Reporting a Bug or Vulnerability
When reporting a bug or vulnerability, please provide the following to contact@grant.io and CC contact@zfnd.org.
* A short summary of the potential impact of the issue (if known).
* Details explaining how to reproduce the issue or how an exploit may be formed.
* Your name (optional). If provided, we will provide credit for disclosure. Otherwise, you will be treated anonymously and your privacy will be respected.
* Your email or other means of contacting you.
* A PGP key/fingerprint for us to provide encrypted responses to your disclosure. If this is not provided, we cannot guarantee that you will receive a response prior to a fix being made and deployed.
## Encrypting the Disclosure
We highly encourage all disclosures to be encrypted to prevent interception and exploitation by third-parties prior to a fix being developed and deployed. Please encrypt using the PGP public key with fingerprint: `46CD57E95AF395A1499C18A3F01C867EEB456C7A`
It may be obtained via:
```
gpg --recv-keys 46CD57E95AF395A1499C18A3F01C867EEB456C7A
```
Alternatively, it may be optained by copying the following into a file, and imported it via:
```
gpg --import <filename>
```
Signing example:
```
gpg --encrypt --sign --armor -r contact@grant.io <path/to/filename>
```
```
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: Keybase OpenPGP v2.1.0
Comment: https://keybase.io/crypto
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
=1KTe
-----END PGP PUBLIC KEY BLOCK-----
```
##### Inspired by [this](https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/DISCLOSURE_POLICY.md) dislosure policy

View File

@ -19,6 +19,7 @@ import RFPDetail from 'components/RFPDetail';
import Contributions from 'components/Contributions';
import ContributionForm from 'components/ContributionForm';
import ContributionDetail from 'components/ContributionDetail';
import Financials from 'components/Financials';
import Moderation from 'components/Moderation';
import Settings from 'components/Settings';
@ -54,6 +55,7 @@ class Routes extends React.Component<Props> {
<Route path="/contributions/:id/edit" component={ContributionForm} />
<Route path="/contributions/:id" component={ContributionDetail} />
<Route path="/contributions" component={Contributions} />
<Route path="/financials" component={Financials} />
<Route path="/emails/:type?" component={Emails} />
<Route path="/moderation" component={Moderation} />
<Route path="/settings/2fa-reset" render={() => <MFAuth isReset={true} />} />

View File

@ -0,0 +1,56 @@
.Financials {
&-zcash {
font-size: 0.8rem;
vertical-align: text-top;
display: inline-block;
padding-top: 0.15rem;
}
&-bottomLine {
& > div {
display: flex;
justify-content: space-between;
&.is-net {
margin-top: 0.5rem;
border-top: 1px solid rgba(0, 0, 0, 0.65);
padding-top: 0.5rem;
}
& .Info {
font-size: 0.9rem;
}
& > div + div {
font-family: 'Courier New', Courier, monospace;
min-width: 250px;
}
small {
display: inline-block;
padding-right: 0.1rem;
}
}
font-size: 1.2rem;
}
h1 {
font-size: 1.5rem;
}
.ant-card {
margin-bottom: 16px;
}
.antd-pro-charts-pie-total {
.pie-sub-title {
margin: 0;
}
}
.antd-pro-charts-pie-legend {
li {
margin-bottom: 0;
}
}
}

View File

@ -0,0 +1,138 @@
import React from 'react';
import { Spin, Card, Row, Col } from 'antd';
import { Charts } from 'ant-design-pro';
import { view } from 'react-easy-state';
import store from '../../store';
import Info from 'components/Info';
import './index.less';
class Financials extends React.Component {
componentDidMount() {
store.fetchFinancials();
}
render() {
const { contributions, grants, payouts } = store.financials;
if (!store.financialsFetched) {
return <Spin tip="Loading financials..." />;
}
return (
<div className="Financials">
<Row gutter={16}>
<Col span={12}>
<Card size="small" title="Contributions">
<Charts.Pie
hasLegend
title="Contributions"
subTitle="Total"
total={() => (
<span
dangerouslySetInnerHTML={{
__html: 'ⓩ ' + contributions.total,
}}
/>
)}
data={[
{ x: 'funded', y: parseFloat(contributions.funded) },
{ x: 'funding', y: parseFloat(contributions.funding) },
{ x: 'refunding', y: parseFloat(contributions.refunding) },
{ x: 'refunded', y: parseFloat(contributions.refunded) },
{ x: 'staking', y: parseFloat(contributions.staking) },
]}
valueFormat={val => <span dangerouslySetInnerHTML={{ __html: val }} />}
height={180}
/>
</Card>
<Card
size="small"
title={
<Info
content={
<>
<p>
Matching and bounty obligations for active and completed
proposals.
</p>
<b>matching</b> - total matching amount pleged
<br />
<b>bounties</b> - total bounty amount pledged
<br />
</>
}
>
Grants
</Info>
}
>
<Charts.Pie
hasLegend
title="Grants"
subTitle="Total"
total={() => (
<span
dangerouslySetInnerHTML={{
__html: 'ⓩ ' + grants.total,
}}
/>
)}
data={[
{ x: 'bounties', y: parseFloat(grants.bounty) },
{ x: 'matching', y: parseFloat(grants.matching) },
]}
valueFormat={val => <span dangerouslySetInnerHTML={{ __html: val }} />}
height={180}
/>
</Card>
<Card
size="small"
title={
<Info
content={
<>
<p>Milestone payouts.</p>
<b>due</b> - payouts currently accepted but not paid
<br />
<b>future</b> - payouts that are not yet paid, but expected to be
requested in the future
<br />
<b>paid</b> - total milestone payouts marked as paid, regardless of
proposal status
<br />
</>
}
>
Payouts
</Info>
}
>
<Charts.Pie
hasLegend
title="Payouts"
subTitle="Total"
total={() => (
<span
dangerouslySetInnerHTML={{
__html: 'ⓩ ' + payouts.total,
}}
/>
)}
data={[
{ x: 'due', y: parseFloat(payouts.due) },
{ x: 'future', y: parseFloat(payouts.future) },
{ x: 'paid', y: parseFloat(payouts.paid) },
]}
valueFormat={val => <span dangerouslySetInnerHTML={{ __html: val }} />}
height={180}
/>
</Card>
</Col>
</Row>
</div>
);
}
}
export default view(Financials);

View File

@ -63,6 +63,12 @@ class Template extends React.Component<Props> {
<span className="nav-text">Contributions</span>
</Link>
</Menu.Item>
<Menu.Item key="financials">
<Link to="/financials">
<Icon type="audit" />
<span className="nav-text">Financials</span>
</Link>
</Menu.Item>
<Menu.Item key="emails">
<Link to="/emails">
<Icon type="mail" />

View File

@ -74,6 +74,11 @@ async function fetchStats() {
return data;
}
async function fetchFinancials() {
const { data } = await api.get('/admin/financials');
return data;
}
async function fetchUsers(params: Partial<PageQuery>) {
const { data } = await api.get('/admin/users', { params });
return data;
@ -219,6 +224,31 @@ const app = store({
contributionRefundableCount: 0,
},
financialsFetched: false,
financialsFetching: false,
financials: {
grants: {
total: '0',
matching: '0',
bounty: '0',
},
contributions: {
total: '0',
gross: '0',
staking: '0',
funding: '0',
funded: '0',
refunding: '0',
refunded: '0',
},
payouts: {
total: '0',
due: '0',
paid: '0',
future: '0',
},
},
users: {
page: createDefaultPageData<User>('EMAIL:DESC'),
},
@ -346,6 +376,17 @@ const app = store({
app.statsFetching = false;
},
async fetchFinancials() {
app.financialsFetching = true;
try {
app.financials = await fetchFinancials();
app.financialsFetched = true;
} catch (e) {
handleApiError(e);
}
app.financialsFetching = false;
},
// Users
async fetchUsers() {

View File

@ -41,6 +41,16 @@ module.exports = {
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-proposal-class-properties',
['import', { libraryName: 'antd', style: true }],
[
'import',
{
libraryName: 'ant-design-pro',
libraryDirectory: 'lib',
style: true,
camel2DashComponentName: false,
},
'antdproimport',
],
],
presets: ['@babel/react', ['@babel/env', { useBuiltIns: 'entry' }]],
},

View File

@ -4,7 +4,7 @@ from functools import reduce
from flask import Blueprint, request
from marshmallow import fields, validate
from sqlalchemy import func, or_
from sqlalchemy import func, or_, text
import grant.utils.admin as admin
import grant.utils.auth as auth
@ -712,3 +712,99 @@ def edit_comment(comment_id, hidden, reported):
db.session.commit()
return admin_comment_schema.dump(comment)
# Financials
@blueprint.route("/financials", methods=["GET"])
@admin.admin_auth_required
def financials():
nfmt = '999999.99999999' # smallest unit of ZEC
def sql_pc(where: str):
return f"SELECT SUM(TO_NUMBER(amount, '{nfmt}')) FROM proposal_contribution WHERE {where}"
def sql_pc_p(where: str):
return f'''
SELECT SUM(TO_NUMBER(amount, '{nfmt}'))
FROM proposal_contribution as pc
INNER JOIN proposal as p ON pc.proposal_id = p.id
WHERE {where}
'''
def sql_ms(where: str):
return f'''
SELECT SUM(TO_NUMBER(ms.payout_percent, '999')/100 * TO_NUMBER(p.target, '999999.99999999'))
FROM milestone as ms
INNER JOIN proposal as p ON ms.proposal_id = p.id
WHERE {where}
'''
def ex(sql: str):
res = db.engine.execute(text(sql))
return [row[0] if row[0] else Decimal(0) for row in res][0].normalize()
contributions = {
'total': str(ex(sql_pc("status = 'CONFIRMED' AND staking = FALSE"))),
'staking': str(ex(sql_pc("status = 'CONFIRMED' AND staking = TRUE"))),
'funding': str(ex(sql_pc_p("pc.status = 'CONFIRMED' AND pc.staking = FALSE AND p.stage = 'FUNDING_REQUIRED'"))),
'funded': str(ex(sql_pc_p("pc.status = 'CONFIRMED' AND pc.staking = FALSE AND p.stage in ('WIP', 'COMPLETED')"))),
'refunding': str(ex(sql_pc_p(
"pc.status = 'CONFIRMED' AND pc.staking = FALSE AND pc.refund_tx_id IS NULL AND p.stage IN ('CANCELED', 'FAILED')"
))),
'refunded': str(ex(sql_pc_p(
"pc.status = 'CONFIRMED' AND pc.staking = FALSE AND pc.refund_tx_id IS NOT NULL AND p.stage IN ('CANCELED', 'FAILED')"
))),
'gross': str(ex(sql_pc_p("pc.status = 'CONFIRMED' AND pc.refund_tx_id IS NULL"))),
}
po_due = ex(sql_ms("ms.stage = 'ACCEPTED'")) # payments accepted but not yet marked as paid
po_paid = ex(sql_ms("ms.stage = 'PAID'")) # will catch paid ms from all proposals regardless of status/stage
# expected payments
po_future = ex(sql_ms("ms.stage IN ('IDLE', 'REJECTED', 'REQUESTED') AND p.stage IN ('WIP', 'COMPLETED')"))
po_total = po_due + po_paid + po_future
payouts = {
'total': str(po_total),
'due': str(po_due),
'paid': str(po_paid),
'future': str(po_future),
}
grants = {
'total': '0',
'matching': '0',
'bounty': '0',
}
def add_str_dec(a: str, b: str):
return str(Decimal(a) + Decimal(b))
proposals = Proposal.query.all()
for p in proposals:
# CANCELED proposals excluded, though they could have had milestones paid out with grant funds
if p.stage in [ProposalStage.WIP, ProposalStage.COMPLETED]:
# matching
matching = Decimal(p.contributed) * Decimal(p.contribution_matching)
remaining = Decimal(p.target) - Decimal(p.contributed)
if matching > remaining:
matching = remaining
# bounty
bounty = Decimal(p.contribution_bounty)
remaining = Decimal(p.target) - (matching + Decimal(p.contributed))
if bounty > remaining:
bounty = remaining
grants['matching'] = add_str_dec(grants['matching'], matching)
grants['bounty'] = add_str_dec(grants['bounty'], bounty)
grants['total'] = add_str_dec(grants['total'], matching + bounty)
return {
'grants': grants,
'contributions': contributions,
'payouts': payouts,
'net': str(Decimal(contributions['gross']) - Decimal(payouts['paid']))
}

View File

@ -48,6 +48,10 @@ def create_app(config_objects=["grant.settings"]):
return jsonify({"message": error_message}), err.code, headers
else:
return jsonify({"message": error_message}), err.code
@app.errorhandler(Exception)
def handle_exception(err):
return jsonify({"message": "Something went wrong"}), 500
for conf in config_objects:
app.config.from_object(conf)

View File

@ -286,7 +286,11 @@ class Proposal(db.Model):
raise ValidationException("Proposal must have a {}".format(field))
# Check with node that the address is kosher
res = blockchain_get('/validate/address', {'address': self.payout_address})
try:
res = blockchain_get('/validate/address', {'address': self.payout_address})
except:
raise ValidationException(
"Could not validate your payout address due to an internal server error, please try again later")
if not res['valid']:
raise ValidationException("Payout address is not a valid Zcash address")

View File

@ -463,15 +463,15 @@ def get_proposal_contributions(proposal_id):
@blueprint.route("/<proposal_id>/contributions/<contribution_id>", methods=["GET"])
def get_proposal_contribution(proposal_id, contribution_id):
proposal = Proposal.query.filter_by(id=proposal_id).first()
if proposal:
contribution = ProposalContribution.query.filter_by(id=contribution_id).first()
if contribution:
return proposal_contribution_schema.dump(contribution)
else:
return {"message": "No contribution matching id"}
else:
if not proposal:
return {"message": "No proposal matching id"}, 404
contribution = ProposalContribution.query.filter_by(id=contribution_id).first()
if not contribution:
return {"message": "No contribution matching id"}, 404
return proposal_contribution_schema.dump(contribution)
@blueprint.route("/<proposal_id>/contributions", methods=["POST"])
# TODO add gaurd (minimum, maximum)

View File

@ -342,7 +342,7 @@ def get_user_settings(user_id):
@auth.requires_same_user_auth
# TODO guard all (shape, validity)
@body({
"emailSubscriptions": fields.Dict(required=True),
"emailSubscriptions": fields.Dict(required=False, missing=None),
"refundAddress": fields.Str(required=False, missing=None)
})
def set_user_settings(user_id, email_subscriptions, refund_address):

View File

@ -1,6 +1,7 @@
import React from 'react';
import { Helmet } from 'react-helmet';
import { RouteComponentProps, withRouter } from 'react-router';
import { withNamespaces, WithNamespaces } from 'react-i18next';
import ogpLogo from 'static/images/ogp-logo.png';
import { urlToPublic } from 'utils/helpers';
@ -8,17 +9,22 @@ interface OwnProps {
title: string;
}
type Props = OwnProps & RouteComponentProps<any>;
type Props = OwnProps & RouteComponentProps<any> & WithNamespaces;
class BasicHead extends React.Component<Props> {
render() {
const { children, title } = this.props;
const { children, title, t } = this.props;
const defaultOgpUrl = process.env.PUBLIC_HOST_URL + this.props.location.pathname;
const defaultOgpImage = urlToPublic(ogpLogo);
return (
<div>
<Helmet>
<title>{`ZF Grants - ${title}`}</title>
<meta name="description" content={t('site.description')} />
<meta
name="keywords"
content="Zcash, Zcash Foundation, Zcash Foundation Grants, Zcash Grants, Zcash Grant, ZF Grants, ZFGrants"
/>
<meta name={`${title} page`} content={`${title} page stuff`} />
<link
rel="stylesheet"
@ -30,6 +36,7 @@ class BasicHead extends React.Component<Props> {
{/* open graph protocol defaults, can be overridden in children <HeaderDetails ...> */}
<meta property="og:site_name" content="ZF Grants" />
<meta property="og:title" content={`ZF Grants - ${title}`} />
<meta property="og:description" content={t('site.description')} />
<meta property="og:type" content="website" />
<meta property="og:url" content={defaultOgpUrl} />
<meta property="og:image" content={defaultOgpImage} />
@ -40,8 +47,9 @@ class BasicHead extends React.Component<Props> {
{/* twitter defaults, can be overridden in children <HeaderDetails ...> */}
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:site" content="@io_grant" />
<meta property="twitter:site" content="@zcashfoundation" />
<meta property="twitter:title" content={`ZF Grants - ${title}`} />
<meta property="twitter:description" content={t('site.description')} />
<meta property="twitter:image" content={defaultOgpImage} />
<meta property="twitter:url" content={defaultOgpUrl} />
</Helmet>
@ -51,4 +59,4 @@ class BasicHead extends React.Component<Props> {
}
}
export default withRouter(BasicHead);
export default withNamespaces()(withRouter(BasicHead));

View File

@ -113,7 +113,7 @@ export default class PaymentInfo extends React.Component<Props, State> {
} else {
text = `
Thank you for contributing! Just send using whichever method works best for
you, and we'll let you know once it's been confirmed.
you, and we'll let you know once it's been processed with 6 confirmations.
`;
}
}

View File

@ -66,11 +66,13 @@ export default class ContributionModal extends React.Component<Props, State> {
if (contribution !== this.props.contribution) {
this.setState({ contribution: contribution || null });
}
// When the modal is closed, clear out the contribution and anonymous check
// When the modal is closed, clear out the contribution, error, and anonymous check
if (this.props.isVisible && !isVisible) {
this.setState({
contribution: null,
hasConfirmedAnonymous: false,
hasSent: false,
error: null,
});
}
}
@ -89,19 +91,23 @@ export default class ContributionModal extends React.Component<Props, State> {
<Alert
className="PaymentInfo-anonymous"
type="warning"
message="This contribution is anonymous"
message="This contribution will not be attributed"
description={
<>
You are about to contribute anonymously. Your contribution will show up
without attribution, and even if you're logged in, will not appear anywhere
on your account after you close this modal.
Your contribution will show up without attribution. Even if you're logged
in, the contribution will not appear anywhere on your account after you
close this modal.
<br /> <br />
In the case of a refund, your contribution will be treated as a donation to
the Zcash Foundation instead.
ZF Grants is unable to offer refunds for non-attributed contributions. If
refunds for this campaign are issued, your contribution will be treated as a
donation to the Zcash Foundation.
<br /> <br />
If you would like to have your contribution attached to an account, you can
close this modal, make sure you're logged in, and don't check the
"Contribute anonymously" checkbox.
If you would like to have your contribution attached to an account and
remain eligible for refunds, you can close this modal, make sure you're
logged in, and don't check the "Contribute without attribution" checkbox.
<br /> <br />
NOTE: The Zcash Foundation is unable to accept donations of more than $5,000
USD worth of ZEC from anonymous users.
</>
}
/>
@ -133,7 +139,16 @@ export default class ContributionModal extends React.Component<Props, State> {
if (error) {
okText = 'Done';
onOk = handleClose;
content = error;
content = (
<Result
type="error"
title="Something went wrong"
description={`
We were unable to get your contribution started. Please check back
soon, we're working to fix the problem as soon as possible.
`}
/>
);
} else {
okText = 'Ive sent it';
onOk = this.confirmSend;

View File

@ -2,6 +2,7 @@ import React from 'react';
import { connect } from 'react-redux';
import { Icon } from 'antd';
import { Link } from 'react-router-dom';
import Result from 'ant-design-pro/lib/Result';
import Loader from 'components/Loader';
import { createActions } from 'modules/create';
import { AppState } from 'store/reducers';
@ -28,6 +29,7 @@ type Props = OwnProps & StateProps & DispatchProps;
const STATE = {
contribution: null as null | ContributionWithAddresses,
contributionError: null as null | Error,
};
type State = typeof STATE;
@ -49,7 +51,7 @@ class CreateFinal extends React.Component<Props, State> {
render() {
const { submittedProposal, submitError, goBack } = this.props;
const { contribution } = this.state;
const { contribution, contributionError } = this.state;
const ready = submittedProposal && (submittedProposal.isStaked || contribution);
const staked = submittedProposal && submittedProposal.isStaked;
@ -100,8 +102,8 @@ class CreateFinal extends React.Component<Props, State> {
<Link to={`/profile?tab=funded`}>profile's funded tab</Link>.
</p>
<p>
Once your payment has been sent and confirmed, you will receive an
email. Visit your{' '}
Once your payment has been sent and processed with 6
confirmations, you will receive an email. Visit your{' '}
<Link to={`/profile?tab=pending`}>
profile's pending proposals tab
</Link>{' '}
@ -120,6 +122,20 @@ class CreateFinal extends React.Component<Props, State> {
)}
</>
);
} else if (contributionError) {
content = (
<Result
type="error"
title="Something went wrong"
description={
<>
We were unable to get your staking contribution started. You can finish
staking from <Link to="/profile?tab=pending">your profile</Link>, please try
again from there soon.
</>
}
/>
);
} else {
content = <Loader size="large" tip="Submitting your proposal..." />;
}
@ -136,8 +152,12 @@ class CreateFinal extends React.Component<Props, State> {
private getStakingContribution = async () => {
const { submittedProposal } = this.props;
if (submittedProposal) {
const res = await getProposalStakingContribution(submittedProposal.proposalId);
this.setState({ contribution: res.data });
try {
const res = await getProposalStakingContribution(submittedProposal.proposalId);
this.setState({ contribution: res.data });
} catch (err) {
this.setState({ contributionError: err });
}
}
};
}

View File

@ -231,9 +231,11 @@ class CreateFlow extends React.Component<Props, State> {
</>
)}
<button className="CreateFlow-footer-example" onClick={this.fillInExample}>
<Icon type="fast-forward" />
</button>
{process.env.NODE_ENV !== 'production' && (
<button className="CreateFlow-footer-example" onClick={this.fillInExample}>
<Icon type="fast-forward" />
</button>
)}
</div>
)}
{isSavingDraft && (

View File

@ -1,11 +1,12 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { Icon } from 'antd';
import { withNamespaces, WithNamespaces } from 'react-i18next';
import ZFGrantsLogo from 'static/images/logo-name-light.svg';
import GrantIoLogo from 'static/images/grantio-logo-name.svg';
import './style.less';
export default () => (
const Footer: React.SFC<WithNamespaces> = ({ t }) => (
<footer className="Footer">
<div className="Footer-attribution">
<div className="Footer-attribution-copyright">
@ -23,13 +24,13 @@ export default () => (
<Link className="Footer-main-title" to="/">
<ZFGrantsLogo className="Footer-main-title-logo" />
</Link>
<p className="Footer-main-about">
ZF Grants is an open-source, community driven platform that helps
creators get funding to build a better Zcash. ZF Grants is owned
and operated by the Zcash Foundation.
</p>
<p className="Footer-main-about">{t('site.description')}</p>
<div className="Footer-main-links">
<a href="https://www.zfnd.org/about/" className="Footer-main-links-link" target="_blank">
<a
href="https://www.zfnd.org/about/"
className="Footer-main-links-link"
target="_blank"
>
About
</a>
<Link to="/contact" className="Footer-main-links-link">
@ -47,12 +48,24 @@ export default () => (
</div>
</div>
<div className="Footer-social">
<a className="Footer-social-link" href="https://twitter.com/zcashfoundation" target="_blank" rel="noopener nofollow">
<a
className="Footer-social-link"
href="https://twitter.com/zcashfoundation"
target="_blank"
rel="noopener nofollow"
>
@zcashfoundation <Icon type="twitter" />
</a>
<a className="Footer-social-link" href="https://github.com/zcashfoundation" target="_blank" rel="noopener nofollow">
<a
className="Footer-social-link"
href="https://github.com/zcashfoundation"
target="_blank"
rel="noopener nofollow"
>
zcashfoundation <Icon type="github" />
</a>
</div>
</footer>
);
export default withNamespaces()(Footer);

View File

@ -39,7 +39,7 @@
&-title {
margin-bottom: 1.25rem;
opacity: 0.8;
opacity: 0.7;
transition: transform 100ms ease, opacity 100ms ease;
&:hover,
@ -51,9 +51,9 @@
}
&-logo {
height: 6.8rem;
margin-bottom: 0.5rem;
margin-top: -1.25rem;
height: 3.4rem;
margin-bottom: 0.75rem;
margin-top: -0.75rem;
}
}

View File

@ -1,5 +1,5 @@
@import '~styles/variables.less';
@header-height: 68px;
@header-height: 64px;
@header-transition: 200ms;
@link-padding: 0.7rem;
@small-query: ~'(max-width: 820px)';
@ -44,22 +44,22 @@
transition: transform 100ms ease, opacity 100ms ease;
flex-grow: 1;
text-align: center;
opacity: 0.8;
opacity: 0.7;
&:hover,
&:focus {
color: inherit;
transform: translateY(-2px) translate(-50%, -50%);
opacity: 0.9;
}
&-logo {
height: 3.6rem;
height: 2rem;
width: auto;
transform: translateY(-7%);
transition: transform @header-transition ease;
.is-transparent & {
transform: scale(1.4) translateY(20%);
transform: scale(1.4) translateY(18%);
}
}
}

View File

@ -8,6 +8,7 @@ import { formatTxExplorerUrl } from 'utils/formatters';
import { deleteContribution } from 'modules/users/actions';
import { UserContribution } from 'types';
import './ProfileContribution.less';
import { PROPOSAL_STAGE } from 'api/constants';
interface OwnProps {
userId: number;
@ -26,7 +27,10 @@ class ProfileContribution extends React.Component<Props> {
const { contribution } = this.props;
const { proposal } = contribution;
const isConfirmed = contribution.status === 'CONFIRMED';
const isExpired = !isConfirmed && contribution.dateCreated < Date.now() / 1000 - ONE_DAY;
const isExpired =
(!isConfirmed && contribution.dateCreated < Date.now() / 1000 - ONE_DAY) ||
(proposal.stage === PROPOSAL_STAGE.CANCELED ||
proposal.stage === PROPOSAL_STAGE.FAILED);
let tag;
let actions: React.ReactNode;
@ -43,15 +47,14 @@ class ProfileContribution extends React.Component<Props> {
} else if (isExpired) {
tag = <Tag color="red">Expired</Tag>;
// TODO: Link to support
actions = <>
<Popconfirm
title="Are you sure?"
onConfirm={this.deleteContribution}
>
<a>Delete</a>
</Popconfirm>
<Link to="/support">Contact support</Link>
</>;
actions = (
<>
<Popconfirm title="Are you sure?" onConfirm={this.deleteContribution}>
<a>Delete</a>
</Popconfirm>
<Link to="/support">Contact support</Link>
</>
);
} else {
tag = <Tag color="orange">Pending</Tag>;
actions = (
@ -76,9 +79,7 @@ class ProfileContribution extends React.Component<Props> {
<div className="ProfileContribution-state-amount">
+<UnitDisplay value={contribution.amount} symbol="ZEC" />
</div>
<div className="ProfileContribution-state-actions">
{actions}
</div>
<div className="ProfileContribution-state-actions">{actions}</div>
</div>
</div>
);
@ -89,6 +90,9 @@ class ProfileContribution extends React.Component<Props> {
};
}
export default connect<{}, DispatchProps, OwnProps, {}>(undefined, {
deleteContribution,
})(ProfileContribution);
export default connect<{}, DispatchProps, OwnProps, {}>(
undefined,
{
deleteContribution,
},
)(ProfileContribution);

View File

@ -143,8 +143,8 @@ class ProfilePending extends React.Component<Props, State> {
<p>
Please send the staking contribution of{' '}
<b>{stakeContribution && stakeContribution.amount} ZEC</b> using the
instructions below. Once your payment has been sent and confirmed, you
will receive an email.
instructions below. Once your payment has been sent and received 6
confirmations, you will receive an email.
</p>
}
/>
@ -194,7 +194,8 @@ class ProfilePending extends React.Component<Props, State> {
this.setState({ isLoadingStake: false });
});
} catch (err) {
message.error(err.message, 3);
console.error(err);
message.error('Failed to get staking contribution, try again later', 3);
this.setState({ isLoadingStake: false });
}
};

View File

@ -191,8 +191,8 @@ export class ProposalCampaignBlock extends React.Component<Props, State> {
{amountToRaise &&
!!authUser && (
<Checkbox checked={isAnonymous} onChange={this.handleChangeAnonymity}>
Contribute anonymously
<Tooltip title="Contribute with no attribution to your account. This will make you ineligible for refunds.">
Contribute without attribution
<Tooltip title="Your contribution will not be linked to your account. ZF Grants cannot refund non-attributed contributions.">
<Icon type="question-circle" />
</Tooltip>
</Checkbox>

View File

@ -1,8 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 266 45" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polygon fill="#FFFFFF" points="39 45 0 45 0 38.7138616 24.152269 8.73001057 1.84706215 8.73001057 1.84706215 1 37.4067709 1 37.4067709 7.34749556 13.0638763 37.2689998 39 37.2689998"></polygon>
<path d="M67,1.24923059 C64.2456536,3.27874037 61.8906957,5.81889405 60.0748075,8.73001057 L46.9989843,8.73001057 L46.9989843,19.5427228 L56.2192795,19.5427228 C56.0745901,20.6747333 56,21.8286559 56,23 C56,24.4542938 56.1149784,25.881733 56.3363408,27.273723 L46.9989843,27.273723 L46.9989843,45 L37,45 L37,1 L67,1 L67,1.24923059 Z" fill="#CF8900"></path>
<path d="M60,22.5 C60,16.2049861 62.2021991,10.9072022 66.5436775,6.54432133 C70.8851558,2.18144044 76.6737935,0 83.7837508,0 C89.3207086,0 94.6059866,1.86980609 99.6395846,5.60941828 L94.7947465,12.7770083 C91.1453879,10.0969529 87.5589493,8.78808864 84.0983506,8.85041551 C73.4019548,8.85041551 69.7525962,16.3296399 69.7525962,22.6246537 C69.7525962,26.5512465 71.0109957,29.7922438 73.5907147,32.3476454 C76.1075137,34.9030471 79.3793525,36.1495845 83.3433109,36.1495845 C86.5522297,36.1495845 89.2577886,35.5886427 91.4599878,34.5290859 L91.4599878,28.2963989 L80.3231521,28.2963989 L80.3231521,20.567867 L100.583384,20.567867 L100.583384,38.3310249 C95.5497862,42.7562327 89.8240684,45 83.4062309,45 C76.7367135,45 71.1997557,42.8185596 66.7324374,38.3933518 C62.2651191,34.0304709 60,28.732687 60,22.5 Z M107.756261,12.3407202 L116.879658,12.3407202 L116.879658,19.3213296 C118.012217,13.7119114 122.857056,11.468144 125.751374,11.6551247 C126.443494,11.6551247 127.261454,11.7174515 128.142334,11.9044321 L128.142334,21.066482 C126.946854,20.7548476 125.625535,20.6301939 124.178375,20.6301939 C120.340257,20.6301939 117.131338,22.9362881 117.131338,26.9252078 L117.131338,44.3144044 L107.756261,44.3144044 L107.756261,12.3407202 Z M140.474649,28.234072 C140.474649,33.4695291 143.746487,37.4584488 148.780086,37.4584488 C153.624924,37.4584488 157.211362,34.2797784 157.211362,28.732687 C157.211362,22.9362881 153.750764,19.1966759 148.528406,19.1966759 C143.557728,19.1966759 140.474649,23.0609418 140.474649,28.234072 Z M156.959682,16.7036011 L156.959682,12.3407202 L166.334759,12.3407202 L166.334759,44.3144044 L156.959682,44.3144044 L156.959682,39.6398892 C154.442883,43.1925208 151.045205,45 146.829566,45 C142.047648,45 138.20953,43.3795014 135.378131,40.200831 C132.546732,37.0221607 131.099572,32.9709141 131.099572,28.1717452 C131.099572,23.4972299 132.483812,19.5706371 135.252291,16.3919668 C137.95785,13.2132964 141.795968,11.6551247 146.640806,11.6551247 C150.856445,11.6551247 154.694563,13.6495845 156.959682,16.7036011 Z M183.763592,44.3144044 L174.388516,44.3144044 L174.388516,12.3407202 L183.763592,12.3407202 L183.763592,16.7036011 C186.217471,13.3379501 189.55223,11.6551247 193.767868,11.6551247 C201.444105,11.6551247 205.282224,16.765928 205.282224,26.9252078 L205.282224,44.3144044 L195.907147,44.3144044 L195.907147,27.1121884 C195.907147,21.9390582 193.893708,19.3213296 189.92975,19.3213296 C185.839951,19.3213296 183.763592,22.4376731 183.763592,27.1745152 L183.763592,44.3144044 Z M217.299939,4.48753463 L224.535736,4.48753463 L224.535736,12.3407202 L233.470373,12.3407202 L233.470373,19.632964 L224.535736,19.632964 L224.535736,34.5914127 C224.535736,36.4612188 225.353696,37.3961219 226.926695,37.3961219 C228.562615,37.3961219 229.380574,36.398892 229.380574,34.4044321 C229.380574,33.3448753 229.254734,32.4722992 228.940134,31.6620499 L236.364692,31.6620499 C236.868051,32.7216066 237.119731,33.968144 237.119731,35.4639889 C237.119731,40.699446 233.470373,45 226.360415,45 C218.872938,45 215.16066,41.2603878 215.16066,33.7188366 L215.16066,19.632964 L210.315822,19.632964 L210.315822,12.3407202 L215.852779,12.3407202 L217.299939,4.48753463 Z M239.25901,36.8351801 L246.054368,33.033241 C246.872327,36.3365651 249.829566,37.83241 252.849725,37.83241 C255.114844,37.83241 257.065363,36.8975069 257.065363,35.401662 C257.065363,34.3421053 256.247404,33.531856 254.674404,32.9709141 L249.011607,30.6024931 C245.488088,29.3559557 243.034209,27.4238227 242.090409,25.4916898 C241.14661,23.5595568 240.95785,22.5 240.95785,21.4404432 C240.95785,18.3864266 242.153329,15.9556787 244.544288,14.2105263 C246.935247,12.5277008 249.955406,11.6551247 253.604765,11.6551247 C259.015883,11.6551247 262.916921,13.898892 265.24496,18.3864266 L258.009163,21.6897507 C257.317043,19.632964 255.806964,18.6357341 253.416005,18.6357341 C251.591326,18.6357341 249.829566,19.6952909 249.829566,21.2534626 C249.829566,22.3130194 250.836286,23.2479224 252.849725,23.9958449 L257.694563,25.865651 C261.218082,26.8628809 263.734881,28.6080332 264.7416,30.5401662 C265.74832,32.4722992 266,33.6565097 266,35.0900277 C266,38.2063712 264.7416,40.6371191 262.224801,42.3822715 C259.708002,44.1274238 256.562004,45 252.786805,45 C249.829566,45 247.061087,44.3767313 244.544288,43.1301939 C242.027489,41.9459834 240.26573,39.8268698 239.25901,36.8351801 Z" fill="#FFFFFF"></path>
<svg viewBox="0 0 656 139" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="logo-name" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-34" transform="translate(0.000000, 0.089000)">
<path d="M167.865968,133.056065 C169.773318,134.793804 171.796751,136.45683 173.948397,138.056065 L0.2132,138.056065 L0.2132,133.056065 L167.865968,133.056065 Z M215.555918,133.056065 L655.2132,133.056065 L655.2132,138.056065 L209.490433,138.056065 C211.125673,136.825903 212.710759,135.54063 214.242902,134.20267 L215.555918,133.056065 Z" id="Combined-Shape" fill="#CF8A00"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Stroke-4" fill="#FF0000"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Fill-2" fill="#000000"></path>
<polygon id="Fill-6" fill="#FFFFFF" points="76.1546 121.355 0.2136 121.355 0.2136 108.946 47.2426 49.756 3.8116 49.756 3.8116 34.494 73.0516 34.494 73.0516 47.027 25.6506 106.092 76.1546 106.092"></polygon>
<polygon id="Fill-8" fill="#CF8A00" points="72.9431 121.355 72.9431 34.494 130.6431 34.494 130.6431 49.756 92.1761 49.756 92.1761 71.099 125.5551 71.099 125.5551 86.363 92.1761 86.363 92.1761 121.355"></polygon>
<path d="M299.3211,33.9009 C312.3591,33.9009 321.4611,38.3299 330.3171,44.9709 L320.8461,59.1169 C316.1721,55.6719 308.4231,51.2449 299.9361,51.3679 C279.0261,51.3679 271.8921,66.1279 271.8921,78.5499 C271.8921,94.0479 282.8391,105.2419 298.4601,105.2419 C303.7491,105.2419 309.7761,104.2579 314.3271,102.0439 L314.3271,89.7439 L292.5561,89.7439 L292.5561,74.4919 L332.1621,74.4919 L332.1621,109.5469 C319.3701,120.9859 306.4551,122.7079 298.5831,122.7079 C272.1381,122.7079 252.8261,102.6589 252.8261,78.3039 C252.8261,54.3199 270.5391,33.9009 299.3211,33.9009" id="Fill-10" fill="#FFFFFF"></path>
<path d="M364.0174,72.0317 C366.1094,60.5927 375.8264,56.9027 381.3614,56.9027 C383.4524,56.9027 384.0674,57.0257 386.0354,57.3937 L386.0354,75.4747 C383.4524,74.8607 380.1304,74.6147 378.2864,74.6147 C371.3984,74.6147 364.5094,78.6737 364.5094,87.0377 L364.5094,121.3547 L346.1824,121.3547 L346.1824,58.2557 L364.0174,58.2557 L364.0174,72.0317 Z" id="Fill-12" fill="#FFFFFF"></path>
<path d="M425.8855,107.8247 C434.8645,107.8247 442.3675,102.0437 442.3675,90.6047 C442.3675,78.9197 435.3565,71.7857 425.3935,71.7857 C415.3075,71.7857 409.6495,79.9037 409.6495,89.6207 C409.6495,99.7067 415.7995,107.8247 425.8855,107.8247 L425.8855,107.8247 Z M460.2025,58.2557 L460.2025,121.3547 L441.8755,121.3547 L441.8755,112.1307 C437.3245,118.6487 431.2975,122.7077 422.0725,122.7077 C402.8845,122.7077 391.3225,107.9477 391.3225,89.4977 C391.3225,71.7857 402.0235,56.9027 421.7035,56.9027 C430.1905,56.9027 437.5715,61.0847 441.8755,66.8657 L441.8755,58.2557 L460.2025,58.2557 Z" id="Fill-14" fill="#FFFFFF"></path>
<path d="M475.9451,58.2554 L494.2721,58.2554 L494.2721,66.8654 C499.5611,59.4854 506.2031,56.9024 513.8291,56.9024 C531.5421,56.9024 536.3391,71.0474 536.3391,87.0374 L536.3391,121.3554 L518.0111,121.3554 L518.0111,87.4064 C518.0111,78.6734 514.8131,72.0314 506.3261,72.0314 C497.8391,72.0314 494.2721,78.7964 494.2721,87.5294 L494.2721,121.3554 L475.9451,121.3554 L475.9451,58.2554 Z" id="Fill-16" fill="#FFFFFF"></path>
<path d="M573.2371,58.2554 L590.7031,58.2554 L590.7031,72.6474 L573.2371,72.6474 L573.2371,102.1664 C573.2371,104.8724 574.3441,107.7014 577.9111,107.7014 C581.4781,107.7014 582.7091,104.7494 582.7091,101.7974 C582.7091,99.9524 582.2161,97.3694 581.8471,96.3864 L596.3611,96.3864 C597.4681,98.7234 597.8381,101.6754 597.8381,103.8894 C597.8381,113.2364 591.6871,122.7074 576.8041,122.7074 C565.7341,122.7074 554.9101,118.7724 554.9101,100.4444 L554.9101,72.6474 L545.4391,72.6474 L545.4391,58.2554 L556.2631,58.2554 L559.0921,42.7574 L573.2371,42.7574 L573.2371,58.2554 Z" id="Fill-18" fill="#FFFFFF"></path>
<path d="M615.3025,99.0913 C617.1475,106.3493 623.5435,108.5633 628.5865,108.5633 C632.6455,108.5633 636.8275,106.9633 636.8275,103.7663 C636.8275,101.6753 635.5975,100.1983 632.1545,98.9693 L621.0835,94.2943 C606.0775,89.0053 605.3395,79.0423 605.3395,76.2133 C605.3395,63.5443 616.5325,56.9033 630.0625,56.9033 C637.3205,56.9033 646.9135,58.8703 652.8185,70.1873 L638.6725,76.7053 C637.0735,71.6623 632.5225,70.6783 629.6945,70.6783 C626.2495,70.6783 622.6825,72.6473 622.6825,75.8443 C622.6825,78.5503 625.3885,80.0273 628.5865,81.2563 L638.0575,84.9463 C652.9415,89.2513 654.2935,98.9693 654.2935,103.1513 C654.2935,116.0663 642.3635,122.7073 628.4635,122.7073 C619.1155,122.7073 606.3235,119.7563 602.0185,106.5953 L615.3025,99.0913 Z" id="Fill-20" fill="#FFFFFF"></path>
<path d="M162.7156,43.8618 C164.2086,43.0068 165.7466,42.0428 167.2336,41.1108 C169.2056,39.8748 171.2456,38.6038 173.4316,37.3958 L173.4756,31.9548 C173.5176,26.7528 175.4906,21.8898 179.0326,18.2648 C182.5106,14.7058 187.1146,12.7928 191.9376,12.8108 C202.0356,12.8988 210.1806,21.6348 210.0946,32.2838 L210.0536,37.4068 C212.0626,38.5688 214.1476,39.8348 216.3656,41.2488 C218.4956,42.6068 220.4006,43.7758 222.2136,44.6918 L222.3126,32.3828 C222.4536,15.0008 208.8746,0.7388 192.0446,0.5928 C183.7956,0.4918 176.1176,3.7638 170.2936,9.7248 C164.5346,15.6208 161.3246,23.4798 161.2576,31.8558 L161.1556,44.4878 L161.5816,44.4918 C161.9516,44.2918 162.3276,44.0838 162.7156,43.8618" id="Fill-22" fill="#FFFFFF"></path>
<path d="M227.9856,53.604 C222.9546,53.195 218.7026,50.904 213.8736,47.875 L213.8736,55.496 C218.1106,57.9 222.3716,59.698 227.3756,60.082 C227.4276,60.129 227.6316,60.457 227.5926,61.077 C227.4506,63.344 227.2956,65.374 227.1186,67.282 C226.0906,78.333 223.9576,87.807 220.5966,96.242 C218.7636,100.84 216.5066,105.108 213.8736,109.036 L213.8736,119.774 C219.2046,113.684 223.5056,106.6 226.6696,98.662 C230.2656,89.636 232.5416,79.57 233.6276,67.886 C233.8116,65.913 233.9706,63.819 234.1166,61.484 C234.3776,57.298 231.7416,53.911 227.9856,53.604" id="Fill-24" fill="#FFFFFF"></path>
<path d="M227.9856,53.604 C222.9546,53.195 218.7026,50.904 213.8736,47.875 L213.8736,55.496 C218.1106,57.9 222.3716,59.698 227.3756,60.082 C227.4276,60.129 227.6316,60.457 227.5926,61.077 C227.4506,63.344 227.2956,65.374 227.1186,67.282 C226.0906,78.333 223.9576,87.807 220.5966,96.242 C218.7636,100.84 216.5066,105.108 213.8736,109.036 L213.8736,119.774 C219.2046,113.684 223.5056,106.6 226.6696,98.662 C230.2656,89.636 232.5416,79.57 233.6276,67.886 C233.8116,65.913 233.9706,63.819 234.1166,61.484 C234.3776,57.298 231.7416,53.911 227.9856,53.604 Z" id="Stroke-26" stroke="#FFFFFF" stroke-width="3.329"></path>
<path d="M207.3367,117.2476 C207.2627,117.3256 207.1927,117.4096 207.1187,117.4876 L207.3367,117.6966 L207.3367,117.2476 Z" id="Fill-28" fill="#3A3A3A"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Fill-30" fill="#CF8A00"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Stroke-32" stroke="#CF8A00" stroke-width="3.329"></path>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 13 KiB

View File

@ -1,7 +1,24 @@
<svg viewBox="0 0 266 45" xmlns="http://www.w3.org/2000/svg">
<g stroke="none" stroke-width="1" fill-rule="evenodd">
<polygon points="39 45 0 45 0 38.7138616 24.152269 8.73001057 1.84706215 8.73001057 1.84706215 1 37.4067709 1 37.4067709 7.34749556 13.0638763 37.2689998 39 37.2689998" fill="#2D2A26"></polygon>
<path d="M67,1.24923059 C64.2456536,3.27874037 61.8906957,5.81889405 60.0748075,8.73001057 L46.9989843,8.73001057 L46.9989843,19.5427228 L56.2192795,19.5427228 C56.0745901,20.6747333 56,21.8286559 56,23 C56,24.4542938 56.1149784,25.881733 56.3363408,27.273723 L46.9989843,27.273723 L46.9989843,45 L37,45 L37,1 L67,1 L67,1.24923059 Z" fill="#CF8900"></path>
<path d="M60,22.5 C60,16.2049861 62.2021991,10.9072022 66.5436775,6.54432133 C70.8851558,2.18144044 76.6737935,0 83.7837508,0 C89.3207086,0 94.6059866,1.86980609 99.6395846,5.60941828 L94.7947465,12.7770083 C91.1453879,10.0969529 87.5589493,8.78808864 84.0983506,8.85041551 C73.4019548,8.85041551 69.7525962,16.3296399 69.7525962,22.6246537 C69.7525962,26.5512465 71.0109957,29.7922438 73.5907147,32.3476454 C76.1075137,34.9030471 79.3793525,36.1495845 83.3433109,36.1495845 C86.5522297,36.1495845 89.2577886,35.5886427 91.4599878,34.5290859 L91.4599878,28.2963989 L80.3231521,28.2963989 L80.3231521,20.567867 L100.583384,20.567867 L100.583384,38.3310249 C95.5497862,42.7562327 89.8240684,45 83.4062309,45 C76.7367135,45 71.1997557,42.8185596 66.7324374,38.3933518 C62.2651191,34.0304709 60,28.732687 60,22.5 Z M107.756261,12.3407202 L116.879658,12.3407202 L116.879658,19.3213296 C118.012217,13.7119114 122.857056,11.468144 125.751374,11.6551247 C126.443494,11.6551247 127.261454,11.7174515 128.142334,11.9044321 L128.142334,21.066482 C126.946854,20.7548476 125.625535,20.6301939 124.178375,20.6301939 C120.340257,20.6301939 117.131338,22.9362881 117.131338,26.9252078 L117.131338,44.3144044 L107.756261,44.3144044 L107.756261,12.3407202 Z M140.474649,28.234072 C140.474649,33.4695291 143.746487,37.4584488 148.780086,37.4584488 C153.624924,37.4584488 157.211362,34.2797784 157.211362,28.732687 C157.211362,22.9362881 153.750764,19.1966759 148.528406,19.1966759 C143.557728,19.1966759 140.474649,23.0609418 140.474649,28.234072 Z M156.959682,16.7036011 L156.959682,12.3407202 L166.334759,12.3407202 L166.334759,44.3144044 L156.959682,44.3144044 L156.959682,39.6398892 C154.442883,43.1925208 151.045205,45 146.829566,45 C142.047648,45 138.20953,43.3795014 135.378131,40.200831 C132.546732,37.0221607 131.099572,32.9709141 131.099572,28.1717452 C131.099572,23.4972299 132.483812,19.5706371 135.252291,16.3919668 C137.95785,13.2132964 141.795968,11.6551247 146.640806,11.6551247 C150.856445,11.6551247 154.694563,13.6495845 156.959682,16.7036011 Z M183.763592,44.3144044 L174.388516,44.3144044 L174.388516,12.3407202 L183.763592,12.3407202 L183.763592,16.7036011 C186.217471,13.3379501 189.55223,11.6551247 193.767868,11.6551247 C201.444105,11.6551247 205.282224,16.765928 205.282224,26.9252078 L205.282224,44.3144044 L195.907147,44.3144044 L195.907147,27.1121884 C195.907147,21.9390582 193.893708,19.3213296 189.92975,19.3213296 C185.839951,19.3213296 183.763592,22.4376731 183.763592,27.1745152 L183.763592,44.3144044 Z M217.299939,4.48753463 L224.535736,4.48753463 L224.535736,12.3407202 L233.470373,12.3407202 L233.470373,19.632964 L224.535736,19.632964 L224.535736,34.5914127 C224.535736,36.4612188 225.353696,37.3961219 226.926695,37.3961219 C228.562615,37.3961219 229.380574,36.398892 229.380574,34.4044321 C229.380574,33.3448753 229.254734,32.4722992 228.940134,31.6620499 L236.364692,31.6620499 C236.868051,32.7216066 237.119731,33.968144 237.119731,35.4639889 C237.119731,40.699446 233.470373,45 226.360415,45 C218.872938,45 215.16066,41.2603878 215.16066,33.7188366 L215.16066,19.632964 L210.315822,19.632964 L210.315822,12.3407202 L215.852779,12.3407202 L217.299939,4.48753463 Z M239.25901,36.8351801 L246.054368,33.033241 C246.872327,36.3365651 249.829566,37.83241 252.849725,37.83241 C255.114844,37.83241 257.065363,36.8975069 257.065363,35.401662 C257.065363,34.3421053 256.247404,33.531856 254.674404,32.9709141 L249.011607,30.6024931 C245.488088,29.3559557 243.034209,27.4238227 242.090409,25.4916898 C241.14661,23.5595568 240.95785,22.5 240.95785,21.4404432 C240.95785,18.3864266 242.153329,15.9556787 244.544288,14.2105263 C246.935247,12.5277008 249.955406,11.6551247 253.604765,11.6551247 C259.015883,11.6551247 262.916921,13.898892 265.24496,18.3864266 L258.009163,21.6897507 C257.317043,19.632964 255.806964,18.6357341 253.416005,18.6357341 C251.591326,18.6357341 249.829566,19.6952909 249.829566,21.2534626 C249.829566,22.3130194 250.836286,23.2479224 252.849725,23.9958449 L257.694563,25.865651 C261.218082,26.8628809 263.734881,28.6080332 264.7416,30.5401662 C265.74832,32.4722992 266,33.6565097 266,35.0900277 C266,38.2063712 264.7416,40.6371191 262.224801,42.3822715 C259.708002,44.1274238 256.562004,45 252.786805,45 C249.829566,45 247.061087,44.3767313 244.544288,43.1301939 C242.027489,41.9459834 240.26573,39.8268698 239.25901,36.8351801 Z" fill="#2D2A26"></path>
<?xml version="1.0" encoding="UTF-8"?>
<svg viewBox="0 0 656 139" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="grant-logo-name" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-34" transform="translate(0.000000, 0.089000)">
<path d="M167.865968,133.056065 C169.773318,134.793804 171.796751,136.45683 173.948397,138.056065 L0.2132,138.056065 L0.2132,133.056065 L167.865968,133.056065 Z M215.555918,133.056065 L655.2132,133.056065 L655.2132,138.056065 L209.490433,138.056065 C211.125673,136.825903 212.710759,135.54063 214.242902,134.20267 L215.555918,133.056065 Z" id="Combined-Shape" fill="#CF8A00"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Stroke-4" fill="#FF0000"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Fill-2" fill="#000000"></path>
<polygon id="Fill-6" fill="#000000" points="76.1546 121.355 0.2136 121.355 0.2136 108.946 47.2426 49.756 3.8116 49.756 3.8116 34.494 73.0516 34.494 73.0516 47.027 25.6506 106.092 76.1546 106.092"></polygon>
<polygon id="Fill-8" fill="#CF8A00" points="72.9431 121.355 72.9431 34.494 130.6431 34.494 130.6431 49.756 92.1761 49.756 92.1761 71.099 125.5551 71.099 125.5551 86.363 92.1761 86.363 92.1761 121.355"></polygon>
<path d="M299.3211,33.9009 C312.3591,33.9009 321.4611,38.3299 330.3171,44.9709 L320.8461,59.1169 C316.1721,55.6719 308.4231,51.2449 299.9361,51.3679 C279.0261,51.3679 271.8921,66.1279 271.8921,78.5499 C271.8921,94.0479 282.8391,105.2419 298.4601,105.2419 C303.7491,105.2419 309.7761,104.2579 314.3271,102.0439 L314.3271,89.7439 L292.5561,89.7439 L292.5561,74.4919 L332.1621,74.4919 L332.1621,109.5469 C319.3701,120.9859 306.4551,122.7079 298.5831,122.7079 C272.1381,122.7079 252.8261,102.6589 252.8261,78.3039 C252.8261,54.3199 270.5391,33.9009 299.3211,33.9009" id="Fill-10" fill="#000000"></path>
<path d="M364.0174,72.0317 C366.1094,60.5927 375.8264,56.9027 381.3614,56.9027 C383.4524,56.9027 384.0674,57.0257 386.0354,57.3937 L386.0354,75.4747 C383.4524,74.8607 380.1304,74.6147 378.2864,74.6147 C371.3984,74.6147 364.5094,78.6737 364.5094,87.0377 L364.5094,121.3547 L346.1824,121.3547 L346.1824,58.2557 L364.0174,58.2557 L364.0174,72.0317 Z" id="Fill-12" fill="#000000"></path>
<path d="M425.8855,107.8247 C434.8645,107.8247 442.3675,102.0437 442.3675,90.6047 C442.3675,78.9197 435.3565,71.7857 425.3935,71.7857 C415.3075,71.7857 409.6495,79.9037 409.6495,89.6207 C409.6495,99.7067 415.7995,107.8247 425.8855,107.8247 L425.8855,107.8247 Z M460.2025,58.2557 L460.2025,121.3547 L441.8755,121.3547 L441.8755,112.1307 C437.3245,118.6487 431.2975,122.7077 422.0725,122.7077 C402.8845,122.7077 391.3225,107.9477 391.3225,89.4977 C391.3225,71.7857 402.0235,56.9027 421.7035,56.9027 C430.1905,56.9027 437.5715,61.0847 441.8755,66.8657 L441.8755,58.2557 L460.2025,58.2557 Z" id="Fill-14" fill="#000000"></path>
<path d="M475.9451,58.2554 L494.2721,58.2554 L494.2721,66.8654 C499.5611,59.4854 506.2031,56.9024 513.8291,56.9024 C531.5421,56.9024 536.3391,71.0474 536.3391,87.0374 L536.3391,121.3554 L518.0111,121.3554 L518.0111,87.4064 C518.0111,78.6734 514.8131,72.0314 506.3261,72.0314 C497.8391,72.0314 494.2721,78.7964 494.2721,87.5294 L494.2721,121.3554 L475.9451,121.3554 L475.9451,58.2554 Z" id="Fill-16" fill="#000000"></path>
<path d="M573.2371,58.2554 L590.7031,58.2554 L590.7031,72.6474 L573.2371,72.6474 L573.2371,102.1664 C573.2371,104.8724 574.3441,107.7014 577.9111,107.7014 C581.4781,107.7014 582.7091,104.7494 582.7091,101.7974 C582.7091,99.9524 582.2161,97.3694 581.8471,96.3864 L596.3611,96.3864 C597.4681,98.7234 597.8381,101.6754 597.8381,103.8894 C597.8381,113.2364 591.6871,122.7074 576.8041,122.7074 C565.7341,122.7074 554.9101,118.7724 554.9101,100.4444 L554.9101,72.6474 L545.4391,72.6474 L545.4391,58.2554 L556.2631,58.2554 L559.0921,42.7574 L573.2371,42.7574 L573.2371,58.2554 Z" id="Fill-18" fill="#000000"></path>
<path d="M615.3025,99.0913 C617.1475,106.3493 623.5435,108.5633 628.5865,108.5633 C632.6455,108.5633 636.8275,106.9633 636.8275,103.7663 C636.8275,101.6753 635.5975,100.1983 632.1545,98.9693 L621.0835,94.2943 C606.0775,89.0053 605.3395,79.0423 605.3395,76.2133 C605.3395,63.5443 616.5325,56.9033 630.0625,56.9033 C637.3205,56.9033 646.9135,58.8703 652.8185,70.1873 L638.6725,76.7053 C637.0735,71.6623 632.5225,70.6783 629.6945,70.6783 C626.2495,70.6783 622.6825,72.6473 622.6825,75.8443 C622.6825,78.5503 625.3885,80.0273 628.5865,81.2563 L638.0575,84.9463 C652.9415,89.2513 654.2935,98.9693 654.2935,103.1513 C654.2935,116.0663 642.3635,122.7073 628.4635,122.7073 C619.1155,122.7073 606.3235,119.7563 602.0185,106.5953 L615.3025,99.0913 Z" id="Fill-20" fill="#000000"></path>
<path d="M162.7156,43.8618 C164.2086,43.0068 165.7466,42.0428 167.2336,41.1108 C169.2056,39.8748 171.2456,38.6038 173.4316,37.3958 L173.4756,31.9548 C173.5176,26.7528 175.4906,21.8898 179.0326,18.2648 C182.5106,14.7058 187.1146,12.7928 191.9376,12.8108 C202.0356,12.8988 210.1806,21.6348 210.0946,32.2838 L210.0536,37.4068 C212.0626,38.5688 214.1476,39.8348 216.3656,41.2488 C218.4956,42.6068 220.4006,43.7758 222.2136,44.6918 L222.3126,32.3828 C222.4536,15.0008 208.8746,0.7388 192.0446,0.5928 C183.7956,0.4918 176.1176,3.7638 170.2936,9.7248 C164.5346,15.6208 161.3246,23.4798 161.2576,31.8558 L161.1556,44.4878 L161.5816,44.4918 C161.9516,44.2918 162.3276,44.0838 162.7156,43.8618" id="Fill-22" fill="#000000"></path>
<path d="M227.9856,53.604 C222.9546,53.195 218.7026,50.904 213.8736,47.875 L213.8736,55.496 C218.1106,57.9 222.3716,59.698 227.3756,60.082 C227.4276,60.129 227.6316,60.457 227.5926,61.077 C227.4506,63.344 227.2956,65.374 227.1186,67.282 C226.0906,78.333 223.9576,87.807 220.5966,96.242 C218.7636,100.84 216.5066,105.108 213.8736,109.036 L213.8736,119.774 C219.2046,113.684 223.5056,106.6 226.6696,98.662 C230.2656,89.636 232.5416,79.57 233.6276,67.886 C233.8116,65.913 233.9706,63.819 234.1166,61.484 C234.3776,57.298 231.7416,53.911 227.9856,53.604" id="Fill-24" fill="#000000"></path>
<path d="M227.9856,53.604 C222.9546,53.195 218.7026,50.904 213.8736,47.875 L213.8736,55.496 C218.1106,57.9 222.3716,59.698 227.3756,60.082 C227.4276,60.129 227.6316,60.457 227.5926,61.077 C227.4506,63.344 227.2956,65.374 227.1186,67.282 C226.0906,78.333 223.9576,87.807 220.5966,96.242 C218.7636,100.84 216.5066,105.108 213.8736,109.036 L213.8736,119.774 C219.2046,113.684 223.5056,106.6 226.6696,98.662 C230.2656,89.636 232.5416,79.57 233.6276,67.886 C233.8116,65.913 233.9706,63.819 234.1166,61.484 C234.3776,57.298 231.7416,53.911 227.9856,53.604 Z" id="Stroke-26" stroke="#000000" stroke-width="3.329"></path>
<path d="M207.3367,117.2476 C207.2627,117.3256 207.1927,117.4096 207.1187,117.4876 L207.3367,117.6966 L207.3367,117.2476 Z" id="Fill-28" fill="#3A3A3A"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Fill-30" fill="#CF8A00"></path>
<path d="M207.1184,117.4878 C203.0494,121.7408 198.2764,125.5018 192.9324,128.6638 C191.7474,129.3648 191.4724,129.2058 191.1574,129.0178 C185.4894,125.6948 180.8424,122.1418 176.9514,118.1558 C169.0354,110.0468 163.5104,100.1848 160.0624,88.0108 C157.8254,80.1128 156.4944,71.5578 155.8764,61.0918 C155.8134,60.0308 156.2434,60.0008 156.6964,59.9688 C161.7244,59.6138 165.9454,57.5378 169.4104,55.5528 C171.1134,54.5778 172.7774,53.5358 174.3884,52.5268 C176.4194,51.2548 178.3384,50.0508 180.3384,48.9668 C183.0274,47.5088 185.8874,46.1628 188.6534,44.8598 C189.7024,44.3668 190.7504,43.8728 191.7944,43.3718 C196.5584,45.2708 201.4444,47.8248 207.3364,51.4888 L207.3364,43.8438 C202.3604,40.9228 197.9934,38.7688 193.6474,37.0758 L193.4744,37.0088 C192.2554,36.3808 190.9234,36.4508 189.5084,37.2168 C188.2994,37.8008 187.0844,38.3738 185.8684,38.9458 C183.0204,40.2878 180.0744,41.6748 177.2224,43.2208 C175.0424,44.4028 172.9454,45.7168 170.9174,46.9868 C169.3614,47.9628 167.7534,48.9688 166.1624,49.8808 C163.1964,51.5788 159.9404,53.1868 156.2354,53.4478 C151.9204,53.7538 149.0894,57.0548 149.3514,61.4768 C149.9974,72.4288 151.4024,81.4258 153.7724,89.7938 C157.5254,103.0418 163.5774,113.8118 172.2744,122.7218 C176.5774,127.1318 181.6724,131.0358 187.8504,134.6578 C189.0514,135.3618 190.3024,135.7138 191.5964,135.7138 C193.0984,135.7138 194.6584,135.2388 196.2624,134.2898 C200.2584,131.9248 203.9594,129.2428 207.3364,126.2938 L207.1184,117.4878 Z" id="Stroke-32" stroke="#CF8A00" stroke-width="3.329"></path>
</g>
</g>
</svg>
</svg>

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -1,4 +1,7 @@
{
"site": {
"description": "ZF Grants is an open-source, community driven platform that helps creators get funding to build a better Zcash. ZF Grants is owned and operated by the Zcash Foundation."
},
"home": {
"title": "Home",
"description": "ZF Grants organizes creators and community members to incentivize ecosystem improvements",

View File

@ -1,21 +1,79 @@
# Code of Conduct
# Community Guidelines
### Lorem Ipsum
Commenters on ZF Grants should strive to be kind, respectful, and interesting. Ideally, your presence in the community should improve the experience for everyone.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
<a name="rules"></a>
### Duis Aute Irure
## [Rules](#rules)
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
We are committed to making participation in this forum a harassment-free experience for everyone, regardless of a person's...
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
* Level of experience.
* Gender identity and expression.
* Sexual orientation.
* Disability.
* Personal appearance.
* Body size.
* Race.
* Ethnicity.
* Age.
* Religion.
* Nationality.
### Ullamco Laboris Reprehenderit
Examples of **unacceptable** behavior include:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
* Using sexualized language or imagery.
* Personal attacks.
* Trolling and insulting or derogatory comments.
* Public or private harassment.
* Publishing another person's private information, such as physical or electronic addresses, without explicit permission (AKA doxxing).
* Other unethical or unprofessional conduct, at the discretion of the ZF Grants admins.
### Fugiat
<a name="moderation"></a>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
## [Moderation](#moderation)
**Effective:** Oct 25, 2018
ZF Grants has the right and responsibility to remove, edit, or reject posts, comments and other contributions that are not aligned with these Community Guidelines, or to suspend or ban any ZF Grants user for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
By adopting these Community Guidelines, the admins of ZF Grants commit themselves to fairly and consistently applying these principles to every aspect of managing discussions on the platform.
<a name="reporting"></a>
## [Reporting](#reporting)
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by flagging the post or comment in question, or by emailing contact@zfnd.org.
All complaints will be reviewed, investigated, and will result in a response that is deemed necessary and appropriate for the circumstances. **ZF Grants is obligated to maintain confidentiality with regard to the reporter of an incident.**
_The guidelines listed in the sections above were adapted from the [rules of the Zcash Community Forum](https://forum.zcashcommunity.com/faq), which came from the [Zcash core contributor code of conduct](https://github.com/zcash/zcash/blob/master/code_of_conduct.md), which is itself based on [version 1.3.0 of the Contributor Covenant](https://www.contributor-covenant.org/version/1/3/0/code-of-conduct.html)._
<a name="etiquette"></a>
## [Etiquette](#etiquette)
Please do not:
* Post topics unrelated to Zcash.
* Solicit domain sales (even if related to Zcash).
* Bump comments sections without something new to add.
* Derail topics.
* Post links to phishing sites.
* Post spam.
* Create topics or replies for the sole purpose of causing unrest.
* Repost or comment excessively.
* Create and use multiple accounts as sockpuppets.
* Post solicitations for or about services considered illegal in the United States.
* Post links to internet gambling operations.
* It's a crime for internet gambling operations to accept bets from United States persons, and the Justice Department takes the position that people who post advertisements or promotions for online gambling may be aiding and abetting those activities.
<a name="stealing"></a>
## [Copyright](#stealing)
You may not post anything digital that belongs to someone else without permission. You may not post descriptions of, links to, or methods for stealing someones intellectual property (software, video, audio, images), or for breaking any other law.
<a name="tos"></a>
## [Legal](#tos)
To use ZF Grants, you must agree to abide by our [Terms of Service](/tos). The data that constitutes your ZF Grants account and its activities is covered by our [Privacy Policy](/privacy).

View File

@ -129,7 +129,7 @@
"react-helmet": "^5.2.0",
"react-hot-loader": "^4.3.8",
"react-i18next": "^8.3.5",
"react-mde": "7.0.3",
"react-mde": "7.0.4",
"react-redux": "^5.0.7",
"react-router": "4.4.0-beta.6",
"react-router-dom": "4.4.0-beta.6",

File diff suppressed because it is too large Load Diff