├── .gitignore ├── .travis.yml ├── README.md ├── dist └── .keep ├── docs ├── logo.png └── screenshot.png ├── favicon.ico ├── fonts ├── icomoon.eot ├── icomoon.svg ├── icomoon.ttf └── icomoon.woff ├── img ├── logo-blue.png └── logo.png ├── index.html ├── karma.conf.js ├── package.json ├── src ├── actions │ ├── feed.js │ └── menu.js ├── api │ └── feed.js ├── components │ ├── bookmark-slider.js │ ├── button-comment.js │ ├── button-favorite.js │ ├── comments.js │ ├── header.js │ ├── item.js │ ├── keyword-input.js │ ├── keyword-list.js │ ├── pasta.js │ └── side-menu.js ├── constants │ └── action-types.js ├── containers │ └── app.js ├── index.js ├── lib │ ├── db.js │ └── utils.js ├── reducers │ ├── feed.js │ ├── index.js │ └── menu.js └── stores │ └── configure-store.js ├── stylesheets └── .keep ├── stylus ├── base │ ├── base.styl │ └── normalize.styl ├── block │ ├── bookmark-slider.styl │ ├── comments.styl │ ├── content.styl │ ├── header.styl │ ├── item.styl │ ├── keyword-input.styl │ ├── keywords.styl │ ├── rect-spinner.styl │ └── side-menu.styl ├── lib │ ├── animate.styl │ └── social-font.styl └── main.styl └── test ├── actions └── test-menu.js ├── api └── test-feed.js ├── components ├── test-button-comment.js ├── test-button-favorite.js ├── test-comments.js ├── test-header.js ├── test-item.js ├── test-keyword-input.js ├── test-keyword-list.js └── test-side-menu.js └── reducers └── test-menu.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | dist/ 3 | stylesheets/ 4 | npm-debug.log 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - '4.2.2' 5 | 6 | install: 7 | - npm i 8 | 9 | script: 10 | - 'npm test' -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ![TunaPasta](https://github.com/bokuweb/tuna_pasta/blob/master/docs/logo.png?raw=true) 2 | 3 | [![Build Status](https://travis-ci.org/bokuweb/tuna_pasta.svg?branch=master)](https://travis-ci.org/bokuweb/tuna_pasta) 4 | [![Code Climate](https://codeclimate.com/github/bokuweb/tuna_pasta/badges/gpa.svg)](https://codeclimate.com/github/bokuweb/tuna_pasta) 5 | ![License](http://img.shields.io/npm/l/object.assign.svg) 6 | 7 | 8 | Pasta is Hatena Bookmark Viwer, build with React/Redux, focused on keyword. 9 | 10 | 11 | [http://tuna.pasta.in.net/](http://tuna.pasta.in.net/) 12 | P 13 | ![screenshot](https://github.com/bokuweb/tuna_pasta/blob/master/docs/screenshot.png?raw=true) 14 | 15 | ## Run 16 | 17 | ``` sh 18 | npm run build 19 | ``` 20 | 21 | and open index.html. 22 | 23 | ## Build 24 | 25 | ``` sh 26 | npm run build 27 | ``` 28 | 29 | ## Test 30 | 31 | ``` 32 | npm run test 33 | ``` 34 | 35 | ## License 36 | 37 | The MIT License (MIT) 38 | 39 | Copyright (c) 2015 @Bokuweb 40 | 41 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 42 | 43 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 44 | 45 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 46 | -------------------------------------------------------------------------------- /dist/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/dist/.keep -------------------------------------------------------------------------------- /docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/docs/logo.png -------------------------------------------------------------------------------- /docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/docs/screenshot.png -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/favicon.ico -------------------------------------------------------------------------------- /fonts/icomoon.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/fonts/icomoon.eot -------------------------------------------------------------------------------- /fonts/icomoon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /fonts/icomoon.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/fonts/icomoon.ttf -------------------------------------------------------------------------------- /fonts/icomoon.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/fonts/icomoon.woff -------------------------------------------------------------------------------- /img/logo-blue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/img/logo-blue.png -------------------------------------------------------------------------------- /img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/img/logo.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Pasta - Hatena Bookmark Viewer - 7 | 8 | 9 | 10 | 11 | 12 |
13 | Fork me on GitHub 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // Generated on Fri Sep 25 2015 15:55:15 GMT+0900 (東京 (標準時)) 3 | 4 | module.exports = function(config) { 5 | config.set({ 6 | 7 | // base path that will be used to resolve all patterns (eg. files, exclude) 8 | basePath: '', 9 | 10 | // frameworks to use 11 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 12 | frameworks: ['mocha', 'browserify'], 13 | 14 | // list of files / patterns to load in the browser 15 | files: [ 16 | './node_modules/phantomjs-polyfill/bind-polyfill.js', 17 | './node_modules/babel-polyfill/dist/polyfill.js', 18 | 'test/*/*.js' 19 | ], 20 | 21 | // list of files to exclude 22 | exclude: [ 23 | ], 24 | 25 | browserify: { 26 | debug: true, 27 | extensions: ['.js'], 28 | transform: [ 29 | require('babelify').configure({ 30 | plugins: ['babel-plugin-espower'] 31 | }) 32 | ] 33 | }, 34 | // preprocess matching files before serving them to the browser 35 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 36 | preprocessors: { 37 | 'test/*/*.js': ['browserify'] 38 | }, 39 | 40 | 41 | // test results reporter to use 42 | // possible values: 'dots', 'progress' 43 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 44 | reporters: ['progress'], 45 | 46 | 47 | // web server port 48 | port: 9876, 49 | 50 | 51 | // enable / disable colors in the output (reporters and logs) 52 | colors: true, 53 | 54 | 55 | // level of logging 56 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 57 | logLevel: config.LOG_INFO, 58 | 59 | 60 | // enable / disable watching file and executing tests whenever any file changes 61 | autoWatch: false, 62 | 63 | 64 | // start these browsers 65 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 66 | browsers: ['PhantomJS'], 67 | 68 | 69 | // Continuous Integration mode 70 | // if true, Karma captures browsers, runs the tests and exits 71 | singleRun: true 72 | }) 73 | } 74 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pasta", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "dist/bundle.js", 6 | "scripts": { 7 | "build" : "npm run build:js & npm run build:stylus", 8 | "build:js": "browserify --extension=js -o dist/bundle.js src/index.js", 9 | "watch": "npm run watch:js & npm run watch:stylus", 10 | "watch:js": "watchify --extension=js -o dist/bundle.js src/index.js", 11 | "watch:stylus": "stylus stylus/ --watch --out stylesheets/", 12 | "build:stylus": "stylus stylus/ --out stylesheets/", 13 | "test": "karma start" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/bokuweb/tuna_pasta.git" 18 | }, 19 | "author": "bokuweb", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/bokuweb/tuna_pasta/issues" 23 | }, 24 | "homepage": "https://github.com/bokuweb/tuna_pasta", 25 | "dependencies": { 26 | "dexie": "^1.2.0", 27 | "jsonp": "~0.2.0", 28 | "lodash": "^3.10.1", 29 | "material-ui": "^0.13.1", 30 | "react": "~0.14.2", 31 | "react-addons-create-fragment": "^0.14.1", 32 | "react-addons-pure-render-mixin": "^0.14.1", 33 | "react-addons-transition-group": "^0.14.1", 34 | "react-addons-update": "^0.14.1", 35 | "react-dom": "~0.14.2", 36 | "react-infinite": "~0.5.8", 37 | "react-redux": "~4.0.0", 38 | "react-tap-event-plugin": "^0.2.1", 39 | "redux": "~3.0.4", 40 | "redux-logger": "~2.0.4", 41 | "redux-thunk": "~1.0.0" 42 | }, 43 | "devDependencies": { 44 | "babel-plugin-espower": "1.0.0", 45 | "babel-polyfill": "^6.2.0", 46 | "babelify": "6.4.0", 47 | "browserify": "^12.0.1", 48 | "espower-babel": "3.3.0", 49 | "espower-loader": "1.0.0", 50 | "espowerify": "1.0.0", 51 | "intelli-espower-loader": "1.0.0", 52 | "karma": "0.13.11", 53 | "karma-browserify": "4.4.0", 54 | "karma-chrome-launcher": "0.2.1", 55 | "karma-cli": "0.1.1", 56 | "karma-mocha": "0.2.0", 57 | "karma-phantomjs-launcher": "0.2.1", 58 | "mocha": "2.3.3", 59 | "nock": "^3.3.2", 60 | "phantomjs": "1.9.18", 61 | "phantomjs-polyfill": "0.0.1", 62 | "power-assert": "1.1.0", 63 | "querystring": "^0.2.0", 64 | "react-addons-test-utils": "0.14.2", 65 | "stylus": "0.52.4", 66 | "watchify": "3.5.0" 67 | }, 68 | "browserify": { 69 | "transform": [ 70 | "babelify" 71 | ] 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/actions/feed.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import {fetch, fetchWithGoogleFeedApi} from '../api/feed' 3 | import * as types from '../constants/action-types'; 4 | import DbManager from '../lib/db' 5 | 6 | const HATENA_URL = 'http://b.hatena.ne.jp/' 7 | const HATENA_BOOKMARK_COUNT_URL = 'http://api.b.st-hatena.com/entry.counts?'; 8 | const HATENA_SEARCH_URL = HATENA_URL + 'search/text?mode=rss&safe=off&q=' 9 | const HATENA_ENTRY_URL = HATENA_URL + 'entry/json/?' 10 | const GOOGLEAPI_URI = 'https://ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=-1&q='; 11 | 12 | const db = new DbManager('pastaDB'); 13 | 14 | function getItems(feed) { 15 | console.log('---------- fetch feed -----------'); 16 | console.dir(feed); 17 | if (feed.responseData === null) return; 18 | if (feed.responseData.feed === undefined) return []; 19 | return feed.responseData.feed.entries; 20 | } 21 | 22 | export function initialize() { 23 | return dispatch => { 24 | console.log("initialize.."); 25 | db.create({keywords: "name, icon"}); 26 | db.create({favorites: "link, title, content, contentSnippet, publishedDate, categories, isFavorited"}); 27 | db.getArray('keywords').then((keywords) => { 28 | dispatch({type: types.INITIALIZE_KEYWORD, keywords}); 29 | if (keywords.length !== 0) { 30 | for (let keyword of keywords) _fetchFeed(dispatch, keyword.name, 0, 1); 31 | } 32 | }); 33 | db.getArray('favorites').then((favorites) => { 34 | dispatch({type: types.INITIALIZE_FAVORITE, favorites }); 35 | }); 36 | dispatch({type: types.INITIALIZING}); 37 | } 38 | } 39 | 40 | function fetchingItems(keyword) { 41 | return { 42 | type: types.FETCHING_ITEMS, 43 | keyword 44 | }; 45 | } 46 | 47 | function recieveItems(items, keyword, length) { 48 | return { 49 | type: types.RECIEVE_ITEMS, 50 | items, 51 | keyword, 52 | length 53 | }; 54 | } 55 | 56 | export function filterFavoriteItems(items) { 57 | return { 58 | type: types.FILTER_FAVORITE_ITEMS, 59 | items 60 | }; 61 | } 62 | 63 | export function clearFeeds(menu) { 64 | return { 65 | type: types.CLEAR_ITEMS, 66 | keywords : menu.keywords 67 | }; 68 | } 69 | 70 | export function fetchFeed(feed, menu) { 71 | return dispatch => { 72 | const keyword = menu.activeKeyword; 73 | if (keyword === 'all') { 74 | for (let keyword of menu.keywords) { 75 | let page = feed[keyword.name].page; 76 | _fetchFeed(dispatch, keyword.name, page, menu.bookmarkFilter); 77 | } 78 | } else if (keyword === 'favorite') { 79 | db.getArray('favorites').then((favorites) => { 80 | _getBookmarkCount(favorites).then((bookmarks) => { 81 | const filteredItems = _.filter(favorites, (item) => bookmarks[item.link] >= menu.bookmarkFilter); 82 | dispatch(filterFavoriteItems(filteredItems, keyword)); 83 | }); 84 | }); 85 | } else { 86 | let page = feed[keyword].page; 87 | _fetchFeed(dispatch, keyword, page, menu.bookmarkFilter); 88 | } 89 | } 90 | } 91 | 92 | export function addFavorite(item, threshold) { 93 | return dispatch => { 94 | item.isFavorited = true; 95 | db.put('favorites', item).then(() => { 96 | db.getArray('favorites').then((favorites) => { 97 | _getBookmarkCount(favorites).then((bookmarks) => { 98 | const filteredItem = (bookmarks[item.link] >= threshold)? item : null; 99 | dispatch({type: types.ADD_FAVORITE, item:filteredItem}); 100 | }); 101 | }); 102 | }); 103 | } 104 | } 105 | 106 | export function removeFavorite(item, threshold) { 107 | return dispatch => { 108 | db.remove('favorites', item.link).then(() => dispatch({type: types.REMOVE_FAVORITE, item})); 109 | } 110 | } 111 | 112 | export function openComment(item, keyword) { 113 | const url = HATENA_ENTRY_URL + 'url=' + encodeURIComponent(item.link); 114 | return dispatch => { 115 | fetch(url).then((res) => { 116 | const commentedBookmarks = _.filter(res.bookmarks, bookmark => bookmark.comment !== ''); 117 | dispatch({type: types.OPEN_COMMENT, keyword, link: item.link, comments: commentedBookmarks}); 118 | }, (error) => console.log(error)); 119 | dispatch({type: types.FETCHING_COMMENT, keyword, link: item.link}); 120 | } 121 | } 122 | 123 | export function closeComment(item, keyword) { 124 | return ({ 125 | type: types.CLOSE_COMMENT, 126 | keyword, 127 | link: item.link 128 | }); 129 | } 130 | 131 | export function changeElementHeight(elementHeight, keyword) { 132 | return ({ 133 | type: types.CHANGE_ELEMENT_HEIGHT, 134 | elementHeight, 135 | keyword 136 | }); 137 | } 138 | 139 | 140 | function _fetchFeed(dispatch, keyword, page = 0, threshold) { 141 | const id = /^id:(.*)/.exec(keyword.replace(/\s+/g, "")); 142 | if (id === null) { 143 | _fetchSearchFeed(dispatch, keyword, page, threshold); 144 | } else { 145 | _fetchUserFeed(dispatch, keyword, id[1], page, threshold) 146 | } 147 | } 148 | 149 | function _fetchSearchFeed(dispatch, keyword, page = 0, threshold) { 150 | const url = HATENA_SEARCH_URL + keyword + '&of=' + page * 40 + '&users=' + threshold; 151 | fetch(GOOGLEAPI_URI + encodeURIComponent(url)).then((feed) => { 152 | const items = getItems(feed); 153 | dispatch(recieveItems(items, keyword, items.length)); 154 | }, (error) => console.log(error)); 155 | dispatch(fetchingItems(keyword)); 156 | } 157 | 158 | function _fetchUserFeed(dispatch, keyword, user, page = 0, threshold) { 159 | const url = HATENA_URL + user + '/rss?of=' + page * 20; 160 | fetch(GOOGLEAPI_URI + encodeURIComponent(url)).then((feed) => { 161 | const items = getItems(feed); 162 | _getBookmarkCount(items).then((bookmarks) => { 163 | const filteredItems = _.filter(items, (item) => bookmarks[item.link] >= threshold); 164 | dispatch(recieveItems(filteredItems, keyword, items.length)); 165 | }); 166 | }, (error) => console.log(error)); 167 | dispatch(fetchingItems(keyword)); 168 | } 169 | 170 | function _getBookmarkCount(items) { 171 | return new Promise((resolve, reject) => { 172 | let url = HATENA_BOOKMARK_COUNT_URL; 173 | for (let item of items) url += 'url=' + encodeURIComponent(item.link) + '&'; 174 | fetch(url).then((res) => { 175 | resolve(res); 176 | }, (error) => console.log(error)); 177 | }); 178 | } 179 | 180 | 181 | -------------------------------------------------------------------------------- /src/actions/menu.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/action-types'; 2 | import DbManager from '../lib/db' 3 | 4 | const db = new DbManager('pastaDB'); 5 | 6 | export function selectKeyword(keyword) { 7 | return { 8 | type: types.SELECT_KEYWORD, 9 | keyword 10 | }; 11 | } 12 | 13 | export function changeKeywordInput(value) { 14 | return { 15 | type: types.CHANGE_KEYWORD_INPUT, 16 | value 17 | }; 18 | } 19 | 20 | export function changeBookmarkThreshold(value, x) { 21 | return { 22 | type: types.CHANGE_BOOKMARK_FILTER, 23 | value, 24 | x 25 | }; 26 | } 27 | 28 | export function toggleMenu() { 29 | return { 30 | type: types.TOGGLE_MENU 31 | }; 32 | } 33 | 34 | export function addKeyword(keyword) { 35 | return dispatch => { 36 | if (keyword === '') return; 37 | const id = /^id:(.*)/.exec(keyword.replace(/\s+/g, "")); 38 | let icon = (id === null)? 'tag' : 'user'; 39 | db.put('keywords', {name: keyword, icon}).then(() => { 40 | db.getArray('keywords').then((keywords) => { 41 | console.log(keywords); 42 | dispatch({ 43 | type: types.ADD_KEYWORD_COMPLETE, 44 | keywords 45 | }); 46 | }); 47 | }); 48 | dispatch({type: types.ADD_KEYWORD, keyword}); 49 | } 50 | } 51 | 52 | export function removeKeyword(keyword) { 53 | return dispatch => { 54 | db.remove('keywords', keyword).then(() => { 55 | db.getArray('keywords').then((keywords) => { 56 | dispatch({ 57 | type: types.REMOVE_KEYWORD, 58 | keywords, 59 | keyword 60 | }); 61 | }); 62 | }); 63 | } 64 | } 65 | 66 | -------------------------------------------------------------------------------- /src/api/feed.js: -------------------------------------------------------------------------------- 1 | import jsonp from 'jsonp'; 2 | 3 | export function fetch(url) { 4 | return new Promise((resolve, reject) => { 5 | jsonp(url, {}, (err, data) => { 6 | if (err) reject(err); 7 | resolve(data); 8 | }); 9 | }); 10 | } 11 | 12 | -------------------------------------------------------------------------------- /src/components/bookmark-slider.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Slider from 'material-ui/lib/slider'; 3 | 4 | export default class BookmarkSlider extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | onSliderChange(e, value) { 10 | this.props.changeBookmarkThreshold(~~value, e.clientX); 11 | } 12 | 13 | render() { 14 | let x = this.props.bookmarkFilterX - 24; 15 | x = (x > 210)? 210 : x; 16 | x = (x < 10)? 10 : x; 17 | return ( 18 |
19 |
20 | 21 | {this.props.bookmarkFilter} 22 |
23 | 29 |
30 | ); 31 | } 32 | } 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/components/button-comment.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class ButtonComment extends Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | onCommentClick(item) { 9 | if (item.isCommentOpen) 10 | this.props.closeComment(item, this.props.activeKeyword); 11 | else 12 | this.props.openComment(item, this.props.activeKeyword); 13 | } 14 | 15 | render() { 16 | const {item} = this.props; 17 | const icon = item.isCommentFetching ? "item__icon--comment fa fa-spinner fa-spin" 18 | : "item__icon--comment fa fa-commenting"; 19 | const text = item.isCommentOpen? "コメントを閉じる" : "コメントを見る"; 20 | return ( 21 |
22 | {text} 23 |
24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/components/button-favorite.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class ButtonFavorite extends Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | onFavoriteClick(item) { 9 | if (item.isFavorited) 10 | this.props.removeFavorite(item, this.props.bookmarkFilter); 11 | else 12 | this.props.addFavorite(item, this.props.bookmarkFilter); 13 | } 14 | 15 | render() { 16 | const {item} = this.props; 17 | const favoriteButtonClass = item.isFavorited ? "item__button--favorite item__button--favorited" 18 | : "item__button--favorite"; 19 | return ( 20 |
21 | お気に入り 22 |
23 | ); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/components/comments.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class Comments extends Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | getComments(item) { 9 | const notFoundMessage = コメントがありませんでした; 10 | if(item.comments === undefined || item.comments.length === 0) return notFoundMessage; 11 | return item.comments.map(comment => { 12 | return ( 13 |
14 |
15 | 16 | 17 | 18 | {comment.user} 19 |
20 |
21 |

{comment.comment}

22 |
23 |
24 | ); 25 | }); 26 | } 27 | render() { 28 | return ( 29 |
30 | {this.getComments(this.props.item)} 31 |
32 | ); 33 | } 34 | } 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/components/header.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class Header extends Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | onMenuButtonClick() { 9 | this.props.toggleMenu(); 10 | } 11 | render() { 12 | return ( 13 |
14 | 15 | 18 |
19 | ); 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /src/components/item.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Comments from './comments'; 3 | import ButtonFavorite from './button-favorite'; 4 | import ButtonComment from './button-comment'; 5 | import _ from 'lodash'; 6 | import {unescapeHTML} from '../lib/utils'; 7 | 8 | const FAVICON_URI = 'http://cdn-ak.favicon.st-hatena.com/?url='; 9 | const ENTRY_URI = 'http://b.hatena.ne.jp/entry/'; 10 | const BOOKMARK_IMAGE_URI = ENTRY_URI + 'image/'; 11 | 12 | export default class item extends Component { 13 | constructor(props) { 14 | super(props); 15 | } 16 | 17 | getCategories(categories) { 18 | return categories.map((category) => { 19 | return ( 20 | 23 | {category} 24 | ); 25 | }); 26 | } 27 | 28 | render() { 29 | const {item, activeKeyword, id, bookmarkFilter} = this.props; 30 | const favicon = FAVICON_URI + encodeURIComponent(item.link); 31 | const hatebuHref = ENTRY_URI + encodeURIComponent(item.link); 32 | const hatebuImage = BOOKMARK_IMAGE_URI + item.link; 33 | return ( 34 |
35 | favicon 36 | {item.title} 37 | 38 | 39 |
40 | {item.publishedDate} 41 | {this.getCategories(item.categories)}
42 |

{unescapeHTML(item.contentSnippet)}

43 | 48 | 53 | 54 |
55 | ); 56 | } 57 | } 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /src/components/keyword-input.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import RaisedButton from 'material-ui/lib/raised-button'; 3 | 4 | export default class KeywordInput extends Component { 5 | constructor(props) { 6 | super(props); 7 | } 8 | 9 | render() { 10 | return ( 11 |
12 | 17 | 22 |
23 | ); 24 | } 25 | } 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/components/keyword-list.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | export default class KeywordList extends Component { 4 | constructor(props) { 5 | super(props); 6 | } 7 | 8 | onSelect(name) { 9 | this.props.onSelect(name); 10 | } 11 | 12 | onRemove(name) { 13 | this.props.onRemove(name); 14 | } 15 | 16 | getKeywordList() { 17 | const {activeKeyword, keywords} = this.props; 18 | return keywords.map((keyword) => { 19 | const listClassName = keyword.name === activeKeyword ? 'keywords__list keywords__list--selected' : 'keywords__list'; 20 | return ( 21 |
  • 22 |
    23 | 24 | {keyword.name} 25 |
    26 |
    27 | 28 |
    29 |
  • 30 | ); 31 | }); 32 | } 33 | 34 | render() { 35 | const {activeKeyword} = this.props; 36 | return ( 37 | 54 | ); 55 | } 56 | } 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/components/pasta.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import Infinite from 'react-infinite'; 3 | import _ from 'lodash'; 4 | import Header from './header'; 5 | import SideMenu from './side-menu'; 6 | import Comments from './comments'; 7 | import Item from './item'; 8 | import {unescapeHTML} from '../lib/utils'; 9 | 10 | const FAVICON_URI = 'http://cdn-ak.favicon.st-hatena.com/?url='; 11 | const ENTRY_URI = 'http://b.hatena.ne.jp/entry/'; 12 | const BOOKMARK_IMAGE_URI = ENTRY_URI + 'image/'; 13 | 14 | export default class Pasta extends Component { 15 | constructor(props) { 16 | super(props); 17 | this.props.initialize(); 18 | this.innerHeight = document.documentElement.clientHeight; 19 | window.onresize = () => { 20 | this.innerHeight = document.documentElement.clientHeight; 21 | this.forceUpdate(); 22 | } 23 | 24 | // HACK: Adjust element height by interbal timer 25 | setInterval(() => { 26 | if (!this.props.feed.isInitialized) return; 27 | // If the number of items is not enough to scroll, polling itmes by the following timer 28 | const feed = this.props.feed[this.props.menu.activeKeyword]; 29 | const isLoadingNeeded = feed.items.length < 40 && !feed.isPageEnd && !feed.isInfiniteLoading; 30 | if (isLoadingNeeded && this.props.menu.activeKeyword !== 'all') { 31 | this.props.fetchFeed(this.props.feed, this.props.menu); 32 | } 33 | let elementHeight = feed.items.map((item, i) => { 34 | const el = document.getElementById(this.props.menu.activeKeyword + i); 35 | if (el) return el.clientHeight; 36 | else if (feed.elementHeight[i]) return feed.elementHeight[i]; 37 | else return 200; 38 | }); 39 | if (feed.items.length === 0) elementHeight = 200; 40 | if (!_.isEqual(feed.elementHeight, elementHeight)) { 41 | this.onChangeHeight(elementHeight); 42 | } 43 | }, 200); 44 | } 45 | 46 | onInfiniteLoad() { 47 | if (this.props.menu.keywords.length === 0) return; 48 | if (this.props.feed[this.props.menu.activeKeyword].isPageEnd) return; 49 | console.log("loading.."); 50 | this.props.fetchFeed(this.props.feed, this.props.menu); 51 | } 52 | 53 | elementInfiniteLoad() { 54 | if (this.props.feed[this.props.menu.activeKeyword].isPageEnd) return; 55 | return
    ; 56 | } 57 | 58 | onChangeHeight(elementHeight) { 59 | this.props.changeElementHeight(elementHeight, this.props.menu.activeKeyword); 60 | } 61 | 62 | getItems() { 63 | const keyword = this.props.menu.activeKeyword; 64 | const feed = this.props.feed[keyword]; 65 | if (this.props.menu.keywords.length === 0) return
    まだ記事はありません。キーワードを追加してください。
    ; 66 | else if (feed.items.length === 0 && feed.isPageEnd) return
    記事が見つかりませんでした。
    ; 67 | return feed.items.map((item, i) => { 68 | return ( 69 | 81 | ); 82 | }); 83 | } 84 | 85 | render() { 86 | if (!this.props.feed.isInitialized) return
    ; 87 | const feed = this.props.feed[this.props.menu.activeKeyword]; 88 | return ( 89 |
    90 |
    93 | 105 |
    106 | 114 | {this.getItems()} 115 | 116 |
    117 |
    118 | ); 119 | } 120 | } 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/components/side-menu.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import BookmarkSlider from './bookmark-slider'; 3 | import KeywordInput from './keyword-input'; 4 | import KeywordList from './keyword-list'; 5 | 6 | export default class SideMenu extends Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | onSliderChanged() { 12 | this.props.clearFeeds(this.props.menu); 13 | this.props.fetchFeed(this.props.feed, this.props.menu); 14 | } 15 | 16 | onKeywordInputChange(e) { 17 | this.props.changeKeywordInput(e.target.value); 18 | } 19 | 20 | onKeywordSubmit() { 21 | this.props.addKeyword(this.props.menu.keywordInput); 22 | this.props.fetchFeed(this.props.feed, this.props.menu); 23 | } 24 | 25 | onSelectKeyword(name) { 26 | this.props.selectKeyword(name); 27 | this.props.fetchFeed(this.props.feed, this.props.menu); 28 | } 29 | 30 | onKeywordRemove(name) { 31 | this.props.removeKeyword(name); 32 | this.props.fetchFeed(this.props.feed, this.props.menu); 33 | } 34 | 35 | onMenuButtonClick() { 36 | this.props.toggleMenu(); 37 | } 38 | 39 | render() { 40 | return ( 41 |
    44 | Pasta 45 | 53 | 57 | 62 |
    63 | ); 64 | } 65 | } 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/constants/action-types.js: -------------------------------------------------------------------------------- 1 | export const INITIALIZING = 'INITIALIZING'; 2 | export const INITIALIZE_KEYWORD = 'INITIALIZE_KEYWORD'; 3 | export const INITIALIZE_FAVORITE = 'INITIALIZE_FAVORITE'; 4 | export const RECIEVE_ITEMS = 'RECIEVE_ITEMS'; 5 | export const FETCHING_ITEMS = 'FETCHING_ITEMS'; 6 | export const CLEAR_ITEMS = 'CLEAR_ITEMS'; 7 | export const ADD_KEYWORD = 'ADD_KEYWORD'; 8 | export const FILTER_FAVORITE_ITEMS = 'FILTER_FAVORITE_ITEMS'; 9 | export const ADD_KEYWORD_COMPLETE = 'ADD_KEYWORD_COMPLETE'; 10 | export const REMOVE_KEYWORD = 'REMOVE_KEYWORD'; 11 | export const SELECT_KEYWORD = 'SELECT_KEYWORD'; 12 | export const CHANGE_BOOKMARK_FILTER = 'CHANGE_BOOKMARK_FILTER'; 13 | export const CHANGE_KEYWORD_INPUT = 'CHANGE_KEYWORD_INPUT'; 14 | export const ADD_FAVORITE = 'ADD_FAVORITE'; 15 | export const REMOVE_FAVORITE = 'REMOVE_FAVORITE'; 16 | export const TOGGLE_MENU = 'TOGGLE_MENU'; 17 | export const FETCHING_COMMENT = 'FETCHING_COMMENT'; 18 | export const OPEN_COMMENT = 'OPEN_COMMENT'; 19 | export const CLOSE_COMMENT = 'CLOSE_COMMENT'; 20 | export const CHANGE_ELEMENT_HEIGHT = 'CHANGE_ELEMENT_HEIGHT'; 21 | -------------------------------------------------------------------------------- /src/containers/app.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import { connect } from 'react-redux'; 3 | import { bindActionCreators } from 'redux'; 4 | import Pasta from '../components/pasta'; 5 | import * as feedActions from '../actions/feed'; 6 | import * as menuActions from '../actions/menu'; 7 | 8 | function mapStateToProps(state) { 9 | return state; 10 | //}; 11 | } 12 | 13 | function mapDispatchToProps(dispatch) { 14 | const actions = _.assign({}, feedActions, menuActions); 15 | return bindActionCreators(actions, dispatch); 16 | } 17 | 18 | export default connect( 19 | mapStateToProps, 20 | mapDispatchToProps 21 | )(Pasta); 22 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import { Provider } from 'react-redux'; 4 | import configureStore from './stores/configure-store'; 5 | import App from './containers/app'; 6 | import Pasta from './components/pasta'; 7 | 8 | const store = configureStore(); 9 | 10 | render( 11 | 12 | 13 | , 14 | document.getElementById('pasta') 15 | ); 16 | -------------------------------------------------------------------------------- /src/lib/db.js: -------------------------------------------------------------------------------- 1 | import Dexie from 'dexie'; 2 | 3 | let instance = null; 4 | 5 | export default class DbManager { 6 | constructor(name) { 7 | if(!instance) { 8 | this.db = new Dexie(name); 9 | instance = this; 10 | } 11 | return instance; 12 | } 13 | 14 | create(schemes) { 15 | //this.db.delete(); 16 | this.db.version(1).stores(schemes); 17 | this.db.open(); 18 | } 19 | 20 | put(table, doc) { 21 | return this.db[table].put(doc); 22 | } 23 | 24 | remove(table, key) { 25 | return this.db[table].delete(key); 26 | } 27 | 28 | getArray(table) { 29 | return new Promise((resolve, reject) => { 30 | this.db[table].toArray((docs) => { 31 | resolve(docs); 32 | }); 33 | }); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/lib/utils.js: -------------------------------------------------------------------------------- 1 | export function unescapeHTML(str) { 2 | let div = document.createElement("div"); 3 | div.innerHTML = str.replace(//g,">") 5 | .replace(/ /g, " ") 6 | .replace(/\r/g, " ") 7 | .replace(/\n/g, " "); 8 | return div.textContent || div.innerText; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /src/reducers/feed.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/action-types'; 2 | import _ from 'lodash'; 3 | 4 | function _createProps() { 5 | return { 6 | page : 0, 7 | items : [], 8 | isPageEnd : false, 9 | isInfiniteLoading : false, 10 | elementHeight : 200 11 | }; 12 | } 13 | 14 | function _getItemsUpdatedByFavorite(items, favorites) { 15 | return _.map(items, (item) => { 16 | if (_.some(favorites, 'link', item.link)) item.isFavorited = true; 17 | else item.isFavorited = false; 18 | return item; 19 | }); 20 | } 21 | 22 | // FIXME 23 | function _updateAllByFavorite(state, favorites) { 24 | for (let name in state) { 25 | if(state[name].items !== undefined) { 26 | state[name].items = _getItemsUpdatedByFavorite(state[name].items, favorites) 27 | } 28 | } 29 | } 30 | 31 | export default function feed(state={}, action) { 32 | let elementHeight; 33 | switch(action.type){ 34 | case types.INITIALIZING : 35 | state.isInitialized = false; 36 | state.all = _createProps(); 37 | state.favorite = _createProps(); 38 | return Object.assign({}, state); 39 | 40 | case types.INITIALIZE_KEYWORD : 41 | for (let keyword of action.keywords) state[keyword.name] = _createProps(); 42 | state.favorite.isPageEnd = true; 43 | state.favorite.isInfiniteLoading = false; 44 | state.isInitialized = true; 45 | return Object.assign({}, state); 46 | 47 | case types.INITIALIZE_FAVORITE : 48 | state.favorite.items = action.favorites; 49 | return Object.assign({}, state); 50 | 51 | case types.ADD_FAVORITE : 52 | if (action.item !== null) { 53 | action.item.isFavorite = true; 54 | state.favorite.items.push(action.item); 55 | } 56 | if (state.favorite.elementHeight.length > 0) 57 | state.favorite.elementHeight.push(200); 58 | else 59 | state.favorite.elementHeight = 200; 60 | _updateAllByFavorite(state, state.favorite.items); 61 | return Object.assign({}, state); 62 | 63 | case types.REMOVE_FAVORITE : 64 | state.favorite.items.map((item, i) => { 65 | if (action.item.link === item.link) { 66 | state.favorite.items.splice( i , 1); 67 | if (state.favorite.elementHeight.length > 0) 68 | state.favorite.elementHeight.splice( i , 1); 69 | } 70 | }); 71 | _updateAllByFavorite(state, state.favorite.items); 72 | return Object.assign({}, state); 73 | 74 | case types.FILTER_FAVORITE_ITEMS: 75 | state.favorite.items = action.items; 76 | return Object.assign({}, state); 77 | 78 | case types.RECIEVE_ITEMS : 79 | const items = _getItemsUpdatedByFavorite(action.items, state.favorite.items); 80 | const keyword = action.keyword; 81 | const elementHeight = items.map(item => 200); 82 | if (elementHeight.length > 0) { 83 | if (state.all.elementHeight.length > 0) 84 | state.all.elementHeight = state.all.elementHeight.concat(elementHeight); 85 | else 86 | state.all.elementHeight = elementHeight; 87 | if (state[keyword].elementHeight.length > 0) 88 | state[keyword].elementHeight = state[keyword].elementHeight.concat(elementHeight); 89 | else 90 | state[keyword].elementHeight = elementHeight; 91 | } 92 | state[keyword].isInfiniteLoading = false; 93 | if (items === null) { 94 | state[keyword].isPageEnd = true; 95 | return Object.assign({}, state); 96 | } 97 | state.all.items = state.all.items.concat(items); 98 | state[keyword].items = state[keyword].items.concat(items); 99 | state[keyword].isPageEnd = action.length === 0; 100 | state[keyword].page += 1; 101 | return Object.assign({}, state); 102 | 103 | case types.CLEAR_ITEMS : 104 | state.all = _createProps(); 105 | for (let keyword of action.keywords) state[keyword.name] = _createProps(); 106 | return Object.assign({}, state); 107 | 108 | case types.FETCHING_ITEMS : 109 | state[action.keyword].isInfiniteLoading = true; 110 | return Object.assign({}, state); 111 | 112 | case types.ADD_KEYWORD : 113 | state[action.keyword] = _createProps(); 114 | return Object.assign({}, state); 115 | 116 | case types.REMOVE_KEYWORD : 117 | state.all = _createProps(); 118 | return Object.assign({}, state); 119 | 120 | case types.FETCHING_COMMENT : 121 | state[action.keyword].items = _.map(state[action.keyword].items, item => { 122 | if (item.link === action.link) item.isCommentFetching = true; 123 | return item; 124 | }); 125 | return Object.assign({}, state); 126 | 127 | case types.OPEN_COMMENT : 128 | state[action.keyword].items = _.map(state[action.keyword].items, item => { 129 | if (item.link === action.link) { 130 | item.isCommentFetching = false; 131 | item.isCommentOpen = true; 132 | item.comments = action.comments; 133 | } 134 | return item; 135 | }); 136 | return Object.assign({}, state); 137 | 138 | case types.CLOSE_COMMENT : 139 | state[action.keyword].items = _.map(state[action.keyword].items, item => { 140 | if (item.link === action.link) item.isCommentOpen = false; 141 | return item; 142 | }); 143 | return Object.assign({}, state); 144 | 145 | case types.CLOSE_COMMENT : 146 | state[action.keyword].items = _.map(state[action.keyword].items, item => { 147 | if (item.link === action.link) item.isCommentOpen = false; 148 | return item; 149 | }); 150 | return Object.assign({}, state); 151 | 152 | case types.CHANGE_ELEMENT_HEIGHT : 153 | state[action.keyword].elementHeight = action.elementHeight; 154 | return Object.assign({}, state); 155 | 156 | default: 157 | return state; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | import { combineReducers } from 'redux'; 2 | import feed from './feed'; 3 | import menu from './menu'; 4 | 5 | const rootReducer = combineReducers({ 6 | feed, 7 | menu 8 | }); 9 | 10 | export default rootReducer; 11 | -------------------------------------------------------------------------------- /src/reducers/menu.js: -------------------------------------------------------------------------------- 1 | import * as types from '../constants/action-types'; 2 | 3 | export default function menu(state={}, action) { 4 | switch(action.type){ 5 | case types.INITIALIZE_KEYWORD : 6 | state.keywords = action.keywords; 7 | state.activeKeyword = 'all'; 8 | state.bookmarkFilter = 1; 9 | state.bookmarkFilterX = 15; 10 | state.keywordInput = ''; 11 | state.isMenuOpen = false; 12 | return Object.assign({}, state); 13 | 14 | case types.SELECT_KEYWORD : 15 | state.activeKeyword = action.keyword; 16 | return Object.assign({}, state); 17 | 18 | case types.CHANGE_BOOKMARK_FILTER : 19 | state.bookmarkFilter = action.value; 20 | state.bookmarkFilterX = action.x; 21 | return Object.assign({}, state); 22 | 23 | case types.CHANGE_KEYWORD_INPUT : 24 | state.keywordInput = action.value; 25 | return Object.assign({}, state); 26 | 27 | case types.ADD_KEYWORD : 28 | state.activeKeyword = action.keyword; 29 | state.keywordInput = ''; 30 | return Object.assign({}, state); 31 | 32 | case types.ADD_KEYWORD_COMPLETE : 33 | state.keywords = action.keywords; 34 | return Object.assign({}, state); 35 | 36 | case types.TOGGLE_MENU : 37 | state.isMenuOpen = !state.isMenuOpen; 38 | return Object.assign({}, state); 39 | 40 | case types.REMOVE_KEYWORD : 41 | state.keywords = action.keywords; 42 | if (state.keywords.length === 0 || action.keyword === state.activeKeyword) 43 | state.activeKeyword = 'all' 44 | return Object.assign({}, state); 45 | 46 | default: 47 | return state; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/stores/configure-store.js: -------------------------------------------------------------------------------- 1 | import {createStore, applyMiddleware} from 'redux'; 2 | import reducers from '../reducers' 3 | import thunk from 'redux-thunk'; 4 | import createLogger from 'redux-logger'; 5 | 6 | export default function configureStore() { 7 | const logger = createLogger(); 8 | const createStoreWithMiddleware = applyMiddleware( 9 | thunk, 10 | logger 11 | )(createStore); 12 | return createStoreWithMiddleware(reducers); 13 | } 14 | -------------------------------------------------------------------------------- /stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bokuweb/tuna_pasta/59355d8bd150946ec2774ec10714d8b86642fc9d/stylesheets/.keep -------------------------------------------------------------------------------- /stylus/base/base.styl: -------------------------------------------------------------------------------- 1 | html, body, #pasta 2 | height 100% 3 | padding 0 4 | margin 0 5 | -webkit-text-size-adjust 100% 6 | -ms-text-size-adjust 100% 7 | background #f5f5f5 8 | font-family helvetica, "メイリオ", arial, 'hiragino kaku gothic pro', meiryo, 'ms pgothic', sans-serif 9 | 10 | div, 11 | input, 12 | textarea 13 | font-family helvetica, "メイリオ", arial, 'hiragino kaku gothic pro', meiryo, 'ms pgothic', sans-serif 14 | 15 | input, 16 | textarea, 17 | select 18 | outline none 19 | 20 | html, 21 | a, 22 | input, 23 | textarea 24 | -webkit-font-smoothing antialiased 25 | text-shadow 1px 1px 1px rgba(0, 0, 0, 0.004) 26 | color #ccc 27 | 28 | ul 29 | padding 0 30 | 31 | li 32 | list-style none 33 | 34 | a 35 | text-decoration none 36 | 37 | #container 38 | height 100% 39 | width 100% 40 | display flex 41 | flex-direction row 42 | box-orient horizontal 43 | 44 | 45 | -------------------------------------------------------------------------------- /stylus/base/normalize.styl: -------------------------------------------------------------------------------- 1 | /*! normalize.css v3.0.2 | MIT License | git.io/normalize */ 2 | 3 | /** 4 | * 1. Set default font family to sans-serif. 5 | * 2. Prevent iOS text size adjust after orientation change, without disabling 6 | * user zoom. 7 | */ 8 | 9 | html { 10 | font-family: sans-serif; /* 1 */ 11 | -ms-text-size-adjust: 100%; /* 2 */ 12 | -webkit-text-size-adjust: 100%; /* 2 */ 13 | } 14 | 15 | /** 16 | * Remove default margin. 17 | */ 18 | 19 | body { 20 | margin: 0; 21 | } 22 | 23 | /* HTML5 display definitions 24 | ========================================================================== */ 25 | 26 | /** 27 | * Correct `block` display not defined for any HTML5 element in IE 8/9. 28 | * Correct `block` display not defined for `details` or `summary` in IE 10/11 29 | * and Firefox. 30 | * Correct `block` display not defined for `main` in IE 11. 31 | */ 32 | 33 | article, 34 | aside, 35 | details, 36 | figcaption, 37 | figure, 38 | footer, 39 | header, 40 | hgroup, 41 | main, 42 | menu, 43 | nav, 44 | section, 45 | summary { 46 | display: block; 47 | } 48 | 49 | /** 50 | * 1. Correct `inline-block` display not defined in IE 8/9. 51 | * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. 52 | */ 53 | 54 | audio, 55 | canvas, 56 | progress, 57 | video { 58 | display: inline-block; /* 1 */ 59 | vertical-align: baseline; /* 2 */ 60 | } 61 | 62 | /** 63 | * Prevent modern browsers from displaying `audio` without controls. 64 | * Remove excess height in iOS 5 devices. 65 | */ 66 | 67 | audio:not([controls]) { 68 | display: none; 69 | height: 0; 70 | } 71 | 72 | /** 73 | * Address `[hidden]` styling not present in IE 8/9/10. 74 | * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. 75 | */ 76 | 77 | [hidden], 78 | template { 79 | display: none; 80 | } 81 | 82 | /* Links 83 | ========================================================================== */ 84 | 85 | /** 86 | * Remove the gray background color from active links in IE 10. 87 | */ 88 | 89 | a { 90 | background-color: transparent; 91 | } 92 | 93 | /** 94 | * Improve readability when focused and also mouse hovered in all browsers. 95 | */ 96 | 97 | a:active, 98 | a:hover { 99 | outline: 0; 100 | } 101 | 102 | /* Text-level semantics 103 | ========================================================================== */ 104 | 105 | /** 106 | * Address styling not present in IE 8/9/10/11, Safari, and Chrome. 107 | */ 108 | 109 | abbr[title] { 110 | border-bottom: 1px dotted; 111 | } 112 | 113 | /** 114 | * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. 115 | */ 116 | 117 | b, 118 | strong { 119 | font-weight: bold; 120 | } 121 | 122 | /** 123 | * Address styling not present in Safari and Chrome. 124 | */ 125 | 126 | dfn { 127 | font-style: italic; 128 | } 129 | 130 | /** 131 | * Address variable `h1` font-size and margin within `section` and `article` 132 | * contexts in Firefox 4+, Safari, and Chrome. 133 | */ 134 | 135 | h1 { 136 | font-size: 2em; 137 | margin: 0.67em 0; 138 | } 139 | 140 | /** 141 | * Address styling not present in IE 8/9. 142 | */ 143 | 144 | mark { 145 | background: #ff0; 146 | color: #000; 147 | } 148 | 149 | /** 150 | * Address inconsistent and variable font size in all browsers. 151 | */ 152 | 153 | small { 154 | font-size: 80%; 155 | } 156 | 157 | /** 158 | * Prevent `sub` and `sup` affecting `line-height` in all browsers. 159 | */ 160 | 161 | sub, 162 | sup { 163 | font-size: 75%; 164 | line-height: 0; 165 | position: relative; 166 | vertical-align: baseline; 167 | } 168 | 169 | sup { 170 | top: -0.5em; 171 | } 172 | 173 | sub { 174 | bottom: -0.25em; 175 | } 176 | 177 | /* Embedded content 178 | ========================================================================== */ 179 | 180 | /** 181 | * Remove border when inside `a` element in IE 8/9/10. 182 | */ 183 | 184 | img { 185 | border: 0; 186 | } 187 | 188 | /** 189 | * Correct overflow not hidden in IE 9/10/11. 190 | */ 191 | 192 | svg:not(:root) { 193 | overflow: hidden; 194 | } 195 | 196 | /* Grouping content 197 | ========================================================================== */ 198 | 199 | /** 200 | * Address margin not present in IE 8/9 and Safari. 201 | */ 202 | 203 | figure { 204 | margin: 1em 40px; 205 | } 206 | 207 | /** 208 | * Address differences between Firefox and other browsers. 209 | */ 210 | 211 | hr { 212 | -moz-box-sizing: content-box; 213 | box-sizing: content-box; 214 | height: 0; 215 | } 216 | 217 | /** 218 | * Contain overflow in all browsers. 219 | */ 220 | 221 | pre { 222 | overflow: auto; 223 | } 224 | 225 | /** 226 | * Address odd `em`-unit font size rendering in all browsers. 227 | */ 228 | 229 | code, 230 | kbd, 231 | pre, 232 | samp { 233 | font-family: monospace, monospace; 234 | font-size: 1em; 235 | } 236 | 237 | /* Forms 238 | ========================================================================== */ 239 | 240 | /** 241 | * Known limitation: by default, Chrome and Safari on OS X allow very limited 242 | * styling of `select`, unless a `border` property is set. 243 | */ 244 | 245 | /** 246 | * 1. Correct color not being inherited. 247 | * Known issue: affects color of disabled elements. 248 | * 2. Correct font properties not being inherited. 249 | * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. 250 | */ 251 | 252 | button, 253 | input, 254 | optgroup, 255 | select, 256 | textarea { 257 | color: inherit; /* 1 */ 258 | font: inherit; /* 2 */ 259 | margin: 0; /* 3 */ 260 | } 261 | 262 | /** 263 | * Address `overflow` set to `hidden` in IE 8/9/10/11. 264 | */ 265 | 266 | button { 267 | overflow: visible; 268 | } 269 | 270 | /** 271 | * Address inconsistent `text-transform` inheritance for `button` and `select`. 272 | * All other form control elements do not inherit `text-transform` values. 273 | * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. 274 | * Correct `select` style inheritance in Firefox. 275 | */ 276 | 277 | button, 278 | select { 279 | text-transform: none; 280 | } 281 | 282 | /** 283 | * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` 284 | * and `video` controls. 285 | * 2. Correct inability to style clickable `input` types in iOS. 286 | * 3. Improve usability and consistency of cursor style between image-type 287 | * `input` and others. 288 | */ 289 | 290 | button, 291 | html input[type="button"], /* 1 */ 292 | input[type="reset"], 293 | input[type="submit"] { 294 | -webkit-appearance: button; /* 2 */ 295 | cursor: pointer; /* 3 */ 296 | } 297 | 298 | /** 299 | * Re-set default cursor for disabled elements. 300 | */ 301 | 302 | button[disabled], 303 | html input[disabled] { 304 | cursor: default; 305 | } 306 | 307 | /** 308 | * Remove inner padding and border in Firefox 4+. 309 | */ 310 | 311 | button::-moz-focus-inner, 312 | input::-moz-focus-inner { 313 | border: 0; 314 | padding: 0; 315 | } 316 | 317 | /** 318 | * Address Firefox 4+ setting `line-height` on `input` using `!important` in 319 | * the UA stylesheet. 320 | */ 321 | 322 | input { 323 | line-height: normal; 324 | } 325 | 326 | /** 327 | * It's recommended that you don't attempt to style these elements. 328 | * Firefox's implementation doesn't respect box-sizing, padding, or width. 329 | * 330 | * 1. Address box sizing set to `content-box` in IE 8/9/10. 331 | * 2. Remove excess padding in IE 8/9/10. 332 | */ 333 | 334 | input[type="checkbox"], 335 | input[type="radio"] { 336 | box-sizing: border-box; /* 1 */ 337 | padding: 0; /* 2 */ 338 | } 339 | 340 | /** 341 | * Fix the cursor style for Chrome's increment/decrement buttons. For certain 342 | * `font-size` values of the `input`, it causes the cursor style of the 343 | * decrement button to change from `default` to `text`. 344 | */ 345 | 346 | input[type="number"]::-webkit-inner-spin-button, 347 | input[type="number"]::-webkit-outer-spin-button { 348 | height: auto; 349 | } 350 | 351 | /** 352 | * 1. Address `appearance` set to `searchfield` in Safari and Chrome. 353 | * 2. Address `box-sizing` set to `border-box` in Safari and Chrome 354 | * (include `-moz` to future-proof). 355 | */ 356 | 357 | input[type="search"] { 358 | -webkit-appearance: textfield; /* 1 */ 359 | -moz-box-sizing: content-box; 360 | -webkit-box-sizing: content-box; /* 2 */ 361 | box-sizing: content-box; 362 | } 363 | 364 | /** 365 | * Remove inner padding and search cancel button in Safari and Chrome on OS X. 366 | * Safari (but not Chrome) clips the cancel button when the search input has 367 | * padding (and `textfield` appearance). 368 | */ 369 | 370 | input[type="search"]::-webkit-search-cancel-button, 371 | input[type="search"]::-webkit-search-decoration { 372 | -webkit-appearance: none; 373 | } 374 | 375 | /** 376 | * Define consistent border, margin, and padding. 377 | */ 378 | 379 | fieldset { 380 | border: 1px solid #c0c0c0; 381 | margin: 0 2px; 382 | padding: 0.35em 0.625em 0.75em; 383 | } 384 | 385 | /** 386 | * 1. Correct `color` not being inherited in IE 8/9/10/11. 387 | * 2. Remove padding so people aren't caught out if they zero out fieldsets. 388 | */ 389 | 390 | legend { 391 | border: 0; /* 1 */ 392 | padding: 0; /* 2 */ 393 | } 394 | 395 | /** 396 | * Remove default vertical scrollbar in IE 8/9/10/11. 397 | */ 398 | 399 | textarea { 400 | overflow: auto; 401 | } 402 | 403 | /** 404 | * Don't inherit the `font-weight` (applied by a rule above). 405 | * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. 406 | */ 407 | 408 | optgroup { 409 | font-weight: bold; 410 | } 411 | 412 | /* Tables 413 | ========================================================================== */ 414 | 415 | /** 416 | * Remove most spacing between table cells. 417 | */ 418 | 419 | table { 420 | border-collapse: collapse; 421 | border-spacing: 0; 422 | } 423 | 424 | td, 425 | th { 426 | padding: 0; 427 | } 428 | -------------------------------------------------------------------------------- /stylus/block/bookmark-slider.styl: -------------------------------------------------------------------------------- 1 | .bookmarkslider 2 | width 100% 3 | margin 0 auto 4 | position relative 5 | padding 15px 0 0 0 6 | 7 | > div[name="bookmarkslider"] 8 | width 70% 9 | margin 0 0 0 15% 10 | 11 | .bookmarkslider__count 12 | background #34495E 13 | color #f5f5f5 14 | padding 8px 15 | width 40px 16 | position absolute 17 | top 0 18 | left 10px 19 | border-radius 4px 20 | text-align center 21 | vertical-align middle 22 | 23 | i.bookmarkslider__icon 24 | color #f5f5f5 25 | margin 0 2px -2px 0 26 | display inline-block 27 | 28 | .bookmarkslider__count:after 29 | content '' 30 | position absolute 31 | border-top 10px solid #34495E 32 | border-right 5px solid transparent 33 | border-left 5px solid transparent 34 | bottom -9px 35 | left 20px 36 | -------------------------------------------------------------------------------- /stylus/block/comments.styl: -------------------------------------------------------------------------------- 1 | .comments 2 | padding 20px 0 20px 0 3 | transition all .4s ease 4 | 5 | .comments--close 6 | transition all .4s ease 7 | display none 8 | 9 | .comments--open 10 | height auto 11 | 12 | .comments__user-name 13 | color #34495E 14 | padding 5px 5px 0 5px 15 | font-size 11px 16 | display inline-block 17 | width 40px 18 | 19 | .comments__text--notfound 20 | font-size 12px 21 | 22 | .comments__comment-balloon 23 | position relative 24 | background #fff 25 | padding 5px 10px 26 | border-radius 10px 27 | width calc(100% - 90px) 28 | color #34495E 29 | font-size 11px 30 | float right 31 | 32 | .comments__comment-balloon:after, 33 | .comments__comment-balloon:before 34 | top: 50% 35 | border: solid transparent 36 | content: " " 37 | height: 0 38 | width: 0 39 | position: absolute 40 | pointer-events: none 41 | right 100% 42 | border-width 15px 43 | margin-top -16px 44 | border-right-color #fff 45 | 46 | .comments__comment 47 | float left 48 | width 60px 49 | padding 5px 0 0 0 50 | height auto 51 | 52 | .comments__avatar 53 | border-radius 50% 54 | width 32px 55 | height 32px 56 | margin-left 10px 57 | border solid 2px #1ABC9C 58 | 59 | .comments__comment-box 60 | margin-bottom: 25px 61 | overflow: hidden 62 | 63 | .comments__comment-box > p 64 | line-height 1.5 65 | -------------------------------------------------------------------------------- /stylus/block/content.styl: -------------------------------------------------------------------------------- 1 | .content 2 | flex 1 3 | box-flex 1 4 | text-shadow -1px 1px 0 rgba(255, 255, 255, 1) 5 | color #7F8C8D 6 | width 100% 7 | min-height 100% 8 | 9 | 10 | 11 | .content > div::-webkit-scrollbar 12 | width 10px 13 | height 10px 14 | 15 | .content > div::-webkit-scrollbar-thumb 16 | background #34495E 17 | border-radius 2px 18 | 19 | .content__items 20 | padding 20px 30px 0 50px 21 | height 100% 22 | 23 | @media screen and (max-width: 768px) 24 | .content 25 | padding 40px 0 0 0 26 | 27 | .content__items 28 | padding 10px 15px 0 15px 29 | height 100% 30 | 31 | .github-ribbon 32 | display none 33 | 34 | @media screen and (min-width: 769px) 35 | .content 36 | overflow-y auto 37 | max-height 100% 38 | width 100% 39 | -------------------------------------------------------------------------------- /stylus/block/header.styl: -------------------------------------------------------------------------------- 1 | @media screen and (max-width: 768px) 2 | .header 3 | display block 4 | position fixed 5 | height 48px 6 | width 100% 7 | border-bottom solid 1px #ddd 8 | background #f5f5f5 9 | top 0 10 | left 0 11 | z-index 999 12 | 13 | .header__logo 14 | height 52px 15 | width auto 16 | display block 17 | margin 0 auto 18 | 19 | .header__button--menu 20 | position absolute 21 | top 16px 22 | left calc(100% - 30px) 23 | 24 | @media screen and (min-width: 769px) 25 | .header 26 | display none 27 | -------------------------------------------------------------------------------- /stylus/block/item.styl: -------------------------------------------------------------------------------- 1 | .item 2 | min-height 160px 3 | max-width 800px 4 | padding 20px 0 0 0 5 | border-bottom solid 1px #DDD 6 | 7 | .item__favicon 8 | margin 0 8px -2px 0 9 | 10 | .item__image--hatebu 11 | margin 0px 0 -2px 5px 12 | 13 | .item__title 14 | line-height 28px 15 | font-size 95% 16 | padding 0 0 3px 17 | color #34495E 18 | transition all .4s ease 19 | 20 | .item__title:hover 21 | color #2980B9 22 | 23 | .item__publish-date 24 | margin 5px 0 0 0 25 | font-size 10px 26 | color #95A5A6 27 | 28 | .item__category 29 | font-size 11px 30 | background #16A085 31 | padding 3px 32 | border-radius 2px 33 | line-height 11px 34 | color #fff 35 | font-weight bold 36 | display inline-block 37 | text-shadow none 38 | margin 0 0 0 10px 39 | 40 | .item__content-snippet 41 | color #7F8C8D 42 | font-size 90% 43 | padding 10px 0 10px 0 44 | //border-bottom solid 1px #DDD 45 | line-height 20px 46 | word-break break-all 47 | 48 | .item__button--comment 49 | margin 0 0 25px 10px 50 | font-size 11px 51 | cursor pointer 52 | transition all .4s ease 53 | display inline-block 54 | border-radius 3px 55 | background #ECF0F1 56 | text-shadow none 57 | padding 3px 10px 58 | > i 59 | margin 0 12px 0 0 60 | 61 | .item__button--comment:hover 62 | color #E74C3C 63 | 64 | .item__button--favorite 65 | margin 0 0 25px 0 66 | font-size 11px 67 | cursor pointer 68 | transition all .4s ease 69 | display inline-block 70 | border-radius 3px 71 | background #ECF0F1 72 | text-shadow none 73 | padding 3px 10px 74 | > i 75 | margin 0 12px 0 0 76 | 77 | .item__button--favorite:hover 78 | color #E74C3C 79 | 80 | .item__button--favorited 81 | color #E74C3C 82 | 83 | @media screen and (max-width: 768px) 84 | .item 85 | min-height 130px 86 | max-width 100% 87 | padding 10px 5px 10px 5px 88 | border-bottom solid 1px #DDD 89 | 90 | .item__content-snippet 91 | //display none 92 | overflow hidden 93 | white-space nowrap 94 | text-overflow ellipsis 95 | 96 | .item__button--favorite 97 | margin 10px 10px 10px 0 98 | font-size 11px 99 | cursor pointer 100 | transition all .4s ease 101 | display inline-block 102 | > i 103 | margin 0 10px 0 0 104 | 105 | .item__button--comment 106 | margin 10px 0 10px 107 | font-size 11px 108 | cursor pointer 109 | transition all .4s ease 110 | display inline-block 111 | > i 112 | margin 0 10px 0 0 113 | 114 | .item__publish-date 115 | margin 0 0 20px 0 -------------------------------------------------------------------------------- /stylus/block/keyword-input.styl: -------------------------------------------------------------------------------- 1 | .keyword-input 2 | margin 0 0 46px 20px 3 | display -webkit-flex 4 | display flex 5 | -webkit-flex-direction row 6 | flex-direction row 7 | 8 | .keyword-input__input 9 | border 0 10 | border solid 1px #2C3E50 11 | background #34495E 12 | opacity 0.9 13 | padding 0 10px 14 | color #f5f5f5 15 | border-radius 3px 16 | margin 0 5px 0 0 17 | -moz-box-shadow inset 0 0 4px rgba(0,0,0,0.1) 18 | -webkit-box-shadow inset 0 0 4px rgba(0, 0, 0, 0.1) 19 | box-shadow inner 0 0 4px rgba(0, 0, 0, 0.1) 20 | height 26px 21 | line-height 26px 22 | font-size 14px 23 | width 140px -------------------------------------------------------------------------------- /stylus/block/keywords.styl: -------------------------------------------------------------------------------- 1 | .keywords 2 | color #ECF0F1 3 | margin 20px 0 0 0 4 | 5 | .keywords__list 6 | font-size 16px 7 | margin 5px 0 8px 0 8 | padding 0px 0 0px 60px 9 | line-height 32px 10 | border-radius 0 4px 4px 0 11 | width 200px 12 | transition all .5s ease 13 | position relative 14 | height 32px 15 | 16 | .keywords__keyword 17 | display inline-block 18 | width 160px 19 | overflow hidden 20 | white-space nowrap 21 | text-overflow ellipsis 22 | 23 | .keywords__icon 24 | font-size 12px 25 | margin -1px 30px 0 0 26 | 27 | .keywords__name 28 | cursor pointer 29 | 30 | .keywords__remove 31 | display none 32 | cursor pointer 33 | 34 | .keywords__list--selected 35 | font-size 16px 36 | margin 5px 0 8px 0 37 | background #34495E 38 | padding 0 0 0 60px 39 | 40 | .keywords__list:not(.keywords__list--selected):hover 41 | background #D35400 42 | 43 | .keywords__list:hover > .keywords__remove 44 | display inline-block 45 | position absolute 46 | left 230px -------------------------------------------------------------------------------- /stylus/block/rect-spinner.styl: -------------------------------------------------------------------------------- 1 | .rect-spinner 2 | width 40px 3 | height 40px 4 | background-color #3498DB 5 | margin 100px auto 6 | -webkit-animation rect-sk-rotateplane 1.2s infinite ease-in-out 7 | animation rect-sk-rotateplane 1.2s infinite ease-in-out 8 | 9 | @-webkit-keyframes rect-sk-rotateplane 10 | 0% -webkit-transform perspective(120px) 11 | 50% -webkit-transform perspective(120px) rotateY(180deg) 12 | 100% -webkit-transform perspective(120px) rotateY(180deg) rotateX(180deg) 13 | 14 | @keyframes rect-sk-rotateplane 15 | 0% 16 | transform perspective(120px) rotateX(0deg) rotateY(0deg) 17 | -webkit-transform perspective(120px) rotateX(0deg) rotateY(0deg) 18 | 50% 19 | transform perspective(120px) rotateX(-180.1deg) rotateY(0deg) 20 | -webkit-transform perspective(120px) rotateX(-180.1deg) rotateY(0deg) 21 | 100% 22 | transform perspective(120px) rotateX(-180deg) rotateY(-179.9deg) 23 | -webkit-transform perspective(120px) rotateX(-180deg) rotateY(-179.9deg) 24 | 25 | -------------------------------------------------------------------------------- /stylus/block/side-menu.styl: -------------------------------------------------------------------------------- 1 | .side-menu 2 | background #2980B9 3 | width 280px 4 | height 100% 5 | flex 0 280px 6 | box-flex 0 7 | padding 0 8 | font-size 14px 9 | overflow-y auto 10 | scrollbar-face-color accent-color 11 | scrollbar-track-color rgba(0, 0, 0, .1) 12 | 13 | .side-menu__logo 14 | width 160px 15 | height auto 16 | margin 15px auto 0 60px 17 | 18 | .side-menu::-webkit-scrollbar 19 | width 6px 20 | height 6px 21 | 22 | .side-menu::-webkit-scrollbar-thumb 23 | background rgba(0, 0, 0, 0.4) 24 | border-radius 2px 25 | 26 | @media screen and (max-width: 768px) 27 | .side-menu 28 | position fixed 29 | transition all .4s ease 30 | z-index 1000 31 | padding 40px 0 0 0 32 | 33 | .side-menu__logo 34 | display none 35 | 36 | .side-menu__close 37 | left -800px 38 | top 0 39 | 40 | .side-menu__open 41 | top 0 42 | left 0px -------------------------------------------------------------------------------- /stylus/lib/animate.styl: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /*! 4 | Animate.css - http://daneden.me/animate 5 | Version - 3.4.0 6 | Licensed under the MIT license - http://opensource.org/licenses/MIT 7 | 8 | Copyright (c) 2015 Daniel Eden 9 | */ 10 | 11 | .animated { 12 | -webkit-animation-duration: 1s; 13 | animation-duration: 1s; 14 | -webkit-animation-fill-mode: both; 15 | animation-fill-mode: both; 16 | } 17 | 18 | .animated.infinite { 19 | -webkit-animation-iteration-count: infinite; 20 | animation-iteration-count: infinite; 21 | } 22 | 23 | .animated.hinge { 24 | -webkit-animation-duration: 2s; 25 | animation-duration: 2s; 26 | } 27 | 28 | .animated.bounceIn, 29 | .animated.bounceOut { 30 | -webkit-animation-duration: .75s; 31 | animation-duration: .75s; 32 | } 33 | 34 | .animated.flipOutX, 35 | .animated.flipOutY { 36 | -webkit-animation-duration: .75s; 37 | animation-duration: .75s; 38 | } 39 | 40 | @-webkit-keyframes bounce { 41 | from, 20%, 53%, 80%, to { 42 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 43 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 44 | -webkit-transform: translate3d(0,0,0); 45 | transform: translate3d(0,0,0); 46 | } 47 | 48 | 40%, 43% { 49 | -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 50 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 51 | -webkit-transform: translate3d(0, -30px, 0); 52 | transform: translate3d(0, -30px, 0); 53 | } 54 | 55 | 70% { 56 | -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 57 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 58 | -webkit-transform: translate3d(0, -15px, 0); 59 | transform: translate3d(0, -15px, 0); 60 | } 61 | 62 | 90% { 63 | -webkit-transform: translate3d(0,-4px,0); 64 | transform: translate3d(0,-4px,0); 65 | } 66 | } 67 | 68 | @keyframes bounce { 69 | from, 20%, 53%, 80%, to { 70 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 71 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 72 | -webkit-transform: translate3d(0,0,0); 73 | transform: translate3d(0,0,0); 74 | } 75 | 76 | 40%, 43% { 77 | -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 78 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 79 | -webkit-transform: translate3d(0, -30px, 0); 80 | transform: translate3d(0, -30px, 0); 81 | } 82 | 83 | 70% { 84 | -webkit-animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 85 | animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060); 86 | -webkit-transform: translate3d(0, -15px, 0); 87 | transform: translate3d(0, -15px, 0); 88 | } 89 | 90 | 90% { 91 | -webkit-transform: translate3d(0,-4px,0); 92 | transform: translate3d(0,-4px,0); 93 | } 94 | } 95 | 96 | .bounce { 97 | -webkit-animation-name: bounce; 98 | animation-name: bounce; 99 | -webkit-transform-origin: center bottom; 100 | transform-origin: center bottom; 101 | } 102 | 103 | @-webkit-keyframes flash { 104 | from, 50%, to { 105 | opacity: 1; 106 | } 107 | 108 | 25%, 75% { 109 | opacity: 0; 110 | } 111 | } 112 | 113 | @keyframes flash { 114 | from, 50%, to { 115 | opacity: 1; 116 | } 117 | 118 | 25%, 75% { 119 | opacity: 0; 120 | } 121 | } 122 | 123 | .flash { 124 | -webkit-animation-name: flash; 125 | animation-name: flash; 126 | } 127 | 128 | /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ 129 | 130 | @-webkit-keyframes pulse { 131 | from { 132 | -webkit-transform: scale3d(1, 1, 1); 133 | transform: scale3d(1, 1, 1); 134 | } 135 | 136 | 50% { 137 | -webkit-transform: scale3d(1.05, 1.05, 1.05); 138 | transform: scale3d(1.05, 1.05, 1.05); 139 | } 140 | 141 | to { 142 | -webkit-transform: scale3d(1, 1, 1); 143 | transform: scale3d(1, 1, 1); 144 | } 145 | } 146 | 147 | @keyframes pulse { 148 | from { 149 | -webkit-transform: scale3d(1, 1, 1); 150 | transform: scale3d(1, 1, 1); 151 | } 152 | 153 | 50% { 154 | -webkit-transform: scale3d(1.05, 1.05, 1.05); 155 | transform: scale3d(1.05, 1.05, 1.05); 156 | } 157 | 158 | to { 159 | -webkit-transform: scale3d(1, 1, 1); 160 | transform: scale3d(1, 1, 1); 161 | } 162 | } 163 | 164 | .pulse { 165 | -webkit-animation-name: pulse; 166 | animation-name: pulse; 167 | } 168 | 169 | @-webkit-keyframes rubberBand { 170 | from { 171 | -webkit-transform: scale3d(1, 1, 1); 172 | transform: scale3d(1, 1, 1); 173 | } 174 | 175 | 30% { 176 | -webkit-transform: scale3d(1.25, 0.75, 1); 177 | transform: scale3d(1.25, 0.75, 1); 178 | } 179 | 180 | 40% { 181 | -webkit-transform: scale3d(0.75, 1.25, 1); 182 | transform: scale3d(0.75, 1.25, 1); 183 | } 184 | 185 | 50% { 186 | -webkit-transform: scale3d(1.15, 0.85, 1); 187 | transform: scale3d(1.15, 0.85, 1); 188 | } 189 | 190 | 65% { 191 | -webkit-transform: scale3d(.95, 1.05, 1); 192 | transform: scale3d(.95, 1.05, 1); 193 | } 194 | 195 | 75% { 196 | -webkit-transform: scale3d(1.05, .95, 1); 197 | transform: scale3d(1.05, .95, 1); 198 | } 199 | 200 | to { 201 | -webkit-transform: scale3d(1, 1, 1); 202 | transform: scale3d(1, 1, 1); 203 | } 204 | } 205 | 206 | @keyframes rubberBand { 207 | from { 208 | -webkit-transform: scale3d(1, 1, 1); 209 | transform: scale3d(1, 1, 1); 210 | } 211 | 212 | 30% { 213 | -webkit-transform: scale3d(1.25, 0.75, 1); 214 | transform: scale3d(1.25, 0.75, 1); 215 | } 216 | 217 | 40% { 218 | -webkit-transform: scale3d(0.75, 1.25, 1); 219 | transform: scale3d(0.75, 1.25, 1); 220 | } 221 | 222 | 50% { 223 | -webkit-transform: scale3d(1.15, 0.85, 1); 224 | transform: scale3d(1.15, 0.85, 1); 225 | } 226 | 227 | 65% { 228 | -webkit-transform: scale3d(.95, 1.05, 1); 229 | transform: scale3d(.95, 1.05, 1); 230 | } 231 | 232 | 75% { 233 | -webkit-transform: scale3d(1.05, .95, 1); 234 | transform: scale3d(1.05, .95, 1); 235 | } 236 | 237 | to { 238 | -webkit-transform: scale3d(1, 1, 1); 239 | transform: scale3d(1, 1, 1); 240 | } 241 | } 242 | 243 | .rubberBand { 244 | -webkit-animation-name: rubberBand; 245 | animation-name: rubberBand; 246 | } 247 | 248 | @-webkit-keyframes shake { 249 | from, to { 250 | -webkit-transform: translate3d(0, 0, 0); 251 | transform: translate3d(0, 0, 0); 252 | } 253 | 254 | 10%, 30%, 50%, 70%, 90% { 255 | -webkit-transform: translate3d(-10px, 0, 0); 256 | transform: translate3d(-10px, 0, 0); 257 | } 258 | 259 | 20%, 40%, 60%, 80% { 260 | -webkit-transform: translate3d(10px, 0, 0); 261 | transform: translate3d(10px, 0, 0); 262 | } 263 | } 264 | 265 | @keyframes shake { 266 | from, to { 267 | -webkit-transform: translate3d(0, 0, 0); 268 | transform: translate3d(0, 0, 0); 269 | } 270 | 271 | 10%, 30%, 50%, 70%, 90% { 272 | -webkit-transform: translate3d(-10px, 0, 0); 273 | transform: translate3d(-10px, 0, 0); 274 | } 275 | 276 | 20%, 40%, 60%, 80% { 277 | -webkit-transform: translate3d(10px, 0, 0); 278 | transform: translate3d(10px, 0, 0); 279 | } 280 | } 281 | 282 | .shake { 283 | -webkit-animation-name: shake; 284 | animation-name: shake; 285 | } 286 | 287 | @-webkit-keyframes swing { 288 | 20% { 289 | -webkit-transform: rotate3d(0, 0, 1, 15deg); 290 | transform: rotate3d(0, 0, 1, 15deg); 291 | } 292 | 293 | 40% { 294 | -webkit-transform: rotate3d(0, 0, 1, -10deg); 295 | transform: rotate3d(0, 0, 1, -10deg); 296 | } 297 | 298 | 60% { 299 | -webkit-transform: rotate3d(0, 0, 1, 5deg); 300 | transform: rotate3d(0, 0, 1, 5deg); 301 | } 302 | 303 | 80% { 304 | -webkit-transform: rotate3d(0, 0, 1, -5deg); 305 | transform: rotate3d(0, 0, 1, -5deg); 306 | } 307 | 308 | to { 309 | -webkit-transform: rotate3d(0, 0, 1, 0deg); 310 | transform: rotate3d(0, 0, 1, 0deg); 311 | } 312 | } 313 | 314 | @keyframes swing { 315 | 20% { 316 | -webkit-transform: rotate3d(0, 0, 1, 15deg); 317 | transform: rotate3d(0, 0, 1, 15deg); 318 | } 319 | 320 | 40% { 321 | -webkit-transform: rotate3d(0, 0, 1, -10deg); 322 | transform: rotate3d(0, 0, 1, -10deg); 323 | } 324 | 325 | 60% { 326 | -webkit-transform: rotate3d(0, 0, 1, 5deg); 327 | transform: rotate3d(0, 0, 1, 5deg); 328 | } 329 | 330 | 80% { 331 | -webkit-transform: rotate3d(0, 0, 1, -5deg); 332 | transform: rotate3d(0, 0, 1, -5deg); 333 | } 334 | 335 | to { 336 | -webkit-transform: rotate3d(0, 0, 1, 0deg); 337 | transform: rotate3d(0, 0, 1, 0deg); 338 | } 339 | } 340 | 341 | .swing { 342 | -webkit-transform-origin: top center; 343 | transform-origin: top center; 344 | -webkit-animation-name: swing; 345 | animation-name: swing; 346 | } 347 | 348 | @-webkit-keyframes tada { 349 | from { 350 | -webkit-transform: scale3d(1, 1, 1); 351 | transform: scale3d(1, 1, 1); 352 | } 353 | 354 | 10%, 20% { 355 | -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); 356 | transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); 357 | } 358 | 359 | 30%, 50%, 70%, 90% { 360 | -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); 361 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); 362 | } 363 | 364 | 40%, 60%, 80% { 365 | -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); 366 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); 367 | } 368 | 369 | to { 370 | -webkit-transform: scale3d(1, 1, 1); 371 | transform: scale3d(1, 1, 1); 372 | } 373 | } 374 | 375 | @keyframes tada { 376 | from { 377 | -webkit-transform: scale3d(1, 1, 1); 378 | transform: scale3d(1, 1, 1); 379 | } 380 | 381 | 10%, 20% { 382 | -webkit-transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); 383 | transform: scale3d(.9, .9, .9) rotate3d(0, 0, 1, -3deg); 384 | } 385 | 386 | 30%, 50%, 70%, 90% { 387 | -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); 388 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, 3deg); 389 | } 390 | 391 | 40%, 60%, 80% { 392 | -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); 393 | transform: scale3d(1.1, 1.1, 1.1) rotate3d(0, 0, 1, -3deg); 394 | } 395 | 396 | to { 397 | -webkit-transform: scale3d(1, 1, 1); 398 | transform: scale3d(1, 1, 1); 399 | } 400 | } 401 | 402 | .tada { 403 | -webkit-animation-name: tada; 404 | animation-name: tada; 405 | } 406 | 407 | /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ 408 | 409 | @-webkit-keyframes wobble { 410 | from { 411 | -webkit-transform: none; 412 | transform: none; 413 | } 414 | 415 | 15% { 416 | -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); 417 | transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); 418 | } 419 | 420 | 30% { 421 | -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); 422 | transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); 423 | } 424 | 425 | 45% { 426 | -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); 427 | transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); 428 | } 429 | 430 | 60% { 431 | -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); 432 | transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); 433 | } 434 | 435 | 75% { 436 | -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); 437 | transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); 438 | } 439 | 440 | to { 441 | -webkit-transform: none; 442 | transform: none; 443 | } 444 | } 445 | 446 | @keyframes wobble { 447 | from { 448 | -webkit-transform: none; 449 | transform: none; 450 | } 451 | 452 | 15% { 453 | -webkit-transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); 454 | transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg); 455 | } 456 | 457 | 30% { 458 | -webkit-transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); 459 | transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg); 460 | } 461 | 462 | 45% { 463 | -webkit-transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); 464 | transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg); 465 | } 466 | 467 | 60% { 468 | -webkit-transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); 469 | transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg); 470 | } 471 | 472 | 75% { 473 | -webkit-transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); 474 | transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg); 475 | } 476 | 477 | to { 478 | -webkit-transform: none; 479 | transform: none; 480 | } 481 | } 482 | 483 | .wobble { 484 | -webkit-animation-name: wobble; 485 | animation-name: wobble; 486 | } 487 | 488 | @-webkit-keyframes jello { 489 | from, 11.1%, to { 490 | -webkit-transform: none; 491 | transform: none; 492 | } 493 | 494 | 22.2% { 495 | -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); 496 | transform: skewX(-12.5deg) skewY(-12.5deg); 497 | } 498 | 499 | 33.3% { 500 | -webkit-transform: skewX(6.25deg) skewY(6.25deg); 501 | transform: skewX(6.25deg) skewY(6.25deg); 502 | } 503 | 504 | 44.4% { 505 | -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); 506 | transform: skewX(-3.125deg) skewY(-3.125deg); 507 | } 508 | 509 | 55.5% { 510 | -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); 511 | transform: skewX(1.5625deg) skewY(1.5625deg); 512 | } 513 | 514 | 66.6% { 515 | -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); 516 | transform: skewX(-0.78125deg) skewY(-0.78125deg); 517 | } 518 | 519 | 77.7% { 520 | -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); 521 | transform: skewX(0.390625deg) skewY(0.390625deg); 522 | } 523 | 524 | 88.8% { 525 | -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); 526 | transform: skewX(-0.1953125deg) skewY(-0.1953125deg); 527 | } 528 | } 529 | 530 | @keyframes jello { 531 | from, 11.1%, to { 532 | -webkit-transform: none; 533 | transform: none; 534 | } 535 | 536 | 22.2% { 537 | -webkit-transform: skewX(-12.5deg) skewY(-12.5deg); 538 | transform: skewX(-12.5deg) skewY(-12.5deg); 539 | } 540 | 541 | 33.3% { 542 | -webkit-transform: skewX(6.25deg) skewY(6.25deg); 543 | transform: skewX(6.25deg) skewY(6.25deg); 544 | } 545 | 546 | 44.4% { 547 | -webkit-transform: skewX(-3.125deg) skewY(-3.125deg); 548 | transform: skewX(-3.125deg) skewY(-3.125deg); 549 | } 550 | 551 | 55.5% { 552 | -webkit-transform: skewX(1.5625deg) skewY(1.5625deg); 553 | transform: skewX(1.5625deg) skewY(1.5625deg); 554 | } 555 | 556 | 66.6% { 557 | -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg); 558 | transform: skewX(-0.78125deg) skewY(-0.78125deg); 559 | } 560 | 561 | 77.7% { 562 | -webkit-transform: skewX(0.390625deg) skewY(0.390625deg); 563 | transform: skewX(0.390625deg) skewY(0.390625deg); 564 | } 565 | 566 | 88.8% { 567 | -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg); 568 | transform: skewX(-0.1953125deg) skewY(-0.1953125deg); 569 | } 570 | } 571 | 572 | .jello { 573 | -webkit-animation-name: jello; 574 | animation-name: jello; 575 | -webkit-transform-origin: center; 576 | transform-origin: center; 577 | } 578 | 579 | @-webkit-keyframes bounceIn { 580 | from, 20%, 40%, 60%, 80%, to { 581 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 582 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 583 | } 584 | 585 | 0% { 586 | opacity: 0; 587 | -webkit-transform: scale3d(.3, .3, .3); 588 | transform: scale3d(.3, .3, .3); 589 | } 590 | 591 | 20% { 592 | -webkit-transform: scale3d(1.1, 1.1, 1.1); 593 | transform: scale3d(1.1, 1.1, 1.1); 594 | } 595 | 596 | 40% { 597 | -webkit-transform: scale3d(.9, .9, .9); 598 | transform: scale3d(.9, .9, .9); 599 | } 600 | 601 | 60% { 602 | opacity: 1; 603 | -webkit-transform: scale3d(1.03, 1.03, 1.03); 604 | transform: scale3d(1.03, 1.03, 1.03); 605 | } 606 | 607 | 80% { 608 | -webkit-transform: scale3d(.97, .97, .97); 609 | transform: scale3d(.97, .97, .97); 610 | } 611 | 612 | to { 613 | opacity: 1; 614 | -webkit-transform: scale3d(1, 1, 1); 615 | transform: scale3d(1, 1, 1); 616 | } 617 | } 618 | 619 | @keyframes bounceIn { 620 | from, 20%, 40%, 60%, 80%, to { 621 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 622 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 623 | } 624 | 625 | 0% { 626 | opacity: 0; 627 | -webkit-transform: scale3d(.3, .3, .3); 628 | transform: scale3d(.3, .3, .3); 629 | } 630 | 631 | 20% { 632 | -webkit-transform: scale3d(1.1, 1.1, 1.1); 633 | transform: scale3d(1.1, 1.1, 1.1); 634 | } 635 | 636 | 40% { 637 | -webkit-transform: scale3d(.9, .9, .9); 638 | transform: scale3d(.9, .9, .9); 639 | } 640 | 641 | 60% { 642 | opacity: 1; 643 | -webkit-transform: scale3d(1.03, 1.03, 1.03); 644 | transform: scale3d(1.03, 1.03, 1.03); 645 | } 646 | 647 | 80% { 648 | -webkit-transform: scale3d(.97, .97, .97); 649 | transform: scale3d(.97, .97, .97); 650 | } 651 | 652 | to { 653 | opacity: 1; 654 | -webkit-transform: scale3d(1, 1, 1); 655 | transform: scale3d(1, 1, 1); 656 | } 657 | } 658 | 659 | .bounceIn { 660 | -webkit-animation-name: bounceIn; 661 | animation-name: bounceIn; 662 | } 663 | 664 | @-webkit-keyframes bounceInDown { 665 | from, 60%, 75%, 90%, to { 666 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 667 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 668 | } 669 | 670 | 0% { 671 | opacity: 0; 672 | -webkit-transform: translate3d(0, -3000px, 0); 673 | transform: translate3d(0, -3000px, 0); 674 | } 675 | 676 | 60% { 677 | opacity: 1; 678 | -webkit-transform: translate3d(0, 25px, 0); 679 | transform: translate3d(0, 25px, 0); 680 | } 681 | 682 | 75% { 683 | -webkit-transform: translate3d(0, -10px, 0); 684 | transform: translate3d(0, -10px, 0); 685 | } 686 | 687 | 90% { 688 | -webkit-transform: translate3d(0, 5px, 0); 689 | transform: translate3d(0, 5px, 0); 690 | } 691 | 692 | to { 693 | -webkit-transform: none; 694 | transform: none; 695 | } 696 | } 697 | 698 | @keyframes bounceInDown { 699 | from, 60%, 75%, 90%, to { 700 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 701 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 702 | } 703 | 704 | 0% { 705 | opacity: 0; 706 | -webkit-transform: translate3d(0, -3000px, 0); 707 | transform: translate3d(0, -3000px, 0); 708 | } 709 | 710 | 60% { 711 | opacity: 1; 712 | -webkit-transform: translate3d(0, 25px, 0); 713 | transform: translate3d(0, 25px, 0); 714 | } 715 | 716 | 75% { 717 | -webkit-transform: translate3d(0, -10px, 0); 718 | transform: translate3d(0, -10px, 0); 719 | } 720 | 721 | 90% { 722 | -webkit-transform: translate3d(0, 5px, 0); 723 | transform: translate3d(0, 5px, 0); 724 | } 725 | 726 | to { 727 | -webkit-transform: none; 728 | transform: none; 729 | } 730 | } 731 | 732 | .bounceInDown { 733 | -webkit-animation-name: bounceInDown; 734 | animation-name: bounceInDown; 735 | } 736 | 737 | @-webkit-keyframes bounceInLeft { 738 | from, 60%, 75%, 90%, to { 739 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 740 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 741 | } 742 | 743 | 0% { 744 | opacity: 0; 745 | -webkit-transform: translate3d(-3000px, 0, 0); 746 | transform: translate3d(-3000px, 0, 0); 747 | } 748 | 749 | 60% { 750 | opacity: 1; 751 | -webkit-transform: translate3d(25px, 0, 0); 752 | transform: translate3d(25px, 0, 0); 753 | } 754 | 755 | 75% { 756 | -webkit-transform: translate3d(-10px, 0, 0); 757 | transform: translate3d(-10px, 0, 0); 758 | } 759 | 760 | 90% { 761 | -webkit-transform: translate3d(5px, 0, 0); 762 | transform: translate3d(5px, 0, 0); 763 | } 764 | 765 | to { 766 | -webkit-transform: none; 767 | transform: none; 768 | } 769 | } 770 | 771 | @keyframes bounceInLeft { 772 | from, 60%, 75%, 90%, to { 773 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 774 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 775 | } 776 | 777 | 0% { 778 | opacity: 0; 779 | -webkit-transform: translate3d(-3000px, 0, 0); 780 | transform: translate3d(-3000px, 0, 0); 781 | } 782 | 783 | 60% { 784 | opacity: 1; 785 | -webkit-transform: translate3d(25px, 0, 0); 786 | transform: translate3d(25px, 0, 0); 787 | } 788 | 789 | 75% { 790 | -webkit-transform: translate3d(-10px, 0, 0); 791 | transform: translate3d(-10px, 0, 0); 792 | } 793 | 794 | 90% { 795 | -webkit-transform: translate3d(5px, 0, 0); 796 | transform: translate3d(5px, 0, 0); 797 | } 798 | 799 | to { 800 | -webkit-transform: none; 801 | transform: none; 802 | } 803 | } 804 | 805 | .bounceInLeft { 806 | -webkit-animation-name: bounceInLeft; 807 | animation-name: bounceInLeft; 808 | } 809 | 810 | @-webkit-keyframes bounceInRight { 811 | from, 60%, 75%, 90%, to { 812 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 813 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 814 | } 815 | 816 | from { 817 | opacity: 0; 818 | -webkit-transform: translate3d(3000px, 0, 0); 819 | transform: translate3d(3000px, 0, 0); 820 | } 821 | 822 | 60% { 823 | opacity: 1; 824 | -webkit-transform: translate3d(-25px, 0, 0); 825 | transform: translate3d(-25px, 0, 0); 826 | } 827 | 828 | 75% { 829 | -webkit-transform: translate3d(10px, 0, 0); 830 | transform: translate3d(10px, 0, 0); 831 | } 832 | 833 | 90% { 834 | -webkit-transform: translate3d(-5px, 0, 0); 835 | transform: translate3d(-5px, 0, 0); 836 | } 837 | 838 | to { 839 | -webkit-transform: none; 840 | transform: none; 841 | } 842 | } 843 | 844 | @keyframes bounceInRight { 845 | from, 60%, 75%, 90%, to { 846 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 847 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 848 | } 849 | 850 | from { 851 | opacity: 0; 852 | -webkit-transform: translate3d(3000px, 0, 0); 853 | transform: translate3d(3000px, 0, 0); 854 | } 855 | 856 | 60% { 857 | opacity: 1; 858 | -webkit-transform: translate3d(-25px, 0, 0); 859 | transform: translate3d(-25px, 0, 0); 860 | } 861 | 862 | 75% { 863 | -webkit-transform: translate3d(10px, 0, 0); 864 | transform: translate3d(10px, 0, 0); 865 | } 866 | 867 | 90% { 868 | -webkit-transform: translate3d(-5px, 0, 0); 869 | transform: translate3d(-5px, 0, 0); 870 | } 871 | 872 | to { 873 | -webkit-transform: none; 874 | transform: none; 875 | } 876 | } 877 | 878 | .bounceInRight { 879 | -webkit-animation-name: bounceInRight; 880 | animation-name: bounceInRight; 881 | } 882 | 883 | @-webkit-keyframes bounceInUp { 884 | from, 60%, 75%, 90%, to { 885 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 886 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 887 | } 888 | 889 | from { 890 | opacity: 0; 891 | -webkit-transform: translate3d(0, 3000px, 0); 892 | transform: translate3d(0, 3000px, 0); 893 | } 894 | 895 | 60% { 896 | opacity: 1; 897 | -webkit-transform: translate3d(0, -20px, 0); 898 | transform: translate3d(0, -20px, 0); 899 | } 900 | 901 | 75% { 902 | -webkit-transform: translate3d(0, 10px, 0); 903 | transform: translate3d(0, 10px, 0); 904 | } 905 | 906 | 90% { 907 | -webkit-transform: translate3d(0, -5px, 0); 908 | transform: translate3d(0, -5px, 0); 909 | } 910 | 911 | to { 912 | -webkit-transform: translate3d(0, 0, 0); 913 | transform: translate3d(0, 0, 0); 914 | } 915 | } 916 | 917 | @keyframes bounceInUp { 918 | from, 60%, 75%, 90%, to { 919 | -webkit-animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 920 | animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000); 921 | } 922 | 923 | from { 924 | opacity: 0; 925 | -webkit-transform: translate3d(0, 3000px, 0); 926 | transform: translate3d(0, 3000px, 0); 927 | } 928 | 929 | 60% { 930 | opacity: 1; 931 | -webkit-transform: translate3d(0, -20px, 0); 932 | transform: translate3d(0, -20px, 0); 933 | } 934 | 935 | 75% { 936 | -webkit-transform: translate3d(0, 10px, 0); 937 | transform: translate3d(0, 10px, 0); 938 | } 939 | 940 | 90% { 941 | -webkit-transform: translate3d(0, -5px, 0); 942 | transform: translate3d(0, -5px, 0); 943 | } 944 | 945 | to { 946 | -webkit-transform: translate3d(0, 0, 0); 947 | transform: translate3d(0, 0, 0); 948 | } 949 | } 950 | 951 | .bounceInUp { 952 | -webkit-animation-name: bounceInUp; 953 | animation-name: bounceInUp; 954 | } 955 | 956 | @-webkit-keyframes bounceOut { 957 | 20% { 958 | -webkit-transform: scale3d(.9, .9, .9); 959 | transform: scale3d(.9, .9, .9); 960 | } 961 | 962 | 50%, 55% { 963 | opacity: 1; 964 | -webkit-transform: scale3d(1.1, 1.1, 1.1); 965 | transform: scale3d(1.1, 1.1, 1.1); 966 | } 967 | 968 | to { 969 | opacity: 0; 970 | -webkit-transform: scale3d(.3, .3, .3); 971 | transform: scale3d(.3, .3, .3); 972 | } 973 | } 974 | 975 | @keyframes bounceOut { 976 | 20% { 977 | -webkit-transform: scale3d(.9, .9, .9); 978 | transform: scale3d(.9, .9, .9); 979 | } 980 | 981 | 50%, 55% { 982 | opacity: 1; 983 | -webkit-transform: scale3d(1.1, 1.1, 1.1); 984 | transform: scale3d(1.1, 1.1, 1.1); 985 | } 986 | 987 | to { 988 | opacity: 0; 989 | -webkit-transform: scale3d(.3, .3, .3); 990 | transform: scale3d(.3, .3, .3); 991 | } 992 | } 993 | 994 | .bounceOut { 995 | -webkit-animation-name: bounceOut; 996 | animation-name: bounceOut; 997 | } 998 | 999 | @-webkit-keyframes bounceOutDown { 1000 | 20% { 1001 | -webkit-transform: translate3d(0, 10px, 0); 1002 | transform: translate3d(0, 10px, 0); 1003 | } 1004 | 1005 | 40%, 45% { 1006 | opacity: 1; 1007 | -webkit-transform: translate3d(0, -20px, 0); 1008 | transform: translate3d(0, -20px, 0); 1009 | } 1010 | 1011 | to { 1012 | opacity: 0; 1013 | -webkit-transform: translate3d(0, 2000px, 0); 1014 | transform: translate3d(0, 2000px, 0); 1015 | } 1016 | } 1017 | 1018 | @keyframes bounceOutDown { 1019 | 20% { 1020 | -webkit-transform: translate3d(0, 10px, 0); 1021 | transform: translate3d(0, 10px, 0); 1022 | } 1023 | 1024 | 40%, 45% { 1025 | opacity: 1; 1026 | -webkit-transform: translate3d(0, -20px, 0); 1027 | transform: translate3d(0, -20px, 0); 1028 | } 1029 | 1030 | to { 1031 | opacity: 0; 1032 | -webkit-transform: translate3d(0, 2000px, 0); 1033 | transform: translate3d(0, 2000px, 0); 1034 | } 1035 | } 1036 | 1037 | .bounceOutDown { 1038 | -webkit-animation-name: bounceOutDown; 1039 | animation-name: bounceOutDown; 1040 | } 1041 | 1042 | @-webkit-keyframes bounceOutLeft { 1043 | 20% { 1044 | opacity: 1; 1045 | -webkit-transform: translate3d(20px, 0, 0); 1046 | transform: translate3d(20px, 0, 0); 1047 | } 1048 | 1049 | to { 1050 | opacity: 0; 1051 | -webkit-transform: translate3d(-2000px, 0, 0); 1052 | transform: translate3d(-2000px, 0, 0); 1053 | } 1054 | } 1055 | 1056 | @keyframes bounceOutLeft { 1057 | 20% { 1058 | opacity: 1; 1059 | -webkit-transform: translate3d(20px, 0, 0); 1060 | transform: translate3d(20px, 0, 0); 1061 | } 1062 | 1063 | to { 1064 | opacity: 0; 1065 | -webkit-transform: translate3d(-2000px, 0, 0); 1066 | transform: translate3d(-2000px, 0, 0); 1067 | } 1068 | } 1069 | 1070 | .bounceOutLeft { 1071 | -webkit-animation-name: bounceOutLeft; 1072 | animation-name: bounceOutLeft; 1073 | } 1074 | 1075 | @-webkit-keyframes bounceOutRight { 1076 | 20% { 1077 | opacity: 1; 1078 | -webkit-transform: translate3d(-20px, 0, 0); 1079 | transform: translate3d(-20px, 0, 0); 1080 | } 1081 | 1082 | to { 1083 | opacity: 0; 1084 | -webkit-transform: translate3d(2000px, 0, 0); 1085 | transform: translate3d(2000px, 0, 0); 1086 | } 1087 | } 1088 | 1089 | @keyframes bounceOutRight { 1090 | 20% { 1091 | opacity: 1; 1092 | -webkit-transform: translate3d(-20px, 0, 0); 1093 | transform: translate3d(-20px, 0, 0); 1094 | } 1095 | 1096 | to { 1097 | opacity: 0; 1098 | -webkit-transform: translate3d(2000px, 0, 0); 1099 | transform: translate3d(2000px, 0, 0); 1100 | } 1101 | } 1102 | 1103 | .bounceOutRight { 1104 | -webkit-animation-name: bounceOutRight; 1105 | animation-name: bounceOutRight; 1106 | } 1107 | 1108 | @-webkit-keyframes bounceOutUp { 1109 | 20% { 1110 | -webkit-transform: translate3d(0, -10px, 0); 1111 | transform: translate3d(0, -10px, 0); 1112 | } 1113 | 1114 | 40%, 45% { 1115 | opacity: 1; 1116 | -webkit-transform: translate3d(0, 20px, 0); 1117 | transform: translate3d(0, 20px, 0); 1118 | } 1119 | 1120 | to { 1121 | opacity: 0; 1122 | -webkit-transform: translate3d(0, -2000px, 0); 1123 | transform: translate3d(0, -2000px, 0); 1124 | } 1125 | } 1126 | 1127 | @keyframes bounceOutUp { 1128 | 20% { 1129 | -webkit-transform: translate3d(0, -10px, 0); 1130 | transform: translate3d(0, -10px, 0); 1131 | } 1132 | 1133 | 40%, 45% { 1134 | opacity: 1; 1135 | -webkit-transform: translate3d(0, 20px, 0); 1136 | transform: translate3d(0, 20px, 0); 1137 | } 1138 | 1139 | to { 1140 | opacity: 0; 1141 | -webkit-transform: translate3d(0, -2000px, 0); 1142 | transform: translate3d(0, -2000px, 0); 1143 | } 1144 | } 1145 | 1146 | .bounceOutUp { 1147 | -webkit-animation-name: bounceOutUp; 1148 | animation-name: bounceOutUp; 1149 | } 1150 | 1151 | @-webkit-keyframes fadeIn { 1152 | from { 1153 | opacity: 0; 1154 | } 1155 | 1156 | to { 1157 | opacity: 1; 1158 | } 1159 | } 1160 | 1161 | @keyframes fadeIn { 1162 | from { 1163 | opacity: 0; 1164 | } 1165 | 1166 | to { 1167 | opacity: 1; 1168 | } 1169 | } 1170 | 1171 | .fadeIn { 1172 | -webkit-animation-name: fadeIn; 1173 | animation-name: fadeIn; 1174 | } 1175 | 1176 | @-webkit-keyframes fadeInDown { 1177 | from { 1178 | opacity: 0; 1179 | -webkit-transform: translate3d(0, -100%, 0); 1180 | transform: translate3d(0, -100%, 0); 1181 | } 1182 | 1183 | to { 1184 | opacity: 1; 1185 | -webkit-transform: none; 1186 | transform: none; 1187 | } 1188 | } 1189 | 1190 | @keyframes fadeInDown { 1191 | from { 1192 | opacity: 0; 1193 | -webkit-transform: translate3d(0, -100%, 0); 1194 | transform: translate3d(0, -100%, 0); 1195 | } 1196 | 1197 | to { 1198 | opacity: 1; 1199 | -webkit-transform: none; 1200 | transform: none; 1201 | } 1202 | } 1203 | 1204 | .fadeInDown { 1205 | -webkit-animation-name: fadeInDown; 1206 | animation-name: fadeInDown; 1207 | } 1208 | 1209 | @-webkit-keyframes fadeInDownBig { 1210 | from { 1211 | opacity: 0; 1212 | -webkit-transform: translate3d(0, -2000px, 0); 1213 | transform: translate3d(0, -2000px, 0); 1214 | } 1215 | 1216 | to { 1217 | opacity: 1; 1218 | -webkit-transform: none; 1219 | transform: none; 1220 | } 1221 | } 1222 | 1223 | @keyframes fadeInDownBig { 1224 | from { 1225 | opacity: 0; 1226 | -webkit-transform: translate3d(0, -2000px, 0); 1227 | transform: translate3d(0, -2000px, 0); 1228 | } 1229 | 1230 | to { 1231 | opacity: 1; 1232 | -webkit-transform: none; 1233 | transform: none; 1234 | } 1235 | } 1236 | 1237 | .fadeInDownBig { 1238 | -webkit-animation-name: fadeInDownBig; 1239 | animation-name: fadeInDownBig; 1240 | } 1241 | 1242 | @-webkit-keyframes fadeInLeft { 1243 | from { 1244 | opacity: 0; 1245 | -webkit-transform: translate3d(-100%, 0, 0); 1246 | transform: translate3d(-100%, 0, 0); 1247 | } 1248 | 1249 | to { 1250 | opacity: 1; 1251 | -webkit-transform: none; 1252 | transform: none; 1253 | } 1254 | } 1255 | 1256 | @keyframes fadeInLeft { 1257 | from { 1258 | opacity: 0; 1259 | -webkit-transform: translate3d(-100%, 0, 0); 1260 | transform: translate3d(-100%, 0, 0); 1261 | } 1262 | 1263 | to { 1264 | opacity: 1; 1265 | -webkit-transform: none; 1266 | transform: none; 1267 | } 1268 | } 1269 | 1270 | .fadeInLeft { 1271 | -webkit-animation-name: fadeInLeft; 1272 | animation-name: fadeInLeft; 1273 | } 1274 | 1275 | @-webkit-keyframes fadeInLeftBig { 1276 | from { 1277 | opacity: 0; 1278 | -webkit-transform: translate3d(-2000px, 0, 0); 1279 | transform: translate3d(-2000px, 0, 0); 1280 | } 1281 | 1282 | to { 1283 | opacity: 1; 1284 | -webkit-transform: none; 1285 | transform: none; 1286 | } 1287 | } 1288 | 1289 | @keyframes fadeInLeftBig { 1290 | from { 1291 | opacity: 0; 1292 | -webkit-transform: translate3d(-2000px, 0, 0); 1293 | transform: translate3d(-2000px, 0, 0); 1294 | } 1295 | 1296 | to { 1297 | opacity: 1; 1298 | -webkit-transform: none; 1299 | transform: none; 1300 | } 1301 | } 1302 | 1303 | .fadeInLeftBig { 1304 | -webkit-animation-name: fadeInLeftBig; 1305 | animation-name: fadeInLeftBig; 1306 | } 1307 | 1308 | @-webkit-keyframes fadeInRight { 1309 | from { 1310 | opacity: 0; 1311 | -webkit-transform: translate3d(100%, 0, 0); 1312 | transform: translate3d(100%, 0, 0); 1313 | } 1314 | 1315 | to { 1316 | opacity: 1; 1317 | -webkit-transform: none; 1318 | transform: none; 1319 | } 1320 | } 1321 | 1322 | @keyframes fadeInRight { 1323 | from { 1324 | opacity: 0; 1325 | -webkit-transform: translate3d(100%, 0, 0); 1326 | transform: translate3d(100%, 0, 0); 1327 | } 1328 | 1329 | to { 1330 | opacity: 1; 1331 | -webkit-transform: none; 1332 | transform: none; 1333 | } 1334 | } 1335 | 1336 | .fadeInRight { 1337 | -webkit-animation-name: fadeInRight; 1338 | animation-name: fadeInRight; 1339 | } 1340 | 1341 | @-webkit-keyframes fadeInRightBig { 1342 | from { 1343 | opacity: 0; 1344 | -webkit-transform: translate3d(2000px, 0, 0); 1345 | transform: translate3d(2000px, 0, 0); 1346 | } 1347 | 1348 | to { 1349 | opacity: 1; 1350 | -webkit-transform: none; 1351 | transform: none; 1352 | } 1353 | } 1354 | 1355 | @keyframes fadeInRightBig { 1356 | from { 1357 | opacity: 0; 1358 | -webkit-transform: translate3d(2000px, 0, 0); 1359 | transform: translate3d(2000px, 0, 0); 1360 | } 1361 | 1362 | to { 1363 | opacity: 1; 1364 | -webkit-transform: none; 1365 | transform: none; 1366 | } 1367 | } 1368 | 1369 | .fadeInRightBig { 1370 | -webkit-animation-name: fadeInRightBig; 1371 | animation-name: fadeInRightBig; 1372 | } 1373 | 1374 | @-webkit-keyframes fadeInUp { 1375 | from { 1376 | opacity: 0; 1377 | -webkit-transform: translate3d(0, 100%, 0); 1378 | transform: translate3d(0, 100%, 0); 1379 | } 1380 | 1381 | to { 1382 | opacity: 1; 1383 | -webkit-transform: none; 1384 | transform: none; 1385 | } 1386 | } 1387 | 1388 | @keyframes fadeInUp { 1389 | from { 1390 | opacity: 0; 1391 | -webkit-transform: translate3d(0, 100%, 0); 1392 | transform: translate3d(0, 100%, 0); 1393 | } 1394 | 1395 | to { 1396 | opacity: 1; 1397 | -webkit-transform: none; 1398 | transform: none; 1399 | } 1400 | } 1401 | 1402 | .fadeInUp { 1403 | -webkit-animation-name: fadeInUp; 1404 | animation-name: fadeInUp; 1405 | } 1406 | 1407 | @-webkit-keyframes fadeInUpBig { 1408 | from { 1409 | opacity: 0; 1410 | -webkit-transform: translate3d(0, 2000px, 0); 1411 | transform: translate3d(0, 2000px, 0); 1412 | } 1413 | 1414 | to { 1415 | opacity: 1; 1416 | -webkit-transform: none; 1417 | transform: none; 1418 | } 1419 | } 1420 | 1421 | @keyframes fadeInUpBig { 1422 | from { 1423 | opacity: 0; 1424 | -webkit-transform: translate3d(0, 2000px, 0); 1425 | transform: translate3d(0, 2000px, 0); 1426 | } 1427 | 1428 | to { 1429 | opacity: 1; 1430 | -webkit-transform: none; 1431 | transform: none; 1432 | } 1433 | } 1434 | 1435 | .fadeInUpBig { 1436 | -webkit-animation-name: fadeInUpBig; 1437 | animation-name: fadeInUpBig; 1438 | } 1439 | 1440 | @-webkit-keyframes fadeOut { 1441 | from { 1442 | opacity: 1; 1443 | } 1444 | 1445 | to { 1446 | opacity: 0; 1447 | } 1448 | } 1449 | 1450 | @keyframes fadeOut { 1451 | from { 1452 | opacity: 1; 1453 | } 1454 | 1455 | to { 1456 | opacity: 0; 1457 | } 1458 | } 1459 | 1460 | .fadeOut { 1461 | -webkit-animation-name: fadeOut; 1462 | animation-name: fadeOut; 1463 | } 1464 | 1465 | @-webkit-keyframes fadeOutDown { 1466 | from { 1467 | opacity: 1; 1468 | } 1469 | 1470 | to { 1471 | opacity: 0; 1472 | -webkit-transform: translate3d(0, 100%, 0); 1473 | transform: translate3d(0, 100%, 0); 1474 | } 1475 | } 1476 | 1477 | @keyframes fadeOutDown { 1478 | from { 1479 | opacity: 1; 1480 | } 1481 | 1482 | to { 1483 | opacity: 0; 1484 | -webkit-transform: translate3d(0, 100%, 0); 1485 | transform: translate3d(0, 100%, 0); 1486 | } 1487 | } 1488 | 1489 | .fadeOutDown { 1490 | -webkit-animation-name: fadeOutDown; 1491 | animation-name: fadeOutDown; 1492 | } 1493 | 1494 | @-webkit-keyframes fadeOutDownBig { 1495 | from { 1496 | opacity: 1; 1497 | } 1498 | 1499 | to { 1500 | opacity: 0; 1501 | -webkit-transform: translate3d(0, 2000px, 0); 1502 | transform: translate3d(0, 2000px, 0); 1503 | } 1504 | } 1505 | 1506 | @keyframes fadeOutDownBig { 1507 | from { 1508 | opacity: 1; 1509 | } 1510 | 1511 | to { 1512 | opacity: 0; 1513 | -webkit-transform: translate3d(0, 2000px, 0); 1514 | transform: translate3d(0, 2000px, 0); 1515 | } 1516 | } 1517 | 1518 | .fadeOutDownBig { 1519 | -webkit-animation-name: fadeOutDownBig; 1520 | animation-name: fadeOutDownBig; 1521 | } 1522 | 1523 | @-webkit-keyframes fadeOutLeft { 1524 | from { 1525 | opacity: 1; 1526 | } 1527 | 1528 | to { 1529 | opacity: 0; 1530 | -webkit-transform: translate3d(-100%, 0, 0); 1531 | transform: translate3d(-100%, 0, 0); 1532 | } 1533 | } 1534 | 1535 | @keyframes fadeOutLeft { 1536 | from { 1537 | opacity: 1; 1538 | } 1539 | 1540 | to { 1541 | opacity: 0; 1542 | -webkit-transform: translate3d(-100%, 0, 0); 1543 | transform: translate3d(-100%, 0, 0); 1544 | } 1545 | } 1546 | 1547 | .fadeOutLeft { 1548 | -webkit-animation-name: fadeOutLeft; 1549 | animation-name: fadeOutLeft; 1550 | } 1551 | 1552 | @-webkit-keyframes fadeOutLeftBig { 1553 | from { 1554 | opacity: 1; 1555 | } 1556 | 1557 | to { 1558 | opacity: 0; 1559 | -webkit-transform: translate3d(-2000px, 0, 0); 1560 | transform: translate3d(-2000px, 0, 0); 1561 | } 1562 | } 1563 | 1564 | @keyframes fadeOutLeftBig { 1565 | from { 1566 | opacity: 1; 1567 | } 1568 | 1569 | to { 1570 | opacity: 0; 1571 | -webkit-transform: translate3d(-2000px, 0, 0); 1572 | transform: translate3d(-2000px, 0, 0); 1573 | } 1574 | } 1575 | 1576 | .fadeOutLeftBig { 1577 | -webkit-animation-name: fadeOutLeftBig; 1578 | animation-name: fadeOutLeftBig; 1579 | } 1580 | 1581 | @-webkit-keyframes fadeOutRight { 1582 | from { 1583 | opacity: 1; 1584 | } 1585 | 1586 | to { 1587 | opacity: 0; 1588 | -webkit-transform: translate3d(100%, 0, 0); 1589 | transform: translate3d(100%, 0, 0); 1590 | } 1591 | } 1592 | 1593 | @keyframes fadeOutRight { 1594 | from { 1595 | opacity: 1; 1596 | } 1597 | 1598 | to { 1599 | opacity: 0; 1600 | -webkit-transform: translate3d(100%, 0, 0); 1601 | transform: translate3d(100%, 0, 0); 1602 | } 1603 | } 1604 | 1605 | .fadeOutRight { 1606 | -webkit-animation-name: fadeOutRight; 1607 | animation-name: fadeOutRight; 1608 | } 1609 | 1610 | @-webkit-keyframes fadeOutRightBig { 1611 | from { 1612 | opacity: 1; 1613 | } 1614 | 1615 | to { 1616 | opacity: 0; 1617 | -webkit-transform: translate3d(2000px, 0, 0); 1618 | transform: translate3d(2000px, 0, 0); 1619 | } 1620 | } 1621 | 1622 | @keyframes fadeOutRightBig { 1623 | from { 1624 | opacity: 1; 1625 | } 1626 | 1627 | to { 1628 | opacity: 0; 1629 | -webkit-transform: translate3d(2000px, 0, 0); 1630 | transform: translate3d(2000px, 0, 0); 1631 | } 1632 | } 1633 | 1634 | .fadeOutRightBig { 1635 | -webkit-animation-name: fadeOutRightBig; 1636 | animation-name: fadeOutRightBig; 1637 | } 1638 | 1639 | @-webkit-keyframes fadeOutUp { 1640 | from { 1641 | opacity: 1; 1642 | } 1643 | 1644 | to { 1645 | opacity: 0; 1646 | -webkit-transform: translate3d(0, -100%, 0); 1647 | transform: translate3d(0, -100%, 0); 1648 | } 1649 | } 1650 | 1651 | @keyframes fadeOutUp { 1652 | from { 1653 | opacity: 1; 1654 | } 1655 | 1656 | to { 1657 | opacity: 0; 1658 | -webkit-transform: translate3d(0, -100%, 0); 1659 | transform: translate3d(0, -100%, 0); 1660 | } 1661 | } 1662 | 1663 | .fadeOutUp { 1664 | -webkit-animation-name: fadeOutUp; 1665 | animation-name: fadeOutUp; 1666 | } 1667 | 1668 | @-webkit-keyframes fadeOutUpBig { 1669 | from { 1670 | opacity: 1; 1671 | } 1672 | 1673 | to { 1674 | opacity: 0; 1675 | -webkit-transform: translate3d(0, -2000px, 0); 1676 | transform: translate3d(0, -2000px, 0); 1677 | } 1678 | } 1679 | 1680 | @keyframes fadeOutUpBig { 1681 | from { 1682 | opacity: 1; 1683 | } 1684 | 1685 | to { 1686 | opacity: 0; 1687 | -webkit-transform: translate3d(0, -2000px, 0); 1688 | transform: translate3d(0, -2000px, 0); 1689 | } 1690 | } 1691 | 1692 | .fadeOutUpBig { 1693 | -webkit-animation-name: fadeOutUpBig; 1694 | animation-name: fadeOutUpBig; 1695 | } 1696 | 1697 | @-webkit-keyframes flip { 1698 | from { 1699 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 1700 | transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 1701 | -webkit-animation-timing-function: ease-out; 1702 | animation-timing-function: ease-out; 1703 | } 1704 | 1705 | 40% { 1706 | -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 1707 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 1708 | -webkit-animation-timing-function: ease-out; 1709 | animation-timing-function: ease-out; 1710 | } 1711 | 1712 | 50% { 1713 | -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 1714 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 1715 | -webkit-animation-timing-function: ease-in; 1716 | animation-timing-function: ease-in; 1717 | } 1718 | 1719 | 80% { 1720 | -webkit-transform: perspective(400px) scale3d(.95, .95, .95); 1721 | transform: perspective(400px) scale3d(.95, .95, .95); 1722 | -webkit-animation-timing-function: ease-in; 1723 | animation-timing-function: ease-in; 1724 | } 1725 | 1726 | to { 1727 | -webkit-transform: perspective(400px); 1728 | transform: perspective(400px); 1729 | -webkit-animation-timing-function: ease-in; 1730 | animation-timing-function: ease-in; 1731 | } 1732 | } 1733 | 1734 | @keyframes flip { 1735 | from { 1736 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 1737 | transform: perspective(400px) rotate3d(0, 1, 0, -360deg); 1738 | -webkit-animation-timing-function: ease-out; 1739 | animation-timing-function: ease-out; 1740 | } 1741 | 1742 | 40% { 1743 | -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 1744 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -190deg); 1745 | -webkit-animation-timing-function: ease-out; 1746 | animation-timing-function: ease-out; 1747 | } 1748 | 1749 | 50% { 1750 | -webkit-transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 1751 | transform: perspective(400px) translate3d(0, 0, 150px) rotate3d(0, 1, 0, -170deg); 1752 | -webkit-animation-timing-function: ease-in; 1753 | animation-timing-function: ease-in; 1754 | } 1755 | 1756 | 80% { 1757 | -webkit-transform: perspective(400px) scale3d(.95, .95, .95); 1758 | transform: perspective(400px) scale3d(.95, .95, .95); 1759 | -webkit-animation-timing-function: ease-in; 1760 | animation-timing-function: ease-in; 1761 | } 1762 | 1763 | to { 1764 | -webkit-transform: perspective(400px); 1765 | transform: perspective(400px); 1766 | -webkit-animation-timing-function: ease-in; 1767 | animation-timing-function: ease-in; 1768 | } 1769 | } 1770 | 1771 | .animated.flip { 1772 | -webkit-backface-visibility: visible; 1773 | backface-visibility: visible; 1774 | -webkit-animation-name: flip; 1775 | animation-name: flip; 1776 | } 1777 | 1778 | @-webkit-keyframes flipInX { 1779 | from { 1780 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1781 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1782 | -webkit-animation-timing-function: ease-in; 1783 | animation-timing-function: ease-in; 1784 | opacity: 0; 1785 | } 1786 | 1787 | 40% { 1788 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1789 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1790 | -webkit-animation-timing-function: ease-in; 1791 | animation-timing-function: ease-in; 1792 | } 1793 | 1794 | 60% { 1795 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 1796 | transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 1797 | opacity: 1; 1798 | } 1799 | 1800 | 80% { 1801 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 1802 | transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 1803 | } 1804 | 1805 | to { 1806 | -webkit-transform: perspective(400px); 1807 | transform: perspective(400px); 1808 | } 1809 | } 1810 | 1811 | @keyframes flipInX { 1812 | from { 1813 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1814 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1815 | -webkit-animation-timing-function: ease-in; 1816 | animation-timing-function: ease-in; 1817 | opacity: 0; 1818 | } 1819 | 1820 | 40% { 1821 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1822 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1823 | -webkit-animation-timing-function: ease-in; 1824 | animation-timing-function: ease-in; 1825 | } 1826 | 1827 | 60% { 1828 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 1829 | transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 1830 | opacity: 1; 1831 | } 1832 | 1833 | 80% { 1834 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 1835 | transform: perspective(400px) rotate3d(1, 0, 0, -5deg); 1836 | } 1837 | 1838 | to { 1839 | -webkit-transform: perspective(400px); 1840 | transform: perspective(400px); 1841 | } 1842 | } 1843 | 1844 | .flipInX { 1845 | -webkit-backface-visibility: visible !important; 1846 | backface-visibility: visible !important; 1847 | -webkit-animation-name: flipInX; 1848 | animation-name: flipInX; 1849 | } 1850 | 1851 | @-webkit-keyframes flipInY { 1852 | from { 1853 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1854 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1855 | -webkit-animation-timing-function: ease-in; 1856 | animation-timing-function: ease-in; 1857 | opacity: 0; 1858 | } 1859 | 1860 | 40% { 1861 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); 1862 | transform: perspective(400px) rotate3d(0, 1, 0, -20deg); 1863 | -webkit-animation-timing-function: ease-in; 1864 | animation-timing-function: ease-in; 1865 | } 1866 | 1867 | 60% { 1868 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); 1869 | transform: perspective(400px) rotate3d(0, 1, 0, 10deg); 1870 | opacity: 1; 1871 | } 1872 | 1873 | 80% { 1874 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); 1875 | transform: perspective(400px) rotate3d(0, 1, 0, -5deg); 1876 | } 1877 | 1878 | to { 1879 | -webkit-transform: perspective(400px); 1880 | transform: perspective(400px); 1881 | } 1882 | } 1883 | 1884 | @keyframes flipInY { 1885 | from { 1886 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1887 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1888 | -webkit-animation-timing-function: ease-in; 1889 | animation-timing-function: ease-in; 1890 | opacity: 0; 1891 | } 1892 | 1893 | 40% { 1894 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -20deg); 1895 | transform: perspective(400px) rotate3d(0, 1, 0, -20deg); 1896 | -webkit-animation-timing-function: ease-in; 1897 | animation-timing-function: ease-in; 1898 | } 1899 | 1900 | 60% { 1901 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 10deg); 1902 | transform: perspective(400px) rotate3d(0, 1, 0, 10deg); 1903 | opacity: 1; 1904 | } 1905 | 1906 | 80% { 1907 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -5deg); 1908 | transform: perspective(400px) rotate3d(0, 1, 0, -5deg); 1909 | } 1910 | 1911 | to { 1912 | -webkit-transform: perspective(400px); 1913 | transform: perspective(400px); 1914 | } 1915 | } 1916 | 1917 | .flipInY { 1918 | -webkit-backface-visibility: visible !important; 1919 | backface-visibility: visible !important; 1920 | -webkit-animation-name: flipInY; 1921 | animation-name: flipInY; 1922 | } 1923 | 1924 | @-webkit-keyframes flipOutX { 1925 | from { 1926 | -webkit-transform: perspective(400px); 1927 | transform: perspective(400px); 1928 | } 1929 | 1930 | 30% { 1931 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1932 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1933 | opacity: 1; 1934 | } 1935 | 1936 | to { 1937 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1938 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1939 | opacity: 0; 1940 | } 1941 | } 1942 | 1943 | @keyframes flipOutX { 1944 | from { 1945 | -webkit-transform: perspective(400px); 1946 | transform: perspective(400px); 1947 | } 1948 | 1949 | 30% { 1950 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1951 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 1952 | opacity: 1; 1953 | } 1954 | 1955 | to { 1956 | -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1957 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 1958 | opacity: 0; 1959 | } 1960 | } 1961 | 1962 | .flipOutX { 1963 | -webkit-animation-name: flipOutX; 1964 | animation-name: flipOutX; 1965 | -webkit-backface-visibility: visible !important; 1966 | backface-visibility: visible !important; 1967 | } 1968 | 1969 | @-webkit-keyframes flipOutY { 1970 | from { 1971 | -webkit-transform: perspective(400px); 1972 | transform: perspective(400px); 1973 | } 1974 | 1975 | 30% { 1976 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); 1977 | transform: perspective(400px) rotate3d(0, 1, 0, -15deg); 1978 | opacity: 1; 1979 | } 1980 | 1981 | to { 1982 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1983 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 1984 | opacity: 0; 1985 | } 1986 | } 1987 | 1988 | @keyframes flipOutY { 1989 | from { 1990 | -webkit-transform: perspective(400px); 1991 | transform: perspective(400px); 1992 | } 1993 | 1994 | 30% { 1995 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, -15deg); 1996 | transform: perspective(400px) rotate3d(0, 1, 0, -15deg); 1997 | opacity: 1; 1998 | } 1999 | 2000 | to { 2001 | -webkit-transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 2002 | transform: perspective(400px) rotate3d(0, 1, 0, 90deg); 2003 | opacity: 0; 2004 | } 2005 | } 2006 | 2007 | .flipOutY { 2008 | -webkit-backface-visibility: visible !important; 2009 | backface-visibility: visible !important; 2010 | -webkit-animation-name: flipOutY; 2011 | animation-name: flipOutY; 2012 | } 2013 | 2014 | @-webkit-keyframes lightSpeedIn { 2015 | from { 2016 | -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); 2017 | transform: translate3d(100%, 0, 0) skewX(-30deg); 2018 | opacity: 0; 2019 | } 2020 | 2021 | 60% { 2022 | -webkit-transform: skewX(20deg); 2023 | transform: skewX(20deg); 2024 | opacity: 1; 2025 | } 2026 | 2027 | 80% { 2028 | -webkit-transform: skewX(-5deg); 2029 | transform: skewX(-5deg); 2030 | opacity: 1; 2031 | } 2032 | 2033 | to { 2034 | -webkit-transform: none; 2035 | transform: none; 2036 | opacity: 1; 2037 | } 2038 | } 2039 | 2040 | @keyframes lightSpeedIn { 2041 | from { 2042 | -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg); 2043 | transform: translate3d(100%, 0, 0) skewX(-30deg); 2044 | opacity: 0; 2045 | } 2046 | 2047 | 60% { 2048 | -webkit-transform: skewX(20deg); 2049 | transform: skewX(20deg); 2050 | opacity: 1; 2051 | } 2052 | 2053 | 80% { 2054 | -webkit-transform: skewX(-5deg); 2055 | transform: skewX(-5deg); 2056 | opacity: 1; 2057 | } 2058 | 2059 | to { 2060 | -webkit-transform: none; 2061 | transform: none; 2062 | opacity: 1; 2063 | } 2064 | } 2065 | 2066 | .lightSpeedIn { 2067 | -webkit-animation-name: lightSpeedIn; 2068 | animation-name: lightSpeedIn; 2069 | -webkit-animation-timing-function: ease-out; 2070 | animation-timing-function: ease-out; 2071 | } 2072 | 2073 | @-webkit-keyframes lightSpeedOut { 2074 | from { 2075 | opacity: 1; 2076 | } 2077 | 2078 | to { 2079 | -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); 2080 | transform: translate3d(100%, 0, 0) skewX(30deg); 2081 | opacity: 0; 2082 | } 2083 | } 2084 | 2085 | @keyframes lightSpeedOut { 2086 | from { 2087 | opacity: 1; 2088 | } 2089 | 2090 | to { 2091 | -webkit-transform: translate3d(100%, 0, 0) skewX(30deg); 2092 | transform: translate3d(100%, 0, 0) skewX(30deg); 2093 | opacity: 0; 2094 | } 2095 | } 2096 | 2097 | .lightSpeedOut { 2098 | -webkit-animation-name: lightSpeedOut; 2099 | animation-name: lightSpeedOut; 2100 | -webkit-animation-timing-function: ease-in; 2101 | animation-timing-function: ease-in; 2102 | } 2103 | 2104 | @-webkit-keyframes rotateIn { 2105 | from { 2106 | -webkit-transform-origin: center; 2107 | transform-origin: center; 2108 | -webkit-transform: rotate3d(0, 0, 1, -200deg); 2109 | transform: rotate3d(0, 0, 1, -200deg); 2110 | opacity: 0; 2111 | } 2112 | 2113 | to { 2114 | -webkit-transform-origin: center; 2115 | transform-origin: center; 2116 | -webkit-transform: none; 2117 | transform: none; 2118 | opacity: 1; 2119 | } 2120 | } 2121 | 2122 | @keyframes rotateIn { 2123 | from { 2124 | -webkit-transform-origin: center; 2125 | transform-origin: center; 2126 | -webkit-transform: rotate3d(0, 0, 1, -200deg); 2127 | transform: rotate3d(0, 0, 1, -200deg); 2128 | opacity: 0; 2129 | } 2130 | 2131 | to { 2132 | -webkit-transform-origin: center; 2133 | transform-origin: center; 2134 | -webkit-transform: none; 2135 | transform: none; 2136 | opacity: 1; 2137 | } 2138 | } 2139 | 2140 | .rotateIn { 2141 | -webkit-animation-name: rotateIn; 2142 | animation-name: rotateIn; 2143 | } 2144 | 2145 | @-webkit-keyframes rotateInDownLeft { 2146 | from { 2147 | -webkit-transform-origin: left bottom; 2148 | transform-origin: left bottom; 2149 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2150 | transform: rotate3d(0, 0, 1, -45deg); 2151 | opacity: 0; 2152 | } 2153 | 2154 | to { 2155 | -webkit-transform-origin: left bottom; 2156 | transform-origin: left bottom; 2157 | -webkit-transform: none; 2158 | transform: none; 2159 | opacity: 1; 2160 | } 2161 | } 2162 | 2163 | @keyframes rotateInDownLeft { 2164 | from { 2165 | -webkit-transform-origin: left bottom; 2166 | transform-origin: left bottom; 2167 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2168 | transform: rotate3d(0, 0, 1, -45deg); 2169 | opacity: 0; 2170 | } 2171 | 2172 | to { 2173 | -webkit-transform-origin: left bottom; 2174 | transform-origin: left bottom; 2175 | -webkit-transform: none; 2176 | transform: none; 2177 | opacity: 1; 2178 | } 2179 | } 2180 | 2181 | .rotateInDownLeft { 2182 | -webkit-animation-name: rotateInDownLeft; 2183 | animation-name: rotateInDownLeft; 2184 | } 2185 | 2186 | @-webkit-keyframes rotateInDownRight { 2187 | from { 2188 | -webkit-transform-origin: right bottom; 2189 | transform-origin: right bottom; 2190 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2191 | transform: rotate3d(0, 0, 1, 45deg); 2192 | opacity: 0; 2193 | } 2194 | 2195 | to { 2196 | -webkit-transform-origin: right bottom; 2197 | transform-origin: right bottom; 2198 | -webkit-transform: none; 2199 | transform: none; 2200 | opacity: 1; 2201 | } 2202 | } 2203 | 2204 | @keyframes rotateInDownRight { 2205 | from { 2206 | -webkit-transform-origin: right bottom; 2207 | transform-origin: right bottom; 2208 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2209 | transform: rotate3d(0, 0, 1, 45deg); 2210 | opacity: 0; 2211 | } 2212 | 2213 | to { 2214 | -webkit-transform-origin: right bottom; 2215 | transform-origin: right bottom; 2216 | -webkit-transform: none; 2217 | transform: none; 2218 | opacity: 1; 2219 | } 2220 | } 2221 | 2222 | .rotateInDownRight { 2223 | -webkit-animation-name: rotateInDownRight; 2224 | animation-name: rotateInDownRight; 2225 | } 2226 | 2227 | @-webkit-keyframes rotateInUpLeft { 2228 | from { 2229 | -webkit-transform-origin: left bottom; 2230 | transform-origin: left bottom; 2231 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2232 | transform: rotate3d(0, 0, 1, 45deg); 2233 | opacity: 0; 2234 | } 2235 | 2236 | to { 2237 | -webkit-transform-origin: left bottom; 2238 | transform-origin: left bottom; 2239 | -webkit-transform: none; 2240 | transform: none; 2241 | opacity: 1; 2242 | } 2243 | } 2244 | 2245 | @keyframes rotateInUpLeft { 2246 | from { 2247 | -webkit-transform-origin: left bottom; 2248 | transform-origin: left bottom; 2249 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2250 | transform: rotate3d(0, 0, 1, 45deg); 2251 | opacity: 0; 2252 | } 2253 | 2254 | to { 2255 | -webkit-transform-origin: left bottom; 2256 | transform-origin: left bottom; 2257 | -webkit-transform: none; 2258 | transform: none; 2259 | opacity: 1; 2260 | } 2261 | } 2262 | 2263 | .rotateInUpLeft { 2264 | -webkit-animation-name: rotateInUpLeft; 2265 | animation-name: rotateInUpLeft; 2266 | } 2267 | 2268 | @-webkit-keyframes rotateInUpRight { 2269 | from { 2270 | -webkit-transform-origin: right bottom; 2271 | transform-origin: right bottom; 2272 | -webkit-transform: rotate3d(0, 0, 1, -90deg); 2273 | transform: rotate3d(0, 0, 1, -90deg); 2274 | opacity: 0; 2275 | } 2276 | 2277 | to { 2278 | -webkit-transform-origin: right bottom; 2279 | transform-origin: right bottom; 2280 | -webkit-transform: none; 2281 | transform: none; 2282 | opacity: 1; 2283 | } 2284 | } 2285 | 2286 | @keyframes rotateInUpRight { 2287 | from { 2288 | -webkit-transform-origin: right bottom; 2289 | transform-origin: right bottom; 2290 | -webkit-transform: rotate3d(0, 0, 1, -90deg); 2291 | transform: rotate3d(0, 0, 1, -90deg); 2292 | opacity: 0; 2293 | } 2294 | 2295 | to { 2296 | -webkit-transform-origin: right bottom; 2297 | transform-origin: right bottom; 2298 | -webkit-transform: none; 2299 | transform: none; 2300 | opacity: 1; 2301 | } 2302 | } 2303 | 2304 | .rotateInUpRight { 2305 | -webkit-animation-name: rotateInUpRight; 2306 | animation-name: rotateInUpRight; 2307 | } 2308 | 2309 | @-webkit-keyframes rotateOut { 2310 | from { 2311 | -webkit-transform-origin: center; 2312 | transform-origin: center; 2313 | opacity: 1; 2314 | } 2315 | 2316 | to { 2317 | -webkit-transform-origin: center; 2318 | transform-origin: center; 2319 | -webkit-transform: rotate3d(0, 0, 1, 200deg); 2320 | transform: rotate3d(0, 0, 1, 200deg); 2321 | opacity: 0; 2322 | } 2323 | } 2324 | 2325 | @keyframes rotateOut { 2326 | from { 2327 | -webkit-transform-origin: center; 2328 | transform-origin: center; 2329 | opacity: 1; 2330 | } 2331 | 2332 | to { 2333 | -webkit-transform-origin: center; 2334 | transform-origin: center; 2335 | -webkit-transform: rotate3d(0, 0, 1, 200deg); 2336 | transform: rotate3d(0, 0, 1, 200deg); 2337 | opacity: 0; 2338 | } 2339 | } 2340 | 2341 | .rotateOut { 2342 | -webkit-animation-name: rotateOut; 2343 | animation-name: rotateOut; 2344 | } 2345 | 2346 | @-webkit-keyframes rotateOutDownLeft { 2347 | from { 2348 | -webkit-transform-origin: left bottom; 2349 | transform-origin: left bottom; 2350 | opacity: 1; 2351 | } 2352 | 2353 | to { 2354 | -webkit-transform-origin: left bottom; 2355 | transform-origin: left bottom; 2356 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2357 | transform: rotate3d(0, 0, 1, 45deg); 2358 | opacity: 0; 2359 | } 2360 | } 2361 | 2362 | @keyframes rotateOutDownLeft { 2363 | from { 2364 | -webkit-transform-origin: left bottom; 2365 | transform-origin: left bottom; 2366 | opacity: 1; 2367 | } 2368 | 2369 | to { 2370 | -webkit-transform-origin: left bottom; 2371 | transform-origin: left bottom; 2372 | -webkit-transform: rotate3d(0, 0, 1, 45deg); 2373 | transform: rotate3d(0, 0, 1, 45deg); 2374 | opacity: 0; 2375 | } 2376 | } 2377 | 2378 | .rotateOutDownLeft { 2379 | -webkit-animation-name: rotateOutDownLeft; 2380 | animation-name: rotateOutDownLeft; 2381 | } 2382 | 2383 | @-webkit-keyframes rotateOutDownRight { 2384 | from { 2385 | -webkit-transform-origin: right bottom; 2386 | transform-origin: right bottom; 2387 | opacity: 1; 2388 | } 2389 | 2390 | to { 2391 | -webkit-transform-origin: right bottom; 2392 | transform-origin: right bottom; 2393 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2394 | transform: rotate3d(0, 0, 1, -45deg); 2395 | opacity: 0; 2396 | } 2397 | } 2398 | 2399 | @keyframes rotateOutDownRight { 2400 | from { 2401 | -webkit-transform-origin: right bottom; 2402 | transform-origin: right bottom; 2403 | opacity: 1; 2404 | } 2405 | 2406 | to { 2407 | -webkit-transform-origin: right bottom; 2408 | transform-origin: right bottom; 2409 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2410 | transform: rotate3d(0, 0, 1, -45deg); 2411 | opacity: 0; 2412 | } 2413 | } 2414 | 2415 | .rotateOutDownRight { 2416 | -webkit-animation-name: rotateOutDownRight; 2417 | animation-name: rotateOutDownRight; 2418 | } 2419 | 2420 | @-webkit-keyframes rotateOutUpLeft { 2421 | from { 2422 | -webkit-transform-origin: left bottom; 2423 | transform-origin: left bottom; 2424 | opacity: 1; 2425 | } 2426 | 2427 | to { 2428 | -webkit-transform-origin: left bottom; 2429 | transform-origin: left bottom; 2430 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2431 | transform: rotate3d(0, 0, 1, -45deg); 2432 | opacity: 0; 2433 | } 2434 | } 2435 | 2436 | @keyframes rotateOutUpLeft { 2437 | from { 2438 | -webkit-transform-origin: left bottom; 2439 | transform-origin: left bottom; 2440 | opacity: 1; 2441 | } 2442 | 2443 | to { 2444 | -webkit-transform-origin: left bottom; 2445 | transform-origin: left bottom; 2446 | -webkit-transform: rotate3d(0, 0, 1, -45deg); 2447 | transform: rotate3d(0, 0, 1, -45deg); 2448 | opacity: 0; 2449 | } 2450 | } 2451 | 2452 | .rotateOutUpLeft { 2453 | -webkit-animation-name: rotateOutUpLeft; 2454 | animation-name: rotateOutUpLeft; 2455 | } 2456 | 2457 | @-webkit-keyframes rotateOutUpRight { 2458 | from { 2459 | -webkit-transform-origin: right bottom; 2460 | transform-origin: right bottom; 2461 | opacity: 1; 2462 | } 2463 | 2464 | to { 2465 | -webkit-transform-origin: right bottom; 2466 | transform-origin: right bottom; 2467 | -webkit-transform: rotate3d(0, 0, 1, 90deg); 2468 | transform: rotate3d(0, 0, 1, 90deg); 2469 | opacity: 0; 2470 | } 2471 | } 2472 | 2473 | @keyframes rotateOutUpRight { 2474 | from { 2475 | -webkit-transform-origin: right bottom; 2476 | transform-origin: right bottom; 2477 | opacity: 1; 2478 | } 2479 | 2480 | to { 2481 | -webkit-transform-origin: right bottom; 2482 | transform-origin: right bottom; 2483 | -webkit-transform: rotate3d(0, 0, 1, 90deg); 2484 | transform: rotate3d(0, 0, 1, 90deg); 2485 | opacity: 0; 2486 | } 2487 | } 2488 | 2489 | .rotateOutUpRight { 2490 | -webkit-animation-name: rotateOutUpRight; 2491 | animation-name: rotateOutUpRight; 2492 | } 2493 | 2494 | @-webkit-keyframes hinge { 2495 | 0% { 2496 | -webkit-transform-origin: top left; 2497 | transform-origin: top left; 2498 | -webkit-animation-timing-function: ease-in-out; 2499 | animation-timing-function: ease-in-out; 2500 | } 2501 | 2502 | 20%, 60% { 2503 | -webkit-transform: rotate3d(0, 0, 1, 80deg); 2504 | transform: rotate3d(0, 0, 1, 80deg); 2505 | -webkit-transform-origin: top left; 2506 | transform-origin: top left; 2507 | -webkit-animation-timing-function: ease-in-out; 2508 | animation-timing-function: ease-in-out; 2509 | } 2510 | 2511 | 40%, 80% { 2512 | -webkit-transform: rotate3d(0, 0, 1, 60deg); 2513 | transform: rotate3d(0, 0, 1, 60deg); 2514 | -webkit-transform-origin: top left; 2515 | transform-origin: top left; 2516 | -webkit-animation-timing-function: ease-in-out; 2517 | animation-timing-function: ease-in-out; 2518 | opacity: 1; 2519 | } 2520 | 2521 | to { 2522 | -webkit-transform: translate3d(0, 700px, 0); 2523 | transform: translate3d(0, 700px, 0); 2524 | opacity: 0; 2525 | } 2526 | } 2527 | 2528 | @keyframes hinge { 2529 | 0% { 2530 | -webkit-transform-origin: top left; 2531 | transform-origin: top left; 2532 | -webkit-animation-timing-function: ease-in-out; 2533 | animation-timing-function: ease-in-out; 2534 | } 2535 | 2536 | 20%, 60% { 2537 | -webkit-transform: rotate3d(0, 0, 1, 80deg); 2538 | transform: rotate3d(0, 0, 1, 80deg); 2539 | -webkit-transform-origin: top left; 2540 | transform-origin: top left; 2541 | -webkit-animation-timing-function: ease-in-out; 2542 | animation-timing-function: ease-in-out; 2543 | } 2544 | 2545 | 40%, 80% { 2546 | -webkit-transform: rotate3d(0, 0, 1, 60deg); 2547 | transform: rotate3d(0, 0, 1, 60deg); 2548 | -webkit-transform-origin: top left; 2549 | transform-origin: top left; 2550 | -webkit-animation-timing-function: ease-in-out; 2551 | animation-timing-function: ease-in-out; 2552 | opacity: 1; 2553 | } 2554 | 2555 | to { 2556 | -webkit-transform: translate3d(0, 700px, 0); 2557 | transform: translate3d(0, 700px, 0); 2558 | opacity: 0; 2559 | } 2560 | } 2561 | 2562 | .hinge { 2563 | -webkit-animation-name: hinge; 2564 | animation-name: hinge; 2565 | } 2566 | 2567 | /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ 2568 | 2569 | @-webkit-keyframes rollIn { 2570 | from { 2571 | opacity: 0; 2572 | -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); 2573 | transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); 2574 | } 2575 | 2576 | to { 2577 | opacity: 1; 2578 | -webkit-transform: none; 2579 | transform: none; 2580 | } 2581 | } 2582 | 2583 | @keyframes rollIn { 2584 | from { 2585 | opacity: 0; 2586 | -webkit-transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); 2587 | transform: translate3d(-100%, 0, 0) rotate3d(0, 0, 1, -120deg); 2588 | } 2589 | 2590 | to { 2591 | opacity: 1; 2592 | -webkit-transform: none; 2593 | transform: none; 2594 | } 2595 | } 2596 | 2597 | .rollIn { 2598 | -webkit-animation-name: rollIn; 2599 | animation-name: rollIn; 2600 | } 2601 | 2602 | /* originally authored by Nick Pettit - https://github.com/nickpettit/glide */ 2603 | 2604 | @-webkit-keyframes rollOut { 2605 | from { 2606 | opacity: 1; 2607 | } 2608 | 2609 | to { 2610 | opacity: 0; 2611 | -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); 2612 | transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); 2613 | } 2614 | } 2615 | 2616 | @keyframes rollOut { 2617 | from { 2618 | opacity: 1; 2619 | } 2620 | 2621 | to { 2622 | opacity: 0; 2623 | -webkit-transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); 2624 | transform: translate3d(100%, 0, 0) rotate3d(0, 0, 1, 120deg); 2625 | } 2626 | } 2627 | 2628 | .rollOut { 2629 | -webkit-animation-name: rollOut; 2630 | animation-name: rollOut; 2631 | } 2632 | 2633 | @-webkit-keyframes zoomIn { 2634 | from { 2635 | opacity: 0; 2636 | -webkit-transform: scale3d(.3, .3, .3); 2637 | transform: scale3d(.3, .3, .3); 2638 | } 2639 | 2640 | 50% { 2641 | opacity: 1; 2642 | } 2643 | } 2644 | 2645 | @keyframes zoomIn { 2646 | from { 2647 | opacity: 0; 2648 | -webkit-transform: scale3d(.3, .3, .3); 2649 | transform: scale3d(.3, .3, .3); 2650 | } 2651 | 2652 | 50% { 2653 | opacity: 1; 2654 | } 2655 | } 2656 | 2657 | .zoomIn { 2658 | -webkit-animation-name: zoomIn; 2659 | animation-name: zoomIn; 2660 | } 2661 | 2662 | @-webkit-keyframes zoomInDown { 2663 | from { 2664 | opacity: 0; 2665 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); 2666 | transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); 2667 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2668 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2669 | } 2670 | 2671 | 60% { 2672 | opacity: 1; 2673 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2674 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2675 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2676 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2677 | } 2678 | } 2679 | 2680 | @keyframes zoomInDown { 2681 | from { 2682 | opacity: 0; 2683 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); 2684 | transform: scale3d(.1, .1, .1) translate3d(0, -1000px, 0); 2685 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2686 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2687 | } 2688 | 2689 | 60% { 2690 | opacity: 1; 2691 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2692 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2693 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2694 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2695 | } 2696 | } 2697 | 2698 | .zoomInDown { 2699 | -webkit-animation-name: zoomInDown; 2700 | animation-name: zoomInDown; 2701 | } 2702 | 2703 | @-webkit-keyframes zoomInLeft { 2704 | from { 2705 | opacity: 0; 2706 | -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); 2707 | transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); 2708 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2709 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2710 | } 2711 | 2712 | 60% { 2713 | opacity: 1; 2714 | -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); 2715 | transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); 2716 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2717 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2718 | } 2719 | } 2720 | 2721 | @keyframes zoomInLeft { 2722 | from { 2723 | opacity: 0; 2724 | -webkit-transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); 2725 | transform: scale3d(.1, .1, .1) translate3d(-1000px, 0, 0); 2726 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2727 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2728 | } 2729 | 2730 | 60% { 2731 | opacity: 1; 2732 | -webkit-transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); 2733 | transform: scale3d(.475, .475, .475) translate3d(10px, 0, 0); 2734 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2735 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2736 | } 2737 | } 2738 | 2739 | .zoomInLeft { 2740 | -webkit-animation-name: zoomInLeft; 2741 | animation-name: zoomInLeft; 2742 | } 2743 | 2744 | @-webkit-keyframes zoomInRight { 2745 | from { 2746 | opacity: 0; 2747 | -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); 2748 | transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); 2749 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2750 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2751 | } 2752 | 2753 | 60% { 2754 | opacity: 1; 2755 | -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); 2756 | transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); 2757 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2758 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2759 | } 2760 | } 2761 | 2762 | @keyframes zoomInRight { 2763 | from { 2764 | opacity: 0; 2765 | -webkit-transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); 2766 | transform: scale3d(.1, .1, .1) translate3d(1000px, 0, 0); 2767 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2768 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2769 | } 2770 | 2771 | 60% { 2772 | opacity: 1; 2773 | -webkit-transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); 2774 | transform: scale3d(.475, .475, .475) translate3d(-10px, 0, 0); 2775 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2776 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2777 | } 2778 | } 2779 | 2780 | .zoomInRight { 2781 | -webkit-animation-name: zoomInRight; 2782 | animation-name: zoomInRight; 2783 | } 2784 | 2785 | @-webkit-keyframes zoomInUp { 2786 | from { 2787 | opacity: 0; 2788 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); 2789 | transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); 2790 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2791 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2792 | } 2793 | 2794 | 60% { 2795 | opacity: 1; 2796 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2797 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2798 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2799 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2800 | } 2801 | } 2802 | 2803 | @keyframes zoomInUp { 2804 | from { 2805 | opacity: 0; 2806 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); 2807 | transform: scale3d(.1, .1, .1) translate3d(0, 1000px, 0); 2808 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2809 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2810 | } 2811 | 2812 | 60% { 2813 | opacity: 1; 2814 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2815 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2816 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2817 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2818 | } 2819 | } 2820 | 2821 | .zoomInUp { 2822 | -webkit-animation-name: zoomInUp; 2823 | animation-name: zoomInUp; 2824 | } 2825 | 2826 | @-webkit-keyframes zoomOut { 2827 | from { 2828 | opacity: 1; 2829 | } 2830 | 2831 | 50% { 2832 | opacity: 0; 2833 | -webkit-transform: scale3d(.3, .3, .3); 2834 | transform: scale3d(.3, .3, .3); 2835 | } 2836 | 2837 | to { 2838 | opacity: 0; 2839 | } 2840 | } 2841 | 2842 | @keyframes zoomOut { 2843 | from { 2844 | opacity: 1; 2845 | } 2846 | 2847 | 50% { 2848 | opacity: 0; 2849 | -webkit-transform: scale3d(.3, .3, .3); 2850 | transform: scale3d(.3, .3, .3); 2851 | } 2852 | 2853 | to { 2854 | opacity: 0; 2855 | } 2856 | } 2857 | 2858 | .zoomOut { 2859 | -webkit-animation-name: zoomOut; 2860 | animation-name: zoomOut; 2861 | } 2862 | 2863 | @-webkit-keyframes zoomOutDown { 2864 | 40% { 2865 | opacity: 1; 2866 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2867 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2868 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2869 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2870 | } 2871 | 2872 | to { 2873 | opacity: 0; 2874 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); 2875 | transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); 2876 | -webkit-transform-origin: center bottom; 2877 | transform-origin: center bottom; 2878 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2879 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2880 | } 2881 | } 2882 | 2883 | @keyframes zoomOutDown { 2884 | 40% { 2885 | opacity: 1; 2886 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2887 | transform: scale3d(.475, .475, .475) translate3d(0, -60px, 0); 2888 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2889 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2890 | } 2891 | 2892 | to { 2893 | opacity: 0; 2894 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); 2895 | transform: scale3d(.1, .1, .1) translate3d(0, 2000px, 0); 2896 | -webkit-transform-origin: center bottom; 2897 | transform-origin: center bottom; 2898 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2899 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2900 | } 2901 | } 2902 | 2903 | .zoomOutDown { 2904 | -webkit-animation-name: zoomOutDown; 2905 | animation-name: zoomOutDown; 2906 | } 2907 | 2908 | @-webkit-keyframes zoomOutLeft { 2909 | 40% { 2910 | opacity: 1; 2911 | -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); 2912 | transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); 2913 | } 2914 | 2915 | to { 2916 | opacity: 0; 2917 | -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); 2918 | transform: scale(.1) translate3d(-2000px, 0, 0); 2919 | -webkit-transform-origin: left center; 2920 | transform-origin: left center; 2921 | } 2922 | } 2923 | 2924 | @keyframes zoomOutLeft { 2925 | 40% { 2926 | opacity: 1; 2927 | -webkit-transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); 2928 | transform: scale3d(.475, .475, .475) translate3d(42px, 0, 0); 2929 | } 2930 | 2931 | to { 2932 | opacity: 0; 2933 | -webkit-transform: scale(.1) translate3d(-2000px, 0, 0); 2934 | transform: scale(.1) translate3d(-2000px, 0, 0); 2935 | -webkit-transform-origin: left center; 2936 | transform-origin: left center; 2937 | } 2938 | } 2939 | 2940 | .zoomOutLeft { 2941 | -webkit-animation-name: zoomOutLeft; 2942 | animation-name: zoomOutLeft; 2943 | } 2944 | 2945 | @-webkit-keyframes zoomOutRight { 2946 | 40% { 2947 | opacity: 1; 2948 | -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); 2949 | transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); 2950 | } 2951 | 2952 | to { 2953 | opacity: 0; 2954 | -webkit-transform: scale(.1) translate3d(2000px, 0, 0); 2955 | transform: scale(.1) translate3d(2000px, 0, 0); 2956 | -webkit-transform-origin: right center; 2957 | transform-origin: right center; 2958 | } 2959 | } 2960 | 2961 | @keyframes zoomOutRight { 2962 | 40% { 2963 | opacity: 1; 2964 | -webkit-transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); 2965 | transform: scale3d(.475, .475, .475) translate3d(-42px, 0, 0); 2966 | } 2967 | 2968 | to { 2969 | opacity: 0; 2970 | -webkit-transform: scale(.1) translate3d(2000px, 0, 0); 2971 | transform: scale(.1) translate3d(2000px, 0, 0); 2972 | -webkit-transform-origin: right center; 2973 | transform-origin: right center; 2974 | } 2975 | } 2976 | 2977 | .zoomOutRight { 2978 | -webkit-animation-name: zoomOutRight; 2979 | animation-name: zoomOutRight; 2980 | } 2981 | 2982 | @-webkit-keyframes zoomOutUp { 2983 | 40% { 2984 | opacity: 1; 2985 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2986 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 2987 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2988 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 2989 | } 2990 | 2991 | to { 2992 | opacity: 0; 2993 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); 2994 | transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); 2995 | -webkit-transform-origin: center bottom; 2996 | transform-origin: center bottom; 2997 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2998 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 2999 | } 3000 | } 3001 | 3002 | @keyframes zoomOutUp { 3003 | 40% { 3004 | opacity: 1; 3005 | -webkit-transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 3006 | transform: scale3d(.475, .475, .475) translate3d(0, 60px, 0); 3007 | -webkit-animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 3008 | animation-timing-function: cubic-bezier(0.550, 0.055, 0.675, 0.190); 3009 | } 3010 | 3011 | to { 3012 | opacity: 0; 3013 | -webkit-transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); 3014 | transform: scale3d(.1, .1, .1) translate3d(0, -2000px, 0); 3015 | -webkit-transform-origin: center bottom; 3016 | transform-origin: center bottom; 3017 | -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 3018 | animation-timing-function: cubic-bezier(0.175, 0.885, 0.320, 1); 3019 | } 3020 | } 3021 | 3022 | .zoomOutUp { 3023 | -webkit-animation-name: zoomOutUp; 3024 | animation-name: zoomOutUp; 3025 | } 3026 | 3027 | @-webkit-keyframes slideInDown { 3028 | from { 3029 | -webkit-transform: translate3d(0, -100%, 0); 3030 | transform: translate3d(0, -100%, 0); 3031 | visibility: visible; 3032 | } 3033 | 3034 | to { 3035 | -webkit-transform: translate3d(0, 0, 0); 3036 | transform: translate3d(0, 0, 0); 3037 | } 3038 | } 3039 | 3040 | @keyframes slideInDown { 3041 | from { 3042 | -webkit-transform: translate3d(0, -100%, 0); 3043 | transform: translate3d(0, -100%, 0); 3044 | visibility: visible; 3045 | } 3046 | 3047 | to { 3048 | -webkit-transform: translate3d(0, 0, 0); 3049 | transform: translate3d(0, 0, 0); 3050 | } 3051 | } 3052 | 3053 | .slideInDown { 3054 | -webkit-animation-name: slideInDown; 3055 | animation-name: slideInDown; 3056 | } 3057 | 3058 | @-webkit-keyframes slideInLeft { 3059 | from { 3060 | -webkit-transform: translate3d(-100%, 0, 0); 3061 | transform: translate3d(-100%, 0, 0); 3062 | visibility: visible; 3063 | } 3064 | 3065 | to { 3066 | -webkit-transform: translate3d(0, 0, 0); 3067 | transform: translate3d(0, 0, 0); 3068 | } 3069 | } 3070 | 3071 | @keyframes slideInLeft { 3072 | from { 3073 | -webkit-transform: translate3d(-100%, 0, 0); 3074 | transform: translate3d(-100%, 0, 0); 3075 | visibility: visible; 3076 | } 3077 | 3078 | to { 3079 | -webkit-transform: translate3d(0, 0, 0); 3080 | transform: translate3d(0, 0, 0); 3081 | } 3082 | } 3083 | 3084 | .slideInLeft { 3085 | -webkit-animation-name: slideInLeft; 3086 | animation-name: slideInLeft; 3087 | } 3088 | 3089 | @-webkit-keyframes slideInRight { 3090 | from { 3091 | -webkit-transform: translate3d(100%, 0, 0); 3092 | transform: translate3d(100%, 0, 0); 3093 | visibility: visible; 3094 | } 3095 | 3096 | to { 3097 | -webkit-transform: translate3d(0, 0, 0); 3098 | transform: translate3d(0, 0, 0); 3099 | } 3100 | } 3101 | 3102 | @keyframes slideInRight { 3103 | from { 3104 | -webkit-transform: translate3d(100%, 0, 0); 3105 | transform: translate3d(100%, 0, 0); 3106 | visibility: visible; 3107 | } 3108 | 3109 | to { 3110 | -webkit-transform: translate3d(0, 0, 0); 3111 | transform: translate3d(0, 0, 0); 3112 | } 3113 | } 3114 | 3115 | .slideInRight { 3116 | -webkit-animation-name: slideInRight; 3117 | animation-name: slideInRight; 3118 | } 3119 | 3120 | @-webkit-keyframes slideInUp { 3121 | from { 3122 | -webkit-transform: translate3d(0, 100%, 0); 3123 | transform: translate3d(0, 100%, 0); 3124 | visibility: visible; 3125 | } 3126 | 3127 | to { 3128 | -webkit-transform: translate3d(0, 0, 0); 3129 | transform: translate3d(0, 0, 0); 3130 | } 3131 | } 3132 | 3133 | @keyframes slideInUp { 3134 | from { 3135 | -webkit-transform: translate3d(0, 100%, 0); 3136 | transform: translate3d(0, 100%, 0); 3137 | visibility: visible; 3138 | } 3139 | 3140 | to { 3141 | -webkit-transform: translate3d(0, 0, 0); 3142 | transform: translate3d(0, 0, 0); 3143 | } 3144 | } 3145 | 3146 | .slideInUp { 3147 | -webkit-animation-name: slideInUp; 3148 | animation-name: slideInUp; 3149 | } 3150 | 3151 | @-webkit-keyframes slideOutDown { 3152 | from { 3153 | -webkit-transform: translate3d(0, 0, 0); 3154 | transform: translate3d(0, 0, 0); 3155 | } 3156 | 3157 | to { 3158 | visibility: hidden; 3159 | -webkit-transform: translate3d(0, 100%, 0); 3160 | transform: translate3d(0, 100%, 0); 3161 | } 3162 | } 3163 | 3164 | @keyframes slideOutDown { 3165 | from { 3166 | -webkit-transform: translate3d(0, 0, 0); 3167 | transform: translate3d(0, 0, 0); 3168 | } 3169 | 3170 | to { 3171 | visibility: hidden; 3172 | -webkit-transform: translate3d(0, 100%, 0); 3173 | transform: translate3d(0, 100%, 0); 3174 | } 3175 | } 3176 | 3177 | .slideOutDown { 3178 | -webkit-animation-name: slideOutDown; 3179 | animation-name: slideOutDown; 3180 | } 3181 | 3182 | @-webkit-keyframes slideOutLeft { 3183 | from { 3184 | -webkit-transform: translate3d(0, 0, 0); 3185 | transform: translate3d(0, 0, 0); 3186 | } 3187 | 3188 | to { 3189 | visibility: hidden; 3190 | -webkit-transform: translate3d(-100%, 0, 0); 3191 | transform: translate3d(-100%, 0, 0); 3192 | } 3193 | } 3194 | 3195 | @keyframes slideOutLeft { 3196 | from { 3197 | -webkit-transform: translate3d(0, 0, 0); 3198 | transform: translate3d(0, 0, 0); 3199 | } 3200 | 3201 | to { 3202 | visibility: hidden; 3203 | -webkit-transform: translate3d(-100%, 0, 0); 3204 | transform: translate3d(-100%, 0, 0); 3205 | } 3206 | } 3207 | 3208 | .slideOutLeft { 3209 | -webkit-animation-name: slideOutLeft; 3210 | animation-name: slideOutLeft; 3211 | } 3212 | 3213 | @-webkit-keyframes slideOutRight { 3214 | from { 3215 | -webkit-transform: translate3d(0, 0, 0); 3216 | transform: translate3d(0, 0, 0); 3217 | } 3218 | 3219 | to { 3220 | visibility: hidden; 3221 | -webkit-transform: translate3d(100%, 0, 0); 3222 | transform: translate3d(100%, 0, 0); 3223 | } 3224 | } 3225 | 3226 | @keyframes slideOutRight { 3227 | from { 3228 | -webkit-transform: translate3d(0, 0, 0); 3229 | transform: translate3d(0, 0, 0); 3230 | } 3231 | 3232 | to { 3233 | visibility: hidden; 3234 | -webkit-transform: translate3d(100%, 0, 0); 3235 | transform: translate3d(100%, 0, 0); 3236 | } 3237 | } 3238 | 3239 | .slideOutRight { 3240 | -webkit-animation-name: slideOutRight; 3241 | animation-name: slideOutRight; 3242 | } 3243 | 3244 | @-webkit-keyframes slideOutUp { 3245 | from { 3246 | -webkit-transform: translate3d(0, 0, 0); 3247 | transform: translate3d(0, 0, 0); 3248 | } 3249 | 3250 | to { 3251 | visibility: hidden; 3252 | -webkit-transform: translate3d(0, -100%, 0); 3253 | transform: translate3d(0, -100%, 0); 3254 | } 3255 | } 3256 | 3257 | @keyframes slideOutUp { 3258 | from { 3259 | -webkit-transform: translate3d(0, 0, 0); 3260 | transform: translate3d(0, 0, 0); 3261 | } 3262 | 3263 | to { 3264 | visibility: hidden; 3265 | -webkit-transform: translate3d(0, -100%, 0); 3266 | transform: translate3d(0, -100%, 0); 3267 | } 3268 | } 3269 | 3270 | .slideOutUp { 3271 | -webkit-animation-name: slideOutUp; 3272 | animation-name: slideOutUp; 3273 | } -------------------------------------------------------------------------------- /stylus/lib/social-font.styl: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'icomoon'; 3 | src:url('../fonts/icomoon.eot?-qz7pb2'); 4 | src:url('../fonts/icomoon.eot?#iefix-qz7pb2') format('embedded-opentype'), 5 | url('../fonts/icomoon.woff?-qz7pb2') format('woff'), 6 | url('../fonts/icomoon.ttf?-qz7pb2') format('truetype'), 7 | url('../fonts/icomoon.svg?-qz7pb2#icomoon') format('svg'); 8 | font-weight: normal; 9 | font-style: normal; 10 | } 11 | 12 | [class^="icon-"], [class*=" icon-"] { 13 | font-family: 'icomoon'; 14 | speak: none; 15 | font-style: normal; 16 | font-weight: normal; 17 | font-variant: normal; 18 | text-transform: none; 19 | line-height: 1; 20 | 21 | /* Better Font Rendering =========== */ 22 | -webkit-font-smoothing: antialiased; 23 | -moz-osx-font-smoothing: grayscale; 24 | } 25 | 26 | .icon-evernote:before { 27 | content: "\e004"; 28 | } 29 | .icon-feedly:before { 30 | content: "\e007"; 31 | } 32 | .icon-pocket:before { 33 | content: "\e008"; 34 | } 35 | .icon-line:before { 36 | content: "\e009"; 37 | } 38 | .icon-hatena:before { 39 | content: "\e00a"; 40 | } 41 | .icon-feedly-square:before { 42 | content: "\e601"; 43 | } 44 | .icon-googleplus:before { 45 | content: "\e608"; 46 | } 47 | .icon-facebook:before { 48 | content: "\e60d"; 49 | } 50 | .icon-instagram:before { 51 | content: "\e610"; 52 | } 53 | .icon-twitter:before { 54 | content: "\e611"; 55 | } 56 | .icon-feed:before { 57 | content: "\e614"; 58 | } 59 | .icon-youtube:before { 60 | content: "\e617"; 61 | } 62 | .icon-flickr2:before { 63 | content: "\e61e"; 64 | } 65 | .icon-githubmark:before { 66 | content: "\e626"; 67 | } 68 | .icon-github:before { 69 | content: "\e627"; 70 | } 71 | .icon-wordpress:before { 72 | content: "\e629"; 73 | } 74 | .icon-tumblr:before { 75 | content: "\e62d"; 76 | } 77 | .icon-yahoo:before { 78 | content: "\e62f"; 79 | } 80 | .icon-apple:before { 81 | content: "\e631"; 82 | } 83 | .icon-android:before { 84 | content: "\e633"; 85 | } 86 | .icon-windows:before { 87 | content: "\e634"; 88 | } 89 | .icon-windows8:before { 90 | content: "\e635"; 91 | } 92 | .icon-skype:before { 93 | content: "\e636"; 94 | } 95 | .icon-delicious:before { 96 | content: "\e638"; 97 | } 98 | .icon-pinterest:before { 99 | content: "\e63a"; 100 | } 101 | -------------------------------------------------------------------------------- /stylus/main.styl: -------------------------------------------------------------------------------- 1 | @import 'base/normalize' 2 | @import 'base/base' 3 | @import 'lib/social-font' 4 | @import 'lib/animate' 5 | @import 'block/header' 6 | @import 'block/keyword-input' 7 | @import 'block/bookmark-slider' 8 | @import 'block/keywords' 9 | @import 'block/item' 10 | @import 'block/comments' 11 | @import 'block/content' 12 | @import 'block/rect-spinner' 13 | @import 'block/side-menu' 14 | -------------------------------------------------------------------------------- /test/actions/test-menu.js: -------------------------------------------------------------------------------- 1 | import assert from 'power-assert'; 2 | import React from 'react'; 3 | import { applyMiddleware } from 'redux' 4 | import thunk from 'redux-thunk' 5 | import TestUtils from 'react-addons-test-utils'; 6 | import * as actions from '../../src/actions/menu'; 7 | import * as types from '../../src/constants/action-types'; 8 | import _ from 'lodash' 9 | import DbManager from '../../src/lib/db' 10 | 11 | const db = new DbManager('pastaDB'); 12 | const middlewares = [ thunk ] 13 | db.create({keywords: "name, icon"}); 14 | 15 | /** 16 | * Creates a mock of Redux store with middleware. 17 | */ 18 | function mockStore(getState, expectedActions, done) { 19 | if (!Array.isArray(expectedActions)) { 20 | throw new Error('expectedActions should be an array of expected actions.') 21 | } 22 | if (typeof done !== 'undefined' && typeof done !== 'function') { 23 | throw new Error('done should either be undefined or function.') 24 | } 25 | 26 | function mockStoreWithoutMiddleware() { 27 | return { 28 | getState() { 29 | return typeof getState === 'function' ? 30 | getState() : 31 | getState 32 | }, 33 | 34 | dispatch(action) { 35 | const expectedAction = expectedActions.shift() 36 | 37 | try { 38 | assert(_.isEqual(action,expectedAction)); 39 | if (done && !expectedActions.length) { 40 | done() 41 | } 42 | return action 43 | } catch (e) { 44 | done(e) 45 | } 46 | } 47 | } 48 | } 49 | 50 | const mockStoreWithMiddleware = applyMiddleware( 51 | ...middlewares 52 | )(mockStoreWithoutMiddleware) 53 | 54 | return mockStoreWithMiddleware() 55 | } 56 | 57 | describe('Menu Action test', () => { 58 | it ('should create an action to select keyword', (done) => { 59 | const keyword = 'react'; 60 | const expectedAction = { 61 | type: types.SELECT_KEYWORD, 62 | keyword 63 | } 64 | assert(_.isEqual(actions.selectKeyword(keyword), expectedAction)); 65 | done(); 66 | }); 67 | 68 | it ('should create an action to change keyword input', (done) => { 69 | const value = 'react'; 70 | const expectedAction = { 71 | type: types.CHANGE_KEYWORD_INPUT, 72 | value 73 | } 74 | assert(_.isEqual(actions.changeKeywordInput(value), expectedAction)); 75 | done(); 76 | }); 77 | 78 | it ('should create an action to change bookmark filter', (done) => { 79 | const value = 250; 80 | const x = 100; 81 | const expectedAction = { 82 | type: types.CHANGE_BOOKMARK_FILTER, 83 | value, 84 | x 85 | } 86 | assert(_.isEqual(actions.changeBookmarkThreshold(value, x), expectedAction)); 87 | done(); 88 | }); 89 | 90 | it ('should create an action to toggle menu', (done) => { 91 | const expectedAction = { 92 | type: types.TOGGLE_MENU 93 | } 94 | assert(_.isEqual(actions.toggleMenu(), expectedAction)); 95 | done(); 96 | }); 97 | 98 | it ('should create an action to toggle menu', (done) => { 99 | const keyword = "react"; 100 | const expectedActions = [ 101 | { type: types.ADD_KEYWORD, keyword}, 102 | // TODO: IndexedDB put callback not work 103 | //{ type: types.ADD_KEYWORD_COMPLETE, keywords: [keyword]} 104 | ]; 105 | const store = mockStore({ keywords : [] }, expectedActions, done) 106 | store.dispatch(actions.addKeyword("react")); 107 | }); 108 | 109 | }); 110 | -------------------------------------------------------------------------------- /test/api/test-feed.js: -------------------------------------------------------------------------------- 1 | import assert from 'power-assert'; 2 | import querystring from 'querystring'; 3 | import _ from 'lodash'; 4 | //import nock from 'nock'; 5 | import {fetch} from '../../src/api/feed'; 6 | 7 | const ENDPOINT = 'http://jsfiddle.net/echo/jsonp/'; 8 | 9 | const expectedObj = { 10 | hello: 'world' 11 | }; 12 | const q = querystring.encode(expectedObj); 13 | 14 | describe('Feed fetch lib test', () => { 15 | it ('Should render correct DOM', (done) => { 16 | const url = ENDPOINT + '?' + q; 17 | fetch(url).then((data) => { 18 | assert(_.isEqual(data, expectedObj)); 19 | done(); 20 | }); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /test/components/test-button-comment.js: -------------------------------------------------------------------------------- 1 | import assert from 'power-assert'; 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import TestUtils from 'react-addons-test-utils'; 5 | import Button from '../../src/components/button-comment'; 6 | 7 | describe('Comment Button Component test', () => { 8 | it ('Should button text is show comment, when not oepned', (done) => { 9 | const button = TestUtils.renderIntoDocument(