diff options
52 files changed, 1183 insertions, 360 deletions
diff --git a/README.md b/README.md index 0eb9bbe3e..3add10473 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ If you would like, you can [support the development of this project on Patreon][ - `LOCAL_DOMAIN` should be the domain/hostname of your instance. This is **absolutely required** as it is used for generating unique IDs for everything federation-related - `LOCAL_HTTPS` set it to `true` if HTTPS works on your website. This is used to generate canonical URLs, which is also important when generating and parsing federation-related IDs -- `HUB_URL` should be the URL of the PubsubHubbub service that your instance is going to use. By default it is the open service of Superfeedr Consult the example configuration file, `.env.production.sample` for the full list. Among other things you need to set details for the SMTP server you are going to use. diff --git a/app/assets/images/mastodon.jpg b/app/assets/images/mastodon.jpg new file mode 100644 index 000000000..f22a252a6 --- /dev/null +++ b/app/assets/images/mastodon.jpg Binary files differdiff --git a/app/assets/images/mastodon_small.jpg b/app/assets/images/mastodon_small.jpg new file mode 100644 index 000000000..cb8cdc992 --- /dev/null +++ b/app/assets/images/mastodon_small.jpg Binary files differdiff --git a/app/assets/javascripts/application_public.js b/app/assets/javascripts/application_public.js index 31a96fd2d..f131a267a 100644 --- a/app/assets/javascripts/application_public.js +++ b/app/assets/javascripts/application_public.js @@ -1,2 +1,3 @@ //= require jquery //= require jquery_ujs +//= require extras diff --git a/app/assets/javascripts/components/actions/compose.jsx b/app/assets/javascripts/components/actions/compose.jsx index ec5465381..a9fbe6b91 100644 --- a/app/assets/javascripts/components/actions/compose.jsx +++ b/app/assets/javascripts/components/actions/compose.jsx @@ -185,13 +185,14 @@ export function readyComposeSuggestions(token, accounts) { }; }; -export function selectComposeSuggestion(position, accountId) { +export function selectComposeSuggestion(position, token, accountId) { return (dispatch, getState) => { const completion = getState().getIn(['accounts', accountId, 'acct']); dispatch({ type: COMPOSE_SUGGESTION_SELECT, position, + token, completion }); }; diff --git a/app/assets/javascripts/components/components/autosuggest_textarea.jsx b/app/assets/javascripts/components/components/autosuggest_textarea.jsx new file mode 100644 index 000000000..95ca5f2f6 --- /dev/null +++ b/app/assets/javascripts/components/components/autosuggest_textarea.jsx @@ -0,0 +1,155 @@ +import AutosuggestAccountContainer from '../features/compose/containers/autosuggest_account_container'; +import ImmutablePropTypes from 'react-immutable-proptypes'; + +const textAtCursorMatchesToken = (str, caretPosition) => { + let word; + + let left = str.slice(0, caretPosition).search(/\S+$/); + let right = str.slice(caretPosition).search(/\s/); + + if (right < 0) { + word = str.slice(left); + } else { + word = str.slice(left, right + caretPosition); + } + + if (!word || word.trim().length < 2 || word[0] !== '@') { + return [null, null]; + } + + word = word.trim().toLowerCase().slice(1); + + if (word.length > 0) { + return [left + 1, word]; + } else { + return [null, null]; + } +}; + +const AutosuggestTextarea = React.createClass({ + + propTypes: { + value: React.PropTypes.string, + suggestions: ImmutablePropTypes.list, + disabled: React.PropTypes.bool, + placeholder: React.PropTypes.string, + onSuggestionSelected: React.PropTypes.func.isRequired, + onSuggestionsClearRequested: React.PropTypes.func.isRequired, + onSuggestionsFetchRequested: React.PropTypes.func.isRequired, + onChange: React.PropTypes.func.isRequired, + onKeyUp: React.PropTypes.func + }, + + getInitialState () { + return { + suggestionsHidden: false, + selectedSuggestion: 0, + lastToken: null, + tokenStart: 0 + }; + }, + + onChange (e) { + const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart); + + if (token != null && this.state.lastToken !== token) { + this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); + this.props.onSuggestionsFetchRequested(token); + } else if (token === null && this.state.lastToken != null) { + this.setState({ lastToken: null }); + this.props.onSuggestionsClearRequested(); + } + + this.props.onChange(e); + }, + + onKeyDown (e) { + const { suggestions, disabled } = this.props; + const { selectedSuggestion, suggestionsHidden } = this.state; + + if (disabled) { + e.preventDefault(); + return; + } + + switch(e.key) { + case 'Escape': + if (!suggestionsHidden) { + e.preventDefault(); + this.setState({ suggestionsHidden: true }); + } + + break; + case 'ArrowDown': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); + } + + break; + case 'ArrowUp': + if (suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); + } + + break; + case 'Enter': + case 'Tab': + // Select suggestion + if (this.state.lastToken != null && suggestions.size > 0 && !suggestionsHidden) { + e.preventDefault(); + e.stopPropagation(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); + } + + break; + } + }, + + onSuggestionClick (suggestion, e) { + e.preventDefault(); + this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); + }, + + componentWillReceiveProps (nextProps) { + if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden) { + this.setState({ suggestionsHidden: false }); + } + }, + + setTextarea (c) { + this.textarea = c; + }, + + render () { + const { value, suggestions, disabled, placeholder, onKeyUp } = this.props; + const { suggestionsHidden, selectedSuggestion } = this.state; + + return ( + <div className='autosuggest-textarea'> + <textarea + ref={this.setTextarea} + className='autosuggest-textarea__textarea' + disabled={disabled} + placeholder={placeholder} + value={value} + onChange={this.onChange} + onKeyDown={this.onKeyDown} + onKeyUp={onKeyUp} + /> + + <div style={{ display: (suggestions.size > 0 && !suggestionsHidden) ? 'block' : 'none' }} className='autosuggest-textarea__suggestions'> + {suggestions.map((suggestion, i) => ( + <div key={suggestion} className={`autosuggest-textarea__suggestions__item ${i === selectedSuggestion ? 'selected' : ''}`} onClick={this.onSuggestionClick.bind(this, suggestion)}> + <AutosuggestAccountContainer id={suggestion} /> + </div> + ))} + </div> + </div> + ); + } + +}); + +export default AutosuggestTextarea; diff --git a/app/assets/javascripts/components/features/compose/components/compose_form.jsx b/app/assets/javascripts/components/features/compose/components/compose_form.jsx index 00589b3c8..200502dad 100644 --- a/app/assets/javascripts/components/features/compose/components/compose_form.jsx +++ b/app/assets/javascripts/components/features/compose/components/compose_form.jsx @@ -4,7 +4,7 @@ import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ReplyIndicator from './reply_indicator'; import UploadButton from './upload_button'; -import Autosuggest from 'react-autosuggest'; +import AutosuggestTextarea from '../../../components/autosuggest_textarea'; import AutosuggestAccountContainer from '../../compose/containers/autosuggest_account_container'; import { debounce } from 'react-decoration'; import UploadButtonContainer from '../containers/upload_button_container'; @@ -16,59 +16,12 @@ const messages = defineMessages({ publish: { id: 'compose_form.publish', defaultMessage: 'Publish' } }); -const getTokenForSuggestions = (str, caretPosition) => { - let word; - - let left = str.slice(0, caretPosition).search(/\S+$/); - let right = str.slice(caretPosition).search(/\s/); - - if (right < 0) { - word = str.slice(left); - } else { - word = str.slice(left, right + caretPosition); - } - - if (!word || word.trim().length < 2 || word[0] !== '@') { - return null; - } - - word = word.trim().toLowerCase().slice(1); - - if (word.length > 0) { - return word; - } else { - return null; - } -}; - -const getSuggestionValue = suggestionId => suggestionId; -const renderSuggestion = suggestionId => <AutosuggestAccountContainer id={suggestionId} />; - -const textareaStyle = { - display: 'block', - boxSizing: 'border-box', - width: '100%', - height: '100px', - resize: 'none', - border: 'none', - color: '#282c37', - padding: '10px', - fontFamily: 'Roboto', - fontSize: '14px', - margin: '0', - resize: 'vertical' -}; - -const renderInputComponent = inputProps => ( - <textarea {...inputProps} className='compose-form__textarea' style={textareaStyle} /> -); - const ComposeForm = React.createClass({ propTypes: { text: React.PropTypes.string.isRequired, suggestion_token: React.PropTypes.string, - suggestions: React.PropTypes.array, + suggestions: ImmutablePropTypes.list, sensitive: React.PropTypes.bool, unlisted: React.PropTypes.bool, is_submitting: React.PropTypes.bool, @@ -87,10 +40,6 @@ const ComposeForm = React.createClass({ mixins: [PureRenderMixin], handleChange (e) { - if (typeof e.target.value === 'undefined' || typeof e.target.value === 'number') { - return; - } - this.props.onChange(e.target.value); }, @@ -104,45 +53,17 @@ const ComposeForm = React.createClass({ this.props.onSubmit(); }, - componentDidUpdate (prevProps) { - if (prevProps.text !== this.props.text || prevProps.in_reply_to !== this.props.in_reply_to) { - const textarea = this.autosuggest.input; - - if (textarea) { - textarea.focus(); - } - } - }, - onSuggestionsClearRequested () { this.props.onClearSuggestions(); }, @debounce(500) - onSuggestionsFetchRequested ({ value }) { - const textarea = this.autosuggest.input; - - if (textarea) { - const token = getTokenForSuggestions(value, textarea.selectionStart); - - if (token !== null) { - this.props.onFetchSuggestions(token); - } else { - this.props.onClearSuggestions(); - } - } - }, - - onSuggestionSelected (e, { suggestionValue }) { - const textarea = this.autosuggest.input; - - if (textarea) { - this.props.onSuggestionSelected(textarea.selectionStart, suggestionValue); - } + onSuggestionsFetchRequested (token) { + this.props.onFetchSuggestions(token); }, - setRef (c) { - this.autosuggest = c; + onSuggestionSelected (tokenStart, token, value) { + this.props.onSuggestionSelected(tokenStart, token, value); }, handleChangeSensitivity (e) { @@ -153,6 +74,16 @@ const ComposeForm = React.createClass({ this.props.onChangeVisibility(e.target.checked); }, + componentDidUpdate (prevProps) { + if (prevProps.in_reply_to !== this.props.in_reply_to) { + this.autosuggestTextarea.textarea.focus(); + } + }, + + setAutosuggestTextarea (c) { + this.autosuggestTextarea = c; + }, + render () { const { intl } = this.props; let replyArea = ''; @@ -162,29 +93,21 @@ const ComposeForm = React.createClass({ replyArea = <ReplyIndicator status={this.props.in_reply_to} onCancel={this.props.onCancelReply} />; } - const inputProps = { - placeholder: intl.formatMessage(messages.placeholder), - value: this.props.text, - onKeyUp: this.handleKeyUp, - onChange: this.handleChange, - disabled: disabled - }; - return ( <div style={{ padding: '10px' }}> {replyArea} - <Autosuggest - ref={this.setRef} + <AutosuggestTextarea + ref={this.setAutosuggestTextarea} + placeholder={intl.formatMessage(messages.placeholder)} + disabled={disabled} + value={this.props.text} + onChange={this.handleChange} suggestions={this.props.suggestions} - focusFirstSuggestion={true} + onKeyUp={this.handleKeyUp} onSuggestionsFetchRequested={this.onSuggestionsFetchRequested} onSuggestionsClearRequested={this.onSuggestionsClearRequested} onSuggestionSelected={this.onSuggestionSelected} - getSuggestionValue={getSuggestionValue} - renderSuggestion={renderSuggestion} - renderInputComponent={renderInputComponent} - inputProps={inputProps} /> <div style={{ marginTop: '10px', overflow: 'hidden' }}> diff --git a/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx b/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx index 8aa719476..c774b2687 100644 --- a/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx +++ b/app/assets/javascripts/components/features/compose/containers/compose_form_container.jsx @@ -19,7 +19,7 @@ const makeMapStateToProps = () => { return { text: state.getIn(['compose', 'text']), suggestion_token: state.getIn(['compose', 'suggestion_token']), - suggestions: state.getIn(['compose', 'suggestions']).toJS(), + suggestions: state.getIn(['compose', 'suggestions']), sensitive: state.getIn(['compose', 'sensitive']), unlisted: state.getIn(['compose', 'unlisted']), is_submitting: state.getIn(['compose', 'is_submitting']), @@ -53,8 +53,8 @@ const mapDispatchToProps = function (dispatch) { dispatch(fetchComposeSuggestions(token)); }, - onSuggestionSelected (position, accountId) { - dispatch(selectComposeSuggestion(position, accountId)); + onSuggestionSelected (position, token, accountId) { + dispatch(selectComposeSuggestion(position, token, accountId)); }, onChangeSensitivity (checked) { diff --git a/app/assets/javascripts/components/reducers/compose.jsx b/app/assets/javascripts/components/reducers/compose.jsx index 9d1d53083..4bb76dff0 100644 --- a/app/assets/javascripts/components/reducers/compose.jsx +++ b/app/assets/javascripts/components/reducers/compose.jsx @@ -75,11 +75,9 @@ function removeMedia(state, mediaId) { }); }; -const insertSuggestion = (state, position, completion) => { - const token = state.get('suggestion_token'); - +const insertSuggestion = (state, position, token, completion) => { return state.withMutations(map => { - map.update('text', oldText => `${oldText.slice(0, position - token.length)}${completion}${oldText.slice(position + token.length)}`); + map.update('text', oldText => `${oldText.slice(0, position)}${completion}${oldText.slice(position + token.length)}`); map.set('suggestion_token', null); map.update('suggestions', Immutable.List(), list => list.clear()); }); @@ -130,7 +128,7 @@ export default function compose(state = initialState, action) { case COMPOSE_SUGGESTIONS_READY: return state.set('suggestions', Immutable.List(action.accounts.map(item => item.id))).set('suggestion_token', action.token); case COMPOSE_SUGGESTION_SELECT: - return insertSuggestion(state, action.position, action.completion); + return insertSuggestion(state, action.position, action.token, action.completion); case TIMELINE_DELETE: if (action.id === state.get('in_reply_to')) { return state.set('in_reply_to', null); diff --git a/app/assets/javascripts/extras.jsx b/app/assets/javascripts/extras.jsx new file mode 100644 index 000000000..9fd769c0b --- /dev/null +++ b/app/assets/javascripts/extras.jsx @@ -0,0 +1,20 @@ +import emojify from './components/emoji' + +$(() => { + $.each($('.entry .content, .entry .status__content, .display-name, .name, .account__header__content'), (_, content) => { + const $content = $(content); + $content.html(emojify($content.html())); + }); + + $('.video-player video').on('click', e => { + if (e.target.paused) { + e.target.play(); + } else { + e.target.pause(); + } + }); + + $('.media-spoiler').on('click', e => { + $(e.target).hide(); + }); +}); diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 609b30726..6dd89c0ea 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -114,6 +114,18 @@ body { padding: 0; } + &.embed { + background: transparent; + margin: 0; + + .container { + position: absolute; + width: 100%; + height: 100%; + overflow: hidden; + } + } + @media screen and (max-width: 360px) { padding-bottom: 0; } diff --git a/app/assets/stylesheets/components.scss b/app/assets/stylesheets/components.scss index 517fcd3f1..210e722cc 100644 --- a/app/assets/stylesheets/components.scss +++ b/app/assets/stylesheets/components.scss @@ -530,3 +530,43 @@ background: lighten(#373b4a, 5%); } } + +.autosuggest-textarea { + position: relative; +} + +.autosuggest-textarea__textarea { + display: block; + box-sizing: border-box; + width: 100%; + height: 100px; + resize: none; + border: none; + color: #282c37; + padding: 10px; + font-family: 'Roboto'; + font-size: 14px; + margin: 0; + resize: vertical; +} + +.autosuggest-textarea__suggestions { + position: absolute; + top: 100%; + width: 100%; + z-index: 99; + box-shadow: 0 0 15px rgba(0, 0, 0, 0.4); + background: #d9e1e8; + color: #282c37; + font-size: 14px; +} + +.autosuggest-textarea__suggestions__item { + padding: 10px; + cursor: pointer; + + &.selected { + background: #2b90d9; + color: #fff; + } +} diff --git a/app/assets/stylesheets/stream_entries.scss b/app/assets/stylesheets/stream_entries.scss index 1e29ee718..5cd140aac 100644 --- a/app/assets/stylesheets/stream_entries.scss +++ b/app/assets/stylesheets/stream_entries.scss @@ -3,232 +3,302 @@ box-shadow: 0 0 15px rgba(0, 0, 0, 0.2); .entry { - border-bottom: 1px solid #d9e1e8; - background: #fff; - border-left: 2px solid #fff; + .status.light, .detailed-status.light { + border-bottom: 1px solid #d9e1e8; + } - &.entry-reblog { - border-left-color: #2b90d9; + &:last-child { + .status.light, .detailed-status.light { + border-bottom: 0; + border-radius: 0 0 4px 4px; + } } - &.entry-predecessor, &.entry-successor { - background: #d9e1e8; - border-left-color: #d9e1e8; - border-bottom-color: darken(#d9e1e8, 10%); + &:first-child { + .status.light, .detailed-status.light { + border-radius: 4px 4px 0 0; + } - .header { - .header__right { - .counter-btn { - color: darken(#d9e1e8, 15%); - } + &:last-child { + .status.light, .detailed-status.light { + border-radius: 4px; } } } + } - &.entry-center { - border-bottom-color: darken(#d9e1e8, 10%); - } + .status.light { + padding: 14px 14px 14px (48px + 14px*2); + position: relative; + min-height: 48px; + cursor: default; + background: lighten(#d9e1e8, 8%); - &.entry-follow, &.entry-favourite { - .content { - padding-top: 10px; - padding-bottom: 10px; + .status__header { + font-size: 15px; - strong { - font-weight: 500; + .status__meta { + float: right; + font-size: 14px; + + .status__relative-time { + color: #9baec8; } } } - &:last-child { - border-bottom: 0; - border-radius: 0 0 4px 4px; + .status__display-name { + display: block; + max-width: 100%; + padding-right: 25px; + color: #282c37; } - } - .entry:first-child { - border-radius: 4px 4px 0 0; + .status__avatar { + position: absolute; + left: 14px; + top: 14px; + width: 48px; + height: 48px; - &:last-child { - border-radius: 4px; + & > div { + width: 48px; + height: 48px; + } + + img { + display: block; + border-radius: 4px; + } } - } - @media screen and (max-width: 700px) { - border-radius: 0; - box-shadow: none; + .display-name { + display: block; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; - .entry { - &:last-child { - border-radius: 0; + strong { + font-weight: 500; + color: #282c37; } - &:first-child { - border-radius: 0; + span { + font-size: 14px; + color: #9baec8; + } + } - &:last-child { - border-radius: 0; - } + .status__content { + color: #282c37; + + a { + color: #2b90d9; } } - } - .entry__container { - overflow: hidden; + .status__attachments { + margin-top: 8px; + overflow: hidden; + width: 100%; + box-sizing: border-box; + height: 110px; + display: flex; + } } - .avatar { - width: 56px; - padding: 15px 10px; - padding-right: 5px; - float: left; + .detailed-status.light { + padding: 14px; + background: #fff; + cursor: default; - img { - width: 56px; - height: 56px; + .detailed-status__display-name { display: block; - border-radius: 4px; - } - } + overflow: hidden; + margin-bottom: 15px; - .entry__container__container { - margin-left: 71px; - } + & > div { + float: left; + margin-right: 10px; + } - .header { - margin-bottom: 10px; - padding: 15px; - padding-bottom: 0; - padding-left: 8px; - display: flex; + .display-name { + display: block; + max-width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + + strong { + font-weight: 500; + color: #282c37; + } - .header__left { - flex: 1; + span { + font-size: 14px; + color: #9baec8; + } + } } - .header__right { + .avatar { + width: 48px; + height: 48px; + img { + display: block; + border-radius: 4px; + } } - .name { - text-decoration: none; + .status__content { + color: #282c37; + + a { + color: #2b90d9; + } + } + + .detailed-status__meta { + margin-top: 15px; color: #9baec8; + font-size: 14px; + line-height: 18px; - strong { - color: #282c37; - font-weight: 500; + a { + color: inherit; } - &:hover { - strong { - text-decoration: underline; - } + span > span { + font-weight: 500; + font-size: 12px; + margin-left: 6px; + display: inline-block; } } - } - - .pre-header { - border-bottom: 1px solid #d9e1e8; - color: #2b90d9; - padding: 5px 10px; - padding-left: 8px; - clear: both; - .name { - color: #2b90d9; - font-weight: 500; - text-decoration: none; + .detailed-status__attachments { + margin-top: 8px; + overflow: hidden; + width: 100%; + box-sizing: border-box; + height: 300px; + display: flex; + } - &:hover { - text-decoration: underline; + .video-player { + margin-top: 8px; + height: 300px; + overflow: hidden; + + video { + position: relative; + z-index: 1; + width: 100%; + height: 100%; + object-fit: cover; + top: 50%; + transform: translateY(-50%); } } } - .content { - font-size: 14px; - padding: 0 15px; - padding-left: 8px; - padding-bottom: 15px; - color: #282c37; - word-wrap: break-word; - overflow: hidden; - white-space: pre-wrap; - - p { - margin-bottom: 18px; + .media-item, .video-item { + box-sizing: border-box; + position: relative; + left: auto; + top: auto; + right: auto; + bottom: auto; + float: left; + border: medium none; + display: block; + flex: 1 1 auto; + height: 100%; + margin-right: 2px; - &:last-child { - margin-bottom: 0; - } + &:last-child { + margin-right: 0; } a { - color: #2b90d9; + display: block; + width: 100%; + height: 100%; + background: no-repeat scroll center center / cover; text-decoration: none; + cursor: zoom-in; + } + } - &:hover { - text-decoration: underline; - } + .video-item { + max-width: 196px; - &.mention { - &:hover { - text-decoration: none; + a { + cursor: pointer; + } - span { - text-decoration: underline; - } - } - } + .video-item__play { + position: absolute; + top: 50%; + left: 50%; + font-size: 36px; + transform: translate(-50%, -50%); + padding: 5px; + border-radius: 100px; + color: rgba(255, 255, 255, 0.8); } } - .time { - text-decoration: none; - color: #9baec8; + .media-spoiler { + background: #9baec8; + width: 100%; + height: 100%; + cursor: pointer; + display: flex; + align-items: center; + justify-content: center; + flex-direction: column; + text-align: center; + transition: all 100ms linear; &:hover { - text-decoration: underline; + background: darken(#9baec8, 5%); } - } - .media-attachments { - list-style: none; - margin: 0; - padding: 0; - display: block; - overflow: hidden; - padding-left: 10px; - margin-bottom: 15px; - - li { + span { display: block; - float: left; - width: 120px; - height: 100px; - border-radius: 4px; - margin-right: 4px; - margin-bottom: 4px; - a { - display: block; - width: 120px; - height: 100px; - border-radius: 4px; - background-position: center; - background-repeat: none; - background-size: cover; + &:first-child { + font-size: 14px; + } + + &:last-child { + font-size: 11px; + font-weight: 500; } } } +} - @media screen and (max-width: 360px) { - .avatar { - display: none; - } +.embed { + .activity-stream { + border-radius: 4px; + box-shadow: none; - .entry__container__container { - margin-left: 7px; + .entry { + &:last-child { + border-radius: 0 0 4px 4px; + } + + &:first-child { + border-radius: 4px 4px 0 0; + + &:last-child { + border-radius: 4px; + } + } } } } diff --git a/app/controllers/api/oembed_controller.rb b/app/controllers/api/oembed_controller.rb index 4a591dc22..2360061ff 100644 --- a/app/controllers/api/oembed_controller.rb +++ b/app/controllers/api/oembed_controller.rb @@ -5,8 +5,8 @@ class Api::OembedController < ApiController def show @stream_entry = stream_entry_from_url(params[:url]) - @width = [300, params[:maxwidth].to_i].min - @height = [200, params[:maxheight].to_i].min + @width = params[:maxwidth].present? ? params[:maxwidth].to_i : 400 + @height = params[:maxheight].present? ? params[:maxheight].to_i : 600 end private diff --git a/app/controllers/stream_entries_controller.rb b/app/controllers/stream_entries_controller.rb index 98d029030..58dd423f7 100644 --- a/app/controllers/stream_entries_controller.rb +++ b/app/controllers/stream_entries_controller.rb @@ -9,8 +9,6 @@ class StreamEntriesController < ApplicationController before_action :check_account_suspension def show - @type = @stream_entry.activity_type.downcase - respond_to do |format| format.html do return gone if @stream_entry.activity.nil? @@ -25,6 +23,15 @@ class StreamEntriesController < ApplicationController end end + def embed + response.headers['X-Frame-Options'] = 'ALLOWALL' + @external_links = true + + return gone if @stream_entry.activity.nil? + + render layout: 'embedded' + end + private def set_account @@ -37,6 +44,7 @@ class StreamEntriesController < ApplicationController def set_stream_entry @stream_entry = @account.stream_entries.find(params[:id]) + @type = @stream_entry.activity_type.downcase end def check_account_suspension diff --git a/app/helpers/stream_entries_helper.rb b/app/helpers/stream_entries_helper.rb index 0aa7008be..5cd65008e 100644 --- a/app/helpers/stream_entries_helper.rb +++ b/app/helpers/stream_entries_helper.rb @@ -5,6 +5,10 @@ module StreamEntriesHelper account.display_name.blank? ? account.username : account.display_name end + def acct(account) + "@#{account.acct}#{@external_links && account.local? ? "@#{Rails.configuration.x.local_domain}" : ''}" + end + def avatar_for_status_url(status) status.reblog? ? status.reblog.account.avatar.url( :original) : status.account.avatar.url( :original) end diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb index a97fe89a5..2a5d23739 100644 --- a/app/models/media_attachment.rb +++ b/app/models/media_attachment.rb @@ -45,14 +45,14 @@ class MediaAttachment < ApplicationRecord if f.instance.image? { original: '1280x1280>', - small: '250x250>', + small: '400x400>', } else { small: { convert_options: { output: { - vf: 'scale=\'min(250\, iw):min(250\, ih)\':force_original_aspect_ratio=decrease', + vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease', }, }, format: 'png', diff --git a/app/models/tag.rb b/app/models/tag.rb index e5b0511ae..77a73cce8 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -3,7 +3,7 @@ class Tag < ApplicationRecord has_and_belongs_to_many :statuses - HASHTAG_RE = /(?:^|[^\/\w])#([[:word:]_]+)/i + HASHTAG_RE = /(?:^|[^\/\w])#([[:word:]_]*[[:alpha:]_][[:word:]_]*)/i validates :name, presence: true, uniqueness: true diff --git a/app/services/favourite_service.rb b/app/services/favourite_service.rb index 2f280e03f..5c04cfee4 100644 --- a/app/services/favourite_service.rb +++ b/app/services/favourite_service.rb @@ -8,7 +8,6 @@ class FavouriteService < BaseService def call(account, status) favourite = Favourite.create!(account: account, status: status) - HubPingWorker.perform_async(account.id) Pubsubhubbub::DistributionWorker.perform_async(favourite.stream_entry.id) if status.local? diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index 423b833cf..ed9b62455 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -20,7 +20,6 @@ class FollowService < BaseService merge_into_timeline(target_account, source_account) - HubPingWorker.perform_async(source_account.id) Pubsubhubbub::DistributionWorker.perform_async(follow.stream_entry.id) follow diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index 9e0ced129..d5204151b 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -16,7 +16,6 @@ class PostStatusService < BaseService process_hashtags_service.call(status) DistributionWorker.perform_async(status.id) - HubPingWorker.perform_async(account.id) Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id) status diff --git a/app/services/reblog_service.rb b/app/services/reblog_service.rb index 39fdb4ea7..7d0c90d2f 100644 --- a/app/services/reblog_service.rb +++ b/app/services/reblog_service.rb @@ -9,7 +9,6 @@ class ReblogService < BaseService reblog = account.statuses.create!(reblog: reblogged_status, text: '') DistributionWorker.perform_async(reblog.id) - HubPingWorker.perform_async(account.id) Pubsubhubbub::DistributionWorker.perform_async(reblog.stream_entry.id) if reblogged_status.local? diff --git a/app/services/remove_status_service.rb b/app/services/remove_status_service.rb index fa55e668e..836b8fdc5 100644 --- a/app/services/remove_status_service.rb +++ b/app/services/remove_status_service.rb @@ -13,7 +13,6 @@ class RemoveStatusService < BaseService return unless status.account.local? - HubPingWorker.perform_async(status.account.id) Pubsubhubbub::DistributionWorker.perform_async(status.stream_entry.id) end diff --git a/app/views/about/index.html.haml b/app/views/about/index.html.haml index 307d75c81..160a66710 100644 --- a/app/views/about/index.html.haml +++ b/app/views/about/index.html.haml @@ -1,6 +1,15 @@ - content_for :page_title do = Rails.configuration.x.local_domain +- content_for :header_tags do + %meta{ property: 'og:site_name', content: 'Mastodon' }/ + %meta{ property: 'og:type', content: 'website' }/ + %meta{ property: 'og:title', content: Rails.configuration.x.local_domain }/ + %meta{ property: 'og:description', content: "Mastodon is a free, open-source social network server. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly" }/ + %meta{ property: 'og:image', content: asset_url('mastodon_small.jpg') }/ + %meta{ property: 'og:image:width', content: '400' }/ + %meta{ property: 'og:image:height', content: '400' }/ + .wrapper %h1 = image_tag 'logo.png' diff --git a/app/views/accounts/show.atom.ruby b/app/views/accounts/show.atom.ruby index b2903d189..a22568396 100644 --- a/app/views/accounts/show.atom.ruby +++ b/app/views/accounts/show.atom.ruby @@ -15,7 +15,6 @@ Nokogiri::XML::Builder.new do |xml| link_alternate xml, TagManager.instance.url_for(@account) link_self xml, account_url(@account, format: 'atom') link_hub xml, api_push_url - link_hub xml, Rails.configuration.x.hub_url link_salmon xml, api_salmon_url(@account.id) @entries.each do |stream_entry| diff --git a/app/views/api/oembed/show.json.rabl b/app/views/api/oembed/show.json.rabl index e035bc13c..f33b70ee5 100644 --- a/app/views/api/oembed/show.json.rabl +++ b/app/views/api/oembed/show.json.rabl @@ -9,6 +9,6 @@ node(:author_url) { |entry| account_url(entry.account) } node(:provider_name) { Rails.configuration.x.local_domain } node(:provider_url) { root_url } node(:cache_age) { 86_400 } -node(:html, &:content) +node(:html) { |entry| "<iframe src=\"#{embed_account_stream_entry_url(entry.account, entry)}\" style=\"width: 100%; overflow: hidden\" frameborder=\"0\" width=\"#{@width}\" height=\"#{@height}\" scrolling=\"no\"></iframe>" } node(:width) { @width } -node(:height) { @height } +node(:height) { nil } diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml index 498fae105..0adce05bf 100644 --- a/app/views/home/index.html.haml +++ b/app/views/home/index.html.haml @@ -1,4 +1,5 @@ - content_for :header_tags do + %meta{:name => "apple-mobile-web-app-capable", :content => "yes"}/ = javascript_include_tag 'application' = react_component 'Mastodon', default_props, class: 'app-holder', prerender: false diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 87f98198c..7e28d27ec 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -9,7 +9,6 @@ %link{:rel => "manifest", :href => "/manifest.json"}/ %meta{:name => "msapplication-config", :content => "/browserconfig.xml"}/ %meta{:name => "theme-color", :content => "#2b90d9"}/ - %meta{:name => "apple-mobile-web-app-capable", :content => "yes"}/ %title = "#{yield(:page_title)} - " if content_for?(:page_title) diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml new file mode 100644 index 000000000..adbf0a287 --- /dev/null +++ b/app/views/layouts/embedded.html.haml @@ -0,0 +1,8 @@ +!!! 5 +%html{:lang => 'en'} + %head + %meta{:charset => 'utf-8'}/ + = stylesheet_link_tag 'application', media: 'all' + = javascript_include_tag 'application_public' + %body.embed + = yield diff --git a/app/views/stream_entries/_content_spoiler.html.haml b/app/views/stream_entries/_content_spoiler.html.haml new file mode 100644 index 000000000..d80ea46a0 --- /dev/null +++ b/app/views/stream_entries/_content_spoiler.html.haml @@ -0,0 +1,3 @@ +.media-spoiler + %span= t('stream_entries.sensitive_content') + %span= t('stream_entries.click_to_show') diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml new file mode 100644 index 000000000..94451d3bd --- /dev/null +++ b/app/views/stream_entries/_detailed_status.html.haml @@ -0,0 +1,36 @@ +.detailed-status.light + = link_to TagManager.instance.url_for(status.account), class: 'detailed-status__display-name', target: @external_links ? '_blank' : nil, rel: 'noopener' do + %div + %div.avatar + = image_tag status.account.avatar.url(:original), width: 48, height: 48, alt: '' + %span.display-name + %strong= display_name(status.account) + %span= acct(status.account) + + .status__content= Formatter.instance.format(status) + + - unless status.media_attachments.empty? + - if status.media_attachments.first.video? + .video-player + - if status.sensitive? + = render partial: 'stream_entries/content_spoiler' + %video{ src: status.media_attachments.first.file.url(:original), loop: true } + - else + .detailed-status__attachments + - if status.sensitive? + = render partial: 'stream_entries/content_spoiler' + - status.media_attachments.each do |media| + .media-item + = link_to '', (media.remote_url.blank? ? media.file.url(:original) : media.remote_url), style: "background-image: url(#{media.file.url(:original)})", target: '_blank', rel: 'noopener' + + %div.detailed-status__meta + = link_to TagManager.instance.url_for(status), class: 'detailed-status__datetime', target: @external_links ? '_blank' : nil, rel: 'noopener' do + %span= l(status.created_at) + · + %span + = fa_icon('retweet') + %span= status.reblogs.count + · + %span + = fa_icon('star') + %span= status.favourites.count diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml new file mode 100644 index 000000000..da3bc0ccb --- /dev/null +++ b/app/views/stream_entries/_simple_status.html.haml @@ -0,0 +1,28 @@ +.status.light + .status__header + .status__meta + = link_to time_ago_in_words(status.created_at), TagManager.instance.url_for(status), class: 'status__relative-time', title: l(status.created_at), target: @external_links ? '_blank' : nil, rel: 'noopener' + + = link_to TagManager.instance.url_for(status.account), class: 'status__display-name', target: @external_links ? '_blank' : nil, rel: 'noopener' do + .status__avatar + %div + = image_tag status.account.avatar(:original), width: 48, height: 48, alt: '' + %span.display-name + %strong= display_name(status.account) + %span= acct(status.account) + + .status__content= Formatter.instance.format(status) + + - unless status.media_attachments.empty? + .status__attachments + - if status.sensitive? + = render partial: 'stream_entries/content_spoiler' + - if status.media_attachments.first.video? + .video-item + = link_to (status.media_attachments.first.remote_url.blank? ? status.media_attachments.first.file.url(:original) : status.media_attachments.first.remote_url), style: "background-image: url(#{status.media_attachments.first.file.url(:small)})", target: '_blank', rel: 'noopener' do + .video-item__play + = fa_icon('play') + - else + - status.media_attachments.each do |media| + .media-item + = link_to '', (media.remote_url.blank? ? media.file.url(:original) : media.remote_url), style: "background-image: url(#{media.file.url(:original)})", target: '_blank', rel: 'noopener' diff --git a/app/views/stream_entries/_status.html.haml b/app/views/stream_entries/_status.html.haml index 8169b8178..67cb06a83 100644 --- a/app/views/stream_entries/_status.html.haml +++ b/app/views/stream_entries/_status.html.haml @@ -1,7 +1,7 @@ - include_threads ||= false - is_predecessor ||= false - is_successor ||= false -- centered = include_threads && !is_predecessor && !is_successor +- centered ||= include_threads && !is_predecessor && !is_successor - if status.reply? && include_threads = render partial: 'status', collection: @ancestors, as: :status, locals: { is_predecessor: true } @@ -13,28 +13,7 @@ Shared by = link_to display_name(status.account), TagManager.instance.url_for(status.account), class: 'name' - .entry__container - .avatar - = image_tag avatar_for_status_url(status) - - .entry__container__container - .header - .header__left - = link_to TagManager.instance.url_for(proper_status(status).account), class: 'name' do - %strong= display_name(proper_status(status).account) - = "@#{proper_status(status).account.acct}" - - .header__right - = link_to TagManager.instance.url_for(proper_status(status)), class: 'time' do - %span{ title: proper_status(status).created_at } - = relative_time(proper_status(status).created_at) - - .content= Formatter.instance.format(proper_status(status)) - - - if (status.reblog? ? status.reblog : status).media_attachments.size > 0 - %ul.media-attachments - - (status.reblog? ? status.reblog : status).media_attachments.each do |media| - %li.transparent-background= link_to '', media.file.url( :original), style: "background-image: url(#{media.file.url( :small)})", target: '_blank' + = render partial: centered ? 'stream_entries/detailed_status' : 'stream_entries/simple_status', locals: { status: proper_status(status) } - if include_threads = render partial: 'status', collection: @descendants, as: :status, locals: { is_successor: true } diff --git a/app/views/stream_entries/embed.html.haml b/app/views/stream_entries/embed.html.haml new file mode 100644 index 000000000..fd07fdd91 --- /dev/null +++ b/app/views/stream_entries/embed.html.haml @@ -0,0 +1,2 @@ +.activity-stream.activity-stream-headless + = render partial: @type, locals: { @type.to_sym => @stream_entry.activity, centered: true } diff --git a/app/workers/hub_ping_worker.rb b/app/workers/hub_ping_worker.rb deleted file mode 100644 index 14a151ba0..000000000 --- a/app/workers/hub_ping_worker.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -class HubPingWorker - include Sidekiq::Worker - include RoutingHelper - - def perform(account_id) - account = Account.find(account_id) - return unless account.local? - OStatus2::Publication.new(account_url(account, format: 'atom'), [Rails.configuration.x.hub_url]).publish - end -end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 4dc6985b7..e72063844 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -33,6 +33,7 @@ search: ignore_unused: - 'activerecord.attributes.*' - '{devise,will_paginate,doorkeeper}.*' + - '{datetime,time}.*' - 'simple_form.{yes,no}' - 'simple_form.{placeholders,hints,labels}.*' - 'simple_form.{error_notification,required}.:' diff --git a/config/initializers/ostatus.rb b/config/initializers/ostatus.rb index c5723b2e9..faa9940b0 100644 --- a/config/initializers/ostatus.rb +++ b/config/initializers/ostatus.rb @@ -6,7 +6,6 @@ https = ENV['LOCAL_HTTPS'] == 'true' Rails.application.configure do config.x.local_domain = host - config.x.hub_url = ENV.fetch('HUB_URL') { 'https://pubsubhubbub.superfeedr.com' } config.x.use_https = https config.x.use_s3 = ENV['S3_ENABLED'] == 'true' diff --git a/config/locales/en.yml b/config/locales/en.yml index 50a1f0e95..f58ce9a71 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -26,6 +26,20 @@ en: resend_confirmation: Resend confirmation instructions reset_password: Reset password set_new_password: Set new password + datetime: + distance_in_words: + about_x_hours: "%{count}h" + about_x_months: "%{count}mo" + about_x_years: "%{count}y" + almost_x_years: "%{count}y" + half_a_minute: Just now + less_than_x_minutes: "%{count}m" + less_than_x_seconds: Just now + over_x_years: "%{count}y" + x_days: "%{count}d" + x_minutes: "%{count}m" + x_months: "%{count}mo" + x_seconds: "%{count}s" generic: changes_saved_msg: Changes successfully saved! powered_by: powered by %{link} @@ -53,8 +67,13 @@ en: edit_profile: Edit profile preferences: Preferences stream_entries: + click_to_show: Click to show favourited: favourited a post by is_now_following: is now following + sensitive_content: Sensitive content + time: + formats: + default: "%b %d, %Y, %H:%M" users: invalid_email: The e-mail address is invalid will_paginate: diff --git a/config/routes.rb b/config/routes.rb index 2d70bdcea..fd187dc42 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,7 +25,11 @@ Rails.application.routes.draw do } resources :accounts, path: 'users', only: [:show], param: :username do - resources :stream_entries, path: 'updates', only: [:show] + resources :stream_entries, path: 'updates', only: [:show] do + member do + get :embed + end + end member do get :followers diff --git a/package.json b/package.json index ab75c5be5..05663a729 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "browserify-incremental": "^3.1.1", "chai": "^3.5.0", "chai-enzyme": "^0.5.2", + "css-loader": "^0.26.1", "emojione": "^2.2.6", "enzyme": "^2.4.1", "es6-promise": "^3.2.1", @@ -25,6 +26,7 @@ "intl": "^1.2.5", "jsdom": "^9.6.0", "mocha": "^3.1.1", + "node-sass": "^4.0.0", "react": "^15.3.2", "react-addons-perf": "^15.3.2", "react-addons-pure-render-mixin": "^15.3.1", @@ -42,13 +44,14 @@ "react-router": "^2.8.0", "react-router-scroll": "^0.3.2", "react-simple-dropdown": "^1.1.4", + "react-storybook-addon-intl": "^0.1.0", + "react-toggle": "^2.1.1", "redux": "^3.5.2", "redux-immutable": "^3.0.8", "redux-thunk": "^2.1.0", "reselect": "^2.5.4", - "sinon": "^1.17.6" - }, - "dependencies": { - "react-toggle": "^2.1.1" + "sass-loader": "^4.0.2", + "sinon": "^1.17.6", + "style-loader": "^0.13.1" } } diff --git a/public/500.html b/public/500.html index d656269aa..915b890f1 100644 --- a/public/500.html +++ b/public/500.html @@ -20,6 +20,7 @@ margin: 20px auto; margin-top: 50px; max-width: 600px; + width: 100%; height: auto; } diff --git a/spec/controllers/api/v1/follows_controller_spec.rb b/spec/controllers/api/v1/follows_controller_spec.rb index 1346141fa..97d69ab7b 100644 --- a/spec/controllers/api/v1/follows_controller_spec.rb +++ b/spec/controllers/api/v1/follows_controller_spec.rb @@ -18,7 +18,6 @@ RSpec.describe Api::V1::FollowsController, type: :controller do stub_request(:get, "https://quitter.no/avatar/7477-300-20160211190340.png").to_return(request_fixture('avatar.txt')) stub_request(:post, "https://quitter.no/main/push/hub").to_return(:status => 200, :body => "", :headers => {}) stub_request(:post, "https://quitter.no/main/salmon/user/7477").to_return(:status => 200, :body => "", :headers => {}) - stub_request(:post, "https://pubsubhubbub.superfeedr.com/").to_return(:status => 200, :body => "", :headers => {}) post :create, params: { uri: 'gargron@quitter.no' } end @@ -39,10 +38,6 @@ RSpec.describe Api::V1::FollowsController, type: :controller do expect(a_request(:post, "https://quitter.no/main/salmon/user/7477")).to have_been_made end - it 'notifies own hub' do - expect(a_request(:post, "https://pubsubhubbub.superfeedr.com/")).to have_been_made - end - it 'subscribes to remote hub' do expect(a_request(:post, "https://quitter.no/main/push/hub")).to have_been_made end diff --git a/spec/services/reblog_service_spec.rb b/spec/services/reblog_service_spec.rb index f0a40fe91..5f89169e9 100644 --- a/spec/services/reblog_service_spec.rb +++ b/spec/services/reblog_service_spec.rb @@ -8,7 +8,6 @@ RSpec.describe ReblogService do subject { ReblogService.new } before do - stub_request(:post, Rails.configuration.x.hub_url) stub_request(:post, 'http://salmon.example.com') subject.(alice, status) @@ -18,10 +17,6 @@ RSpec.describe ReblogService do expect(status.reblogs.count).to eq 1 end - it 'pings PubSubHubbub hubs' do - expect(a_request(:post, Rails.configuration.x.hub_url)).to have_been_made - end - it 'sends a Salmon slap for a remote reblog' do expect(a_request(:post, 'http://salmon.example.com')).to have_been_made end diff --git a/storybook/config.js b/storybook/config.js index d9fde833c..4a111a8b9 100644 --- a/storybook/config.js +++ b/storybook/config.js @@ -1,8 +1,14 @@ -import { configure } from '@kadira/storybook'; +import { configure, setAddon } from '@kadira/storybook'; +import IntlAddon from 'react-storybook-addon-intl'; import React from 'react'; import { storiesOf, action } from '@kadira/storybook'; +import { addLocaleData } from 'react-intl'; +import en from 'react-intl/locale-data/en'; +import '../app/assets/stylesheets/components.scss' +import './storybook.scss' -import './storybook.css' +setAddon(IntlAddon); +addLocaleData(en); window.storiesOf = storiesOf; window.action = action; @@ -11,7 +17,7 @@ window.React = React; function loadStories () { require('./stories/loading_indicator.story.jsx'); require('./stories/button.story.jsx'); - require('./stories/tabs_bar.story.jsx'); + require('./stories/autosuggest_textarea.story.jsx'); } configure(loadStories, module); diff --git a/storybook/stories/autosuggest_textarea.story.jsx b/storybook/stories/autosuggest_textarea.story.jsx new file mode 100644 index 000000000..7d84ff1e1 --- /dev/null +++ b/storybook/stories/autosuggest_textarea.story.jsx @@ -0,0 +1,6 @@ +import { storiesOf } from '@kadira/storybook'; +import AutosuggestTextarea from '../../app/assets/javascripts/components/components/autosuggest_textarea.jsx' + +storiesOf('AutosuggestTextarea', module) + .add('default state', () => <AutosuggestTextarea />) + .add('with text', () => <AutosuggestTextarea value='Hello' />) diff --git a/storybook/stories/button.story.jsx b/storybook/stories/button.story.jsx index fe6d57ad0..fc392abef 100644 --- a/storybook/stories/button.story.jsx +++ b/storybook/stories/button.story.jsx @@ -1,3 +1,4 @@ +import { storiesOf } from '@kadira/storybook'; import Button from '../../app/assets/javascripts/components/components/button.jsx' storiesOf('Button', module) diff --git a/storybook/stories/loading_indicator.story.jsx b/storybook/stories/loading_indicator.story.jsx index d169e4f55..f4a961c4e 100644 --- a/storybook/stories/loading_indicator.story.jsx +++ b/storybook/stories/loading_indicator.story.jsx @@ -1,6 +1,6 @@ +import { storiesOf } from '@kadira/storybook'; import LoadingIndicator from '../../app/assets/javascripts/components/components/loading_indicator.jsx' +import { IntlProvider } from 'react-intl'; storiesOf('LoadingIndicator', module) - .add('default state', () => ( - <LoadingIndicator /> - )); + .add('default state', () => <IntlProvider><LoadingIndicator /></IntlProvider>); diff --git a/storybook/stories/tabs_bar.story.jsx b/storybook/stories/tabs_bar.story.jsx deleted file mode 100644 index daaedca5a..000000000 --- a/storybook/stories/tabs_bar.story.jsx +++ /dev/null @@ -1,6 +0,0 @@ -import TabsBar from '../../app/assets/javascripts/components/features/ui/components/tabs_bar.jsx' - -storiesOf('TabsBar', module) - .add('default state', () => ( - <TabsBar /> - )); diff --git a/storybook/storybook.css b/storybook/storybook.css deleted file mode 100644 index 3bda9e64c..000000000 --- a/storybook/storybook.css +++ /dev/null @@ -1,3 +0,0 @@ -#root { - padding: 4rem; -} diff --git a/storybook/storybook.scss b/storybook/storybook.scss new file mode 100644 index 000000000..b0145f9bd --- /dev/null +++ b/storybook/storybook.scss @@ -0,0 +1,15 @@ +@import url(https://fonts.googleapis.com/css?family=Roboto:400,500,400italic); +@import url(https://fonts.googleapis.com/css?family=Roboto+Mono:400,500); + +#root { + font-family: 'Roboto', sans-serif; + background: #282c37; + font-size: 13px; + line-height: 18px; + font-weight: 400; + color: #fff; + padding-bottom: 140px; + text-rendering: optimizelegibility; + font-feature-settings: "kern"; + padding: 4rem; +} diff --git a/storybook/webpack.config.js b/storybook/webpack.config.js new file mode 100644 index 000000000..0ce563e1a --- /dev/null +++ b/storybook/webpack.config.js @@ -0,0 +1,13 @@ +const path = require('path'); + +module.exports = { + module: { + loaders: [ + { + test: /.scss$/, + loaders: ["style", "css", "sass"], + include: path.resolve(__dirname, '../') + } + ] + } +} diff --git a/yarn.lock b/yarn.lock index 733ef7e92..f71a8ae10 100644 --- a/yarn.lock +++ b/yarn.lock @@ -231,6 +231,10 @@ array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -242,6 +246,13 @@ array-includes@^3.0.2: define-properties "^1.1.2" es-abstract "^1.5.0" +array-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" + dependencies: + debug "^2.2.0" + es6-symbol "^3.0.2" + array-map@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" @@ -302,6 +313,10 @@ async-each@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" +async-foreach@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" + async@^0.9.0: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -310,6 +325,12 @@ async@^1.3.0, async@^1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" +async@^2.0.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.4.tgz#2d2160c7788032e4dd6cbe2502f1f9a2c8f6cde4" + dependencies: + lodash "^4.14.0" + async@~0.2.6: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" @@ -1244,14 +1265,33 @@ buffer@^4.1.0, buffer@^4.9.0: ieee754 "^1.1.4" isarray "^1.0.0" +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + builtin-status-codes@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-2.0.0.tgz#6f22003baacf003ccd287afe6872151fddc58579" +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + camelcase@^1.0.2: version "1.2.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + caniuse-db@^1.0.30000539, caniuse-db@^1.0.30000540: version "1.0.30000554" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000554.tgz#cd1dbe423d00b6203ba93f05973a476428dec919" @@ -1347,6 +1387,14 @@ cliui@^2.1.0: right-align "^0.1.1" wordwrap "0.0.2" +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + clone@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.2.tgz#260b7a99ebb1edfe247538175f783243cb19d149" @@ -1535,6 +1583,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2: create-hash "^1.1.0" inherits "^2.0.1" +cross-spawn@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + cryptiles@2.x.x: version "2.0.5" resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" @@ -1585,6 +1640,23 @@ css-loader@0.25.0: postcss-modules-values "^1.1.0" source-list-map "^0.1.4" +css-loader@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-0.26.1.tgz#2ba7f20131b93597496b3e9bb500785a49cd29ea" + dependencies: + babel-code-frame "^6.11.0" + css-selector-tokenizer "^0.7.0" + cssnano ">=2.6.1 <4" + loader-utils "~0.2.2" + lodash.camelcase "^4.3.0" + object-assign "^4.0.1" + postcss "^5.0.6" + postcss-modules-extract-imports "^1.0.0" + postcss-modules-local-by-default "^1.0.1" + postcss-modules-scope "^1.0.0" + postcss-modules-values "^1.1.0" + source-list-map "^0.1.4" + css-select@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" @@ -1602,6 +1674,14 @@ css-selector-tokenizer@^0.6.0: fastparse "^1.1.1" regexpu-core "^1.0.0" +css-selector-tokenizer@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86" + dependencies: + cssesc "^0.1.0" + fastparse "^1.1.1" + regexpu-core "^1.0.0" + css-what@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd" @@ -1664,6 +1744,18 @@ cssom@0.3.x, "cssom@>= 0.3.0 < 0.4.0": dependencies: cssom "0.3.x" +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + dependencies: + array-find-index "^1.0.1" + +d@^0.1.1, d@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" + dependencies: + es5-ext "~0.10.2" + dashdash@^1.12.0: version "1.14.0" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.0.tgz#29e486c5418bf0f356034a993d51686a33e84141" @@ -1680,7 +1772,7 @@ debug@2.2.0, debug@^2.1.1, debug@^2.2.0, debug@~2.2.0: dependencies: ms "0.7.1" -decamelize@^1.0.0, decamelize@^1.1.2: +decamelize@^1.0.0, decamelize@^1.1.1, decamelize@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -1894,6 +1986,12 @@ errno@^0.1.3: dependencies: prr "~0.0.0" +error-ex@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.0.tgz#e67b43f3e82c96ea3a584ffee0b9fc3325d802d9" + dependencies: + is-arrayish "^0.2.1" + error-stack-parser@^1.3.6: version "1.3.6" resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-1.3.6.tgz#e0e73b93e417138d1cd7c0b746b1a4a14854c292" @@ -1917,10 +2015,25 @@ es-to-primitive@^1.1.1: is-date-object "^1.0.1" is-symbol "^1.0.1" +es5-ext@^0.10.7, es5-ext@~0.10.11, es5-ext@~0.10.2: + version "0.10.12" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.12.tgz#aa84641d4db76b62abba5e45fd805ecbab140047" + dependencies: + es6-iterator "2" + es6-symbol "~3.1" + es5-shim@^4.5.9: version "4.5.9" resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.5.9.tgz#2a1e2b9e583ff5fed0c20a3ee2cbf3f75230a5c0" +es6-iterator@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.0.tgz#bd968567d61635e33c0b80727613c9cb4b096bac" + dependencies: + d "^0.1.1" + es5-ext "^0.10.7" + es6-symbol "3" + es6-promise@^3.2.1: version "3.3.1" resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" @@ -1929,6 +2042,13 @@ es6-shim@^0.35.1: version "0.35.1" resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.1.tgz#a23524009005b031ab4a352ac196dfdfd1144ab7" +es6-symbol@3, es6-symbol@^3.0.2, es6-symbol@~3.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.0.tgz#94481c655e7a7cad82eba832d97d5433496d7ffa" + dependencies: + d "~0.1.1" + es5-ext "~0.10.11" + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -2205,6 +2325,12 @@ gauge@~2.6.0: strip-ansi "^3.0.1" wide-align "^1.1.0" +gaze@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.2.tgz#847224677adb8870d679257ed3388fdb61e40105" + dependencies: + globule "^1.0.0" + generate-function@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" @@ -2215,6 +2341,10 @@ generate-object-property@^1.1.0: dependencies: is-property "^1.0.0" +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -2238,7 +2368,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@7.0.5, glob@^7.0.0, glob@^7.0.5: +glob@7.0.5, glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: version "7.0.5" resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.5.tgz#b4202a69099bbb4d292a7c1b95b6682b67ebdc95" dependencies: @@ -2259,10 +2389,29 @@ glob@^5.0.15: once "^1.3.0" path-is-absolute "^1.0.0" +glob@~7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^8.3.0: version "8.18.0" resolved "https://registry.yarnpkg.com/globals/-/globals-8.18.0.tgz#93d4a62bdcac38cfafafc47d6b034768cb0ffcb4" +globule@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-1.1.0.tgz#c49352e4dc183d85893ee825385eb994bb6df45f" + dependencies: + glob "~7.1.1" + lodash "~4.16.4" + minimatch "~3.0.2" + graceful-fs@^4.1.2: version "4.1.9" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.9.tgz#baacba37d19d11f9d146d3578bc99958c3787e29" @@ -2347,6 +2496,10 @@ home-or-tmp@^1.0.0: os-tmpdir "^1.0.1" user-home "^1.1.1" +hosted-git-info@^2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + html-comment-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" @@ -2430,6 +2583,16 @@ imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" +in-publish@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + indexes-of@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" @@ -2514,6 +2677,10 @@ invariant@2.x.x, invariant@^2.0.0, invariant@^2.1.1, invariant@^2.2.0, invariant dependencies: loose-envify "^1.0.0" +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + ipaddr.js@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.1.1.tgz#c791d95f52b29c1247d5df80ada39b8a73647230" @@ -2522,6 +2689,10 @@ is-absolute-url@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.0.0.tgz#9c4b20b0e5c0cbef9a479a367ede6f991679f359" +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2532,6 +2703,12 @@ is-buffer@^1.0.2, is-buffer@^1.1.0: version "1.1.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.4.tgz#cfc86ccd5dc5a52fa80489111c6920c457e2d98b" +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + is-callable@^1.1.1, is-callable@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.3.tgz#86eb75392805ddc33af71c92a0eedf74ee7604b2" @@ -2651,6 +2828,10 @@ is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + isarray@0.0.1, isarray@~0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" @@ -2659,6 +2840,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" +isexe@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-1.1.2.tgz#36f3e22e60750920f5e7241a476a8c6a42275ad0" + isobject@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/isobject/-/isobject-1.0.2.tgz#f0f9b8ce92dd540fa0740882e3835a2e022ec78a" @@ -2835,6 +3020,12 @@ lazy-cache@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -2848,6 +3039,16 @@ lexical-scope@^1.2.0: dependencies: astw "^2.0.0" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + loader-utils@0.2.x, loader-utils@^0.2.11, loader-utils@^0.2.15, loader-utils@^0.2.7, loader-utils@~0.2.2, loader-utils@~0.2.5: version "0.2.16" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.16.tgz#f08632066ed8282835dff88dfb52704765adee6d" @@ -2915,12 +3116,24 @@ lodash.assign@^3.2.0: lodash._createassigner "^3.0.0" lodash.keys "^3.0.0" +lodash.assign@^4.0.3, lodash.assign@^4.0.6, lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + lodash.camelcase@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-3.0.1.tgz#932c8b87f8a4377897c67197533282f97aeac298" dependencies: lodash._createcompounder "^3.0.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + +lodash.clonedeep@^4.3.2: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + lodash.create@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" @@ -2947,6 +3160,10 @@ lodash.isarray@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" +lodash.isarray@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-4.0.0.tgz#2aca496b28c4ca6d726715313590c02e6ea34403" + lodash.keys@^3.0.0, lodash.keys@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" @@ -2959,6 +3176,10 @@ lodash.memoize@~3.0.3: version "3.0.4" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f" +lodash.mergewith@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz#150cf0a16791f5903b8891eab154609274bdea55" + lodash.pick@^4.2.0, lodash.pick@^4.2.1: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" @@ -2973,7 +3194,7 @@ lodash.words@^3.0.0: dependencies: lodash._root "^3.0.0" -lodash@^4.1.0, lodash@^4.13.1, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.6.1: +lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.6.1, lodash@~4.16.4: version "4.16.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.16.4.tgz#01ce306b9bad1319f2a5528674f88297aeb70127" @@ -2991,6 +3212,20 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.2.0: dependencies: js-tokens "^1.0.1" +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.0.2.tgz#1d17679c069cda5d040991a09dbc2c0db377e55e" + dependencies: + pseudomap "^1.0.1" + yallist "^2.0.0" + macaddress@^0.2.8: version "0.2.8" resolved "https://registry.yarnpkg.com/macaddress/-/macaddress-0.2.8.tgz#5904dc537c39ec6dbefeae902327135fa8511f12" @@ -3003,6 +3238,10 @@ mantra-core@^1.6.1: react-komposer "^1.9.0" react-simple-di "^1.2.0" +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + math-expression-evaluator@^1.2.14: version "1.2.14" resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.14.tgz#39511771ed9602405fba9affff17eb4d2a3843ab" @@ -3024,6 +3263,21 @@ memory-fs@~0.3.0: errno "^0.1.3" readable-stream "^2.0.1" +meow@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" @@ -3079,7 +3333,7 @@ minimalistic-assert@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" -"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2: +"minimatch@2 || 3", minimatch@^3.0.0, minimatch@^3.0.2, minimatch@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" dependencies: @@ -3089,7 +3343,7 @@ minimist@0.0.8, minimist@~0.0.1: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" -minimist@^1.1.0, minimist@^1.2.0: +minimist@^1.1.0, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" @@ -3142,7 +3396,7 @@ ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" -nan@^2.3.0: +nan@^2.3.0, nan@^2.3.2: version "2.4.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.4.0.tgz#fb3c59d45fe4effe215f0b890f8adf6eb32d2232" @@ -3157,6 +3411,25 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-gyp@^3.3.1: + version "3.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + node-libs-browser@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-0.6.0.tgz#244806d44d319e048bc8607b5cc4eaf9a29d2e3c" @@ -3199,16 +3472,48 @@ node-pre-gyp@^0.6.29: tar "~2.2.0" tar-pack "~3.1.0" +node-sass@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.0.0.tgz#3208301ad5a6096de227f3fc4c3ce682b9816afc" + dependencies: + async-foreach "^0.1.3" + chalk "^1.1.1" + cross-spawn "^3.0.0" + gaze "^1.0.0" + get-stdin "^4.0.1" + glob "^7.0.3" + in-publish "^2.0.0" + lodash.assign "^4.2.0" + lodash.clonedeep "^4.3.2" + lodash.isarray "^4.0.0" + lodash.mergewith "^4.6.0" + meow "^3.7.0" + mkdirp "^0.5.1" + nan "^2.3.2" + node-gyp "^3.3.1" + npmlog "^4.0.0" + request "^2.61.0" + sass-graph "^2.1.1" + node-uuid@~1.4.7: version "1.4.7" resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.7.tgz#6da5a17668c4b3dd59623bda11cf7fa4c1f60a6f" -nopt@~3.0.1: +"nopt@2 || 3", nopt@~3.0.1: version "3.0.6" resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" dependencies: abbrev "1" +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.5.tgz#8d924f142960e1777e7ffe170543631cc7cb02df" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" @@ -3226,7 +3531,16 @@ normalize-url@^1.4.0: query-string "^4.1.0" sort-keys "^1.0.0" -npmlog@4.x: +"npmlog@0 || 1 || 2 || 3": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +npmlog@4.x, npmlog@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.0.tgz#e094503961c70c1774eb76692080e8d578a9f88f" dependencies: @@ -3357,11 +3671,17 @@ os-homedir@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + os-tmpdir@^1.0.0, os-tmpdir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" -osenv@^0.1.0: +osenv@0, osenv@^0.1.0: version "0.1.3" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.3.tgz#83cf05c6d6458fc4d5ac6362ea325d92f2754217" dependencies: @@ -3397,6 +3717,12 @@ parse-glob@^3.0.4: is-extglob "^1.0.0" is-glob "^2.0.0" +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + parse5@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-1.5.1.tgz#9b7f3b0de32be78dc2401b17573ccaf0f6f59d94" @@ -3405,6 +3731,12 @@ parseurl@~1.3.0, parseurl@~1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" +path-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" + dependencies: + array-index "^1.0.0" + path-browserify@0.0.0, path-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" @@ -3431,6 +3763,14 @@ path-to-regexp@0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + pbkdf2-compat@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/pbkdf2-compat/-/pbkdf2-compat-2.0.1.tgz#b6e0c8fa99494d94e0511575802a59a5c142f288" @@ -3445,6 +3785,10 @@ performance-now@^0.2.0, performance-now@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -3742,6 +4086,10 @@ prr@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" +pseudomap@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + public-encrypt@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" @@ -3994,6 +4342,10 @@ react-simple-dropdown@^1.1.4: dependencies: classnames "^2.1.2" +react-storybook-addon-intl@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/react-storybook-addon-intl/-/react-storybook-addon-intl-0.1.0.tgz#4d46c9e6c7be0ad4e4f7de72d907ec764743dee8" + react-themeable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/react-themeable/-/react-themeable-1.1.0.tgz#7d4466dd9b2b5fa75058727825e9f152ba379a0e" @@ -4021,6 +4373,21 @@ read-only-stream@^2.0.0: dependencies: readable-stream "^2.0.2" +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + readable-stream@1.1, readable-stream@^1.0.27-1, readable-stream@^1.1.13: version "1.1.14" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" @@ -4076,6 +4443,13 @@ redbox-react@^1.2.2: object-assign "^4.0.1" react-dom "^0.14.0 || ^15.0.0" +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + reduce-css-calc@^1.2.6: version "1.3.0" resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716" @@ -4164,7 +4538,13 @@ repeating@^1.1.0: dependencies: is-finite "^1.0.0" -request@2.x, request@^2.55.0, request@^2.74.0: +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@2, request@2.x, request@^2.55.0, request@^2.61.0, request@^2.74.0: version "2.75.0" resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" dependencies: @@ -4190,6 +4570,14 @@ request@2.x, request@^2.55.0, request@^2.74.0: tough-cookie "~2.3.0" tunnel-agent "~0.4.1" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + reselect@^2.5.4: version "2.5.4" resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047" @@ -4222,6 +4610,22 @@ samsam@1.1.2, samsam@~1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.1.2.tgz#bec11fdc83a9fda063401210e40176c3024d1567" +sass-graph@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.1.2.tgz#965104be23e8103cb7e5f710df65935b317da57b" + dependencies: + glob "^7.0.0" + lodash "^4.0.0" + yargs "^4.7.1" + +sass-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-4.0.2.tgz#a616eb770366543e64f547c8630f39c4da75f15d" + dependencies: + async "^2.0.1" + loader-utils "^0.2.15" + object-assign "^4.1.0" + sax@^1.1.4, sax@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" @@ -4237,7 +4641,7 @@ section-iterator@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/section-iterator/-/section-iterator-2.0.0.tgz#bf444d7afeeb94ad43c39ad2fb26151627ccba2a" -semver@~5.3.0: +"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" @@ -4277,7 +4681,7 @@ serve-static@~1.11.1: parseurl "~1.3.1" send "0.14.1" -set-blocking@~2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -4402,6 +4806,20 @@ source-map@~0.4.1: dependencies: amdefine ">=0.0.4" +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4527,11 +4945,23 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + dependencies: + get-stdin "^4.0.1" + strip-json-comments@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" -style-loader@0.13.1: +style-loader@0.13.1, style-loader@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-0.13.1.tgz#468280efbc0473023cd3a6cd56e33b5a1d7fc3a9" dependencies: @@ -4596,7 +5026,7 @@ tar-pack@~3.1.0: tar "~2.2.1" uid-number "~0.0.6" -tar@~2.2.0, tar@~2.2.1: +tar@^2.0.0, tar@~2.2.0, tar@~2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" dependencies: @@ -4641,6 +5071,10 @@ traverse@^0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + tty-browserify@0.0.0, tty-browserify@~0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" @@ -4764,6 +5198,13 @@ uuid@^2.0.1, uuid@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + vary@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" @@ -4878,6 +5319,16 @@ whet.extend@~0.9.9: version "0.9.9" resolved "https://registry.yarnpkg.com/whet.extend/-/whet.extend-0.9.9.tgz#f877d5bf648c97e5aa542fadc16d6a259b9c11a1" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +which@1, which@^1.2.9: + version "1.2.12" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.12.tgz#de67b5e450269f194909ef23ece4ebe416fa1192" + dependencies: + isexe "^1.1.1" + wide-align@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" @@ -4888,6 +5339,10 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" @@ -4900,6 +5355,13 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -4926,6 +5388,40 @@ xtend@^4.0.0, xtend@~4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yallist@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.0.0.tgz#306c543835f09ee1a4cb23b7bce9ab341c91cdd4" + +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" |