Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d35cab0a67 |
@@ -1,21 +0,0 @@
|
|||||||
# unconventional js
|
|
||||||
/blueprints/*/files/
|
|
||||||
/vendor/
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist/
|
|
||||||
/tmp/
|
|
||||||
/release/
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/bower_components/
|
|
||||||
/node_modules/
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/coverage/
|
|
||||||
!.*
|
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
/bower.json.ember-try
|
|
||||||
/package.json.ember-try
|
|
||||||
+3
-15
@@ -1,7 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
root: true,
|
root: true,
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
ecmaVersion: 2018,
|
ecmaVersion: 2017,
|
||||||
sourceType: 'module'
|
sourceType: 'module'
|
||||||
},
|
},
|
||||||
globals: {
|
globals: {
|
||||||
@@ -25,14 +25,10 @@ module.exports = {
|
|||||||
// node files
|
// node files
|
||||||
{
|
{
|
||||||
files: [
|
files: [
|
||||||
'.eslintrc.js',
|
|
||||||
'.template-lintrc.js',
|
|
||||||
'ember-cli-build.js',
|
'ember-cli-build.js',
|
||||||
'testem.js',
|
'testem.js',
|
||||||
'blueprints/*/index.js',
|
|
||||||
'config/**/*.js',
|
'config/**/*.js',
|
||||||
'lib/*/index.js',
|
'lib/*/index.js'
|
||||||
'server/**/*.js'
|
|
||||||
],
|
],
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
sourceType: 'script',
|
sourceType: 'script',
|
||||||
@@ -41,15 +37,7 @@ module.exports = {
|
|||||||
env: {
|
env: {
|
||||||
browser: false,
|
browser: false,
|
||||||
node: true
|
node: true
|
||||||
},
|
}
|
||||||
plugins: ['node'],
|
|
||||||
rules: Object.assign({}, require('eslint-plugin-node').configs.recommended.rules, {
|
|
||||||
// add your custom rules and overrides for node files here
|
|
||||||
|
|
||||||
// this can be removed once the following is fixed
|
|
||||||
// https://github.com/mysticatea/eslint-plugin-node/issues/77
|
|
||||||
'node/no-unpublished-require': 'off'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
template: |
|
|
||||||
## Changes
|
|
||||||
|
|
||||||
$CHANGES
|
|
||||||
+11
-13
@@ -1,26 +1,24 @@
|
|||||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist/
|
/dist
|
||||||
/tmp/
|
/tmp
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/bower_components/
|
/node_modules
|
||||||
/node_modules/
|
/bower_components
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
/.env*
|
|
||||||
/.pnp*
|
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage/
|
/coverage/*
|
||||||
/libpeerconnection.log
|
/libpeerconnection.log
|
||||||
/npm-debug.log*
|
npm-debug.log*
|
||||||
/testem.log
|
yarn-error.log
|
||||||
/yarn-error.log
|
testem.log
|
||||||
.tm_properties
|
.tm_properties
|
||||||
|
|
||||||
# ember-try
|
# ember-try
|
||||||
/.node_modules.ember-try/
|
.node_modules.ember-try/
|
||||||
/bower.json.ember-try
|
bower.json.ember-try
|
||||||
/package.json.ember-try
|
package.json.ember-try
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
extends: 'recommended',
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
'simple-unless': false,
|
|
||||||
'no-nested-interactive': false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+5
-8
@@ -1,15 +1,10 @@
|
|||||||
---
|
---
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "10"
|
- "6"
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
dist: xenial
|
dist: trusty
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
on_failure: always
|
|
||||||
|
|
||||||
addons:
|
addons:
|
||||||
chrome: stable
|
chrome: stable
|
||||||
@@ -23,7 +18,9 @@ env:
|
|||||||
# See https://git.io/vdao3 for details.
|
# See https://git.io/vdao3 for details.
|
||||||
- JOBS=1
|
- JOBS=1
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
- npm config set spin false
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm run lint:hbs
|
|
||||||
- npm run lint:js
|
- npm run lint:js
|
||||||
- npm test
|
- npm test
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ Make use of the many generators for code, try `ember help generate` for more det
|
|||||||
|
|
||||||
### Linting
|
### Linting
|
||||||
|
|
||||||
* `npm run lint:hbs`
|
|
||||||
* `npm run lint:js`
|
* `npm run lint:js`
|
||||||
* `npm run lint:js -- --fix`
|
* `npm run lint:js -- --fix`
|
||||||
|
|
||||||
@@ -61,7 +60,8 @@ The smart contracts and their JavaScript wrapper library are developed in the
|
|||||||
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
|
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
|
||||||
|
|
||||||
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
||||||
network, provided e.g. by [ganache](http://truffleframework.com/ganache/).
|
network, provided e.g. by [ganache](http://truffleframework.com/ganache/) or
|
||||||
|
[ganache-cli](https://github.com/trufflesuite/ganache-cli).
|
||||||
|
|
||||||
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
|
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
|
||||||
to start and set up such a simulated network, as well as to deploy smart
|
to start and set up such a simulated network, as well as to deploy smart
|
||||||
@@ -71,38 +71,27 @@ These are the basic steps to get up and running:
|
|||||||
|
|
||||||
#### 1. IPFS
|
#### 1. IPFS
|
||||||
|
|
||||||
Run a local IPFS deamon.
|
Run a local IPFS deamon in offline mode.
|
||||||
|
|
||||||
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
||||||
* `ipfs daemon`
|
* `ipfs daemon --offline`
|
||||||
|
|
||||||
#### 2. kredits-contracts
|
#### 2. kredits-contracts
|
||||||
|
|
||||||
Get your local Ethereum development node running. (See [kredits-contracts README](https://github.com/67P/kredits-contracts)
|
Get your local Ethereum development node running.
|
||||||
for details.
|
|
||||||
|
|
||||||
* Clone [kredits-contracts](https://github.com/67P/kredits-contracts)
|
* Clone [kredits-contracts](https://github.com/67P/kredits-contracts)
|
||||||
* `npm install`
|
* `npm install`
|
||||||
* `npm run devchain` - runs a local development chain
|
* `npm run ganache` - which is basically: `ganache-cli -p 7545 -i 100` (we use the non-default port for local networks and a fixed network id)
|
||||||
* `npm run bootstrap` - bootstrap runs deploys all the contracts
|
* `npm run bootstrap` - bootstrap runs fresh migrations, adds some seed data and writes the address/abi information to JSON that will be used by kredits-web
|
||||||
* `npm link` - make the `kredits-contracts` module linkable as `kredits-contracts` on your machine (currently broken :( )
|
* `npm link` - make the `kredits-contracts` module linkable as `kredits-contracts` on your machine
|
||||||
|
|
||||||
#### 3. kredits-web
|
#### 3. kredits-web
|
||||||
|
|
||||||
With IPFS and Ethereum/ganache running, you can now start this Ember app.
|
With IPFS and Ethereum/ganache running, you can now start this Ember app.
|
||||||
|
|
||||||
* `npm link kredits-contracts` - link the local `kredits-contracts` package
|
* `npm link kredits-contracts` - link the local `kredits-contracts` package
|
||||||
* `npm run start:local` - WEB3_PROVIDER_URL=http://localhost:7545 must be set for local settings
|
* `npm run start:local` - NETWORK_ID=100 and WEB3_PROVIDER_URL=http://localhost:7545 must be set for local settings
|
||||||
|
|
||||||
If you restart the devchain your network ID changes. So kredits-contracts does not find the correct DAO address.
|
|
||||||
If that is the case the DAO address must be provided as `KREDITS_DAO_ADDRESS` environment variable.
|
|
||||||
|
|
||||||
* `npm run dao:address` in the kredits-contracts repo to find your address
|
|
||||||
* `KREDITS_DAO_ADDRESS=<0xYOURADDRESS> npm run start:local`
|
|
||||||
|
|
||||||
#### 4. Metamask network
|
|
||||||
|
|
||||||
Switch the network in Metamask to "Custom RPC" with the RPC URL `http://localhost:7545`.
|
|
||||||
|
|
||||||
#### IPFS
|
#### IPFS
|
||||||
|
|
||||||
@@ -112,7 +101,6 @@ Install IPFS with your favorite package manager and run
|
|||||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["localhost:4200"]'
|
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["localhost:4200"]'
|
||||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
|
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
|
||||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
|
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
|
||||||
ipfs config Addresses.Gateway /ip4/127.0.0.1/tcp/8080
|
|
||||||
|
|
||||||
## Further Reading / Useful Links
|
## Further Reading / Useful Links
|
||||||
|
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { and, notEmpty } from '@ember/object/computed';
|
|
||||||
import moment from 'moment';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
|
|
||||||
attributes: null,
|
|
||||||
contributors: Object.freeze([]),
|
|
||||||
|
|
||||||
isValidContributor: notEmpty('contributorId'),
|
|
||||||
isValidKind: notEmpty('kind'),
|
|
||||||
isValidAmount: computed('amount', function() {
|
|
||||||
return parseInt(this.amount, 10) > 0;
|
|
||||||
}),
|
|
||||||
isValidDescription: notEmpty('description'),
|
|
||||||
isValidUrl: notEmpty('url'),
|
|
||||||
isValid: and('isValidContributor',
|
|
||||||
'isValidKind',
|
|
||||||
'isValidAmount',
|
|
||||||
'isValidDescription'),
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('defaultDate', moment().startOf('hour').toDate());
|
|
||||||
|
|
||||||
// Default attributes used by reset
|
|
||||||
this.set('attributes', {
|
|
||||||
contributorId: null,
|
|
||||||
kind: null,
|
|
||||||
date: this.defaultDate,
|
|
||||||
amount: null,
|
|
||||||
description: null,
|
|
||||||
url: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
|
|
||||||
reset () {
|
|
||||||
this.setProperties(this.attributes);
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
submit () {
|
|
||||||
if (!this.isValid) {
|
|
||||||
alert('Invalid data. Please review and try again.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const attributes = this.getProperties(Object.keys(this.attributes));
|
|
||||||
|
|
||||||
let dateInput = (attributes.date instanceof Array) ?
|
|
||||||
attributes.date[0] : attributes.date;
|
|
||||||
|
|
||||||
const [ date, time ] = dateInput.toISOString().split('T');
|
|
||||||
[ attributes.date, attributes.time ] = [ date, time ];
|
|
||||||
|
|
||||||
this.set('inProgress', true);
|
|
||||||
|
|
||||||
this.save(attributes)
|
|
||||||
.then((/*contribution*/) => {
|
|
||||||
this.reset();
|
|
||||||
}, err => {
|
|
||||||
console.warn(err);
|
|
||||||
window.alert('Something went wrong. Check the browser console for details.');
|
|
||||||
})
|
|
||||||
.finally(() => this.set('inProgress', false));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
<form {{action "submit" on="submit"}}>
|
|
||||||
<label>
|
|
||||||
<p class="label">Contributor:</p>
|
|
||||||
<p>
|
|
||||||
<select required onchange={{action (mut contributorId) value="target.value"}}>
|
|
||||||
<option value="" selected disabled hidden></option>
|
|
||||||
{{#each contributors as |contributor|}}
|
|
||||||
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p class="label">Kind:</p>
|
|
||||||
<p>
|
|
||||||
<select required onchange={{action (mut kind) value="target.value"}}>
|
|
||||||
<option value="" selected disabled hidden></option>
|
|
||||||
<option value="community" selected={{eq kind "community"}}>Community</option>
|
|
||||||
<option value="design" selected={{eq kind "design"}}>Design</option>
|
|
||||||
<option value="dev" selected={{eq kind "dev"}}>Development</option>
|
|
||||||
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
|
|
||||||
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
|
|
||||||
<option value="special" selected={{eq kind "special"}}>Special</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p class="label">Date:</p>
|
|
||||||
<p>
|
|
||||||
{{ember-flatpickr
|
|
||||||
date=date
|
|
||||||
defaultDate=defaultDate
|
|
||||||
maxDate=defaultDate
|
|
||||||
enableTime=true
|
|
||||||
time_24hr=true
|
|
||||||
onChange=(action (mut date))
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p class="label">Amount:</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
placeholder="500"
|
|
||||||
value=amount
|
|
||||||
class=(if isValidAmount "valid" "")}}
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p class="label">Description:</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
value=description
|
|
||||||
class=(if isValidDescription "valid" "")}}
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p class="label">URL (optional):</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
value=url
|
|
||||||
class=(if isValidUrl "valid" "")}}
|
|
||||||
</p>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<p class="actions">
|
|
||||||
{{input type="submit"
|
|
||||||
disabled=inProgress
|
|
||||||
value=(if inProgress "Processing" "Save")}}
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
@@ -1,83 +1,64 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { and, notEmpty } from '@ember/object/computed';
|
import { and, notEmpty } from '@ember/object/computed';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as injectService } from '@ember/service';
|
||||||
import { isPresent } from '@ember/utils';
|
|
||||||
import { isAddress } from 'web3-utils';
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
kredits: injectService(),
|
||||||
|
|
||||||
kredits: service(),
|
// Default attributes used by reset
|
||||||
|
attributes: {
|
||||||
attributes: null,
|
|
||||||
|
|
||||||
isValidAccount: computed('account', function() {
|
|
||||||
return isAddress(this.account);
|
|
||||||
}),
|
|
||||||
|
|
||||||
isValidName: notEmpty('name'),
|
|
||||||
isValidURL: notEmpty('url'),
|
|
||||||
isValidGithubUID: notEmpty('github_uid'),
|
|
||||||
isValidGithubUsername: notEmpty('github_username'),
|
|
||||||
isValidGiteaUsername: notEmpty('gitea_username'),
|
|
||||||
isValidWikiUsername: notEmpty('wiki_username'),
|
|
||||||
|
|
||||||
isValid: and(
|
|
||||||
'isValidAccount',
|
|
||||||
'isValidName',
|
|
||||||
'isValidGithubUID'
|
|
||||||
),
|
|
||||||
|
|
||||||
inProgress: false,
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.setDefaultAttributes();
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
|
|
||||||
setDefaultAttributes () {
|
|
||||||
if (isPresent(this.attributes)) { return; }
|
|
||||||
|
|
||||||
this.set('attributes', {
|
|
||||||
account: null,
|
account: null,
|
||||||
name: null,
|
name: null,
|
||||||
kind: 'person',
|
kind: 'person',
|
||||||
url: null,
|
url: null,
|
||||||
github_username: null,
|
github_username: null,
|
||||||
github_uid: null,
|
github_uid: null,
|
||||||
gitea_username: null,
|
wiki_username: null,
|
||||||
wiki_username: null
|
isCore: false,
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO: add proper address validation
|
||||||
|
isValidAccount: notEmpty('account'),
|
||||||
|
isValidName: notEmpty('name'),
|
||||||
|
isValidURL: notEmpty('url'),
|
||||||
|
isValidGithubUID: notEmpty('github_uid'),
|
||||||
|
isValidGithubUsername: notEmpty('github_username'),
|
||||||
|
isValidWikiUsername: notEmpty('wiki_username'),
|
||||||
|
isValid: and(
|
||||||
|
'isValidAccount',
|
||||||
|
'isValidName',
|
||||||
|
'isValidGithubUID'
|
||||||
|
),
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this.setProperties(this.attributes);
|
this.setProperties(this.attributes);
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
submit() {
|
submit() {
|
||||||
if (!this.isValid) {
|
if (!this.isValid) {
|
||||||
alert('Invalid data. Please review and try again.');
|
alert('Invalid data. Please review and try again.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const attributes = Object.keys(this.attributes);
|
let attributes = Object.keys(this.attributes);
|
||||||
const contributor = this.getProperties(attributes);
|
let contributor = this.getProperties(attributes);
|
||||||
|
let saved = this.save(contributor);
|
||||||
|
|
||||||
this.set('inProgress', true);
|
// The promise handles inProgress
|
||||||
|
this.set('inProgress', saved);
|
||||||
|
|
||||||
this.save(contributor).then(() => {
|
saved.then(() => {
|
||||||
this.reset();
|
this.reset();
|
||||||
}).catch(err => {
|
window.scroll(0,0);
|
||||||
console.warn(err);
|
window.alert('Contributor added.');
|
||||||
window.alert('Something went wrong. Please check the browser console.');
|
|
||||||
}).finally(() => {
|
|
||||||
this.set('inProgress', false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,50 +1,64 @@
|
|||||||
<form {{action "submit" on="submit"}}>
|
<form {{action "submit" on="submit"}}>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-account">Ethereum account</label>
|
{{input name="is-core"
|
||||||
{{input name="account" id="c-account"
|
type="checkbox"
|
||||||
type="text" value=account
|
id="is-core"
|
||||||
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
checked=isCore}}
|
||||||
class=(if isValidAccount "valid" "")}}
|
<label for="is-core" class="checkbox">
|
||||||
|
Core team member (can add contributors)
|
||||||
|
</label>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-kind">Kind</label>
|
{{input name="account"
|
||||||
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind">
|
type="text"
|
||||||
|
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
||||||
|
value=account
|
||||||
|
class=(if isValidAccount 'valid' '')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<select required onchange={{action (mut kind) value="target.value"}}>
|
||||||
<option value="person" selected={{eq kind "person"}}>Person</option>
|
<option value="person" selected={{eq kind "person"}}>Person</option>
|
||||||
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
|
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-name">Name</label>
|
{{input name="name"
|
||||||
{{input name="name" type="text" value=name placeholder="Zero Cool"
|
type="text"
|
||||||
class=(if isValidName "valid" "") id="c-name"}}
|
placeholder="Name"
|
||||||
|
value=name
|
||||||
|
class=(if isValidName 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-url">URL</label>
|
{{input name="url"
|
||||||
{{input name="url" type="text" value=url placeholder="http://zerocool.bit"
|
type="text"
|
||||||
class=(if isValidURL "valid" "") id="c-url"}}
|
placeholder="URL"
|
||||||
|
value=url
|
||||||
|
class=(if isValidURL 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-github-uid">GitHub UID</label>
|
{{input name="github_uid"
|
||||||
{{input name="github_uid" type="text" value=github_uid placeholder="2342"
|
type="text"
|
||||||
class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
|
placeholder="GitHub UID (123)"
|
||||||
|
value=github_uid
|
||||||
|
class=(if isValidGithubUID 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-github-username">GitHub username</label>
|
{{input name="github_username"
|
||||||
{{input name="github_username" type="text" value=github_username placeholder="zerocool"
|
type="text"
|
||||||
class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
|
placeholder="GitHub username"
|
||||||
|
value=github_username
|
||||||
|
class=(if isValidGithubUsername 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-gitea-username">Gitea username</label>
|
{{input name="wiki_username"
|
||||||
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
|
type="text"
|
||||||
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
|
placeholder="Wiki Username"
|
||||||
</p>
|
value=wiki_username
|
||||||
<p>
|
class=(if isValidWikiUsername 'valid' '')}}
|
||||||
<label for="c-wiki-username">Wiki username</label>
|
|
||||||
{{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool"
|
|
||||||
class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}}
|
|
||||||
</p>
|
</p>
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
{{input type="submit" disabled=inProgress
|
{{input type="submit"
|
||||||
value=(if inProgress "Processing" "Save")}}
|
disabled=(is-pending inProgress)
|
||||||
|
value=(if (is-pending inProgress) 'Processing' 'Save')}}
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -3,9 +3,21 @@ import { computed } from '@ember/object';
|
|||||||
import { and, notEmpty } from '@ember/object/computed';
|
import { and, notEmpty } from '@ember/object/computed';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
// Default attributes used by reset
|
||||||
|
attributes: {
|
||||||
|
contributorId: null,
|
||||||
|
kind: 'community',
|
||||||
|
amount: null,
|
||||||
|
description: null,
|
||||||
|
url: null,
|
||||||
|
},
|
||||||
|
|
||||||
attributes: null,
|
didInsertElement() {
|
||||||
contributors: Object.freeze([]),
|
this._super(...arguments);
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
|
||||||
|
contributors: [],
|
||||||
|
|
||||||
isValidContributor: notEmpty('contributorId'),
|
isValidContributor: notEmpty('contributorId'),
|
||||||
isValidAmount: computed('amount', function() {
|
isValidAmount: computed('amount', function() {
|
||||||
@@ -17,24 +29,6 @@ export default Component.extend({
|
|||||||
'isValidAmount',
|
'isValidAmount',
|
||||||
'isValidDescription'),
|
'isValidDescription'),
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
|
|
||||||
// Default attributes used by reset
|
|
||||||
this.set('attributes', {
|
|
||||||
contributorId: null,
|
|
||||||
kind: 'community',
|
|
||||||
amount: null,
|
|
||||||
description: null,
|
|
||||||
url: null,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this.setProperties(this.attributes);
|
this.setProperties(this.attributes);
|
||||||
},
|
},
|
||||||
@@ -60,5 +54,4 @@ export default Component.extend({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,25 +20,25 @@
|
|||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
value=amount
|
value=amount
|
||||||
class=(if isValidAmount "valid" "")}}
|
class=(if isValidAmount 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
value=description
|
value=description
|
||||||
class=(if isValidDescription "valid" "")}}
|
class=(if isValidDescription 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="URL (optional)"
|
placeholder="URL (optional)"
|
||||||
value=url
|
value=url
|
||||||
class=(if isValidUrl "valid" "")}}
|
class=(if isValidUrl 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
{{input type="submit"
|
{{input type="submit"
|
||||||
disabled=(is-pending inProgress)
|
disabled=(is-pending inProgress)
|
||||||
value=(if (is-pending inProgress) "Processing" "Save")}}
|
value=(if (is-pending inProgress) 'Processing' 'Save')}}
|
||||||
{{#link-to "index"}}Back{{/link-to}}
|
{{#link-to 'index'}}Back{{/link-to}}
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -12,24 +12,13 @@ let categoryColors = {
|
|||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
contributions: null,
|
contributions: null,
|
||||||
chartOptions: Object.freeze({
|
|
||||||
legend: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
chartData: computed('contributions', function() {
|
chartData: computed('contributions', function() {
|
||||||
let kredits = this.contributions
|
let kredits = this.get('contributions')
|
||||||
.filterBy('vetoed', false)
|
|
||||||
.map(c => {
|
.map(c => {
|
||||||
return { kind: c.kind, amount: c.amount }
|
return { kind: c.kind, amount: c.amount }
|
||||||
})
|
}).reduce(function (kinds, c) {
|
||||||
.reduce(function (kinds, c) {
|
kinds[c.kind] = (kinds[c.kind] || 0) + c.amount;
|
||||||
if (c.kind in kinds) {
|
|
||||||
kinds[c.kind] = kinds[c.kind] + c.amount
|
|
||||||
} else {
|
|
||||||
kinds[c.kind] = c.amount;
|
|
||||||
}
|
|
||||||
return kinds;
|
return kinds;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
@@ -59,6 +48,12 @@ export default Component.extend({
|
|||||||
'Documentation'
|
'Documentation'
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
|
||||||
|
chartOptions: {
|
||||||
|
legend: {
|
||||||
|
display: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<div class="chart">
|
<div class="chart">
|
||||||
{{ember-chart type="doughnut"
|
{{ember-chart type='doughnut'
|
||||||
data=chartData
|
data=chartData
|
||||||
options=chartOptions
|
options=chartOptions
|
||||||
width=200
|
width=200
|
||||||
|
|||||||
@@ -1,72 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { sort } from '@ember/object/computed';
|
|
||||||
import { isPresent } from '@ember/utils';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
|
|
||||||
router: service(),
|
|
||||||
|
|
||||||
tagName: 'div',
|
|
||||||
classNames: ['contributions'],
|
|
||||||
|
|
||||||
selectedContribution: null,
|
|
||||||
|
|
||||||
showQuickFilter: false,
|
|
||||||
hideSmallContributions: false,
|
|
||||||
contributorId: null,
|
|
||||||
contributionKind: null,
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
contributorsSorting: Object.freeze(['name:asc']),
|
|
||||||
contributors: sort('kredits.contributors', 'contributorsSorting'),
|
|
||||||
|
|
||||||
contributorsActive: computed('contributors.[]', 'contributions', function() {
|
|
||||||
let activeIds = this.contributions.mapBy('contributorId')
|
|
||||||
.map(id => id.toString())
|
|
||||||
.uniq();
|
|
||||||
return this.contributors.filter(c => {
|
|
||||||
return activeIds.includes(c.id.toString());
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
contributionKinds: computed('contributions.[]', function() {
|
|
||||||
return this.contributions.mapBy('kind').uniq();
|
|
||||||
}),
|
|
||||||
|
|
||||||
contributionsFiltered: computed('contributions.[]', 'hideSmallContributions', 'contributorId', 'contributionKind', function() {
|
|
||||||
return this.contributions.filter(c => {
|
|
||||||
let included = true;
|
|
||||||
|
|
||||||
if (this.hideSmallContributions &&
|
|
||||||
c.amount <= 500) { included = false; }
|
|
||||||
|
|
||||||
if (isPresent(this.contributorId) &&
|
|
||||||
c.contributorId.toString() !== this.contributorId.toString()) { included = false; }
|
|
||||||
|
|
||||||
if (isPresent(this.contributionKind) &&
|
|
||||||
c.kind !== this.contributionKind) { included = false; }
|
|
||||||
|
|
||||||
return included;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
veto (contributionId) {
|
|
||||||
if (this.contractInteractionEnabled) {
|
|
||||||
this.vetoContribution(contributionId);
|
|
||||||
} else {
|
|
||||||
window.alert('Only members can veto contributions. Please ask someone to set you up.');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
openContributionDetails(contribution) {
|
|
||||||
this.router.transitionTo('dashboard.contributions.show', contribution);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
{{#if showQuickFilter}}
|
|
||||||
<div class="quick-filter">
|
|
||||||
<p>
|
|
||||||
<label class="filter-contributor">
|
|
||||||
Contributor:
|
|
||||||
<select onchange={{action (mut contributorId) value="target.value"}}>
|
|
||||||
<option value="" selected>all</option>
|
|
||||||
{{#each contributorsActive as |contributor|}}
|
|
||||||
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label class="filter-contribution-kind">
|
|
||||||
Kind:
|
|
||||||
<select onchange={{action (mut contributionKind) value="target.value"}}>
|
|
||||||
<option value="" selected>all</option>
|
|
||||||
{{#each contributionKinds as |kind|}}
|
|
||||||
<option value={{kind}} selected={{eq contributionKind kind}}>{{capitalize-string kind}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
<label class="filter-contribution-size">
|
|
||||||
{{input type="checkbox" checked=hideSmallContributions}}
|
|
||||||
Hide small contributions
|
|
||||||
</label>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<ul class="contribution-list">
|
|
||||||
{{#each contributionsFiltered as |contribution|}}
|
|
||||||
<li role="button" {{action "openContributionDetails" contribution}}
|
|
||||||
data-contribution-id={{contribution.id}}
|
|
||||||
class="{{contribution-status contribution}}{{if contribution.vetoed " vetoed"}}{{if (eq contribution.id selectedContributionId) " selected"}}">
|
|
||||||
<p class="meta">
|
|
||||||
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
|
|
||||||
<span class="category {{contribution.kind}}">({{contribution.kind}})</span>
|
|
||||||
<span class="title">{{contribution.description}}</span>
|
|
||||||
</p>
|
|
||||||
<p class="kredits-amount">
|
|
||||||
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
|
|
||||||
</p>
|
|
||||||
{{#unless contribution.vetoed}}
|
|
||||||
{{#unless (is-confirmed-contribution contribution)}}
|
|
||||||
<p class="voting">
|
|
||||||
<button {{action "veto" contribution.id}} class="small danger">veto</button>
|
|
||||||
</p>
|
|
||||||
{{/unless}}
|
|
||||||
{{/unless}}
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
router: service(),
|
|
||||||
|
|
||||||
tagName: 'table',
|
tagName: 'table',
|
||||||
classNames: 'contributor-list',
|
classNames: 'contributor-list',
|
||||||
|
selectedContributor: null,
|
||||||
selectedContributorId: null,
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
openContributorDetails(contributor) {
|
toggleContributorInfo(contributor) {
|
||||||
this.router.transitionTo('dashboard.contributors.show', contributor);
|
if (contributor.get('showMetadata')) {
|
||||||
|
contributor.set('showMetadata', false);
|
||||||
|
} else {
|
||||||
|
this.contributors.setEach('showMetadata', false);
|
||||||
|
contributor.set('showMetadata', true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,27 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{#each contributorList as |c|}}
|
{{#each contributors as |contributor|}}
|
||||||
<tr role="button" {{action "openContributorDetails" c.contributor}}
|
<tr class="{{if contributor.isCurrentUser 'current-user'}}" {{action "toggleContributorInfo" contributor}}>
|
||||||
class="{{if (is-current-user c.contributor) "current-user"}} {{if (eq c.contributor.id selectedContributorId) "selected"}}">
|
|
||||||
<td class="person">
|
<td class="person">
|
||||||
{{user-avatar contributor=c.contributor}} {{c.contributor.name}}
|
<img class="avatar" src={{contributor.avatarURL}}>
|
||||||
|
{{contributor.name}}
|
||||||
</td>
|
</td>
|
||||||
<td class="kredits">
|
<td class="kredits">
|
||||||
<span class="amount">
|
<span class="amount">{{contributor.balance}}</span>
|
||||||
{{#if showUnconfirmedKredits}}
|
|
||||||
{{c.amountTotal}}
|
|
||||||
{{else}}
|
|
||||||
{{c.amountConfirmed}}
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
<span class="symbol">₭S</span>
|
<span class="symbol">₭S</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr class="metadata {{if contributor.isCurrentUser 'current-user'}} {{if contributor.showMetadata 'visible'}}">
|
||||||
|
<td colspan="2">
|
||||||
|
<ul>
|
||||||
|
<li><a href="https://testnet.etherscan.io/address/{{contributor.account}}">Inspect Ethereum transactions</a></li>
|
||||||
|
{{#if contributor.ipfsHash}}
|
||||||
|
<li><a href="https://ipfs.io/ipfs/{{contributor.ipfsHash}}">Inspect IPFS profile</a></li>
|
||||||
|
{{/if}}
|
||||||
|
</ul>
|
||||||
|
{{#if contributor.showMetadata}}
|
||||||
|
<pre>{{contributor.ipfsData}}</pre>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
tagName: "",
|
|
||||||
account: null,
|
|
||||||
|
|
||||||
iconComponentName: computed('account.site', function() {
|
|
||||||
if (this.account.site.match(/github|gitea|wiki/)) {
|
|
||||||
return 'icon-account-' + this.account.site.replace(/\./g, '-');
|
|
||||||
} else {
|
|
||||||
return 'icon-web-globe';
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<a href={{account.url}} target="_blank" rel="noopener" title="{{account.username}} on {{account.site}}">
|
|
||||||
<span class="site">{{account.site}}</span>
|
|
||||||
{{component iconComponentName}}
|
|
||||||
</a>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
tagName: ""
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 7.0 KiB |
@@ -1,5 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
tagName: ""
|
|
||||||
});
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<svg id="svg825" class="icon-github" width="260" height="260" enable-background="new 0 0 212.4575 186.23" version="1.1" viewBox="0 0 260 260" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
||||||
<g transform="translate(23.766 36.885)">
|
|
||||||
<path d="m151.79 86.234c-7.078 0.1229-14.154 0.5605-21.232 0.7069-12.318 0.248-24.64 0.5664-36.961 0.512-11.176-0.0472-22.358-0.9728-33.518-0.7052-7.3164 0.1776-14.373 2.2948-20.131 7.584-9.9472 9.1368-12.522 21-11.314 33.807 1.92 20.357 9.2716 31.449 29.115 37.064 15.793 4.4704 31.963 5.2088 48.199 4.9744 5.254 0 10.51 0.1367 15.758-0.0292 12.723-0.4064 25.264-2.2072 37.358-6.3596 10.846-3.7225 18.799-10.691 22.572-22.166 2.6736-8.1288 3.7148-16.388 2.5544-24.853-1.7772-12.959-13.275-30.86-32.4-30.535zm-81.576 59.996c-8.836 0-16-8.9551-16-20 0-11.045 7.164-20 16-20s16 8.9553 16 20c0 11.045-7.164 20-16 20zm76 0c-8.836 0-16-8.9551-16-20 0-11.045 7.164-20 16-20s16 8.9553 16 20c0 11.045-7.164 20-16 20z" fill="none"/>
|
|
||||||
<path class="fg" d="m200.25 59.188c-2.5076-3.4493-4.3632-6.3888-3.8748-11.44 0.6796-7.0664-0.3536-14.396-1.3204-21.518-1.2188-8.9843-3.5236-17.74-7.1776-26.23-9.0332 1.9356-17.981 3.49-25.963 8.0976-8.4648 4.8908-16.695 10.215-25.08 15.25-0.9532 0.5704-2.3124 0.8848-3.3848 0.7032-17.967-3.1368-35.92-3.0196-53.898-0.086-1.3632 0.2244-3.0724-0.2345-4.2948-0.9608-4.4436-2.6604-8.6564-5.7344-13.123-8.3516-11.656-6.844-23.66-12.822-37.494-14.59-0.3928 0.8597-0.7188 1.4785-0.9612 2.1253-4.164 11.22-6.6424 22.844-7.4276 34.82-0.2872 4.3516-0.6092 8.8048 0 13.072 0.3456 2.4296-4e-3 3.8788-1.3924 5.6132-4.8516 6.0488-8.6368 12.717-11.102 20.219-4.6972 14.295-4.4004 28.861-2.2756 43.475 1.7268 11.974 4.7344 23.537 11.324 33.873 13.186 20.682 32.892 29.774 55.572 31.705 19.308 1.6464 38.8 1.1992 58.213 1.2364 13.855 0.0251 27.57-1.4924 40.715-6.6389 20.375-7.9727 33.859-22.604 40.275-44.166 3.7344-12.545 5.2324-25.396 4.8144-38.498-0.4412-13.81-4.0504-26.566-12.144-37.711zm-18.609 82.435c-3.7736 11.475-11.727 18.444-22.572 22.166-12.094 4.1524-24.635 5.9532-37.358 6.3596-5.248 0.1659-10.504 0.0292-15.758 0.0292-16.236 0.2344-32.406-0.504-48.199-4.9744-19.844-5.6152-27.195-16.707-29.115-37.064-1.2072-12.807 1.3672-24.67 11.314-33.807 5.7576-5.2892 12.814-7.4064 20.131-7.584 11.16-0.2676 22.342 0.658 33.518 0.7052 12.32 0.0544 24.642-0.264 36.961-0.512 7.0784-0.1464 14.154-0.584 21.232-0.7069 19.125-0.3243 30.623 17.576 32.4 30.535 1.1604 8.4647 0.1192 16.724-2.5544 24.853z"/>
|
|
||||||
<ellipse class="fg" cx="70.214" cy="126.23" rx="16" ry="20"/>
|
|
||||||
<ellipse class="fg" cx="146.21" cy="126.23" rx="16" ry="20"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 2.7 KiB |
@@ -1,5 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
tagName: ""
|
|
||||||
});
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<svg class="icon-wiki" width="120" height="120" version="1.1" viewBox="0 0 120 120" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
||||||
<g transform="translate(18.1,3)">
|
|
||||||
<polygon class="fg" transform="translate(-6.2,9)" points="6.2 5 45.7 20.5 45.7 91 6.2 75.5"/>
|
|
||||||
<polygon class="fg" transform="translate(-6.2,9)" points="90 5 50.5 20.5 50.5 91 90 75.5"/>
|
|
||||||
<polygon class="fg" transform="translate(-6.2,9)" points="87 88 87 81.8 60.4 91"/>
|
|
||||||
<polygon class="fg" transform="translate(-6.2,9)" points="9.2 88 9.2 81.8 34.9 91"/>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 703 B |
@@ -1,5 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
tagName: ""
|
|
||||||
});
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
<svg class="icon-web-globe" width="60" height="60" enable-background="new 0 0 64 64" version="1.1" viewBox="0 0 60 60" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
|
||||||
<path class="fg" d="m48.1 14.3c-0.4-0.5-0.9-1-1.4-1.5-4.3-4.2-10.2-6.8-16.7-6.8s-12.4 2.6-16.7 6.8c-0.5 0.5-1 1-1.4 1.5-3.7 4.2-5.9 9.7-5.9 15.7s2.2 11.5 5.8 15.7c0.4 0.5 0.9 1 1.4 1.5 4.3 4.2 10.3 6.8 16.8 6.8s12.5-2.6 16.8-6.9c0.5-0.5 0.9-0.9 1.4-1.5 3.6-4.1 5.8-9.6 5.8-15.6s-2.2-11.5-5.9-15.7zm3.9 14.7h-8.1c-0.1-3-1-7.3-2.4-10.5 1.8-0.8 3.5-1.8 5.1-3 3.1 3.6 5.1 8.5 5.4 13.5zm-21-20.1c3 2.3 5.8 5.2 7.6 8.5-2.4 0.9-4.6 1.3-7.6 1.4zm-2 9.9c-3-0.1-5.2-0.6-7.6-1.4 1.8-3.3 4.6-6.3 7.6-8.5zm0 2v8.2h-10.8c0.1-3 0.9-6.8 2.3-9.8 2.7 1 5.5 1.5 8.5 1.6zm0 10.2v8c-3 0.1-5.9 0.7-8.6 1.7-1.4-3-2.1-5.7-2.3-9.7zm0 10v10.1c-3-2.3-5.8-5.3-7.7-8.6 2.4-0.9 4.7-1.4 7.7-1.5zm2 0c3 0.1 5.3 0.6 7.7 1.5-1.9 3.4-4.7 6.3-7.7 8.6zm0-2v-8h10.8c-0.1 4-0.9 6.7-2.3 9.7-2.6-1-5.5-1.5-8.5-1.7zm0-10v-8.2c3-0.1 5.8-0.7 8.5-1.6 1.4 3 2.2 6.8 2.3 9.8zm9.5-12.3c-1.7-3.2-4.1-6-6.9-8.3 4.4 0.6 8.4 2.7 11.5 5.6-1.4 1.1-3 1.9-4.6 2.7zm-14.1-8.4c-2.9 2.3-5.2 5.2-6.9 8.3-1.6-0.7-3.2-1.6-4.6-2.6 3.1-2.9 7.1-5 11.5-5.7zm-12.9 7.2c1.6 1.2 3.3 2.2 5.1 3-1.5 3.3-2.3 7.5-2.4 10.5h-8.2c0.3-5 2.3-9.9 5.5-13.5zm-5.5 15.5h8.1c0.1 4 1 7.2 2.4 10.5-1.8 0.8-3.5 1.8-5.1 3-3.2-3.7-5.1-8.5-5.4-13.5zm11.4 12.2c1.7 3.2 4.1 6.1 7 8.4-4.5-0.7-8.5-2.8-11.6-5.8 1.5-1 3-1.8 4.6-2.6zm14.2 8.5c2.9-2.4 5.3-5.2 7-8.4 1.6 0.7 3.2 1.6 4.6 2.6-3.1 3-7.2 5-11.6 5.8zm13-7.3c-1.6-1.2-3.3-2.2-5.1-3 1.4-3.2 2.3-6.5 2.4-10.5h8.1c-0.3 5.1-2.2 9.9-5.4 13.5z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 1.7 KiB |
@@ -10,5 +10,5 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Loading data...
|
Loading data from Ethereum...
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
|
|
||||||
tagName: '',
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
router: service(),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
signup() {
|
|
||||||
this.router.transitionTo('signup');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<section id="user-account">
|
|
||||||
{{#if (and kredits.hasAccounts kredits.currentUser)}}
|
|
||||||
{{kredits.currentUser.name}}
|
|
||||||
{{#if kredits.currentUserIsCore}}
|
|
||||||
<span class="core-flag">(core)</span>
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
Anonymous
|
|
||||||
<button {{action "signup"}} class="small green">Sign up</button>
|
|
||||||
{{/if}}
|
|
||||||
</section>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
|
|
||||||
const SIZES = {
|
|
||||||
'small': '128', // pixels
|
|
||||||
'medium': '256',
|
|
||||||
'large': '512'
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
contributor: null,
|
|
||||||
tagName: 'img',
|
|
||||||
classNames: ['avatar'],
|
|
||||||
classNameBindings: ['size'],
|
|
||||||
attributeBindings: ['src', 'title'],
|
|
||||||
size: 'small',
|
|
||||||
|
|
||||||
src: alias('avatarURL'),
|
|
||||||
title: alias('contributor.name'),
|
|
||||||
|
|
||||||
avatarURL: computed('contributor.github_uid', 'size', function() {
|
|
||||||
const github_uid = this.contributor.github_uid;
|
|
||||||
|
|
||||||
if (github_uid) {
|
|
||||||
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=${SIZES[this.size]}`;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as injectService } from '@ember/service';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
kredits: service(),
|
kredits: injectService(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { alias, filterBy, sort } from '@ember/object/computed';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
contributors: alias('kredits.contributors'),
|
|
||||||
minedContributors: filterBy('contributors', 'id'),
|
|
||||||
|
|
||||||
contributorsSorting: Object.freeze(['name:asc']),
|
|
||||||
sortedContributors: sort('minedContributors', 'contributorsSorting'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (contribution) {
|
|
||||||
const contributor = this.contributors.findBy('id', contribution.contributorId);
|
|
||||||
contribution.contributorIpfsHash = contributor.ipfsHash;
|
|
||||||
|
|
||||||
return this.kredits.addContribution(contribution)
|
|
||||||
.then(contribution => {
|
|
||||||
this.transitionToRoute('index');
|
|
||||||
return contribution;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (attributes) {
|
|
||||||
return this.kredits
|
|
||||||
.updateContributor(this.model.id, attributes)
|
|
||||||
.then(() => this.transitionToRoute('index'))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (contributor) {
|
|
||||||
return this.kredits
|
|
||||||
.addContributor(contributor)
|
|
||||||
.then(() => this.transitionToRoute('index'))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { alias, not, sort } from '@ember/object/computed';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
showDetailsPane: false,
|
|
||||||
selectedContributorId: null,
|
|
||||||
selectedContributionId: null,
|
|
||||||
|
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
contributions: alias('kredits.contributions'),
|
|
||||||
contributionsConfirmed: alias('kredits.contributionsConfirmed'),
|
|
||||||
contributionsUnconfirmed: alias('kredits.contributionsUnconfirmed'),
|
|
||||||
|
|
||||||
contributionsSorting: Object.freeze(['date:desc', 'time:desc', 'id:desc']),
|
|
||||||
contributionsUnconfirmedSorted: sort('contributionsUnconfirmed', 'contributionsSorting'),
|
|
||||||
contributionsConfirmedSorted: sort('contributionsConfirmed', 'contributionsSorting'),
|
|
||||||
|
|
||||||
kreditsByContributor: alias('kredits.kreditsByContributor'),
|
|
||||||
|
|
||||||
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
|
|
||||||
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
|
|
||||||
}),
|
|
||||||
kreditsToplist: sort('kreditsByContributor', 'kreditsToplistSorting'),
|
|
||||||
|
|
||||||
showUnconfirmedKredits: true,
|
|
||||||
hideUnconfirmedKredits: not('showUnconfirmedKredits'),
|
|
||||||
|
|
||||||
showQuickFilterUnconfirmed: false,
|
|
||||||
showQuickFilterConfirmed: false,
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
vetoContribution (contributionId) {
|
|
||||||
this.kredits.veto(contributionId).then(transaction => {
|
|
||||||
console.debug('[controllers:index] Veto submitted to Ethereum blockhain: '+transaction.hash);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
confirmProposal (proposalId) {
|
|
||||||
this.kredits.vote(proposalId).then(transaction => {
|
|
||||||
console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleQuickFilterUnconfirmed () {
|
|
||||||
this.toggleProperty('showQuickFilterUnconfirmed');
|
|
||||||
},
|
|
||||||
|
|
||||||
toggleQuickFilterConfirmed () {
|
|
||||||
this.toggleProperty('showQuickFilterConfirmed');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
roleName: computed('model.isCore', 'totalKreditsEarned', function() {
|
|
||||||
if (this.model.isCore) return 'Core Contributor';
|
|
||||||
if (this.model.totalKreditsEarned <= 5000) return 'Newcomer';
|
|
||||||
return 'Contributor';
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import Controller from '@ember/controller';
|
||||||
|
import { alias, filter, filterBy, sort } from '@ember/object/computed';
|
||||||
|
import { inject as injectService } from '@ember/service';
|
||||||
|
|
||||||
|
export default Controller.extend({
|
||||||
|
kredits: injectService(),
|
||||||
|
|
||||||
|
contributors: alias('kredits.contributors'),
|
||||||
|
contributorsWithKredits: filter('contributors', function(contributor) {
|
||||||
|
return contributor.get('balance') !== 0;
|
||||||
|
}),
|
||||||
|
contributorsSorting: ['balance:desc'],
|
||||||
|
contributorsSorted: sort('contributorsWithKredits', 'contributorsSorting'),
|
||||||
|
|
||||||
|
proposals: alias('kredits.proposals'),
|
||||||
|
proposalsOpen: filterBy('proposals', 'isExecuted', false),
|
||||||
|
proposalsClosed: filterBy('proposals', 'isExecuted', true),
|
||||||
|
proposalsSorting: ['id:desc'],
|
||||||
|
proposalsClosedSorted: sort('proposalsClosed', 'proposalsSorting'),
|
||||||
|
proposalsOpenSorted: sort('proposalsOpen', 'proposalsSorting'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
confirmProposal(proposalId) {
|
||||||
|
this.kredits.vote(proposalId).then(transaction => {
|
||||||
|
window.confirm('Vote submitted to Ethereum blockhain: '+transaction.hash);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
save(contributor) {
|
||||||
|
return this.kredits.addContributor(contributor)
|
||||||
|
.then((contributor) => {
|
||||||
|
this.contributors.pushObject(contributor);
|
||||||
|
return contributor;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
import { alias, filterBy } from '@ember/object/computed';
|
import { alias, filterBy } from '@ember/object/computed';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as injectService } from '@ember/service';
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Controller.extend({
|
||||||
kredits: service(),
|
kredits: injectService(),
|
||||||
|
|
||||||
contributors: alias('kredits.contributors'),
|
contributors: alias('kredits.contributors'),
|
||||||
minedContributors: filterBy('contributors', 'id'),
|
minedContributors: filterBy('contributors', 'id'),
|
||||||
|
|||||||
@@ -1,49 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { alias, not } from '@ember/object/computed';
|
|
||||||
import { isAddress } from 'web3-utils';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import config from 'kredits-web/config/environment';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
ethAddress: null,
|
|
||||||
githubAccessToken: alias('kredits.githubAccessToken'),
|
|
||||||
|
|
||||||
isValidEthAccount: computed('ethAddress', function() {
|
|
||||||
return isAddress(this.ethAddress);
|
|
||||||
}),
|
|
||||||
|
|
||||||
signupButtonDisabled: not('isValidEthAccount'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
completeSignup () {
|
|
||||||
const payload = {
|
|
||||||
accessToken: this.githubAccessToken,
|
|
||||||
account: this.ethAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
fetch(config.githubSignupUrl, {
|
|
||||||
method: 'POST',
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify(payload)
|
|
||||||
})
|
|
||||||
.then(res => res.json())
|
|
||||||
.then(data => {
|
|
||||||
console.log('Created contributor:', data);
|
|
||||||
|
|
||||||
this.setProperties({
|
|
||||||
githubAccessToken: null,
|
|
||||||
ethAddress: null
|
|
||||||
});
|
|
||||||
|
|
||||||
this.transitionToRoute('signup.complete');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import config from 'kredits-web/config/environment';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
connectGithub () {
|
|
||||||
window.location = config.githubConnectUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
compute([string]) {
|
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
compute([contribution]) {
|
|
||||||
if (contribution.vetoed) {
|
|
||||||
return 'vetoed';
|
|
||||||
} else if (contribution.confirmedAt > this.currentBlock) {
|
|
||||||
return 'unconfirmed';
|
|
||||||
} else {
|
|
||||||
return 'confirmed'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
compute([contribution]) {
|
|
||||||
return !contribution.vetoed &&
|
|
||||||
(contribution.confirmedAt <= this.currentBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
import { isPresent } from '@ember/utils';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentUser: alias('kredits.currentUser'),
|
|
||||||
|
|
||||||
compute([contributor]) {
|
|
||||||
return isPresent(contributor) && isPresent(this.currentUser) &&
|
|
||||||
contributor.account === this.currentUser.account;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import EmberObject, { computed } from '@ember/object';
|
|
||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
|
||||||
|
|
||||||
export default EmberObject.extend({
|
|
||||||
|
|
||||||
// Contract
|
|
||||||
id: null,
|
|
||||||
contributorId: null,
|
|
||||||
amount: null,
|
|
||||||
confirmedAt: bignumber('confirmedAtBlock', 'toNumber'),
|
|
||||||
vetoed: null,
|
|
||||||
ipfsHash: null,
|
|
||||||
|
|
||||||
creatorAccount: null,
|
|
||||||
|
|
||||||
// IPFS
|
|
||||||
kind: null,
|
|
||||||
description: null,
|
|
||||||
details: null,
|
|
||||||
url: null,
|
|
||||||
date: null,
|
|
||||||
time: null,
|
|
||||||
ipfsData: '',
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('details', {});
|
|
||||||
},
|
|
||||||
|
|
||||||
iso8601Date: computed('date', 'time', function() {
|
|
||||||
return this.time ? `${this.date}T${this.time}` : this.date;
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
|
import { computed } from '@ember/object';
|
||||||
import EmberObject from '@ember/object';
|
import EmberObject from '@ember/object';
|
||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
import bignumber from 'kredits-web/utils/cps/bignumber';
|
||||||
import kreditsValue from 'kredits-web/utils/cps/kredits';
|
|
||||||
|
|
||||||
export default EmberObject.extend({
|
export default EmberObject.extend({
|
||||||
// Contract
|
// Contract
|
||||||
id: bignumber('idRaw', 'toString'),
|
id: bignumber('idRaw', 'toString'),
|
||||||
account: null,
|
account: null,
|
||||||
balance: kreditsValue('balanceRaw'),
|
balance: bignumber('balanceRaw', 'toNumber'),
|
||||||
totalKreditsEarned: bignumber('totalKreditsEarnedRaw', 'toNumber'),
|
|
||||||
contributionsCount: bignumber('contributionsCountRaw', 'toNumber'),
|
|
||||||
isCore: false,
|
isCore: false,
|
||||||
ipfsHash: null,
|
ipfsHash: null,
|
||||||
|
|
||||||
@@ -19,6 +17,15 @@ export default EmberObject.extend({
|
|||||||
github_username: null,
|
github_username: null,
|
||||||
github_uid: null,
|
github_uid: null,
|
||||||
wiki_username: null,
|
wiki_username: null,
|
||||||
ipfsData: ''
|
ipfsData: '',
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
|
isCurrentUser: false,
|
||||||
|
|
||||||
|
avatarURL: computed('github_uid', function() {
|
||||||
|
let github_uid = this.github_uid;
|
||||||
|
if (github_uid) {
|
||||||
|
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=128`;
|
||||||
|
}
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import { alias } from '@ember/object/computed';
|
|||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
import bignumber from 'kredits-web/utils/cps/bignumber';
|
||||||
|
|
||||||
export default EmberObject.extend({
|
export default EmberObject.extend({
|
||||||
|
|
||||||
// Contract
|
// Contract
|
||||||
id: bignumber('idRaw', 'toString'),
|
id: bignumber('idRaw', 'toString'),
|
||||||
creatorAccount: null,
|
creatorAccount: null,
|
||||||
@@ -20,13 +19,7 @@ export default EmberObject.extend({
|
|||||||
// IPFS
|
// IPFS
|
||||||
kind: null,
|
kind: null,
|
||||||
description: null,
|
description: null,
|
||||||
details: null,
|
details: {},
|
||||||
url: null,
|
url: null,
|
||||||
ipfsData: '',
|
ipfsData: '',
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('details', {});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,30 +7,9 @@ const Router = EmberRouter.extend({
|
|||||||
});
|
});
|
||||||
|
|
||||||
Router.map(function() {
|
Router.map(function() {
|
||||||
this.route('dashboard', function() {
|
|
||||||
this.route('contributors', function() {
|
|
||||||
this.route('show', { path: ':id' });
|
|
||||||
});
|
|
||||||
|
|
||||||
this.route('contributions', function() {
|
|
||||||
this.route('show', { path: ':id' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
this.route('proposals', function() {
|
this.route('proposals', function() {
|
||||||
this.route('new');
|
this.route('new');
|
||||||
});
|
});
|
||||||
this.route('contributions', function() {
|
|
||||||
this.route('new');
|
|
||||||
});
|
|
||||||
this.route('contributors', function() {
|
|
||||||
this.route('new');
|
|
||||||
this.route('edit', { path: ':id/edit' });
|
|
||||||
});
|
|
||||||
this.route('signup', function() {
|
|
||||||
this.route('github');
|
|
||||||
this.route('eth-account');
|
|
||||||
this.route('complete');
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Router;
|
export default Router;
|
||||||
|
|||||||
@@ -1,17 +1,13 @@
|
|||||||
import { inject as service } from '@ember/service';
|
import { inject as injectService } from '@ember/service';
|
||||||
import Route from '@ember/routing/route';
|
import Route from '@ember/routing/route';
|
||||||
|
|
||||||
export default Route.extend({
|
export default Route.extend({
|
||||||
kredits: service(),
|
kredits: injectService(),
|
||||||
|
|
||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
const kredits = this.kredits;
|
const kredits = this.kredits;
|
||||||
|
|
||||||
return kredits.setup().then(() => {
|
return kredits.setup().then(() => {
|
||||||
kredits.get('kredits').preflightChecks().catch((error) => {
|
|
||||||
console.error('Kredits preflight check failed!');
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
if (kredits.get('accountNeedsUnlock')) {
|
if (kredits.get('accountNeedsUnlock')) {
|
||||||
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
|
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
|
||||||
transition.retry();
|
transition.retry();
|
||||||
@@ -23,7 +19,7 @@ export default Route.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
afterModel() {
|
afterModel() {
|
||||||
return this.kredits.loadInitialData()
|
return this.kredits.loadContributorsAndProposals()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.kredits.addContractEventHandlers();
|
this.kredits.addContractEventHandlers();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
contributors: alias('kredits.contributors'),
|
|
||||||
|
|
||||||
model(params) {
|
|
||||||
return this.kredits.contributors.findBy('id', params.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController (controller, model) {
|
|
||||||
this._super(controller, model);
|
|
||||||
|
|
||||||
controller.set('attributes', {
|
|
||||||
account: model.account,
|
|
||||||
name: model.name,
|
|
||||||
kind: model.kind,
|
|
||||||
url: model.url,
|
|
||||||
github_username: model.github_username,
|
|
||||||
github_uid: model.github_uid,
|
|
||||||
gitea_username: model.gitea_username,
|
|
||||||
wiki_username: model.wiki_username
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
contributions: alias('kredits.contributions'),
|
|
||||||
|
|
||||||
model (params) {
|
|
||||||
return this.contributions.findBy('id', parseInt(params.id));
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController (controller, model) {
|
|
||||||
this._super(controller, model);
|
|
||||||
|
|
||||||
this.controllerFor('dashboard')
|
|
||||||
.setProperties({
|
|
||||||
showDetailsPane: true,
|
|
||||||
selectedContributionId: model.id
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
deactivate () {
|
|
||||||
this.controllerFor('dashboard')
|
|
||||||
.setProperties({
|
|
||||||
showDetailsPane: false,
|
|
||||||
selectedContributionId: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
contributors: alias('kredits.contributors'),
|
|
||||||
|
|
||||||
model (params) {
|
|
||||||
return this.contributors.findBy('id', params.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController (controller, model) {
|
|
||||||
this._super(controller, model);
|
|
||||||
|
|
||||||
this.controllerFor('dashboard')
|
|
||||||
.setProperties({
|
|
||||||
showDetailsPane: true,
|
|
||||||
selectedContributorId: model.id
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
deactivate () {
|
|
||||||
this.controllerFor('dashboard')
|
|
||||||
.setProperties({
|
|
||||||
showDetailsPane: false,
|
|
||||||
selectedContributorId: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
redirect () {
|
|
||||||
this.transitionTo('dashboard');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
});
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
});
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { isEmpty } from '@ember/utils';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
redirect () {
|
|
||||||
this._super(...arguments);
|
|
||||||
|
|
||||||
if (isEmpty(this.kredits.githubAccessToken)) {
|
|
||||||
this.transitionTo('signup.index');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
import Route from '@ember/routing/route';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { isEmpty } from '@ember/utils';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
redirect () {
|
|
||||||
this._super(...arguments);
|
|
||||||
|
|
||||||
let accessToken;
|
|
||||||
try {
|
|
||||||
accessToken = window.location.hash.match(/access_token=(.+)/)[1];
|
|
||||||
} catch (error) { /* ignore */ }
|
|
||||||
|
|
||||||
if (isEmpty(accessToken) || accessToken === 'undefined') {
|
|
||||||
console.error('No GitHub access token found.');
|
|
||||||
this.transitionTo('signup');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.kredits.set('githubAccessToken', accessToken);
|
|
||||||
|
|
||||||
this.transitionTo('signup.eth-account');
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
+49
-219
@@ -1,210 +1,106 @@
|
|||||||
import ethers from 'ethers';
|
import ethers from 'npm:ethers';
|
||||||
import Kredits from 'kredits-contracts';
|
import Kredits from 'npm:kredits-contracts';
|
||||||
import RSVP from 'rsvp';
|
import RSVP from 'rsvp';
|
||||||
|
|
||||||
import Service from '@ember/service';
|
import Service from '@ember/service';
|
||||||
import EmberObject from '@ember/object';
|
|
||||||
import { computed } from '@ember/object';
|
import { computed } from '@ember/object';
|
||||||
import { alias, notEmpty } from '@ember/object/computed';
|
import { alias, notEmpty } from '@ember/object/computed';
|
||||||
import { isEmpty } from '@ember/utils';
|
import { isEmpty } from '@ember/utils';
|
||||||
|
|
||||||
import groupBy from 'kredits-web/utils/group-by';
|
|
||||||
import formatKredits from 'kredits-web/utils/format-kredits';
|
|
||||||
|
|
||||||
import config from 'kredits-web/config/environment';
|
import config from 'kredits-web/config/environment';
|
||||||
import Contributor from 'kredits-web/models/contributor'
|
import Contributor from 'kredits-web/models/contributor'
|
||||||
import Proposal from 'kredits-web/models/proposal'
|
import Proposal from 'kredits-web/models/proposal'
|
||||||
import Contribution from 'kredits-web/models/contribution'
|
|
||||||
|
|
||||||
export default Service.extend({
|
export default Service.extend({
|
||||||
|
|
||||||
currentBlock: null,
|
|
||||||
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
||||||
currentUser: null,
|
currentUser: null,
|
||||||
contributors: null,
|
|
||||||
contributions: null,
|
|
||||||
proposals: null,
|
|
||||||
githubAccessToken: null,
|
|
||||||
|
|
||||||
currentUserIsContributor: notEmpty('currentUser'),
|
currentUserIsContributor: notEmpty('currentUser'),
|
||||||
currentUserIsCore: alias('currentUser.isCore'),
|
currentUserIsCore: alias('currentUser.isCore'),
|
||||||
hasAccounts: notEmpty('currentUserAccounts'),
|
hasAccounts: notEmpty('currentUserAccounts'),
|
||||||
|
|
||||||
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
||||||
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
|
// this is called in the routes beforeModel(). So it is initialized before everything else
|
||||||
return this.contributions.filter(contribution => {
|
// and we can rely on the ethProvider and the potential currentUserAccounts to be available
|
||||||
return contribution.confirmedAt > this.currentBlock;
|
getEthProvider: function() {
|
||||||
});
|
return new RSVP.Promise((resolve) => {
|
||||||
}),
|
|
||||||
|
|
||||||
contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
|
|
||||||
return this.contributions
|
|
||||||
.filterBy('vetoed', false)
|
|
||||||
.filter(contribution => {
|
|
||||||
return contribution.confirmedAt <= this.currentBlock;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
|
|
||||||
const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
|
|
||||||
const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
|
|
||||||
const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
|
|
||||||
const contributorsWithOnlyConfirmed = this.contributors.reject(c => contributorsWithUnconfirmed.includes(c.id))
|
|
||||||
|
|
||||||
const kreditsByContributor = contributionsGrouped.map(c => {
|
|
||||||
const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
|
|
||||||
const contributor = this.contributors.findBy('id', c.value.toString());
|
|
||||||
|
|
||||||
return EmberObject.create({
|
|
||||||
contributor: contributor,
|
|
||||||
amountUnconfirmed: amountUnconfirmed,
|
|
||||||
amountConfirmed: contributor.totalKreditsEarned,
|
|
||||||
amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
contributorsWithOnlyConfirmed.forEach(c => {
|
|
||||||
kreditsByContributor.push(EmberObject.create({
|
|
||||||
contributor: c,
|
|
||||||
amountUnconfirmed: 0,
|
|
||||||
amountConfirmed: c.totalKreditsEarned,
|
|
||||||
amountTotal: c.totalKreditsEarned
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
|
|
||||||
return kreditsByContributor;
|
|
||||||
}),
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('contributors', []);
|
|
||||||
this.set('proposals', []);
|
|
||||||
this.set('contributions', []);
|
|
||||||
},
|
|
||||||
|
|
||||||
// This is called in the application route's beforeModel(). So it is
|
|
||||||
// initialized before everything else, and we can rely on the ethProvider and
|
|
||||||
// the potential currentUserAccounts to be available
|
|
||||||
getEthProvider () {
|
|
||||||
let ethProvider;
|
let ethProvider;
|
||||||
|
let networkId;
|
||||||
return new RSVP.Promise(async (resolve) => {
|
if (typeof window.web3 !== 'undefined') {
|
||||||
function instantiateWithoutAccount () {
|
|
||||||
console.debug('[kredits] Creating new instance from npm module class');
|
|
||||||
console.debug(`[kredits] providerURL: ${config.web3ProviderUrl}`);
|
|
||||||
ethProvider = new ethers.providers.JsonRpcProvider(config.web3ProviderUrl);
|
|
||||||
resolve({
|
|
||||||
ethProvider: ethProvider,
|
|
||||||
ethSigner: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function instantiateWithAccount (web3Provider, context) {
|
|
||||||
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
||||||
ethProvider = new ethers.providers.Web3Provider(web3Provider);
|
networkId = parseInt(window.web3.version.network);
|
||||||
// const network = await ethProvider.getNetwork();
|
ethProvider = new ethers.providers.Web3Provider(
|
||||||
ethProvider.listAccounts().then(accounts => {
|
window.web3.currentProvider,
|
||||||
context.set('currentUserAccounts', accounts);
|
{ chainId: networkId }
|
||||||
|
);
|
||||||
|
ethProvider.listAccounts().then((accounts) => {
|
||||||
|
this.set('currentUserAccounts', accounts);
|
||||||
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
|
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
|
||||||
resolve({
|
resolve({
|
||||||
ethProvider,
|
ethProvider,
|
||||||
ethSigner
|
ethSigner
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
} else {
|
||||||
|
console.debug('[kredits] Creating new instance from npm module class');
|
||||||
if (window.ethereum) {
|
networkId = parseInt(config.contractMetadata.networkId);
|
||||||
try {
|
console.debug(`[kredits] networkId=${networkId} providerURL: ${config.web3ProviderUrl}`);
|
||||||
// Request account access if needed
|
ethProvider = new ethers.providers.JsonRpcProvider(
|
||||||
await window.ethereum.enable();
|
config.web3ProviderUrl,
|
||||||
// Acccounts now exposed
|
{ chainId: networkId }
|
||||||
instantiateWithAccount(window.ethereum, this);
|
);
|
||||||
} catch (error) {
|
resolve({
|
||||||
instantiateWithoutAccount();
|
ethProvider: ethProvider,
|
||||||
}
|
ethSigner: null
|
||||||
}
|
});
|
||||||
// Legacy dapp browsers...
|
|
||||||
else if (window.web3) {
|
|
||||||
instantiateWithAccount(window.web3.currentProvider, this);
|
|
||||||
}
|
|
||||||
// Non-dapp browsers...
|
|
||||||
else {
|
|
||||||
instantiateWithoutAccount();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
return this.getEthProvider().then((providerAndSigner) => {
|
return this.getEthProvider().then((providerAndSigner) => {
|
||||||
|
|
||||||
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
|
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
|
||||||
addresses: { Kernel: config.kreditsKernelAddress },
|
|
||||||
apm: config.kreditsApmDomain,
|
|
||||||
ipfsConfig: config.ipfs
|
ipfsConfig: config.ipfs
|
||||||
});
|
});
|
||||||
return kredits
|
return kredits
|
||||||
.init()
|
.init()
|
||||||
.then(async (kredits) => {
|
.then((kredits) => {
|
||||||
this.set('kredits', kredits);
|
this.set('kredits', kredits);
|
||||||
this.set('currentBlock', await kredits.provider.getBlockNumber());
|
|
||||||
|
|
||||||
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
||||||
this.getCurrentUser.then((contributorData) => {
|
this.getCurrentUser.then((contributorData) => {
|
||||||
this.set('currentUser', contributorData);
|
this.set('currentUser', contributorData);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return kredits;
|
return kredits;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
totalSupply: computed(function() {
|
totalSupply: computed(function() {
|
||||||
return this.kredits.Token.functions.totalSupply().then(total => {
|
return this.kredits.Token.functions.totalSupply();
|
||||||
return formatKredits(total);
|
|
||||||
})
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
totalKreditsEarned: computed(function() {
|
contributors: [],
|
||||||
return this.kredits.Contribution.functions.totalKreditsEarned(true)
|
proposals: [],
|
||||||
.then(total => total.toNumber());
|
|
||||||
}),
|
|
||||||
|
|
||||||
|
loadContributorsAndProposals() {
|
||||||
loadInitialData () {
|
|
||||||
return this.getContributors()
|
return this.getContributors()
|
||||||
.then(contributors => this.contributors.pushObjects(contributors))
|
.then(contributors => this.contributors.pushObjects(contributors))
|
||||||
.then(() => this.getContributions())
|
.then(() => this.getProposals())
|
||||||
.then(contributions => this.contributions.pushObjects(contributions))
|
.then(proposals => this.proposals.pushObjects(proposals))
|
||||||
},
|
},
|
||||||
|
|
||||||
addContributor(attributes) {
|
addContributor(attributes) {
|
||||||
if (attributes.github_uid) {
|
|
||||||
const uidInt = parseInt(attributes.github_uid);
|
|
||||||
attributes.github_uid = uidInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] add contributor', attributes);
|
console.debug('[kredits] add contributor', attributes);
|
||||||
|
|
||||||
return this.kredits.Contributor.add(attributes, { gasLimit: 350000 })
|
return this.kredits.Contributor.add(attributes)
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
console.debug('[kredits] add contributor response', data);
|
console.debug('[kredits] add contributor response', data);
|
||||||
});
|
return Contributor.create(attributes);
|
||||||
},
|
|
||||||
|
|
||||||
updateContributor (id, attributes) {
|
|
||||||
if (attributes.github_uid) {
|
|
||||||
const uidInt = parseInt(attributes.github_uid);
|
|
||||||
attributes.github_uid = uidInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] update contributor', attributes);
|
|
||||||
|
|
||||||
return this.kredits.Contributor.updateProfile(id, attributes, { gasLimit: 350000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] updateProfile response', data);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -217,25 +113,10 @@ export default Service.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addContribution (attributes) {
|
|
||||||
console.debug('[kredits] add contribution', attributes);
|
|
||||||
|
|
||||||
return this.kredits.Contribution.addContribution(attributes, { gasLimit: 300000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] add contribution response', data);
|
|
||||||
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
|
|
||||||
const contribution = Contribution.create(attributes);
|
|
||||||
// TODO receive from wrapper
|
|
||||||
contribution.set('confirmedAtBlock', data.blockNumber + 40320);
|
|
||||||
this.contributions.pushObject(contribution);
|
|
||||||
return contribution;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
addProposal(attributes) {
|
addProposal(attributes) {
|
||||||
console.debug('[kredits] add proposal', attributes);
|
console.debug('[kredits] add proposal', attributes);
|
||||||
|
|
||||||
return this.kredits.Proposal.addProposal(attributes)
|
return this.kredits.Operator.addProposal(attributes)
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
console.debug('[kredits] add proposal response', data);
|
console.debug('[kredits] add proposal response', data);
|
||||||
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
|
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
|
||||||
@@ -244,7 +125,7 @@ export default Service.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getProposals() {
|
getProposals() {
|
||||||
return this.kredits.Proposal.all()
|
return this.kredits.Operator.all()
|
||||||
.then((proposals) => {
|
.then((proposals) => {
|
||||||
return proposals.map((proposal) => {
|
return proposals.map((proposal) => {
|
||||||
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
||||||
@@ -253,36 +134,16 @@ export default Service.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getContributions () {
|
|
||||||
return this.kredits.Contribution.all({page: {size: 200}})
|
|
||||||
.then(contributions => {
|
|
||||||
return contributions.map(contribution => {
|
|
||||||
contribution.contributor = this.contributors.findBy('id', contribution.contributorId.toString());
|
|
||||||
return Contribution.create(contribution);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
vote(proposalId) {
|
vote(proposalId) {
|
||||||
console.debug('[kredits] vote for', proposalId);
|
console.debug('[kredits] vote for', proposalId);
|
||||||
|
|
||||||
return this.kredits.Proposal.functions.vote(proposalId)
|
return this.kredits.Operator.functions.vote(proposalId)
|
||||||
.then(data => {
|
.then((data) => {
|
||||||
console.debug('[kredits] vote response', data);
|
console.debug('[kredits] vote response', data);
|
||||||
return data;
|
return data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
veto (contributionId) {
|
|
||||||
console.debug('[kredits] veto against', contributionId);
|
|
||||||
|
|
||||||
return this.kredits.Contribution.functions.veto(contributionId, { gasLimit: 300000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] veto response', data);
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrentUser: computed('kredits.provider', function() {
|
getCurrentUser: computed('kredits.provider', function() {
|
||||||
if (isEmpty(this.currentUserAccounts)) {
|
if (isEmpty(this.currentUserAccounts)) {
|
||||||
return RSVP.resolve();
|
return RSVP.resolve();
|
||||||
@@ -290,6 +151,7 @@ export default Service.extend({
|
|||||||
return this.kredits.Contributor
|
return this.kredits.Contributor
|
||||||
.functions.getContributorIdByAddress(this.get('currentUserAccounts.firstObject'))
|
.functions.getContributorIdByAddress(this.get('currentUserAccounts.firstObject'))
|
||||||
.then((id) => {
|
.then((id) => {
|
||||||
|
id = id.toNumber();
|
||||||
// check if the user is a contributor or not
|
// check if the user is a contributor or not
|
||||||
if (id === 0) {
|
if (id === 0) {
|
||||||
return RSVP.resolve();
|
return RSVP.resolve();
|
||||||
@@ -305,49 +167,17 @@ export default Service.extend({
|
|||||||
|
|
||||||
// Contract events
|
// Contract events
|
||||||
addContractEventHandlers() {
|
addContractEventHandlers() {
|
||||||
this.kredits.Contributor
|
// Operator events
|
||||||
.on('ContributorProfileUpdated', this.handleContributorChange.bind(this))
|
this.kredits.Operator
|
||||||
.on('ContributorAccountUpdated', this.handleContributorChange.bind(this))
|
|
||||||
.on('ContributorAdded', this.handleContributorChange.bind(this))
|
|
||||||
|
|
||||||
this.kredits.Contribution
|
|
||||||
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
|
|
||||||
|
|
||||||
this.kredits.Proposal
|
|
||||||
.on('ProposalCreated', this.handleProposalCreated.bind(this))
|
.on('ProposalCreated', this.handleProposalCreated.bind(this))
|
||||||
.on('ProposalVoted', this.handleProposalVoted.bind(this))
|
.on('ProposalVoted', this.handleProposalVoted.bind(this))
|
||||||
.on('ProposalExecuted', this.handleProposalExecuted.bind(this));
|
.on('ProposalExecuted', this.handleProposalExecuted.bind(this));
|
||||||
|
|
||||||
|
// Token events
|
||||||
this.kredits.Token
|
this.kredits.Token
|
||||||
.on('Transfer', this.handleTransfer.bind(this));
|
.on('Transfer', this.handleTransfer.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
async handleContributorChange (contributorId, ...args) {
|
|
||||||
console.debug('[kredits] Contributor add/update event received for ID', contributorId);
|
|
||||||
console.debug('[kredits] Event data:', args);
|
|
||||||
const contributorData = await this.kredits.Contributor.getById(contributorId);
|
|
||||||
const newContributor = Contributor.create(contributorData);
|
|
||||||
|
|
||||||
const oldContributor = this.contributors.findBy('id', contributorId.toString());
|
|
||||||
if (oldContributor) {
|
|
||||||
console.debug('[kredits] old contributor', oldContributor);
|
|
||||||
this.contributors.removeObject(oldContributor);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] new contributor', newContributor);
|
|
||||||
this.contributors.pushObject(newContributor);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleContributionVetoed (contributionId) {
|
|
||||||
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
|
|
||||||
const contribution = this.contributions.findBy('id', contributionId);
|
|
||||||
console.debug('[kredits] contribution', contribution);
|
|
||||||
|
|
||||||
if (contribution) {
|
|
||||||
contribution.set('vetoed', true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleProposalCreated(proposalId) {
|
handleProposalCreated(proposalId) {
|
||||||
let proposal = this.findProposalById(proposalId);
|
let proposal = this.findProposalById(proposalId);
|
||||||
|
|
||||||
@@ -356,7 +186,7 @@ export default Service.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.kredits.Proposal.getById(proposalId)
|
this.kredits.Operator.getById(proposalId)
|
||||||
.then((proposal) => {
|
.then((proposal) => {
|
||||||
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
||||||
this.proposals.pushObject(Proposal.create(proposal));
|
this.proposals.pushObject(Proposal.create(proposal));
|
||||||
@@ -384,7 +214,7 @@ export default Service.extend({
|
|||||||
|
|
||||||
this.contributors
|
this.contributors
|
||||||
.findBy('id', contributorId.toString())
|
.findBy('id', contributorId.toString())
|
||||||
.incrementProperty('balance', amount);
|
.incrementProperty('balance', amount.toNumber());
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTransfer(from, to, value) {
|
handleTransfer(from, to, value) {
|
||||||
|
|||||||
@@ -1,73 +0,0 @@
|
|||||||
button, input[type=submit], .button {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.6rem 2rem;
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
border: 1px solid rgba(22, 21, 40, 1);
|
|
||||||
border-radius: 3px;
|
|
||||||
color: $primary-color;
|
|
||||||
font-weight: 500;
|
|
||||||
text-decoration: none;
|
|
||||||
text-transform: uppercase;
|
|
||||||
cursor: pointer;
|
|
||||||
letter-spacing: 0.1em;
|
|
||||||
|
|
||||||
&+button, &+input[type=submit], &+.button {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(22, 21, 40, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active, &.active {
|
|
||||||
border-color: $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&[disabled] {
|
|
||||||
color: rgba(255,255,255,0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
font-size: 0.86rem;
|
|
||||||
padding: 0.2rem 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.danger {
|
|
||||||
color: $red;
|
|
||||||
background-color: rgba(40, 21, 21, 0.6);
|
|
||||||
border-color: rgba(40, 21, 21, 1);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(40, 21, 21, 0.8);
|
|
||||||
}
|
|
||||||
&:active, &.active {
|
|
||||||
border-color: $red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.green {
|
|
||||||
color: $green;
|
|
||||||
background-color: rgba(21, 40, 21, 0.6);
|
|
||||||
border-color: rgba(21, 40, 21, 1);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(21, 40, 21, 0.8);
|
|
||||||
}
|
|
||||||
&:active, &.active {
|
|
||||||
border-color: $green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.icon {
|
|
||||||
svg {
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 1rem;
|
|
||||||
|
|
||||||
.fg {
|
|
||||||
fill: $primary-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,12 @@ $primary-color: $blue;
|
|||||||
|
|
||||||
$body-text-color: #fff;
|
$body-text-color: #fff;
|
||||||
|
|
||||||
|
@mixin body-background {
|
||||||
|
background-image: linear-gradient(to bottom, rgba(22, 21, 40, .4), rgba(0, 0, 0, .75)), url('/img/bg.jpg');
|
||||||
|
background-repeat: none;
|
||||||
|
background-attachment: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
#topbar {
|
#topbar {
|
||||||
background-color: rgba(255, 0, 255, .2);
|
background-color: rgba(255, 0, 255, .2);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-83
@@ -1,11 +1,11 @@
|
|||||||
main {
|
#topbar {
|
||||||
padding: 1rem 2rem;
|
height: 3rem;
|
||||||
|
|
||||||
@include media-max(small) {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&#dashboard {
|
main {
|
||||||
|
padding: 1rem;
|
||||||
|
|
||||||
|
&#index {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-row-gap: 2rem;
|
grid-row-gap: 2rem;
|
||||||
@@ -13,69 +13,16 @@ main {
|
|||||||
"stats"
|
"stats"
|
||||||
"contributions";
|
"contributions";
|
||||||
}
|
}
|
||||||
|
|
||||||
&.center-column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
section {
|
|
||||||
width: 600px;
|
|
||||||
max-width: 100%;
|
|
||||||
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
|
||||||
.content {
|
|
||||||
a {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-lg {
|
|
||||||
p {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
line-height: 1.5em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.text-center {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
&.mg-bottom-md {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.actions {
|
|
||||||
text-align: center;
|
|
||||||
padding-top: 2rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
@media (min-width: 550px) {
|
||||||
main {
|
main {
|
||||||
&#dashboard {
|
&#index {
|
||||||
grid-column-gap: 4rem;
|
grid-column-gap: 4rem;
|
||||||
grid-row-gap: 2rem;
|
grid-row-gap: 2rem;
|
||||||
grid-template-columns: 2fr 4fr;
|
grid-template-columns: 2fr 4fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"stats contributions";
|
"stats contributions";
|
||||||
|
|
||||||
&.with-details {
|
|
||||||
grid-column-gap: 3rem;
|
|
||||||
grid-template-columns: 2fr 4fr 2fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"stats contributions details";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,34 +34,20 @@ main section {
|
|||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-max(small) {
|
@include media($mobile) {
|
||||||
margin-bottom: 5rem;
|
margin-bottom: 5rem;
|
||||||
|
|
||||||
|
&#proposals-open, &#proposals-closed {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
margin-bottom: 3rem;
|
padding-bottom: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
&.with-nav {
|
@include media($mobile) {
|
||||||
display: grid;
|
padding-bottom: 2rem;
|
||||||
grid-template-columns: auto 5rem;
|
|
||||||
grid-template-areas:
|
|
||||||
"title" "actions";
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
display: inline-block;
|
|
||||||
// padding-left: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include media-max(small) {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
$breakpoints-max: (
|
|
||||||
small: 600px,
|
|
||||||
medium: 960px,
|
|
||||||
large: 1280px
|
|
||||||
);
|
|
||||||
|
|
||||||
$breakpoints-min: (
|
|
||||||
small: 601px,
|
|
||||||
medium: 961px,
|
|
||||||
large: 1281px
|
|
||||||
);
|
|
||||||
|
|
||||||
@mixin media-max($screen-size) {
|
|
||||||
@if map-has-key($breakpoints-max, $screen-size) {
|
|
||||||
@media (max-width: map-get($breakpoints-max, $screen-size)) {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
} @else {
|
|
||||||
// Debugging
|
|
||||||
@warn "'#{$screen-size}' has not been declared as a breakpoint."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin media-min($screen-size) {
|
|
||||||
@if map-has-key($breakpoints-min, $screen-size) {
|
|
||||||
@media (min-width: map-get($breakpoints-min, $screen-size)) {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
} @else {
|
|
||||||
// Debugging
|
|
||||||
@warn "'#{$screen-size}' has not been declared as a breakpoint."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+35
-30
@@ -2,6 +2,7 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
*:hover, *:active, *:focus {
|
*:hover, *:active, *:focus {
|
||||||
@@ -10,25 +11,22 @@
|
|||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "mediaqueries";
|
@import "bourbon/bourbon";
|
||||||
|
@import "settings/neat";
|
||||||
|
@import "neat/neat";
|
||||||
|
@import "settings/breakpoints";
|
||||||
@import "layout";
|
@import "layout";
|
||||||
@import "colors";
|
@import "colors";
|
||||||
|
|
||||||
$font-family-sans: 'Open Sans', sans-serif;
|
$font-family-sans: 'Open Sans', sans-serif;
|
||||||
|
|
||||||
html, body {
|
body {
|
||||||
|
@include body-background;
|
||||||
font-family: $font-family-sans;
|
font-family: $font-family-sans;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
font-size: 12px;
|
|
||||||
color: $body-text-color;
|
color: $body-text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
|
||||||
background-image: linear-gradient(to bottom, rgba(22, 21, 40, .4), rgba(0, 0, 0, .75)), url('/img/bg.jpg');
|
|
||||||
background-repeat: none;
|
|
||||||
background-attachment: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 900px) {
|
@media screen and (min-width: 900px) {
|
||||||
body {
|
body {
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
@@ -41,10 +39,6 @@ h1, h2, h3, h4, h5, input, button {
|
|||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
section {
|
section {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
@@ -54,13 +48,16 @@ section {
|
|||||||
&#people {
|
&#people {
|
||||||
.content {
|
.content {
|
||||||
p.stats {
|
p.stats {
|
||||||
margin-bottom: 1rem;
|
padding-top: 3rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
span.number {
|
span.number {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
@include media($mobile) {
|
||||||
|
padding-top: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -70,10 +67,10 @@ section {
|
|||||||
width: 50%;
|
width: 50%;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
|
|
||||||
@include media-max(small) {
|
|
||||||
width: 75%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include media($mobile) {
|
||||||
|
width: 90%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +80,7 @@ section {
|
|||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: $primary-color;
|
color: $primary-color;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@include media-max(small) {
|
@include media($mobile) {
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,6 +91,22 @@ section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button, input[type=submit] {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid rgba(22, 21, 40, 1);
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
color: $primary-color;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
cursor: pointer;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(22, 21, 40, 0.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
@media (min-width: 550px) {
|
||||||
section {
|
section {
|
||||||
h2 {
|
h2 {
|
||||||
@@ -102,16 +115,8 @@ section {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "buttons";
|
|
||||||
@import "forms";
|
|
||||||
|
|
||||||
@import "components/contribution-list";
|
|
||||||
@import "components/contribution-details";
|
|
||||||
@import "components/contributor-list";
|
|
||||||
@import "components/contributor-profile";
|
|
||||||
@import "components/external-account-link";
|
|
||||||
@import "components/loading-spinner";
|
|
||||||
@import "components/proposal-list";
|
|
||||||
@import "components/topbar";
|
@import "components/topbar";
|
||||||
@import "components/topbar-account-panel";
|
@import "components/loading-spinner";
|
||||||
@import "components/user-avatar";
|
@import "components/contributor-list";
|
||||||
|
@import "components/add-contributor";
|
||||||
|
@import "components/proposal-list";
|
||||||
|
|||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Throws Sass warnings to announce library deprecations. You can disable them
|
||||||
|
/// by setting the `$output-bourbon-deprecation-warnings` variable to `false`.
|
||||||
|
///
|
||||||
|
/// @access private
|
||||||
|
|
||||||
|
@mixin _bourbon-deprecate($feature, $message: null) {
|
||||||
|
@if $output-bourbon-deprecation-warnings == true {
|
||||||
|
@warn "[Bourbon] [Deprecation] `#{$feature}` is deprecated and will be " +
|
||||||
|
"removed in 5.0.0. #{$message}";
|
||||||
|
@content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin _bourbon-deprecate-for-prefixing($feature) {
|
||||||
|
@include _bourbon-deprecate($feature, "We suggest using an automated " +
|
||||||
|
"prefixing tool, like Autoprefixer.");
|
||||||
|
}
|
||||||
@@ -0,0 +1,425 @@
|
|||||||
|
// The following features have been deprecated and will be removed in the next MAJOR version release
|
||||||
|
|
||||||
|
@mixin inline-block {
|
||||||
|
@include _bourbon-deprecate("inline-block");
|
||||||
|
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin button ($style: simple, $base-color: #4294f0, $text-size: inherit, $padding: 7px 18px) {
|
||||||
|
@include _bourbon-deprecate("button");
|
||||||
|
|
||||||
|
@if type-of($style) == string and type-of($base-color) == color {
|
||||||
|
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($style) == string and type-of($base-color) == number {
|
||||||
|
$padding: $text-size;
|
||||||
|
$text-size: $base-color;
|
||||||
|
$base-color: #4294f0;
|
||||||
|
|
||||||
|
@if $padding == inherit {
|
||||||
|
$padding: 7px 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($style) == color and type-of($base-color) == color {
|
||||||
|
$base-color: $style;
|
||||||
|
$style: simple;
|
||||||
|
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($style) == color and type-of($base-color) == number {
|
||||||
|
$padding: $text-size;
|
||||||
|
$text-size: $base-color;
|
||||||
|
$base-color: $style;
|
||||||
|
$style: simple;
|
||||||
|
|
||||||
|
@if $padding == inherit {
|
||||||
|
$padding: 7px 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if type-of($style) == number {
|
||||||
|
$padding: $base-color;
|
||||||
|
$text-size: $style;
|
||||||
|
$base-color: #4294f0;
|
||||||
|
$style: simple;
|
||||||
|
|
||||||
|
@if $padding == #4294f0 {
|
||||||
|
$padding: 7px 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include buttonstyle($style, $base-color, $text-size, $padding);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Selector Style Button
|
||||||
|
@mixin buttonstyle($type, $b-color, $t-size, $pad) {
|
||||||
|
// Grayscale button
|
||||||
|
@if $type == simple and $b-color == grayscale($b-color) {
|
||||||
|
@include simple($b-color, true, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $type == shiny and $b-color == grayscale($b-color) {
|
||||||
|
@include shiny($b-color, true, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $type == pill and $b-color == grayscale($b-color) {
|
||||||
|
@include pill($b-color, true, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $type == flat and $b-color == grayscale($b-color) {
|
||||||
|
@include flat($b-color, true, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Colored button
|
||||||
|
@if $type == simple {
|
||||||
|
@include simple($b-color, false, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $type == shiny {
|
||||||
|
@include shiny($b-color, false, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $type == pill {
|
||||||
|
@include pill($b-color, false, $t-size, $pad);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $type == flat {
|
||||||
|
@include flat($b-color, false, $t-size, $pad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple Button
|
||||||
|
@mixin simple($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||||
|
$inset-shadow: adjust-color($base-color, $saturation: -8%, $lightness: 15%);
|
||||||
|
$stop-gradient: adjust-color($base-color, $saturation: 9%, $lightness: -11%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 15%, $lightness: -18%);
|
||||||
|
|
||||||
|
@if is-light($base-color) {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border: grayscale($border);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$stop-gradient: grayscale($stop-gradient);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $textsize;
|
||||||
|
font-weight: bold;
|
||||||
|
@include linear-gradient ($base-color, $stop-gradient);
|
||||||
|
padding: $padding;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 1px 0 $text-shadow;
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$base-color-hover: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
|
||||||
|
$inset-shadow-hover: adjust-color($base-color, $saturation: -7%, $lightness: 5%);
|
||||||
|
$stop-gradient-hover: adjust-color($base-color, $saturation: 8%, $lightness: -14%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-hover: grayscale($base-color-hover);
|
||||||
|
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||||
|
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||||
|
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled),
|
||||||
|
&:focus:not(:disabled) {
|
||||||
|
$border-active: adjust-color($base-color, $saturation: 9%, $lightness: -14%);
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $saturation: 7%, $lightness: -17%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border-active: grayscale($border-active);
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border-active;
|
||||||
|
box-shadow: inset 0 0 8px 4px $inset-shadow-active, inset 0 0 8px 4px $inset-shadow-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shiny Button
|
||||||
|
@mixin shiny($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border: adjust-color($base-color, $red: -117, $green: -111, $blue: -81);
|
||||||
|
$border-bottom: adjust-color($base-color, $red: -126, $green: -127, $blue: -122);
|
||||||
|
$fourth-stop: adjust-color($base-color, $red: -79, $green: -70, $blue: -46);
|
||||||
|
$inset-shadow: adjust-color($base-color, $red: 37, $green: 29, $blue: 12);
|
||||||
|
$second-stop: adjust-color($base-color, $red: -56, $green: -50, $blue: -33);
|
||||||
|
$text-shadow: adjust-color($base-color, $red: -140, $green: -141, $blue: -114);
|
||||||
|
$third-stop: adjust-color($base-color, $red: -86, $green: -75, $blue: -48);
|
||||||
|
|
||||||
|
@if is-light($base-color) {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border: grayscale($border);
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$fourth-stop: grayscale($fourth-stop);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$second-stop: grayscale($second-stop);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
$third-stop: grayscale($third-stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include linear-gradient(top, $base-color 0%, $second-stop 50%, $third-stop 50%, $fourth-stop 100%);
|
||||||
|
|
||||||
|
border: 1px solid $border;
|
||||||
|
border-bottom: 1px solid $border-bottom;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $textsize;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: $padding;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$first-stop-hover: adjust-color($base-color, $red: -13, $green: -15, $blue: -18);
|
||||||
|
$second-stop-hover: adjust-color($base-color, $red: -66, $green: -62, $blue: -51);
|
||||||
|
$third-stop-hover: adjust-color($base-color, $red: -93, $green: -85, $blue: -66);
|
||||||
|
$fourth-stop-hover: adjust-color($base-color, $red: -86, $green: -80, $blue: -63);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$first-stop-hover: grayscale($first-stop-hover);
|
||||||
|
$second-stop-hover: grayscale($second-stop-hover);
|
||||||
|
$third-stop-hover: grayscale($third-stop-hover);
|
||||||
|
$fourth-stop-hover: grayscale($fourth-stop-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include linear-gradient(top, $first-stop-hover 0%,
|
||||||
|
$second-stop-hover 50%,
|
||||||
|
$third-stop-hover 50%,
|
||||||
|
$fourth-stop-hover 100%);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled),
|
||||||
|
&:focus:not(:disabled) {
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $red: -111, $green: -116, $blue: -122);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
box-shadow: inset 0 0 20px 0 $inset-shadow-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pill Button
|
||||||
|
@mixin pill($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: -11%, $lightness: -26%);
|
||||||
|
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -21%, $lightness: -21%);
|
||||||
|
$border-top: adjust-color($base-color, $hue: -1, $saturation: -30%, $lightness: -15%);
|
||||||
|
$inset-shadow: adjust-color($base-color, $hue: -1, $saturation: -1%, $lightness: 7%);
|
||||||
|
$stop-gradient: adjust-color($base-color, $hue: 8, $saturation: 14%, $lightness: -10%);
|
||||||
|
$text-shadow: adjust-color($base-color, $hue: 5, $saturation: -19%, $lightness: -15%);
|
||||||
|
|
||||||
|
@if is-light($base-color) {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
$text-shadow: adjust-color($base-color, $saturation: 10%, $lightness: 4%);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$border-sides: grayscale($border-sides);
|
||||||
|
$border-top: grayscale($border-top);
|
||||||
|
$inset-shadow: grayscale($inset-shadow);
|
||||||
|
$stop-gradient: grayscale($stop-gradient);
|
||||||
|
$text-shadow: grayscale($text-shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
border: 1px solid $border-top;
|
||||||
|
border-color: $border-top $border-sides $border-bottom;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $textsize;
|
||||||
|
font-weight: normal;
|
||||||
|
line-height: 1;
|
||||||
|
@include linear-gradient ($base-color, $stop-gradient);
|
||||||
|
padding: $padding;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow;
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
&:hover:not(:disabled) {
|
||||||
|
$base-color-hover: adjust-color($base-color, $lightness: -4.5%);
|
||||||
|
$border-bottom: adjust-color($base-color, $hue: 8, $saturation: 13.5%, $lightness: -32%);
|
||||||
|
$border-sides: adjust-color($base-color, $hue: 4, $saturation: -2%, $lightness: -27%);
|
||||||
|
$border-top: adjust-color($base-color, $hue: -1, $saturation: -17%, $lightness: -21%);
|
||||||
|
$inset-shadow-hover: adjust-color($base-color, $saturation: -1%, $lightness: 3%);
|
||||||
|
$stop-gradient-hover: adjust-color($base-color, $hue: 8, $saturation: -4%, $lightness: -15.5%);
|
||||||
|
$text-shadow-hover: adjust-color($base-color, $hue: 5, $saturation: -5%, $lightness: -22%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-hover: grayscale($base-color-hover);
|
||||||
|
$border-bottom: grayscale($border-bottom);
|
||||||
|
$border-sides: grayscale($border-sides);
|
||||||
|
$border-top: grayscale($border-top);
|
||||||
|
$inset-shadow-hover: grayscale($inset-shadow-hover);
|
||||||
|
$stop-gradient-hover: grayscale($stop-gradient-hover);
|
||||||
|
$text-shadow-hover: grayscale($text-shadow-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include linear-gradient ($base-color-hover, $stop-gradient-hover);
|
||||||
|
|
||||||
|
background-clip: padding-box;
|
||||||
|
border: 1px solid $border-top;
|
||||||
|
border-color: $border-top $border-sides $border-bottom;
|
||||||
|
box-shadow: inset 0 1px 0 0 $inset-shadow-hover;
|
||||||
|
cursor: pointer;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow-hover;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled),
|
||||||
|
&:focus:not(:disabled) {
|
||||||
|
$active-color: adjust-color($base-color, $hue: 4, $saturation: -12%, $lightness: -10%);
|
||||||
|
$border-active: adjust-color($base-color, $hue: 6, $saturation: -2.5%, $lightness: -30%);
|
||||||
|
$border-bottom-active: adjust-color($base-color, $hue: 11, $saturation: 6%, $lightness: -31%);
|
||||||
|
$inset-shadow-active: adjust-color($base-color, $hue: 9, $saturation: 2%, $lightness: -21.5%);
|
||||||
|
$text-shadow-active: adjust-color($base-color, $hue: 5, $saturation: -12%, $lightness: -21.5%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$active-color: grayscale($active-color);
|
||||||
|
$border-active: grayscale($border-active);
|
||||||
|
$border-bottom-active: grayscale($border-bottom-active);
|
||||||
|
$inset-shadow-active: grayscale($inset-shadow-active);
|
||||||
|
$text-shadow-active: grayscale($text-shadow-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
background: $active-color;
|
||||||
|
border: 1px solid $border-active;
|
||||||
|
border-bottom: 1px solid $border-bottom-active;
|
||||||
|
box-shadow: inset 0 0 6px 3px $inset-shadow-active;
|
||||||
|
text-shadow: 0 -1px 1px $text-shadow-active;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flat Button
|
||||||
|
@mixin flat($base-color, $grayscale: false, $textsize: inherit, $padding: 7px 18px) {
|
||||||
|
$color: hsl(0, 0, 100%);
|
||||||
|
|
||||||
|
@if is-light($base-color) {
|
||||||
|
$color: hsl(0, 0, 20%);
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: $base-color;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 0;
|
||||||
|
color: $color;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: $textsize;
|
||||||
|
font-weight: bold;
|
||||||
|
padding: $padding;
|
||||||
|
text-decoration: none;
|
||||||
|
background-clip: padding-box;
|
||||||
|
|
||||||
|
&:hover:not(:disabled){
|
||||||
|
$base-color-hover: adjust-color($base-color, $saturation: 4%, $lightness: 5%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-hover: grayscale($base-color-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: $base-color-hover;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:not(:disabled),
|
||||||
|
&:focus:not(:disabled) {
|
||||||
|
$base-color-active: adjust-color($base-color, $saturation: -4%, $lightness: -5%);
|
||||||
|
|
||||||
|
@if $grayscale == true {
|
||||||
|
$base-color-active: grayscale($base-color-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
background-color: $base-color-active;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flexible grid
|
||||||
|
@function flex-grid($columns, $container-columns: $fg-max-columns) {
|
||||||
|
@if $output-bourbon-deprecation-warnings == true {
|
||||||
|
@warn "[Bourbon] [Deprecation] `flex-grid` is deprecated and will be " +
|
||||||
|
"removed in 5.0.0. For grid functions, check out Bourbon's sister library" +
|
||||||
|
"Neat.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$width: $columns * $fg-column + ($columns - 1) * $fg-gutter;
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($width / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flexible gutter
|
||||||
|
@function flex-gutter($container-columns: $fg-max-columns, $gutter: $fg-gutter) {
|
||||||
|
@if $output-bourbon-deprecation-warnings == true {
|
||||||
|
@warn "[Bourbon] [Deprecation] `flex-gutter` is deprecated and will be " +
|
||||||
|
"removed in 5.0.0. For grid functions, check out Bourbon's sister library" +
|
||||||
|
"Neat.";
|
||||||
|
}
|
||||||
|
|
||||||
|
$container-width: $container-columns * $fg-column + ($container-columns - 1) * $fg-gutter;
|
||||||
|
@return percentage($gutter / $container-width);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function grid-width($n) {
|
||||||
|
@if $output-bourbon-deprecation-warnings == true {
|
||||||
|
@warn "[Bourbon] [Deprecation] `grid-width` is deprecated and will be " +
|
||||||
|
"removed in 5.0.0. For grid functions, check out Bourbon's sister library" +
|
||||||
|
"Neat.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@return $n * $gw-column + ($n - 1) * $gw-gutter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@function golden-ratio($value, $increment) {
|
||||||
|
@if $output-bourbon-deprecation-warnings == true {
|
||||||
|
@warn "[Bourbon] [Deprecation] `golden-ratio` is deprecated and will be " +
|
||||||
|
"removed in 5.0.0. You can use the `modular-scale` function instead.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@return modular-scale($increment, $value, $ratio: $golden);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-sizing($box) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-sizing");
|
||||||
|
|
||||||
|
@include prefixer(box-sizing, $box, webkit moz spec);
|
||||||
|
}
|
||||||
Vendored
+90
@@ -0,0 +1,90 @@
|
|||||||
|
// Bourbon 4.3.0
|
||||||
|
// http://bourbon.io
|
||||||
|
// Copyright 2011-2017 thoughtbot, inc.
|
||||||
|
// MIT License
|
||||||
|
|
||||||
|
@import "settings/deprecation-warnings";
|
||||||
|
@import "settings/prefixer";
|
||||||
|
@import "settings/px-to-em";
|
||||||
|
@import "settings/asset-pipeline";
|
||||||
|
|
||||||
|
@import "bourbon-deprecate";
|
||||||
|
|
||||||
|
@import "functions/assign-inputs";
|
||||||
|
@import "functions/contains";
|
||||||
|
@import "functions/contains-falsy";
|
||||||
|
@import "functions/is-length";
|
||||||
|
@import "functions/is-light";
|
||||||
|
@import "functions/is-number";
|
||||||
|
@import "functions/is-size";
|
||||||
|
@import "functions/px-to-em";
|
||||||
|
@import "functions/px-to-rem";
|
||||||
|
@import "functions/shade";
|
||||||
|
@import "functions/strip-units";
|
||||||
|
@import "functions/tint";
|
||||||
|
@import "functions/transition-property-name";
|
||||||
|
@import "functions/unpack";
|
||||||
|
@import "functions/modular-scale";
|
||||||
|
|
||||||
|
@import "helpers/convert-units";
|
||||||
|
@import "helpers/directional-values";
|
||||||
|
@import "helpers/font-source-declaration";
|
||||||
|
@import "helpers/gradient-positions-parser";
|
||||||
|
@import "helpers/linear-angle-parser";
|
||||||
|
@import "helpers/linear-gradient-parser";
|
||||||
|
@import "helpers/linear-positions-parser";
|
||||||
|
@import "helpers/linear-side-corner-parser";
|
||||||
|
@import "helpers/radial-arg-parser";
|
||||||
|
@import "helpers/radial-positions-parser";
|
||||||
|
@import "helpers/radial-gradient-parser";
|
||||||
|
@import "helpers/render-gradients";
|
||||||
|
@import "helpers/shape-size-stripper";
|
||||||
|
@import "helpers/str-to-num";
|
||||||
|
|
||||||
|
@import "css3/animation";
|
||||||
|
@import "css3/appearance";
|
||||||
|
@import "css3/backface-visibility";
|
||||||
|
@import "css3/background";
|
||||||
|
@import "css3/background-image";
|
||||||
|
@import "css3/border-image";
|
||||||
|
@import "css3/calc";
|
||||||
|
@import "css3/columns";
|
||||||
|
@import "css3/filter";
|
||||||
|
@import "css3/flex-box";
|
||||||
|
@import "css3/font-face";
|
||||||
|
@import "css3/font-feature-settings";
|
||||||
|
@import "css3/hidpi-media-query";
|
||||||
|
@import "css3/hyphens";
|
||||||
|
@import "css3/image-rendering";
|
||||||
|
@import "css3/keyframes";
|
||||||
|
@import "css3/linear-gradient";
|
||||||
|
@import "css3/perspective";
|
||||||
|
@import "css3/placeholder";
|
||||||
|
@import "css3/radial-gradient";
|
||||||
|
@import "css3/selection";
|
||||||
|
@import "css3/text-decoration";
|
||||||
|
@import "css3/transform";
|
||||||
|
@import "css3/transition";
|
||||||
|
@import "css3/user-select";
|
||||||
|
|
||||||
|
@import "addons/border-color";
|
||||||
|
@import "addons/border-radius";
|
||||||
|
@import "addons/border-style";
|
||||||
|
@import "addons/border-width";
|
||||||
|
@import "addons/buttons";
|
||||||
|
@import "addons/clearfix";
|
||||||
|
@import "addons/ellipsis";
|
||||||
|
@import "addons/font-stacks";
|
||||||
|
@import "addons/hide-text";
|
||||||
|
@import "addons/margin";
|
||||||
|
@import "addons/padding";
|
||||||
|
@import "addons/position";
|
||||||
|
@import "addons/prefixer";
|
||||||
|
@import "addons/retina-image";
|
||||||
|
@import "addons/size";
|
||||||
|
@import "addons/text-inputs";
|
||||||
|
@import "addons/timing-functions";
|
||||||
|
@import "addons/triangle";
|
||||||
|
@import "addons/word-wrap";
|
||||||
|
|
||||||
|
@import "bourbon-deprecated-upcoming";
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `border-color` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $vals
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include border-color(#a60b55 #76cd9c null #e8ae1a);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// border-left-color: #e8ae1a;
|
||||||
|
/// border-right-color: #76cd9c;
|
||||||
|
/// border-top-color: #a60b55;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {mixin} directional-property
|
||||||
|
///
|
||||||
|
/// @output `border-color`
|
||||||
|
|
||||||
|
@mixin border-color($vals...) {
|
||||||
|
@include directional-property(border, color, $vals...);
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `border-radius` on both corners on the side of a box.
|
||||||
|
///
|
||||||
|
/// @param {Number} $radii
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element-one {
|
||||||
|
/// @include border-top-radius(5px);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// .element-two {
|
||||||
|
/// @include border-left-radius(3px);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element-one {
|
||||||
|
/// border-top-left-radius: 5px;
|
||||||
|
/// border-top-right-radius: 5px;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// .element-two {
|
||||||
|
/// border-bottom-left-radius: 3px;
|
||||||
|
/// border-top-left-radius: 3px;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @output `border-radius`
|
||||||
|
|
||||||
|
@mixin border-top-radius($radii) {
|
||||||
|
border-top-left-radius: $radii;
|
||||||
|
border-top-right-radius: $radii;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-right-radius($radii) {
|
||||||
|
border-bottom-right-radius: $radii;
|
||||||
|
border-top-right-radius: $radii;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-bottom-radius($radii) {
|
||||||
|
border-bottom-left-radius: $radii;
|
||||||
|
border-bottom-right-radius: $radii;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin border-left-radius($radii) {
|
||||||
|
border-bottom-left-radius: $radii;
|
||||||
|
border-top-left-radius: $radii;
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `border-style` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $vals
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include border-style(dashed null solid);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// border-bottom-style: solid;
|
||||||
|
/// border-top-style: dashed;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {mixin} directional-property
|
||||||
|
///
|
||||||
|
/// @output `border-style`
|
||||||
|
|
||||||
|
@mixin border-style($vals...) {
|
||||||
|
@include directional-property(border, style, $vals...);
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `border-width` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $vals
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include border-width(1em null 20px);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// border-bottom-width: 20px;
|
||||||
|
/// border-top-width: 1em;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {mixin} directional-property
|
||||||
|
///
|
||||||
|
/// @output `border-width`
|
||||||
|
|
||||||
|
@mixin border-width($vals...) {
|
||||||
|
@include directional-property(border, width, $vals...);
|
||||||
|
}
|
||||||
+64
@@ -0,0 +1,64 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Generates variables for all buttons. Please note that you must use interpolation on the variable: `#{$all-buttons}`.
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// #{$all-buttons} {
|
||||||
|
/// background-color: #f00;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #{$all-buttons-focus},
|
||||||
|
/// #{$all-buttons-hover} {
|
||||||
|
/// background-color: #0f0;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #{$all-buttons-active} {
|
||||||
|
/// background-color: #00f;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// button,
|
||||||
|
/// input[type="button"],
|
||||||
|
/// input[type="reset"],
|
||||||
|
/// input[type="submit"] {
|
||||||
|
/// background-color: #f00;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// button:focus,
|
||||||
|
/// input[type="button"]:focus,
|
||||||
|
/// input[type="reset"]:focus,
|
||||||
|
/// input[type="submit"]:focus,
|
||||||
|
/// button:hover,
|
||||||
|
/// input[type="button"]:hover,
|
||||||
|
/// input[type="reset"]:hover,
|
||||||
|
/// input[type="submit"]:hover {
|
||||||
|
/// background-color: #0f0;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// button:active,
|
||||||
|
/// input[type="button"]:active,
|
||||||
|
/// input[type="reset"]:active,
|
||||||
|
/// input[type="submit"]:active {
|
||||||
|
/// background-color: #00f;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require assign-inputs
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
///
|
||||||
|
/// @todo Remove double assigned variables (Lines 59–62) in v5.0.0
|
||||||
|
|
||||||
|
$buttons-list: 'button',
|
||||||
|
'input[type="button"]',
|
||||||
|
'input[type="reset"]',
|
||||||
|
'input[type="submit"]';
|
||||||
|
|
||||||
|
$all-buttons: assign-inputs($buttons-list);
|
||||||
|
$all-buttons-active: assign-inputs($buttons-list, active);
|
||||||
|
$all-buttons-focus: assign-inputs($buttons-list, focus);
|
||||||
|
$all-buttons-hover: assign-inputs($buttons-list, hover);
|
||||||
|
|
||||||
|
$all-button-inputs: $all-buttons;
|
||||||
|
$all-button-inputs-active: $all-buttons-active;
|
||||||
|
$all-button-inputs-focus: $all-buttons-focus;
|
||||||
|
$all-button-inputs-hover: $all-buttons-hover;
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides an easy way to include a clearfix for containing floats.
|
||||||
|
///
|
||||||
|
/// @link http://cssmojo.com/latest_new_clearfix_so_far/
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include clearfix;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element::after {
|
||||||
|
/// clear: both;
|
||||||
|
/// content: "";
|
||||||
|
/// display: table;
|
||||||
|
/// }
|
||||||
|
|
||||||
|
@mixin clearfix {
|
||||||
|
&::after {
|
||||||
|
clear: both;
|
||||||
|
content: "";
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Truncates text and adds an ellipsis to represent overflow.
|
||||||
|
///
|
||||||
|
/// @param {Number} $width [100%]
|
||||||
|
/// Max-width for the string to respect before being truncated
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include ellipsis;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// display: inline-block;
|
||||||
|
/// max-width: 100%;
|
||||||
|
/// overflow: hidden;
|
||||||
|
/// text-overflow: ellipsis;
|
||||||
|
/// white-space: nowrap;
|
||||||
|
/// word-wrap: normal;
|
||||||
|
/// }
|
||||||
|
|
||||||
|
@mixin ellipsis($width: 100%) {
|
||||||
|
display: inline-block;
|
||||||
|
max-width: $width;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
word-wrap: normal;
|
||||||
|
}
|
||||||
+31
@@ -0,0 +1,31 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Georgia font stack.
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$georgia: "Georgia", "Cambria", "Times New Roman", "Times", serif;
|
||||||
|
|
||||||
|
/// Helvetica font stack.
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$helvetica: "Helvetica Neue", "Helvetica", "Roboto", "Arial", sans-serif;
|
||||||
|
|
||||||
|
/// Lucida Grande font stack.
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$lucida-grande: "Lucida Grande", "Tahoma", "Verdana", "Arial", sans-serif;
|
||||||
|
|
||||||
|
/// Monospace font stack.
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$monospace: "Bitstream Vera Sans Mono", "Consolas", "Courier", monospace;
|
||||||
|
|
||||||
|
/// Verdana font stack.
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$verdana: "Verdana", "Geneva", sans-serif;
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
/// Hides the text in an element, commonly used to show an image. Some elements will need block-level styles applied.
|
||||||
|
///
|
||||||
|
/// @link http://zeldman.com/2012/03/01/replacing-the-9999px-hack-new-image-replacement
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include hide-text;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// overflow: hidden;
|
||||||
|
/// text-indent: 101%;
|
||||||
|
/// white-space: nowrap;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @todo Remove height argument in v5.0.0
|
||||||
|
|
||||||
|
@mixin hide-text($height: null) {
|
||||||
|
overflow: hidden;
|
||||||
|
text-indent: 101%;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
@if $height {
|
||||||
|
@warn "The `hide-text` mixin has changed and no longer requires a height. The height argument will no longer be accepted in v5.0.0";
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `margin` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $vals
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include margin(null 10px 3em 20vh);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// margin-bottom: 3em;
|
||||||
|
/// margin-left: 20vh;
|
||||||
|
/// margin-right: 10px;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {mixin} directional-property
|
||||||
|
///
|
||||||
|
/// @output `margin`
|
||||||
|
|
||||||
|
@mixin margin($vals...) {
|
||||||
|
@include directional-property(margin, false, $vals...);
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for targeting `padding` on specific sides of a box. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $vals
|
||||||
|
/// List of arguments
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include padding(12vh null 10px 5%);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// padding-bottom: 10px;
|
||||||
|
/// padding-left: 5%;
|
||||||
|
/// padding-top: 12vh;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {mixin} directional-property
|
||||||
|
///
|
||||||
|
/// @output `padding`
|
||||||
|
|
||||||
|
@mixin padding($vals...) {
|
||||||
|
@include directional-property(padding, false, $vals...);
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides a quick method for setting an element’s position. Use a `null` value to “skip” a side.
|
||||||
|
///
|
||||||
|
/// @param {Position} $position [relative]
|
||||||
|
/// A CSS position value
|
||||||
|
///
|
||||||
|
/// @param {Arglist} $coordinates [null null null null]
|
||||||
|
/// List of values that correspond to the 4-value syntax for the edges of a box
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include position(absolute, 0 null null 10em);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// left: 10em;
|
||||||
|
/// position: absolute;
|
||||||
|
/// top: 0;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {function} is-length
|
||||||
|
/// @require {function} unpack
|
||||||
|
|
||||||
|
@mixin position($position: relative, $coordinates: null null null null) {
|
||||||
|
@if type-of($position) == list {
|
||||||
|
$coordinates: $position;
|
||||||
|
$position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
$coordinates: unpack($coordinates);
|
||||||
|
|
||||||
|
$offsets: (
|
||||||
|
top: nth($coordinates, 1),
|
||||||
|
right: nth($coordinates, 2),
|
||||||
|
bottom: nth($coordinates, 3),
|
||||||
|
left: nth($coordinates, 4)
|
||||||
|
);
|
||||||
|
|
||||||
|
position: $position;
|
||||||
|
|
||||||
|
@each $offset, $value in $offsets {
|
||||||
|
@if is-length($value) {
|
||||||
|
#{$offset}: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+66
@@ -0,0 +1,66 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// A mixin for generating vendor prefixes on non-standardized properties.
|
||||||
|
///
|
||||||
|
/// @param {String} $property
|
||||||
|
/// Property to prefix
|
||||||
|
///
|
||||||
|
/// @param {*} $value
|
||||||
|
/// Value to use
|
||||||
|
///
|
||||||
|
/// @param {List} $prefixes
|
||||||
|
/// Prefixes to define
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .element {
|
||||||
|
/// @include prefixer(border-radius, 10px, webkit ms spec);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .element {
|
||||||
|
/// -webkit-border-radius: 10px;
|
||||||
|
/// -moz-border-radius: 10px;
|
||||||
|
/// border-radius: 10px;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require {variable} $prefix-for-webkit
|
||||||
|
/// @require {variable} $prefix-for-mozilla
|
||||||
|
/// @require {variable} $prefix-for-microsoft
|
||||||
|
/// @require {variable} $prefix-for-opera
|
||||||
|
/// @require {variable} $prefix-for-spec
|
||||||
|
|
||||||
|
@mixin prefixer($property, $value, $prefixes) {
|
||||||
|
@each $prefix in $prefixes {
|
||||||
|
@if $prefix == webkit {
|
||||||
|
@if $prefix-for-webkit {
|
||||||
|
-webkit-#{$property}: $value;
|
||||||
|
}
|
||||||
|
} @else if $prefix == moz {
|
||||||
|
@if $prefix-for-mozilla {
|
||||||
|
-moz-#{$property}: $value;
|
||||||
|
}
|
||||||
|
} @else if $prefix == ms {
|
||||||
|
@if $prefix-for-microsoft {
|
||||||
|
-ms-#{$property}: $value;
|
||||||
|
}
|
||||||
|
} @else if $prefix == o {
|
||||||
|
@if $prefix-for-opera {
|
||||||
|
-o-#{$property}: $value;
|
||||||
|
}
|
||||||
|
} @else if $prefix == spec {
|
||||||
|
@if $prefix-for-spec {
|
||||||
|
#{$property}: $value;
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@warn "Unrecognized prefix: #{$prefix}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin disable-prefix-for-all() {
|
||||||
|
$prefix-for-webkit: false !global;
|
||||||
|
$prefix-for-mozilla: false !global;
|
||||||
|
$prefix-for-microsoft: false !global;
|
||||||
|
$prefix-for-opera: false !global;
|
||||||
|
$prefix-for-spec: false !global;
|
||||||
|
}
|
||||||
+27
@@ -0,0 +1,27 @@
|
|||||||
|
@mixin retina-image($filename, $background-size, $extension: png, $retina-filename: null, $retina-suffix: _2x, $asset-pipeline: $asset-pipeline) {
|
||||||
|
@include _bourbon-deprecate("retina-image");
|
||||||
|
|
||||||
|
@if $asset-pipeline {
|
||||||
|
background-image: image-url("#{$filename}.#{$extension}");
|
||||||
|
} @else {
|
||||||
|
background-image: url("#{$filename}.#{$extension}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@include hidpi {
|
||||||
|
@if $asset-pipeline {
|
||||||
|
@if $retina-filename {
|
||||||
|
background-image: image-url("#{$retina-filename}.#{$extension}");
|
||||||
|
} @else {
|
||||||
|
background-image: image-url("#{$filename}#{$retina-suffix}.#{$extension}");
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
@if $retina-filename {
|
||||||
|
background-image: url("#{$retina-filename}.#{$extension}");
|
||||||
|
} @else {
|
||||||
|
background-image: url("#{$filename}#{$retina-suffix}.#{$extension}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background-size: $background-size;
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+51
@@ -0,0 +1,51 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Sets the `width` and `height` of the element.
|
||||||
|
///
|
||||||
|
/// @param {List} $size
|
||||||
|
/// A list of at most 2 size values.
|
||||||
|
///
|
||||||
|
/// If there is only a single value in `$size` it is used for both width and height. All units are supported.
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .first-element {
|
||||||
|
/// @include size(2em);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// .second-element {
|
||||||
|
/// @include size(auto 10em);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .first-element {
|
||||||
|
/// width: 2em;
|
||||||
|
/// height: 2em;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// .second-element {
|
||||||
|
/// width: auto;
|
||||||
|
/// height: 10em;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @todo Refactor in 5.0.0 to use a comma-separated argument
|
||||||
|
|
||||||
|
@mixin size($value) {
|
||||||
|
$width: nth($value, 1);
|
||||||
|
$height: $width;
|
||||||
|
|
||||||
|
@if length($value) > 1 {
|
||||||
|
$height: nth($value, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@if is-size($height) {
|
||||||
|
height: $height;
|
||||||
|
} @else {
|
||||||
|
@warn "`#{$height}` is not a valid length for the `$height` parameter in the `size` mixin.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@if is-size($width) {
|
||||||
|
width: $width;
|
||||||
|
} @else {
|
||||||
|
@warn "`#{$width}` is not a valid length for the `$width` parameter in the `size` mixin.";
|
||||||
|
}
|
||||||
|
}
|
||||||
+113
@@ -0,0 +1,113 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Generates variables for all text-based inputs. Please note that you must use interpolation on the variable: `#{$all-text-inputs}`.
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// #{$all-text-inputs} {
|
||||||
|
/// border: 1px solid #f00;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #{$all-text-inputs-focus},
|
||||||
|
/// #{$all-text-inputs-hover} {
|
||||||
|
/// border: 1px solid #0f0;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// #{$all-text-inputs-active} {
|
||||||
|
/// border: 1px solid #00f;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// input[type="color"],
|
||||||
|
/// input[type="date"],
|
||||||
|
/// input[type="datetime"],
|
||||||
|
/// input[type="datetime-local"],
|
||||||
|
/// input[type="email"],
|
||||||
|
/// input[type="month"],
|
||||||
|
/// input[type="number"],
|
||||||
|
/// input[type="password"],
|
||||||
|
/// input[type="search"],
|
||||||
|
/// input[type="tel"],
|
||||||
|
/// input[type="text"],
|
||||||
|
/// input[type="time"],
|
||||||
|
/// input[type="url"],
|
||||||
|
/// input[type="week"],
|
||||||
|
/// textarea {
|
||||||
|
/// border: 1px solid #f00;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// input[type="color"]:focus,
|
||||||
|
/// input[type="date"]:focus,
|
||||||
|
/// input[type="datetime"]:focus,
|
||||||
|
/// input[type="datetime-local"]:focus,
|
||||||
|
/// input[type="email"]:focus,
|
||||||
|
/// input[type="month"]:focus,
|
||||||
|
/// input[type="number"]:focus,
|
||||||
|
/// input[type="password"]:focus,
|
||||||
|
/// input[type="search"]:focus,
|
||||||
|
/// input[type="tel"]:focus,
|
||||||
|
/// input[type="text"]:focus,
|
||||||
|
/// input[type="time"]:focus,
|
||||||
|
/// input[type="url"]:focus,
|
||||||
|
/// input[type="week"]:focus,
|
||||||
|
/// textarea:focus,
|
||||||
|
/// input[type="color"]:hover,
|
||||||
|
/// input[type="date"]:hover,
|
||||||
|
/// input[type="datetime"]:hover,
|
||||||
|
/// input[type="datetime-local"]:hover,
|
||||||
|
/// input[type="email"]:hover,
|
||||||
|
/// input[type="month"]:hover,
|
||||||
|
/// input[type="number"]:hover,
|
||||||
|
/// input[type="password"]:hover,
|
||||||
|
/// input[type="search"]:hover,
|
||||||
|
/// input[type="tel"]:hover,
|
||||||
|
/// input[type="text"]:hover,
|
||||||
|
/// input[type="time"]:hover,
|
||||||
|
/// input[type="url"]:hover,
|
||||||
|
/// input[type="week"]:hover,
|
||||||
|
/// textarea:hover {
|
||||||
|
/// border: 1px solid #0f0;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// input[type="color"]:active,
|
||||||
|
/// input[type="date"]:active,
|
||||||
|
/// input[type="datetime"]:active,
|
||||||
|
/// input[type="datetime-local"]:active,
|
||||||
|
/// input[type="email"]:active,
|
||||||
|
/// input[type="month"]:active,
|
||||||
|
/// input[type="number"]:active,
|
||||||
|
/// input[type="password"]:active,
|
||||||
|
/// input[type="search"]:active,
|
||||||
|
/// input[type="tel"]:active,
|
||||||
|
/// input[type="text"]:active,
|
||||||
|
/// input[type="time"]:active,
|
||||||
|
/// input[type="url"]:active,
|
||||||
|
/// input[type="week"]:active,
|
||||||
|
/// textarea:active {
|
||||||
|
/// border: 1px solid #00f;
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @require assign-inputs
|
||||||
|
///
|
||||||
|
/// @type List
|
||||||
|
|
||||||
|
$text-inputs-list: 'input[type="color"]',
|
||||||
|
'input[type="date"]',
|
||||||
|
'input[type="datetime"]',
|
||||||
|
'input[type="datetime-local"]',
|
||||||
|
'input[type="email"]',
|
||||||
|
'input[type="month"]',
|
||||||
|
'input[type="number"]',
|
||||||
|
'input[type="password"]',
|
||||||
|
'input[type="search"]',
|
||||||
|
'input[type="tel"]',
|
||||||
|
'input[type="text"]',
|
||||||
|
'input[type="time"]',
|
||||||
|
'input[type="url"]',
|
||||||
|
'input[type="week"]',
|
||||||
|
'input:not([type])',
|
||||||
|
'textarea';
|
||||||
|
|
||||||
|
$all-text-inputs: assign-inputs($text-inputs-list);
|
||||||
|
$all-text-inputs-active: assign-inputs($text-inputs-list, active);
|
||||||
|
$all-text-inputs-focus: assign-inputs($text-inputs-list, focus);
|
||||||
|
$all-text-inputs-hover: assign-inputs($text-inputs-list, hover);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// CSS cubic-bezier timing functions. Timing functions courtesy of jquery.easie (github.com/jaukia/easie)
|
||||||
|
///
|
||||||
|
/// Timing functions are the same as demoed here: http://jqueryui.com/resources/demos/effect/easing.html
|
||||||
|
///
|
||||||
|
/// @type cubic-bezier
|
||||||
|
|
||||||
|
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530);
|
||||||
|
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190);
|
||||||
|
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220);
|
||||||
|
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060);
|
||||||
|
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715);
|
||||||
|
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035);
|
||||||
|
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335);
|
||||||
|
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
||||||
|
|
||||||
|
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940);
|
||||||
|
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000);
|
||||||
|
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000);
|
||||||
|
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000);
|
||||||
|
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000);
|
||||||
|
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
|
||||||
|
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000);
|
||||||
|
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
||||||
|
|
||||||
|
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955);
|
||||||
|
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000);
|
||||||
|
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000);
|
||||||
|
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000);
|
||||||
|
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950);
|
||||||
|
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000);
|
||||||
|
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860);
|
||||||
|
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550);
|
||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
@mixin triangle($size, $color, $direction) {
|
||||||
|
$width: nth($size, 1);
|
||||||
|
$height: nth($size, length($size));
|
||||||
|
$foreground-color: nth($color, 1);
|
||||||
|
$background-color: if(length($color) == 2, nth($color, 2), transparent);
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
|
||||||
|
@if ($direction == up) or ($direction == down) or ($direction == right) or ($direction == left) {
|
||||||
|
$width: $width / 2;
|
||||||
|
$height: if(length($size) > 1, $height, $height/2);
|
||||||
|
|
||||||
|
@if $direction == up {
|
||||||
|
border-bottom: $height solid $foreground-color;
|
||||||
|
border-left: $width solid $background-color;
|
||||||
|
border-right: $width solid $background-color;
|
||||||
|
} @else if $direction == right {
|
||||||
|
border-bottom: $width solid $background-color;
|
||||||
|
border-left: $height solid $foreground-color;
|
||||||
|
border-top: $width solid $background-color;
|
||||||
|
} @else if $direction == down {
|
||||||
|
border-left: $width solid $background-color;
|
||||||
|
border-right: $width solid $background-color;
|
||||||
|
border-top: $height solid $foreground-color;
|
||||||
|
} @else if $direction == left {
|
||||||
|
border-bottom: $width solid $background-color;
|
||||||
|
border-right: $height solid $foreground-color;
|
||||||
|
border-top: $width solid $background-color;
|
||||||
|
}
|
||||||
|
} @else if ($direction == up-right) or ($direction == up-left) {
|
||||||
|
border-top: $height solid $foreground-color;
|
||||||
|
|
||||||
|
@if $direction == up-right {
|
||||||
|
border-left: $width solid $background-color;
|
||||||
|
} @else if $direction == up-left {
|
||||||
|
border-right: $width solid $background-color;
|
||||||
|
}
|
||||||
|
} @else if ($direction == down-right) or ($direction == down-left) {
|
||||||
|
border-bottom: $height solid $foreground-color;
|
||||||
|
|
||||||
|
@if $direction == down-right {
|
||||||
|
border-left: $width solid $background-color;
|
||||||
|
} @else if $direction == down-left {
|
||||||
|
border-right: $width solid $background-color;
|
||||||
|
}
|
||||||
|
} @else if ($direction == inset-up) {
|
||||||
|
border-color: $background-color $background-color $foreground-color;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: $height $width;
|
||||||
|
} @else if ($direction == inset-down) {
|
||||||
|
border-color: $foreground-color $background-color $background-color;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: $height $width;
|
||||||
|
} @else if ($direction == inset-right) {
|
||||||
|
border-color: $background-color $background-color $background-color $foreground-color;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: $width $height;
|
||||||
|
} @else if ($direction == inset-left) {
|
||||||
|
border-color: $background-color $foreground-color $background-color $background-color;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: $width $height;
|
||||||
|
}
|
||||||
|
}
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
@charset "UTF-8";
|
||||||
|
|
||||||
|
/// Provides an easy way to change the `word-wrap` property.
|
||||||
|
///
|
||||||
|
/// @param {String} $wrap [break-word]
|
||||||
|
/// Value for the `word-break` property.
|
||||||
|
///
|
||||||
|
/// @example scss - Usage
|
||||||
|
/// .wrapper {
|
||||||
|
/// @include word-wrap(break-word);
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// @example css - CSS Output
|
||||||
|
/// .wrapper {
|
||||||
|
/// overflow-wrap: break-word;
|
||||||
|
/// word-break: break-all;
|
||||||
|
/// word-wrap: break-word;
|
||||||
|
/// }
|
||||||
|
|
||||||
|
@mixin word-wrap($wrap: break-word) {
|
||||||
|
overflow-wrap: $wrap;
|
||||||
|
word-wrap: $wrap;
|
||||||
|
|
||||||
|
@if $wrap == break-word {
|
||||||
|
word-break: break-all;
|
||||||
|
} @else {
|
||||||
|
word-break: $wrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
// http://www.w3.org/TR/css3-animations/#the-animation-name-property-
|
||||||
|
// Each of these mixins support comma separated lists of values, which allows different transitions for individual properties to be described in a single style rule. Each value in the list corresponds to the value at that same position in the other properties.
|
||||||
|
|
||||||
|
@mixin animation($animations...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation");
|
||||||
|
|
||||||
|
@include prefixer(animation, $animations, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-name($names...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-name");
|
||||||
|
|
||||||
|
@include prefixer(animation-name, $names, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-duration($times...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-duration");
|
||||||
|
|
||||||
|
@include prefixer(animation-duration, $times, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-timing-function($motions...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-timing-function");
|
||||||
|
|
||||||
|
// ease | linear | ease-in | ease-out | ease-in-out
|
||||||
|
@include prefixer(animation-timing-function, $motions, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-iteration-count($values...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-iteration-count");
|
||||||
|
|
||||||
|
// infinite | <number>
|
||||||
|
@include prefixer(animation-iteration-count, $values, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-direction($directions...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-direction");
|
||||||
|
|
||||||
|
// normal | alternate
|
||||||
|
@include prefixer(animation-direction, $directions, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-play-state($states...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-play-state");
|
||||||
|
|
||||||
|
// running | paused
|
||||||
|
@include prefixer(animation-play-state, $states, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-delay($times...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-delay");
|
||||||
|
|
||||||
|
@include prefixer(animation-delay, $times, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin animation-fill-mode($modes...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("animation-fill-mode");
|
||||||
|
|
||||||
|
// none | forwards | backwards | both
|
||||||
|
@include prefixer(animation-fill-mode, $modes, webkit moz spec);
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
@mixin appearance($value) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("appearance");
|
||||||
|
|
||||||
|
@include prefixer(appearance, $value, webkit moz ms o spec);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@mixin backface-visibility($visibility) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("backface-visibility");
|
||||||
|
|
||||||
|
@include prefixer(backface-visibility, $visibility, webkit spec);
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Background-image property for adding multiple background images with
|
||||||
|
// gradients, or for stringing multiple gradients together.
|
||||||
|
//************************************************************************//
|
||||||
|
|
||||||
|
@mixin background-image($images...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("background-image");
|
||||||
|
|
||||||
|
$webkit-images: ();
|
||||||
|
$spec-images: ();
|
||||||
|
|
||||||
|
@each $image in $images {
|
||||||
|
$webkit-image: ();
|
||||||
|
$spec-image: ();
|
||||||
|
|
||||||
|
@if (type-of($image) == string) {
|
||||||
|
$url-str: str-slice($image, 1, 3);
|
||||||
|
$gradient-type: str-slice($image, 1, 6);
|
||||||
|
|
||||||
|
@if $url-str == "url" {
|
||||||
|
$webkit-image: $image;
|
||||||
|
$spec-image: $image;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "linear" {
|
||||||
|
$gradients: _linear-gradient-parser($image);
|
||||||
|
$webkit-image: map-get($gradients, webkit-image);
|
||||||
|
$spec-image: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "radial" {
|
||||||
|
$gradients: _radial-gradient-parser($image);
|
||||||
|
$webkit-image: map-get($gradients, webkit-image);
|
||||||
|
$spec-image: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$webkit-images: append($webkit-images, $webkit-image, comma);
|
||||||
|
$spec-images: append($spec-images, $spec-image, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
background-image: $webkit-images;
|
||||||
|
background-image: $spec-images;
|
||||||
|
}
|
||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
//************************************************************************//
|
||||||
|
// Background property for adding multiple backgrounds using shorthand
|
||||||
|
// notation.
|
||||||
|
//************************************************************************//
|
||||||
|
|
||||||
|
@mixin background($backgrounds...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("background");
|
||||||
|
|
||||||
|
$webkit-backgrounds: ();
|
||||||
|
$spec-backgrounds: ();
|
||||||
|
|
||||||
|
@each $background in $backgrounds {
|
||||||
|
$webkit-background: ();
|
||||||
|
$spec-background: ();
|
||||||
|
$background-type: type-of($background);
|
||||||
|
|
||||||
|
@if $background-type == string or $background-type == list {
|
||||||
|
$background-str: if($background-type == list, nth($background, 1), $background);
|
||||||
|
|
||||||
|
$url-str: str-slice($background-str, 1, 3);
|
||||||
|
$gradient-type: str-slice($background-str, 1, 6);
|
||||||
|
|
||||||
|
@if $url-str == "url" {
|
||||||
|
$webkit-background: $background;
|
||||||
|
$spec-background: $background;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "linear" {
|
||||||
|
$gradients: _linear-gradient-parser("#{$background}");
|
||||||
|
$webkit-background: map-get($gradients, webkit-image);
|
||||||
|
$spec-background: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "radial" {
|
||||||
|
$gradients: _radial-gradient-parser("#{$background}");
|
||||||
|
$webkit-background: map-get($gradients, webkit-image);
|
||||||
|
$spec-background: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$webkit-background: $background;
|
||||||
|
$spec-background: $background;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$webkit-background: $background;
|
||||||
|
$spec-background: $background;
|
||||||
|
}
|
||||||
|
|
||||||
|
$webkit-backgrounds: append($webkit-backgrounds, $webkit-background, comma);
|
||||||
|
$spec-backgrounds: append($spec-backgrounds, $spec-background, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
background: $webkit-backgrounds;
|
||||||
|
background: $spec-backgrounds;
|
||||||
|
}
|
||||||
+61
@@ -0,0 +1,61 @@
|
|||||||
|
@mixin border-image($borders...) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("border-image");
|
||||||
|
|
||||||
|
$webkit-borders: ();
|
||||||
|
$spec-borders: ();
|
||||||
|
|
||||||
|
@each $border in $borders {
|
||||||
|
$webkit-border: ();
|
||||||
|
$spec-border: ();
|
||||||
|
$border-type: type-of($border);
|
||||||
|
|
||||||
|
@if $border-type == string or list {
|
||||||
|
$border-str: if($border-type == list, nth($border, 1), $border);
|
||||||
|
|
||||||
|
$url-str: str-slice($border-str, 1, 3);
|
||||||
|
$gradient-type: str-slice($border-str, 1, 6);
|
||||||
|
|
||||||
|
@if $url-str == "url" {
|
||||||
|
$webkit-border: $border;
|
||||||
|
$spec-border: $border;
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "linear" {
|
||||||
|
$gradients: _linear-gradient-parser("#{$border}");
|
||||||
|
$webkit-border: map-get($gradients, webkit-image);
|
||||||
|
$spec-border: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else if $gradient-type == "radial" {
|
||||||
|
$gradients: _radial-gradient-parser("#{$border}");
|
||||||
|
$webkit-border: map-get($gradients, webkit-image);
|
||||||
|
$spec-border: map-get($gradients, spec-image);
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$webkit-border: $border;
|
||||||
|
$spec-border: $border;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@else {
|
||||||
|
$webkit-border: $border;
|
||||||
|
$spec-border: $border;
|
||||||
|
}
|
||||||
|
|
||||||
|
$webkit-borders: append($webkit-borders, $webkit-border, comma);
|
||||||
|
$spec-borders: append($spec-borders, $spec-border, comma);
|
||||||
|
}
|
||||||
|
|
||||||
|
-webkit-border-image: $webkit-borders;
|
||||||
|
border-image: $spec-borders;
|
||||||
|
border-style: solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Examples:
|
||||||
|
// @include border-image(url("image.png"));
|
||||||
|
// @include border-image(url("image.png") 20 stretch);
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow));
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow) stretch);
|
||||||
|
// @include border-image(linear-gradient(45deg, orange, yellow) 20 30 40 50 stretch round);
|
||||||
|
// @include border-image(radial-gradient(top, cover, orange, yellow, orange));
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
@mixin calc($property, $value) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("calc");
|
||||||
|
|
||||||
|
#{$property}: -webkit-calc(#{$value});
|
||||||
|
#{$property}: calc(#{$value});
|
||||||
|
}
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
@mixin columns($arg: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("columns");
|
||||||
|
|
||||||
|
// <column-count> || <column-width>
|
||||||
|
@include prefixer(columns, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-count($int: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-count");
|
||||||
|
|
||||||
|
// auto || integer
|
||||||
|
@include prefixer(column-count, $int, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-gap($length: normal) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-gap");
|
||||||
|
|
||||||
|
// normal || length
|
||||||
|
@include prefixer(column-gap, $length, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-fill($arg: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-fill");
|
||||||
|
|
||||||
|
// auto || length
|
||||||
|
@include prefixer(column-fill, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule($arg) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-rule");
|
||||||
|
|
||||||
|
// <border-width> || <border-style> || <color>
|
||||||
|
@include prefixer(column-rule, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-color($color) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-rule-color");
|
||||||
|
|
||||||
|
@include prefixer(column-rule-color, $color, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-style($style: none) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-rule-style");
|
||||||
|
|
||||||
|
// none | hidden | dashed | dotted | double | groove | inset | inset | outset | ridge | solid
|
||||||
|
@include prefixer(column-rule-style, $style, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-rule-width($width: none) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-rule-width");
|
||||||
|
|
||||||
|
@include prefixer(column-rule-width, $width, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-span($arg: none) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-span");
|
||||||
|
|
||||||
|
// none || all
|
||||||
|
@include prefixer(column-span, $arg, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin column-width($length: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("column-width");
|
||||||
|
|
||||||
|
// auto || length
|
||||||
|
@include prefixer(column-width, $length, webkit moz spec);
|
||||||
|
}
|
||||||
Vendored
+6
@@ -0,0 +1,6 @@
|
|||||||
|
@mixin filter($function: none) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("filter");
|
||||||
|
|
||||||
|
// <filter-function> [<filter-function]* | none
|
||||||
|
@include prefixer(filter, $function, webkit spec);
|
||||||
|
}
|
||||||
+327
@@ -0,0 +1,327 @@
|
|||||||
|
// CSS3 Flexible Box Model and property defaults
|
||||||
|
|
||||||
|
// Custom shorthand notation for flexbox
|
||||||
|
@mixin box($orient: inline-axis, $pack: start, $align: stretch) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box");
|
||||||
|
|
||||||
|
@include display-box;
|
||||||
|
@include box-orient($orient);
|
||||||
|
@include box-pack($pack);
|
||||||
|
@include box-align($align);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin display-box {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("display-box");
|
||||||
|
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -ms-flexbox; // IE 10
|
||||||
|
display: box;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-orient($orient: inline-axis) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-orient");
|
||||||
|
|
||||||
|
// horizontal|vertical|inline-axis|block-axis|inherit
|
||||||
|
@include prefixer(box-orient, $orient, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-pack($pack: start) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-pack");
|
||||||
|
|
||||||
|
// start|end|center|justify
|
||||||
|
@include prefixer(box-pack, $pack, webkit moz spec);
|
||||||
|
-ms-flex-pack: $pack; // IE 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-align($align: stretch) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-align");
|
||||||
|
|
||||||
|
// start|end|center|baseline|stretch
|
||||||
|
@include prefixer(box-align, $align, webkit moz spec);
|
||||||
|
-ms-flex-align: $align; // IE 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-direction($direction: normal) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-direction");
|
||||||
|
|
||||||
|
// normal|reverse|inherit
|
||||||
|
@include prefixer(box-direction, $direction, webkit moz spec);
|
||||||
|
-ms-flex-direction: $direction; // IE 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-lines($lines: single) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-lines");
|
||||||
|
|
||||||
|
// single|multiple
|
||||||
|
@include prefixer(box-lines, $lines, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-ordinal-group($int: 1) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-ordinal-group");
|
||||||
|
|
||||||
|
@include prefixer(box-ordinal-group, $int, webkit moz spec);
|
||||||
|
-ms-flex-order: $int; // IE 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-flex($value: 0) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-flex");
|
||||||
|
|
||||||
|
@include prefixer(box-flex, $value, webkit moz spec);
|
||||||
|
-ms-flex: $value; // IE 10
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin box-flex-group($int: 1) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("box-flex-group");
|
||||||
|
|
||||||
|
@include prefixer(box-flex-group, $int, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CSS3 Flexible Box Model and property defaults
|
||||||
|
// Unified attributes for 2009, 2011, and 2012 flavours.
|
||||||
|
|
||||||
|
// 2009 - display (box | inline-box)
|
||||||
|
// 2011 - display (flexbox | inline-flexbox)
|
||||||
|
// 2012 - display (flex | inline-flex)
|
||||||
|
@mixin display($value) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("display");
|
||||||
|
|
||||||
|
// flex | inline-flex
|
||||||
|
@if $value == "flex" {
|
||||||
|
// 2009
|
||||||
|
display: -webkit-box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: box;
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
display: -webkit-flex;
|
||||||
|
display: -moz-flex;
|
||||||
|
display: -ms-flexbox; // 2011 (IE 10)
|
||||||
|
display: flex;
|
||||||
|
} @else if $value == "inline-flex" {
|
||||||
|
display: -webkit-inline-box;
|
||||||
|
display: -moz-inline-box;
|
||||||
|
display: inline-box;
|
||||||
|
|
||||||
|
display: -webkit-inline-flex;
|
||||||
|
display: -moz-inline-flex;
|
||||||
|
display: -ms-inline-flexbox;
|
||||||
|
display: inline-flex;
|
||||||
|
} @else {
|
||||||
|
display: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-flex (integer)
|
||||||
|
// 2011 - flex (decimal | width decimal)
|
||||||
|
// 2012 - flex (integer integer width)
|
||||||
|
@mixin flex($value) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex");
|
||||||
|
|
||||||
|
// Grab flex-grow for older browsers.
|
||||||
|
$flex-grow: nth($value, 1);
|
||||||
|
|
||||||
|
// 2009
|
||||||
|
@include prefixer(box-flex, $flex-grow, webkit moz spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10), 2012
|
||||||
|
@include prefixer(flex, $value, webkit moz ms spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-orient ( horizontal | vertical | inline-axis | block-axis)
|
||||||
|
// - box-direction (normal | reverse)
|
||||||
|
// 2011 - flex-direction (row | row-reverse | column | column-reverse)
|
||||||
|
// 2012 - flex-direction (row | row-reverse | column | column-reverse)
|
||||||
|
@mixin flex-direction($value: row) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-direction");
|
||||||
|
|
||||||
|
// Alt values.
|
||||||
|
$value-2009: $value;
|
||||||
|
$value-2011: $value;
|
||||||
|
$direction: normal;
|
||||||
|
|
||||||
|
@if $value == row {
|
||||||
|
$value-2009: horizontal;
|
||||||
|
} @else if $value == "row-reverse" {
|
||||||
|
$value-2009: horizontal;
|
||||||
|
$direction: reverse;
|
||||||
|
} @else if $value == column {
|
||||||
|
$value-2009: vertical;
|
||||||
|
} @else if $value == "column-reverse" {
|
||||||
|
$value-2009: vertical;
|
||||||
|
$direction: reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009
|
||||||
|
@include prefixer(box-orient, $value-2009, webkit moz spec);
|
||||||
|
@include prefixer(box-direction, $direction, webkit moz spec);
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(flex-direction, $value, webkit moz spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-direction: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-lines (single | multiple)
|
||||||
|
// 2011 - flex-wrap (nowrap | wrap | wrap-reverse)
|
||||||
|
// 2012 - flex-wrap (nowrap | wrap | wrap-reverse)
|
||||||
|
@mixin flex-wrap($value: nowrap) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-wrap");
|
||||||
|
|
||||||
|
// Alt values
|
||||||
|
$alt-value: $value;
|
||||||
|
@if $value == nowrap {
|
||||||
|
$alt-value: single;
|
||||||
|
} @else if $value == wrap {
|
||||||
|
$alt-value: multiple;
|
||||||
|
} @else if $value == "wrap-reverse" {
|
||||||
|
$alt-value: multiple;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include prefixer(box-lines, $alt-value, webkit moz spec);
|
||||||
|
@include prefixer(flex-wrap, $value, webkit moz ms spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - TODO: parse values into flex-direction/flex-wrap
|
||||||
|
// 2011 - TODO: parse values into flex-direction/flex-wrap
|
||||||
|
// 2012 - flex-flow (flex-direction || flex-wrap)
|
||||||
|
@mixin flex-flow($value) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-flow");
|
||||||
|
|
||||||
|
@include prefixer(flex-flow, $value, webkit moz spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-ordinal-group (integer)
|
||||||
|
// 2011 - flex-order (integer)
|
||||||
|
// 2012 - order (integer)
|
||||||
|
@mixin order($int: 0) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("order");
|
||||||
|
|
||||||
|
// 2009
|
||||||
|
@include prefixer(box-ordinal-group, $int, webkit moz spec);
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(order, $int, webkit moz spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-order: $int;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012 - flex-grow (number)
|
||||||
|
@mixin flex-grow($number: 0) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-grow");
|
||||||
|
|
||||||
|
@include prefixer(flex-grow, $number, webkit moz spec);
|
||||||
|
-ms-flex-positive: $number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012 - flex-shrink (number)
|
||||||
|
@mixin flex-shrink($number: 1) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-shrink");
|
||||||
|
|
||||||
|
@include prefixer(flex-shrink, $number, webkit moz spec);
|
||||||
|
-ms-flex-negative: $number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012 - flex-basis (number)
|
||||||
|
@mixin flex-basis($width: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("flex-basis");
|
||||||
|
|
||||||
|
@include prefixer(flex-basis, $width, webkit moz spec);
|
||||||
|
-ms-flex-preferred-size: $width;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-pack (start | end | center | justify)
|
||||||
|
// 2011 - flex-pack (start | end | center | justify)
|
||||||
|
// 2012 - justify-content (flex-start | flex-end | center | space-between | space-around)
|
||||||
|
@mixin justify-content($value: flex-start) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("justify-content");
|
||||||
|
|
||||||
|
// Alt values.
|
||||||
|
$alt-value: $value;
|
||||||
|
@if $value == "flex-start" {
|
||||||
|
$alt-value: start;
|
||||||
|
} @else if $value == "flex-end" {
|
||||||
|
$alt-value: end;
|
||||||
|
} @else if $value == "space-between" {
|
||||||
|
$alt-value: justify;
|
||||||
|
} @else if $value == "space-around" {
|
||||||
|
$alt-value: distribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009
|
||||||
|
@include prefixer(box-pack, $alt-value, webkit moz spec);
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(justify-content, $value, webkit moz ms o spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-pack: $alt-value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009 - box-align (start | end | center | baseline | stretch)
|
||||||
|
// 2011 - flex-align (start | end | center | baseline | stretch)
|
||||||
|
// 2012 - align-items (flex-start | flex-end | center | baseline | stretch)
|
||||||
|
@mixin align-items($value: stretch) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("align-items");
|
||||||
|
|
||||||
|
$alt-value: $value;
|
||||||
|
|
||||||
|
@if $value == "flex-start" {
|
||||||
|
$alt-value: start;
|
||||||
|
} @else if $value == "flex-end" {
|
||||||
|
$alt-value: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2009
|
||||||
|
@include prefixer(box-align, $alt-value, webkit moz spec);
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(align-items, $value, webkit moz ms o spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-align: $alt-value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2011 - flex-item-align (auto | start | end | center | baseline | stretch)
|
||||||
|
// 2012 - align-self (auto | flex-start | flex-end | center | baseline | stretch)
|
||||||
|
@mixin align-self($value: auto) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("align-self");
|
||||||
|
|
||||||
|
$value-2011: $value;
|
||||||
|
@if $value == "flex-start" {
|
||||||
|
$value-2011: start;
|
||||||
|
} @else if $value == "flex-end" {
|
||||||
|
$value-2011: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(align-self, $value, webkit moz spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-item-align: $value-2011;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2011 - flex-line-pack (start | end | center | justify | distribute | stretch)
|
||||||
|
// 2012 - align-content (flex-start | flex-end | center | space-between | space-around | stretch)
|
||||||
|
@mixin align-content($value: stretch) {
|
||||||
|
@include _bourbon-deprecate-for-prefixing("align-content");
|
||||||
|
|
||||||
|
$value-2011: $value;
|
||||||
|
@if $value == "flex-start" {
|
||||||
|
$value-2011: start;
|
||||||
|
} @else if $value == "flex-end" {
|
||||||
|
$value-2011: end;
|
||||||
|
} @else if $value == "space-between" {
|
||||||
|
$value-2011: justify;
|
||||||
|
} @else if $value == "space-around" {
|
||||||
|
$value-2011: distribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2012
|
||||||
|
@include prefixer(align-content, $value, webkit moz spec);
|
||||||
|
|
||||||
|
// 2011 (IE 10)
|
||||||
|
-ms-flex-line-pack: $value-2011;
|
||||||
|
}
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
@mixin font-face(
|
||||||
|
$font-family,
|
||||||
|
$file-path,
|
||||||
|
$weight: normal,
|
||||||
|
$style: normal,
|
||||||
|
$asset-pipeline: $asset-pipeline,
|
||||||
|
$file-formats: eot woff2 woff ttf svg) {
|
||||||
|
|
||||||
|
$font-url-prefix: font-url-prefixer($asset-pipeline);
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: $font-family;
|
||||||
|
font-style: $style;
|
||||||
|
font-weight: $weight;
|
||||||
|
|
||||||
|
src: font-source-declaration(
|
||||||
|
$font-family,
|
||||||
|
$file-path,
|
||||||
|
$asset-pipeline,
|
||||||
|
$file-formats,
|
||||||
|
$font-url-prefix
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user