Merge branch 'develop' of https://github.com/LLK/scratch-www into feature/conference-schedule
* 'develop' of https://github.com/LLK/scratch-www: (32 commits) Lint Bundle all locale data Don't bundle polyfills Set up Raven within init.js Prefix privacyPolicy message string Exclude minified javascript from linting One space more Changes "interfacesto" to "interfaces to" Remove tag target Filter before mapping to avoid returning undefined Fix Pass condition for "static" routes Spacing2 Mangling is the default Spacing Update for typography fixes Cherry pick PR #476 into master Add invisible spacer to anchored sections For Developers Lint JSON, expand and simplify lint step Fix banned user redirect ... # Conflicts: # src/redux/actions.js # src/redux/reducer.js
5
.eslintignore
Normal file
|
@ -0,0 +1,5 @@
|
|||
node_modules/*
|
||||
static/*
|
||||
build/*
|
||||
intl/*
|
||||
**/*.min.js
|
|
@ -25,7 +25,8 @@
|
|||
"jsx": true
|
||||
},
|
||||
"plugins": [
|
||||
"react"
|
||||
"react",
|
||||
"json"
|
||||
],
|
||||
"extends": "eslint:recommended"
|
||||
}
|
||||
|
|
10
.travis.yml
|
@ -4,6 +4,7 @@ node_js:
|
|||
sudo: required
|
||||
cache:
|
||||
directories:
|
||||
- /home/travis/virtualenv/python2.7/lib/python2.7/site-packages
|
||||
- node_modules
|
||||
notifications:
|
||||
slack:
|
||||
|
@ -21,7 +22,6 @@ env:
|
|||
- secure: EX1fyov+f6ytWN2ZSL4dLslwrVkp6Ho/uoSLO38/qNG3XdGmBN4VprxddcQiWfo+Mrg3GdWcfcM/VazhhStBi1uLfZiw3RHZaSGuWbiuD2EtzqtlC+OVvoajgy91QFajh9Zzuwa0rYbEPd/sw01R53NoWJYl0GSteWk7C8Wv6anl4FUJCqgvvTV2ZEcyTtGcVJgUhKi1MfNpTSM6JWBy0DWszcyxj7C8LSs1+l9ZjAtnlUBWY13HsrNu8G5d+FwqGHZLUAjdu2O602wxV897/xLARLduZ+01ALpVefNEEGMB1Wd+xMw4dm2B0Uk86a4TBRCeOgJZ1yoJoPpGPOHTo+dgNXcU8ReszGVoy7uOjFWwu82FQq8gzfcf75yzaRJgG8/BJ6BkJfa0EmFg3iO5CwixQyHR5+CqsedtoLAWVT8zlOfQ/Z6yx4Pm7jXQSOkyvo09YJ2QIn4IFGPvwOVS7Firzi+fLl8GYApeSV9G10e1IzA4pPrKdJMRA4qRMPt9zJGq7ZO1J/d9aW/5KIsJUDnodnl7yXJyDMOyNeljT9I82ciHZcURxRRY080vrW6dgNJE1V9jxBhWEvr2iCeWMMedWaGuC41I7K9L79eW8lmaE+cQ+OZrzpOJP4GbfmIiXrh+0M4ChL/xBpjtiFwpNdkCXXhzWMnjJ4wCrii4yuc=
|
||||
- AWS_ACCESS_KEY_ID=$EB_AWS_ACCESS_KEY_ID
|
||||
- AWS_SECRET_ACCESS_KEY=$EB_AWS_SECRET_ACCESS_KEY
|
||||
- CXX=g++-4.8
|
||||
- FASTLY_ACTIVATE_CHANGES=true
|
||||
# FASTLY_API_KEY
|
||||
- secure: XNWcCnqSAd4MpKg6FVe3WeFmdqfdH753+PBCOEkJrHS+AHmLMuWsjIQFJ3LUR9ylEQRVPR2OyXJW/R8NI9toStREgwE4fwIVo0l4fwYqLStxYpEKlcWfkJ3uNpRZhvcVmUBycelrnjJqXVdrtlxPCKX0tNkpcKH2b98We7A2/r7HxKv13upDxWTQ/qRUv0+SJCRTB4n/QInABi87Ef8Q2rNGrL0WQzQvVBeiEXOP0JSkyYK4+q65gswMKPehgiFagnYVgJN9J9Q1VrBDc06gidbznBcEpPaBAYvsTTY9dWTJxaaKNSrmOIe/OiuJUEHjb+8NL+j6Lp7wX8lzEjbr0FkVlFnxS9VbftS2KFkN7+c3RF57+tsq0xwJ6vgomIVS5FupHgl/oCJicnH/FLfynditOLZhmhF+Ed5GCAoIEamRRzcVHdjvglsEtYsDX1/z2t+HKYtPQuXYOywDRVTSPf88eEbu8ehfgNcYaIAuD6eedyDnKTOIv7owWs3Y7GsxQ2jBLGXq1YoUEkPtB0vfaHi72CeEhDQ53mEn2Ure47UMGMgUjKtiIhDBNTbECwP/ZDJv1accGRljKjDy93aCJeRi1T7Op7tDbHSl4ScieeOwOeKJMcD1U5JGdA/sRnjjgSKb24P2ys4NYr95dgqWNNGPGMxca+lGufzdEaTQT44=
|
||||
|
@ -50,15 +50,9 @@ env:
|
|||
- SKIP_CLEANUP=true
|
||||
- NODE_ENV=production
|
||||
- WWW_VERSION=${TRAVIS_COMMIT:0:5}
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- g++-4.8
|
||||
install:
|
||||
- sudo -H pip install -r requirements.txt
|
||||
- npm install
|
||||
- npm --production=false install
|
||||
deploy:
|
||||
- provider: script
|
||||
skip_cleanup: $SKIP_CLEANUP
|
||||
|
|
16
Makefile
|
@ -24,9 +24,6 @@ deploy:
|
|||
@make build
|
||||
@make sync
|
||||
|
||||
tag:
|
||||
echo $(GIT_VERSION) > ./build/version.txt
|
||||
|
||||
translations:
|
||||
./bin/build-locales intl
|
||||
|
||||
|
@ -62,18 +59,9 @@ test:
|
|||
@echo ""
|
||||
|
||||
lint:
|
||||
$(ESLINT) ./*.js
|
||||
$(ESLINT) ./dev-server/*.js
|
||||
$(ESLINT) ./bin/**/*.js
|
||||
$(ESLINT) ./src/*.js
|
||||
$(ESLINT) ./src/mixins/*.jsx
|
||||
$(ESLINT) ./src/views/**/*.jsx
|
||||
$(ESLINT) ./src/components/**/*.jsx
|
||||
$(ESLINT) ./src/components/**/**/*.jsx
|
||||
$(ESLINT) . --ext .js,.jsx,.json
|
||||
$(SASSLINT) ./src/*.scss
|
||||
$(SASSLINT) ./src/views/**/*.scss
|
||||
$(SASSLINT) ./src/components/**/*.scss
|
||||
$(SASSLINT) ./src/components/**/**/*.scss
|
||||
$(SASSLINT) ./src/**/*.scss
|
||||
|
||||
unit:
|
||||
$(TAP) ./test/unit/*.js
|
||||
|
|
|
@ -19,8 +19,6 @@ var extraAppRoutes = [
|
|||
// Homepage with querystring.
|
||||
// TODO: Should this be added for every route?
|
||||
'^/\\?',
|
||||
// Version output by build
|
||||
'/version\.txt$',
|
||||
// View html
|
||||
'^/[^\/]*\.html'
|
||||
];
|
||||
|
@ -31,7 +29,10 @@ var extraAppRoutes = [
|
|||
*/
|
||||
var getStaticPaths = function (pathToStatic) {
|
||||
var staticPaths = glob.sync(path.resolve(__dirname, pathToStatic));
|
||||
return staticPaths.map(function (pathName) {
|
||||
return staticPaths.filter(function (pathName) {
|
||||
// Exclude view html, resolve everything else in the build
|
||||
return path.extname(pathName) !== '.html';
|
||||
}).map(function (pathName) {
|
||||
// Reduce absolute path to relative paths like '/js'
|
||||
var base = path.dirname(path.resolve(__dirname, pathToStatic));
|
||||
return '^' + pathName.replace(base, '') + (path.extname(pathName) ? '' : '/');
|
||||
|
@ -106,7 +107,7 @@ async.auto({
|
|||
});
|
||||
},
|
||||
notPassRequestCondition: ['version', function (cb, results) {
|
||||
var statement = getAppRouteCondition('../static/*', routes, extraAppRoutes);
|
||||
var statement = getAppRouteCondition('../build/*', routes, extraAppRoutes);
|
||||
var condition = {
|
||||
name: NOT_PASS_REQUEST_CONDITION_NAME,
|
||||
statement: statement,
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
"copy-webpack-plugin": "0.2.0",
|
||||
"css-loader": "0.23.1",
|
||||
"eslint": "1.3.1",
|
||||
"eslint-plugin-json": "1.2.0",
|
||||
"eslint-plugin-react": "3.3.1",
|
||||
"exenv": "1.2.0",
|
||||
"fastly": "1.2.1",
|
||||
|
@ -56,13 +57,17 @@
|
|||
"minilog": "2.0.8",
|
||||
"node-sass": "3.3.3",
|
||||
"pako": "0.2.8",
|
||||
"po2icu": "git://github.com/LLK/po2icu.git#develop",
|
||||
"po2icu": "0.0.2",
|
||||
"postcss-loader": "0.8.2",
|
||||
"react-addons-test-utils": "0.14.7",
|
||||
"raven-js": "3.0.4",
|
||||
"react": "0.14.0",
|
||||
"react-dom": "0.14.0",
|
||||
"react-intl": "2.1.2",
|
||||
"react-modal": "0.6.1",
|
||||
"react-onclickoutside": "4.1.1",
|
||||
"react-redux": "4.4.0",
|
||||
"react-slick": "0.9.2",
|
||||
"redux": "3.5.2",
|
||||
"redux-thunk": "2.0.1",
|
||||
"sass-lint": "1.5.1",
|
||||
"sass-loader": "2.0.1",
|
||||
|
|
|
@ -14,201 +14,145 @@ var Footer = React.createClass({
|
|||
<div className="lists">
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id='general.about'
|
||||
defaultMessage={'About'} />
|
||||
<FormattedMessage id='general.about' />
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="/about/">
|
||||
<FormattedMessage
|
||||
id='footer.about'
|
||||
defaultMessage={'About Scratch'} />
|
||||
<FormattedMessage id='general.aboutScratch' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/parents/">
|
||||
<FormattedMessage
|
||||
id='general.forParents'
|
||||
defaultMessage={'For Parents'} />
|
||||
<FormattedMessage id='general.forParents' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/educators/">
|
||||
<FormattedMessage
|
||||
id='general.forEducators'
|
||||
defaultMessage={'For Educators'} />
|
||||
<FormattedMessage id='general.forEducators' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/info/credits/">
|
||||
<FormattedMessage
|
||||
id='general.credits'
|
||||
defaultMessage={'Credits'} />
|
||||
<FormattedMessage id='general.credits' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/jobs/">
|
||||
<FormattedMessage
|
||||
id='general.jobs'
|
||||
defaultMessage={'Jobs'} />
|
||||
<FormattedMessage id='general.jobs' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="http://wiki.scratch.mit.edu/wiki/Scratch_Press">
|
||||
<FormattedMessage
|
||||
id='general.press'
|
||||
defaultMessage={'Press'} />
|
||||
<FormattedMessage id='general.press' />
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id='general.community'
|
||||
defaultMessage={'Community'} />
|
||||
<FormattedMessage id='general.community' />
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="/community_guidelines/">
|
||||
<FormattedMessage
|
||||
id='general.guidelines'
|
||||
defaultMessage={'Community Guidelines'} />
|
||||
<FormattedMessage id='general.guidelines' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/discuss/">
|
||||
<FormattedMessage
|
||||
id='footer.discuss'
|
||||
defaultMessage={'Discussion Forums'} />
|
||||
<FormattedMessage id='footer.discuss' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="https://wiki.scratch.mit.edu/">
|
||||
<FormattedMessage
|
||||
id='general.wiki'
|
||||
defaultMessage={'Scratch Wiki'} />
|
||||
<FormattedMessage id='general.wiki' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/statistics/">
|
||||
<FormattedMessage
|
||||
id='general.statistics'
|
||||
defaultMessage={'Statistics'} />
|
||||
<FormattedMessage id='general.statistics' />
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id='general.support'
|
||||
defaultMessage={'Support'} />
|
||||
<FormattedMessage id='general.support' />
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="/help/">
|
||||
<FormattedMessage
|
||||
id='footer.help'
|
||||
defaultMessage={'Help Page'} />
|
||||
<FormattedMessage id='footer.help' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/info/faq/">
|
||||
<FormattedMessage
|
||||
id='general.faq'
|
||||
defaultMessage={'FAQ'} />
|
||||
<FormattedMessage id='general.faq' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/scratch2download/">
|
||||
<FormattedMessage
|
||||
id='general.offlineEditor'
|
||||
defaultMessage={'Offline Editor'} />
|
||||
<FormattedMessage id='general.offlineEditor' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/contact-us/">
|
||||
<FormattedMessage
|
||||
id='general.contactUs'
|
||||
defaultMessage={'Contact Us'} />
|
||||
<FormattedMessage id='general.contactUs' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="https://secure.donationpay.org/scratchfoundation/">
|
||||
<FormattedMessage
|
||||
id='general.donate'
|
||||
defaultMessage={'Donate'} />
|
||||
<FormattedMessage id='general.donate'/>
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id='general.legal'
|
||||
defaultMessage={'Legal'} />
|
||||
<FormattedMessage id='general.legal'/>
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="/terms_of_use/">
|
||||
<FormattedMessage
|
||||
id='general.termsOfUse'
|
||||
defaultMessage={'Terms of Use'} />
|
||||
<FormattedMessage id='general.termsOfUse' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/privacy_policy/">
|
||||
<FormattedMessage
|
||||
id='privacyPolicy'
|
||||
defaultMessage={'Privacy Policy'} />
|
||||
<FormattedMessage id='general.privacyPolicy' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/DMCA/">
|
||||
<FormattedMessage
|
||||
id='general.dmca'
|
||||
defaultMessage={'DMCA'} />
|
||||
<FormattedMessage id='general.dmca' />
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<FormattedMessage
|
||||
id='footer.scratchFamily'
|
||||
defaultMessage={'Scratch Family'} />
|
||||
<FormattedMessage id='footer.scratchFamily' />
|
||||
</dt>
|
||||
<dd>
|
||||
<a href="http://scratched.gse.harvard.edu/">
|
||||
<FormattedMessage
|
||||
id='general.scratchEd'
|
||||
defaultMessage={'ScratchEd'} />
|
||||
<FormattedMessage id='general.scratchEd' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="http://www.scratchjr.org/">
|
||||
<FormattedMessage
|
||||
id='general.scratchJr'
|
||||
defaultMessage={'ScratchJr'} />
|
||||
<FormattedMessage id='general.scratchJr' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="http://day.scratch.mit.edu/">
|
||||
<FormattedMessage
|
||||
id='general.scratchday'
|
||||
defaultMessage={'Scratch Day'} />
|
||||
<FormattedMessage id='general.scratchday' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="/conference/">
|
||||
<FormattedMessage
|
||||
id='general.scratchConference'
|
||||
defaultMessage={'Scratch Conference'} />
|
||||
<FormattedMessage id='general.scratchConference' />
|
||||
</a>
|
||||
</dd>
|
||||
<dd>
|
||||
<a href="http://www.scratchfoundation.org/">
|
||||
<FormattedMessage
|
||||
id='general.scratchFoundation'
|
||||
defaultMessage={'Scratch Foundation'} />
|
||||
<FormattedMessage id='general.scratchFoundation' />
|
||||
</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
@ -218,11 +162,7 @@ var Footer = React.createClass({
|
|||
|
||||
<div className="copyright">
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='general.copyright'
|
||||
defaultMessage={
|
||||
'Scratch is a project of the Lifelong Kindergarten Group at the MIT Media Lab'
|
||||
} />
|
||||
<FormattedMessage id='general.copyright' />
|
||||
</p>
|
||||
</div>
|
||||
</FooterBox>
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
li {
|
||||
display: inline-block;
|
||||
margin: 5px;
|
||||
border: 2px solid $active-gray;
|
||||
border: 1px solid $active-gray;
|
||||
border-radius: 50px;
|
||||
padding: .75em 1em;
|
||||
padding: .75em 1.5em;
|
||||
text-decoration: none;
|
||||
color: $type-white;
|
||||
list-style-type: none;
|
||||
|
@ -32,7 +32,7 @@
|
|||
border: 0 solid transparent;
|
||||
box-shadow: inset 0 0 5px $box-shadow-gray;
|
||||
background-color: $active-dark-gray;
|
||||
padding: calc(.75em + 2px) calc(1em + 2px);
|
||||
padding: calc(.75em + 1px) calc(1.5em + 1px);
|
||||
}
|
||||
|
||||
&.description {
|
||||
|
|
11
src/init.js
|
@ -1,5 +1,16 @@
|
|||
var jar = require('./lib/jar');
|
||||
var Raven = require('raven-js');
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------------------------------
|
||||
* Error handling
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
(function () {
|
||||
if (process.env.SENTRY_DSN !== '') {
|
||||
Raven.config(process.env.SENTRY_DSN).install();
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* -----------------------------------------------------------------------------
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"general.myClasses": "My Classes",
|
||||
"general.myStuff": "My Stuff",
|
||||
"general.offlineEditor": "Offline Editor",
|
||||
"general.privacyPolicy": "Privacy Policy",
|
||||
"general.profile": "Profile",
|
||||
"general.scratchConference": "Scratch Conference",
|
||||
"general.scratchday": "Scratch Day",
|
||||
|
@ -49,7 +50,6 @@
|
|||
"general.whatsHappening": "What's Happening?",
|
||||
"general.wiki": "Scratch Wiki",
|
||||
|
||||
"footer.about": "About Scratch",
|
||||
"footer.discuss": "Discussion Forums",
|
||||
"footer.help": "Help Page",
|
||||
"footer.scratchFamily": "Scratch Family",
|
||||
|
|
|
@ -1,12 +1,21 @@
|
|||
var requireAll = require('./require-all');
|
||||
var ReactIntl = require('react-intl');
|
||||
|
||||
var customLanguages = require('../../custom-locales.json');
|
||||
var allLocaleData = requireAll(require.context('react-intl/locale-data', true, /^\.\/.*\.js$/));
|
||||
var customLocaleData = require('../../custom-locales.json');
|
||||
|
||||
/**
|
||||
* Add all locales
|
||||
*/
|
||||
for (var locale in allLocaleData) {
|
||||
ReactIntl.addLocaleData(allLocaleData[locale]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom locales to react-intl if it doesn't have them.
|
||||
*/
|
||||
for (var locale in customLanguages) {
|
||||
ReactIntl.addLocaleData(customLanguages[locale]);
|
||||
for (var customLocale in customLocaleData) {
|
||||
ReactIntl.addLocaleData(customLocaleData[customLocale]);
|
||||
}
|
||||
|
||||
module.exports = ReactIntl;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
var redux = require('redux');
|
||||
var thunk = require('redux-thunk').default;
|
||||
// JSX syntax transforms to React.createElement
|
||||
var React = require('react'); // eslint-disable-line
|
||||
var ReactDOM = require('react-dom');
|
||||
var StoreProvider = require('react-redux').Provider;
|
||||
|
||||
|
|
5
src/lib/require-all.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
var requireAll = function (requireContext) {
|
||||
return requireContext.keys().map(requireContext);
|
||||
};
|
||||
|
||||
module.exports = requireAll;
|
|
@ -17,6 +17,12 @@
|
|||
"view": "components/components",
|
||||
"title": "Components"
|
||||
},
|
||||
{
|
||||
"name": "developers",
|
||||
"pattern": "^/developers/?$",
|
||||
"view": "developers/developers",
|
||||
"title": "Developers"
|
||||
},
|
||||
{
|
||||
"name": "hoc",
|
||||
"pattern": "^/hoc/?$",
|
||||
|
@ -104,5 +110,11 @@
|
|||
"pattern": "^/community_guidelines$",
|
||||
"view": "guidelines/guidelines",
|
||||
"title": "Scratch Community Guidelines"
|
||||
},
|
||||
{
|
||||
"name": "privacypolicy",
|
||||
"pattern": "^/privacy_policy/?$",
|
||||
"view": "privacypolicy/privacypolicy",
|
||||
"title": "Privacy Policy"
|
||||
}
|
||||
]
|
||||
|
|
|
@ -19,14 +19,5 @@ module.exports = {
|
|||
og_image_height: 860,
|
||||
|
||||
// Analytics & Monitoring
|
||||
ga_tracker: process.env.GA_TRACKER || '',
|
||||
|
||||
// Error handling
|
||||
sentry_dsn: process.env.SENTRY_DSN || '',
|
||||
|
||||
// Use minified JS libraries
|
||||
min: (process.env.NODE_ENV === 'production') ? '.min' : '',
|
||||
|
||||
// Redux likes to have this
|
||||
NODE_ENV: process.env.NODE_ENV
|
||||
ga_tracker: process.env.GA_TRACKER || ''
|
||||
};
|
||||
|
|
|
@ -38,31 +38,19 @@
|
|||
};
|
||||
</script>
|
||||
|
||||
<!-- Polyfill & Initialize (Session & Localization)-->
|
||||
<script src="/js/lib/polyfill.min.js"></script>
|
||||
<script src="/js/init.bundle.js"></script>
|
||||
<!-- Polyfills -->
|
||||
<script src="/js/polyfill.min.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
<!-- Vendor & Initialize (Session & Localization)-->
|
||||
<script src="/js/common.bundle.js"></script>
|
||||
<!-- Scripts -->
|
||||
<script src="/js/lib/react{{min}}.js"></script>
|
||||
<script src="/js/lib/react-dom{{min}}.js"></script>
|
||||
<script src="/js/lib/redux{{min}}.js"></script>
|
||||
<script src="/js/lib/react-intl-with-locales{{min}}.js"></script>
|
||||
<script src="/js/lib/raven.min.js"></script>
|
||||
|
||||
<script src="/js/{{name}}.intl.js"></script>
|
||||
<script src="/js/{{name}}.bundle.js"></script>
|
||||
|
||||
<!-- Error logging (Sentry) -->
|
||||
<script>
|
||||
if ('{{&sentry_dsn}}' !== '') {
|
||||
Raven.config('{{&sentry_dsn}}').install();
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Analytics (GA) -->
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
|
@ -75,5 +63,21 @@
|
|||
});
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
|
||||
<!-- translate title element -->
|
||||
<script>
|
||||
var loc = window._locale || 'en';
|
||||
if (typeof window._messages !== 'undefined' && loc !== 'en') {
|
||||
if (typeof window._messages[loc] === 'undefined') {
|
||||
loc = loc.split('-')[0];
|
||||
}
|
||||
if (typeof window._messages[loc] !== 'undefined') {
|
||||
var localizedTitle = window._messages[loc]['general.' + '{{title}}'.toLowerCase()] || '';
|
||||
if (localizedTitle.length > 0) {
|
||||
document.title = 'Scratch - ' + localizedTitle;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,172 +1,174 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
.flex-row {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
.expect {
|
||||
.flex-row {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
|
||||
.card {
|
||||
width: $cols4;
|
||||
.card {
|
||||
width: $cols4;
|
||||
|
||||
p {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.profile {
|
||||
img {
|
||||
border-radius: 8em;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
img {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.uneven {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.keynote {
|
||||
background-color: $ui-purple;
|
||||
padding: 48px 0 64px 0;
|
||||
width: 100%;
|
||||
|
||||
h2,
|
||||
h3,
|
||||
b,
|
||||
p {
|
||||
color: $ui-white;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date {
|
||||
b {
|
||||
border-radius: 20px;
|
||||
background-color: $ui-orange;
|
||||
padding: 5px 15px;
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.card {
|
||||
margin-top: 25px;
|
||||
p {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.schedule {
|
||||
.title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
.profile {
|
||||
img {
|
||||
border-radius: 8em;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin-top: 1.2rem;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
img {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 20px 0;
|
||||
text-align: center;
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.uneven {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.keynote {
|
||||
background-color: $ui-purple;
|
||||
padding: 48px 0 64px 0;
|
||||
width: 100%;
|
||||
|
||||
h2,
|
||||
h3,
|
||||
b,
|
||||
p {
|
||||
color: $ui-white;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin: 0;
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.callout {
|
||||
display: flex;
|
||||
padding: .85rem;
|
||||
align-items: center;
|
||||
h3 {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-right: 30px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.date {
|
||||
b {
|
||||
border-radius: 20px;
|
||||
background-color: $ui-orange;
|
||||
padding: 5px 15px;
|
||||
font-size: .85rem;
|
||||
}
|
||||
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.card {
|
||||
margin-top: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
width: $cols4;
|
||||
|
||||
th {
|
||||
.schedule {
|
||||
.title {
|
||||
display: flex;
|
||||
border-bottom: thin solid $ui-border;
|
||||
padding: 2.5%;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
h3 {
|
||||
h2 {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
.callout {
|
||||
display: flex;
|
||||
padding: .85rem;
|
||||
align-items: center;
|
||||
|
||||
img {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
display: flex;
|
||||
border-bottom: thin solid $ui-border;
|
||||
padding: 2.5%;
|
||||
height: 60px;
|
||||
align-items: center;
|
||||
table {
|
||||
width: $cols4;
|
||||
|
||||
b {
|
||||
width: 30%;
|
||||
line-height: 1.7em;
|
||||
th {
|
||||
display: flex;
|
||||
border-bottom: thin solid $ui-border;
|
||||
padding: 2.5%;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
margin-right: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
width: 70%;
|
||||
td {
|
||||
display: flex;
|
||||
border-bottom: thin solid $ui-border;
|
||||
padding: 2.5%;
|
||||
height: 60px;
|
||||
align-items: center;
|
||||
|
||||
b {
|
||||
width: 30%;
|
||||
line-height: 1.7em;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
table {
|
||||
margin-top: 50px;
|
||||
width: $cols6;
|
||||
text-align: left;
|
||||
table {
|
||||
margin-top: 50px;
|
||||
width: $cols6;
|
||||
text-align: left;
|
||||
|
||||
th {
|
||||
justify-content: center;
|
||||
th {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,57 +6,56 @@
|
|||
min-height: initial;
|
||||
}
|
||||
|
||||
.title-banner {
|
||||
margin-bottom: 0;
|
||||
background-image: url("/images/conference/index/title-banner.jpg");
|
||||
padding: 48px 0;
|
||||
.index {
|
||||
.title-banner {
|
||||
margin-bottom: 0;
|
||||
background-image: url("/images/conference/index/title-banner.jpg");
|
||||
padding: 48px 0;
|
||||
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
p {
|
||||
margin: 0 auto;
|
||||
padding: 5px 0;
|
||||
text-align: center;
|
||||
color: $type-white;
|
||||
}
|
||||
h1,
|
||||
h3,
|
||||
h4,
|
||||
p {
|
||||
margin: 0 auto;
|
||||
padding: 5px 0;
|
||||
text-align: center;
|
||||
color: $type-white;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 3rem;
|
||||
p {
|
||||
margin-top: 3rem;
|
||||
|
||||
a {
|
||||
|
||||
button {
|
||||
background-color: $ui-white;
|
||||
color: $ui-blue;
|
||||
font-size: 1rem;
|
||||
a {
|
||||
|
||||
button {
|
||||
background-color: $ui-white;
|
||||
color: $ui-blue;
|
||||
font-size: 1rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $mobile - 1) {
|
||||
h3 {
|
||||
display: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: .25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $mobile - 1) {
|
||||
h3 {
|
||||
display: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: .25rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.index {
|
||||
.flex-row {
|
||||
align-items: flex-start;
|
||||
|
||||
|
|
|
@ -1,111 +1,113 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
section {
|
||||
border-bottom: 2px solid $ui-border;
|
||||
.plan {
|
||||
section {
|
||||
border-bottom: 2px solid $ui-border;
|
||||
|
||||
&.last {
|
||||
border-bottom: 0;
|
||||
&.last {
|
||||
border-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
.flex-row {
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
|
||||
&.uneven {
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
&.uneven {
|
||||
img {
|
||||
width: 30%;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||
img {
|
||||
width: 70%;
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
img {
|
||||
width: 30%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||
img {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.lodging {
|
||||
text-align: left;
|
||||
.lodging {
|
||||
text-align: left;
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.uneven {
|
||||
.short {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.transportation {
|
||||
.uneven {
|
||||
.short {
|
||||
display: none;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.explore {
|
||||
div {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
max-height: 23rem;
|
||||
flex-flow: column wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
ul {
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
div {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.faq {
|
||||
dl {
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 8px 0 32px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.short {
|
||||
margin-top: 64px;
|
||||
border: 2px solid $ui-border;
|
||||
border-radius: 4px;
|
||||
background-color: $ui-white;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.transportation {
|
||||
.uneven {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
.flex-row {
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.explore {
|
||||
div {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
max-height: 23rem;
|
||||
flex-flow: column wrap;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
ul {
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $desktop - 1) {
|
||||
div {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.faq {
|
||||
dl {
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin: 8px 0 32px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.short {
|
||||
margin-top: 64px;
|
||||
border: 2px solid $ui-border;
|
||||
border-radius: 4px;
|
||||
background-color: $ui-white;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $tablet - 1) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
281
src/views/developers/developers.jsx
Normal file
|
@ -0,0 +1,281 @@
|
|||
var React = require('react');
|
||||
var render = require('../../lib/render.jsx');
|
||||
|
||||
var Page = require('../../components/page/www/page.jsx');
|
||||
var FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
var SubNavigation = require('../../components/subnavigation/subnavigation.jsx');
|
||||
var TitleBanner = require('../../components/title-banner/title-banner.jsx');
|
||||
|
||||
require('./developers.scss');
|
||||
|
||||
var Developers = React.createClass({
|
||||
type: 'About',
|
||||
render: function () {
|
||||
return (
|
||||
<div className="developers">
|
||||
<TitleBanner className="masthead">
|
||||
<div className="inner">
|
||||
<h1>Scratch for Developers</h1>
|
||||
<p className="intro">
|
||||
On this page, you’ll find information about open source projects created and maintained{' '}
|
||||
by the <a href="https://scratch.mit.edu/info/credits">Scratch Team at MIT</a>, as well{' '}
|
||||
as our thoughts on best practices for designing learning experiences for children.
|
||||
</p>
|
||||
</div>
|
||||
<div className="band">
|
||||
<SubNavigation className="inner">
|
||||
<a href="#projects">
|
||||
<li>
|
||||
Projects
|
||||
</li>
|
||||
</a>
|
||||
<a href="#principles">
|
||||
<li>
|
||||
Principles
|
||||
</li>
|
||||
</a>
|
||||
<a href="#donate">
|
||||
<li>
|
||||
Donate
|
||||
</li>
|
||||
</a>
|
||||
<a href="#partners">
|
||||
<li>
|
||||
Partners
|
||||
</li>
|
||||
</a>
|
||||
<a href="#faq">
|
||||
<li>
|
||||
FAQ
|
||||
</li>
|
||||
</a>
|
||||
</SubNavigation>
|
||||
</div>
|
||||
</TitleBanner>
|
||||
|
||||
<div className="inner">
|
||||
<section id="projects">
|
||||
<span className="nav-spacer"></span>
|
||||
<h2>Projects</h2>
|
||||
<p className="intro">
|
||||
The following projects are open source and available for any purpose.
|
||||
</p>
|
||||
<FlexRow className="sidebar-row">
|
||||
<div className="body-copy column">
|
||||
<h3>Scratch Blocks</h3>
|
||||
<p>
|
||||
Scratch Blocks is a new development project for the next generation of{' '}
|
||||
graphical programming blocks, based on a collaboration between Google and MIT’s{' '}
|
||||
Scratch Team — building on Google’s{' '}
|
||||
<a href="https://developers.google.com/blockly/">Blockly technology</a>{' '}
|
||||
and informed by the Scratch Team’s expertise in developing creative{' '}
|
||||
learning tools for young people. Scratch Blocks will provide a framework{' '}
|
||||
for building programming blocks in both vertical (text-based) and horizontal{' '}
|
||||
(icon-based) formats. You can access the code (currently as a{' '}
|
||||
developer-preview) and documentation{' '}
|
||||
<a href="https://github.com/llk/scratch-blocks">here</a>.
|
||||
</p>
|
||||
<p>
|
||||
This first release includes code for Scratch’s Horizontal Grammar. Looking{' '}
|
||||
ahead, we plan to release additional code including but not limited to the{' '}
|
||||
Vertical Grammar (currently used by Scratch), a new Rendering Engine to support{' '}
|
||||
sprites and graphic effects, and a new Audio Engine to support creation with{' '}
|
||||
sound and music.
|
||||
</p>
|
||||
</div>
|
||||
<img className="sidebar column" src="/images/developers/block-sketch.png" alt="blocks" />
|
||||
</FlexRow>
|
||||
<FlexRow className="sidebar-row">
|
||||
<div className="body-copy column">
|
||||
<h3>Scratch WWW</h3>
|
||||
<p>
|
||||
Scratch-www is a standalone web client for the Scratch Community, built{' '}
|
||||
using React and Redux. Access the code and documentation{' '}
|
||||
<a href="https://github.com/LLK/scratch-www">here</a>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<img className="sidebar column" src="/images/developers/www-sketch.png" alt="www" />
|
||||
</FlexRow>
|
||||
</section>
|
||||
|
||||
<section id="principles">
|
||||
<span className="nav-spacer"></span>
|
||||
<h2>Principles</h2>
|
||||
<p className="intro">
|
||||
We created Scratch to empower young people to think creatively, reason systematically,{' '}
|
||||
and work collaboratively. We are guided by a set of <b>Learning Principles</b> and{' '}
|
||||
<b>Design Principles</b> that we hope you will follow as you develop new tools and{' '}
|
||||
technologies with Scratch Blocks.
|
||||
</p>
|
||||
|
||||
<FlexRow className="sidebar-row">
|
||||
<div className="body-copy column">
|
||||
<h3>Learning Principles</h3>
|
||||
<dl>
|
||||
<dt>Projects</dt>
|
||||
<dd>
|
||||
People learn best when they are actively working on projects — generating{' '}
|
||||
new ideas, designing prototypes, making improvements and creating final{' '}
|
||||
products.
|
||||
</dd>
|
||||
<dt>Passion</dt>
|
||||
<dd>
|
||||
When people focus on things they care about, they work longer and harder,{' '}
|
||||
persist in the face of challenges, and learn more in the process.
|
||||
</dd>
|
||||
<dt>Peers</dt>
|
||||
<dd>
|
||||
Learning flourishes as a social activity, with people sharing ideas,{' '}
|
||||
collaborating on projects, and building on one another's work.
|
||||
</dd>
|
||||
<dt>Play</dt>
|
||||
<dd>
|
||||
Learning involves playful experimentation — trying new things, tinkering{' '}
|
||||
with materials, testing boundaries, taking risks, iterating again and again.
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</FlexRow>
|
||||
|
||||
<FlexRow className="sidebar-row">
|
||||
<div className="body-copy column">
|
||||
<h3>Design Principles</h3>
|
||||
<dl>
|
||||
<dt>Low Floor & Wide Walls</dt>
|
||||
<dd>
|
||||
In order to encourage a varied and diverse set of interactions, we{' '}
|
||||
explicitly include elements and features that are easy for kids to{' '}
|
||||
understand (low floor), but general enough to support diverse uses (wide walls).
|
||||
</dd>
|
||||
<dt>Make it as Simple as Possible — And Maybe Even Simpler</dt>
|
||||
<dd>
|
||||
Despite the common drive to add more features to software products, we{' '}
|
||||
have found that reducing the number of features often improves the user{' '}
|
||||
experience. What initially seems like a constraint or limitation can foster{' '}
|
||||
new forms of creativity.
|
||||
</dd>
|
||||
<dt>Many Paths, Many Styles</dt>
|
||||
<dd>
|
||||
Many math and science activities have traditionally been biased towards{' '}
|
||||
specific populations. By paying special attention to creating accessible{' '}
|
||||
and appealing technologies, we are working to close the gap.
|
||||
</dd>
|
||||
<dt>Design for Tinkerability</dt>
|
||||
<dd>
|
||||
We believe that the learning process is inherently iterative. Tinkerers{' '}
|
||||
start by exploring and experimenting, then revising and refining their{' '}
|
||||
goals and creations. To support this style of interaction, we design{' '}
|
||||
our interfaces to encourage quick experimentation and rapid cycles of iteration.
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</FlexRow>
|
||||
</section>
|
||||
|
||||
<section id="donate">
|
||||
<span className="nav-spacer"></span>
|
||||
<h2>Donate</h2>
|
||||
<p>
|
||||
We are pleased to provide Scratch free of charge. If you enjoy using Scratch, please{' '}
|
||||
consider <a href="https://secure.donationpay.org/scratchfoundation/">making a donation{' '}
|
||||
to support Scratch</a>. Donations of any size are appreciated.
|
||||
</p>
|
||||
<p>
|
||||
Your donation to the Scratch Foundation will be used to support future development of{' '}
|
||||
Scratch software and the Scratch website.
|
||||
</p>
|
||||
<p>
|
||||
Thanks for supporting Scratch!
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section id="partners">
|
||||
<span className="nav-spacer"></span>
|
||||
<h3>Partners</h3>
|
||||
<p>
|
||||
The creation and maintenance of this open source code would not be possible without{' '}
|
||||
generous technical and financial support from our partners:
|
||||
</p>
|
||||
|
||||
<FlexRow className="logos">
|
||||
<img className="logo" src="/images/developers/google.png" alt="google" />
|
||||
<img className="logo" src="/images/developers/intel.png" alt="intel" />
|
||||
<img className="logo" src="/images/developers/cn.png" alt="cartoon network" />
|
||||
<img className="logo" src="/images/developers/lemann.png" alt="lemann foundation" />
|
||||
</FlexRow>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<TitleBanner className="faq-banner">
|
||||
<div className="inner">
|
||||
<section id="faq">
|
||||
<span className="nav-spacer"></span>
|
||||
<h3>FAQ</h3>
|
||||
<FlexRow className="three-col-row">
|
||||
<div className="faq column">
|
||||
<h4>Where can I learn more about Scratch?</h4>
|
||||
<p>
|
||||
Scratch is a free programming language and online community where young{' '}
|
||||
people can create their own interactive stories, games, and animations.{' '}
|
||||
Scratch is a project of the{' '}
|
||||
<a href="https://llk.media.mit.edu/">Lifelong Kindergarten</a>{' '}
|
||||
Group at the <a href="http://media.mit.edu/">MIT Media Lab</a>.{' '}
|
||||
You can learn more about Scratch{' '}
|
||||
<a href="https://scratch.mit.edu/about">here</a>.
|
||||
</p>
|
||||
</div>
|
||||
<div className="faq column">
|
||||
<h4>Are there rules to using this code in my application?</h4>
|
||||
<p>
|
||||
You may use this code in accordance with the{' '}
|
||||
<a href="http://www.apache.org/licenses/LICENSE-2.0">Apache 2.0</a> license
|
||||
which governs this project. We also strongly encourage you to consider{' '}
|
||||
the learning and design principles (above, on this page) when building{' '}
|
||||
creative learning experiences for kids of all ages.
|
||||
</p>
|
||||
</div>
|
||||
<div className="faq column">
|
||||
<h4>
|
||||
Am I allowed to use the name "Scratch Blocks" in the description of my{' '}
|
||||
app and other public messaging?
|
||||
</h4>
|
||||
<p>
|
||||
If you wish, you can publicly state that your application is powered by{' '}
|
||||
Scratch Blocks. If you do so, we would also encourage you to link back to{' '}
|
||||
code repository.
|
||||
</p>
|
||||
</div>
|
||||
<div className="faq column">
|
||||
<h4>Are you releasing more code and when?</h4>
|
||||
<p>
|
||||
We plan to open source additional code relating to the Scratch programming{' '}
|
||||
language over the next few months. Keep an eye on this page!
|
||||
</p>
|
||||
</div>
|
||||
<div className="faq column">
|
||||
<h4>What’s the difference between Blockly and Scratch Blocks?</h4>
|
||||
<p>
|
||||
Scratch Blocks builds upon the Blockly code base, and is specifically{' '}
|
||||
designed with our principles in mind to support creative learning experiences.
|
||||
</p>
|
||||
</div>
|
||||
<div className="faq column">
|
||||
<h4>I’d like to collaborate. How do I get in touch?</h4>
|
||||
<p>
|
||||
You can reach us over on <a href="https://github.com/LLK/">github</a> or{' '}
|
||||
you can send an email to{' '}
|
||||
<a href="mailto:help@scratch.mit.edu">help@scratch.mit.edu.</a>{' '}
|
||||
We look forward to hearing from you!
|
||||
</p>
|
||||
</div>
|
||||
</FlexRow>
|
||||
</section>
|
||||
</div>
|
||||
</TitleBanner>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
render(<Page><Developers /></Page>, document.getElementById('app'));
|
246
src/views/developers/developers.scss
Normal file
|
@ -0,0 +1,246 @@
|
|||
@import "../../colors";
|
||||
@import "../../frameless";
|
||||
|
||||
$developer-spot: $ui-aqua;
|
||||
|
||||
#view {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.developers {
|
||||
.title-banner {
|
||||
&.masthead {
|
||||
background-color: $developer-spot;
|
||||
padding-bottom: 0;
|
||||
|
||||
h1 {
|
||||
margin: 0 0 2rem 0;
|
||||
text-align: left;
|
||||
color: $ui-white;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0;
|
||||
width: $cols6;
|
||||
text-align: left;
|
||||
color: $ui-white;
|
||||
|
||||
a {
|
||||
border-bottom: 1px solid $ui-white;
|
||||
color: $ui-white;
|
||||
}
|
||||
}
|
||||
|
||||
.band {
|
||||
$band-color: hsla(360, 100, 100, .15);
|
||||
|
||||
margin-top: 2rem;
|
||||
background-color: $band-color;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
.sub-nav {
|
||||
text-align: left;
|
||||
justify-content: flex-start;
|
||||
|
||||
li {
|
||||
margin: 0 .5rem 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.faq-banner {
|
||||
margin-bottom: 0;
|
||||
background-color: $ui-gray;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.flex-row {
|
||||
&.sidebar-row {
|
||||
margin: 2rem 0;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
.body-copy {
|
||||
width: $cols8;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
width: $cols3;
|
||||
}
|
||||
}
|
||||
|
||||
&.three-col-row {
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.column {
|
||||
$column-margin: 1rem;
|
||||
|
||||
margin: $column-margin;
|
||||
width: calc(#{$cols4} - (#{$column-margin} * 2));
|
||||
|
||||
p {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
margin-bottom: 3rem;
|
||||
|
||||
p {
|
||||
max-width: $cols8;
|
||||
}
|
||||
}
|
||||
|
||||
#projects,
|
||||
#principles,
|
||||
#donate,
|
||||
#partners,
|
||||
#faq {
|
||||
.nav-spacer {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
margin-top: -50px; // height of nav bar
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
#projects,
|
||||
#principles,
|
||||
#donate {
|
||||
|
||||
h3 {
|
||||
border-bottom: 1px solid $ui-border;
|
||||
}
|
||||
|
||||
dl {
|
||||
dt {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-bottom: 1.25rem;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#donate {
|
||||
border-bottom: 1px solid $ui-border;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
#partners {
|
||||
text-align: center;
|
||||
|
||||
p {
|
||||
margin: 0 auto;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.logos {
|
||||
justify-content: center;
|
||||
|
||||
.logo {
|
||||
margin: 10px;
|
||||
width: $cols2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#faq {
|
||||
border-bottom: 1px solid $ui-border;
|
||||
padding-bottom: 2rem;
|
||||
|
||||
h3 {
|
||||
margin-bottom: 2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p {
|
||||
color: $type-gray;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//4 columns
|
||||
@media only screen and (max-width: $mobile - 1) {
|
||||
#view {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.title-banner {
|
||||
&.masthead {
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
.band {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
&.sidebar-row {
|
||||
|
||||
.body-copy {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//6 columns
|
||||
@media only screen and (min-width: $mobile) and (max-width: $tablet - 1) {
|
||||
#view {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
&.sidebar-row {
|
||||
|
||||
.body-copy {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//8 columns
|
||||
@media only screen and (min-width: $tablet) and (max-width: $desktop - 1) {
|
||||
#view {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
&.sidebar-row {
|
||||
|
||||
.body-copy {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
section {
|
||||
p {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
1
src/views/developers/l10n.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
192
src/views/privacypolicy/privacypolicy.jsx
Normal file
|
@ -0,0 +1,192 @@
|
|||
var React = require('react');
|
||||
var render = require('../../lib/render.jsx');
|
||||
var Page = require('../../components/page/www/page.jsx');
|
||||
var Box = require('../../components/box/box.jsx');
|
||||
|
||||
var Privacypolicy = React.createClass({
|
||||
type: 'Privacypolicy',
|
||||
render: function () {
|
||||
return (
|
||||
<div className="inner privacypolicy">
|
||||
<Box title={'Scratch Privacy Policy'}>
|
||||
<p>
|
||||
We made Scratch so people like you could create projects,
|
||||
share ideas, and build a community. To make this happen,
|
||||
we collect some information for our users. The Scratch Team
|
||||
understands how important privacy is to our community,
|
||||
especially kids and parents. We wrote this privacy policy
|
||||
to explain what information we collect, how we use it,
|
||||
and what we're doing to keep it safe. If you have any
|
||||
questions regarding this privacy policy, you can{' '}
|
||||
<a href="/contact-us">contact us</a>.
|
||||
</p>
|
||||
<p><i>
|
||||
Please do not share personal contact information, such as
|
||||
your name, physical address, email address, phone number,
|
||||
or anything else that can be used to make contact outside
|
||||
of the Scratch website. Please report projects, comments,
|
||||
or forum posts that contain this kind of information so
|
||||
the Scratch team can remove it, and please remind the
|
||||
author of our policy.
|
||||
</i></p>
|
||||
<h3>What information does the Scratch Team collect about me?</h3>
|
||||
<p>
|
||||
<b>Account Information: </b>
|
||||
In order to build projects or comment on other users' projects,
|
||||
you need to make an account. During account creation, we ask you
|
||||
for a username, your country, birth month and year, gender, and
|
||||
your email address (or your parent or guardian's email address if
|
||||
you are under 13 years old). We ask that you select a user name
|
||||
that does not disclose your real name or other information that
|
||||
could identify you. Other users can see your username and country,
|
||||
but not your age, gender, or email address.
|
||||
</p>
|
||||
<p>
|
||||
<b>User-generated Content: </b>
|
||||
All of your Scratch projects, comments, and forum posts are stored
|
||||
on the Scratch servers. Other users can see your shared projects,
|
||||
comments, and forum posts, along with your username. Because the
|
||||
Scratch Team is responsible for moderation, we have access to all
|
||||
content stored on the Scratch website, including unshared projects.
|
||||
If you prefer to work on projects in complete privacy, you can use
|
||||
either the <a href="/scratch2download">Scratch 2 offline editor</a>{' '}
|
||||
or <a href="/scratch_1.4">Scratch 1.4</a>.
|
||||
</p>
|
||||
<p>
|
||||
<b>Usage Information: </b>
|
||||
When you use Scratch, our servers will automatically store a limited
|
||||
amount of information about how you use the website. This information
|
||||
includes a number that identifies your computer (the IP address), which
|
||||
pages you visited, and what browser you are using.
|
||||
</p>
|
||||
<p>
|
||||
<b>Google Analytics: </b>
|
||||
We also collect some data on where you click and which parts of the
|
||||
site you visit using Google Analytics. This "click data" helps us figure
|
||||
out ways to improve the website. Information collected and processed by
|
||||
Google Analytics includes the user's IP address, network location, and
|
||||
geographic location. Google Analytics acquires all its information
|
||||
directly from the user, by installing a cookie (see below) on your
|
||||
computer, if you have enabled JavaScript. Scratch does not share any
|
||||
information it collects with Google, and Google does not collect any
|
||||
personal identifying information about you.
|
||||
</p>
|
||||
<p>
|
||||
<b>Cookies: </b>
|
||||
When you log in, the Scratch website asks your browser to put an http
|
||||
"cookie" on your computer. The cookie is actually a small text file
|
||||
that our site can send to your browser for storage on your computer.
|
||||
This allows the website to remember that you are logged in when you
|
||||
go to a different page.
|
||||
</p>
|
||||
<h3>How does the Scratch Team use my information?</h3>
|
||||
<ul>
|
||||
<li>
|
||||
We collect age and gender data so that we know who is using our
|
||||
website.
|
||||
</li>
|
||||
<li>
|
||||
If you forget your password, we will ask you to disclose to us
|
||||
your birth month and year so that we can verify your account, and
|
||||
your email address so that we can send you a new password.
|
||||
</li>
|
||||
<li>
|
||||
We will use your email address to respond to messages you send us
|
||||
or to communicate with you about the Scratch service or your account.
|
||||
</li>
|
||||
<li>
|
||||
We send out occasional email updates about Scratch to the confirmed
|
||||
email address on your account. Scratch will never sell or share your
|
||||
email address without your permission. You can unsubscribe from these
|
||||
updates by clicking the unsubscribe link found at the bottom of the
|
||||
email.
|
||||
</li>
|
||||
<li>
|
||||
Parents and guardians who register their under-13 year olds for
|
||||
Scratch may also receive additional updates from the{' '}
|
||||
<a href="http://www.codetolearn.org/">Scratch Foundation</a>,
|
||||
a non-profit that supports Scratch educational initiatives.
|
||||
The Scratch Foundation will never sell or share your email
|
||||
address without your permission. You can unsubscribe from these
|
||||
updates by clicking the unsubscribe link found at the bottom of
|
||||
the email.
|
||||
</li>
|
||||
<li>
|
||||
If we detect repeated abusive behavior from your account, IP address,
|
||||
or email address, we may share your account name, IP address, and the
|
||||
time and content of the abusive behavior with the IP address owner
|
||||
(such as a school or internet service provided).
|
||||
</li>
|
||||
<li>
|
||||
We may use de-identified location, age, gender, and usage data
|
||||
in research studies intended to improve our understanding of
|
||||
how people learn with Scratch. The results of this research are
|
||||
shared with educators and researchers through conferences,
|
||||
journals, and other publications. You can find out more on our{' '}
|
||||
<a href="/info/research">Research page</a>.
|
||||
</li>
|
||||
<li>
|
||||
We may disclose some of the information we collect to third-party
|
||||
service providers that help us manage communications to and from
|
||||
the Scratch website and improve website performance. We are
|
||||
satisfied that these service providers have privacy policies that
|
||||
restrict them from further disclosing any of your information.
|
||||
</li>
|
||||
<li>
|
||||
Other than as described above, we will never share personally
|
||||
identifiable information about you with any other person,
|
||||
company, or organization, except:
|
||||
<ul>
|
||||
<li>
|
||||
As required to comply with our obligations under the law.
|
||||
</li>
|
||||
<li>
|
||||
For technical reasons, if we are required to transfer the
|
||||
data on our servers to another location or organization.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3>How can I update my personal information?</h3>
|
||||
<p>
|
||||
You can update your password, email address, and country through
|
||||
the <a href="/account/password_change">Account Settings</a> page.
|
||||
You can also reset your password through the{' '}
|
||||
<a href="/account/password_reset">Account Reset</a>{' '}
|
||||
page. You cannot change your username, but you can make a new
|
||||
account and manually copy your projects to the new account.
|
||||
</p>
|
||||
<p>
|
||||
If you want to delete your account entirely, log in to Scratch,
|
||||
and then click your username in the top right-hand corner. Select
|
||||
"Account Settings," then click the "I want to delete my account"
|
||||
link at the bottom of the page.
|
||||
</p>
|
||||
<h3>How does the Scratch Team protect my information?</h3>
|
||||
<p>
|
||||
The Scratch Team has in place physical and electronic procedures
|
||||
to protect the information we collect on the Scratch website. We
|
||||
strictly limit individual access to the Scratch servers and the
|
||||
data we store on them. However, as effective as these measures
|
||||
are, no security system is impenetrable. We cannot completely
|
||||
guarantee the security of our database, nor can we guarantee that
|
||||
the information you supply will not be intercepted while being
|
||||
transmitted to us over the Internet.
|
||||
</p>
|
||||
<h3>Notifications of Changes to the Privacy Policy</h3>
|
||||
<p>
|
||||
We review our security measures and Privacy Policy on a periodic
|
||||
basis, and we may modify our policies as appropriate. We may also
|
||||
change or update our Privacy Policy if we add new services or
|
||||
features. If we make any changes to our privacy practices, we will
|
||||
amend this Privacy Policy accordingly and post the amended policy
|
||||
on the Scratch website. We encourage you to review our Privacy
|
||||
Policy on a regular basis.
|
||||
</p>
|
||||
</Box>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
render(<Page><Privacypolicy /></Page>, document.getElementById('app'));
|
|
@ -4,7 +4,7 @@ var omit = require('lodash.omit');
|
|||
var React = require('react');
|
||||
var render = require('../../lib/render.jsx');
|
||||
|
||||
var authActions = require('../../redux/auth.js');
|
||||
var authActions = require('../../redux/actions.js');
|
||||
|
||||
var Api = require('../../mixins/api.jsx');
|
||||
|
||||
|
|
BIN
static/images/developers/block-sketch.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
static/images/developers/cn.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
static/images/developers/google.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
static/images/developers/intel.png
Normal file
After Width: | Height: | Size: 6.2 KiB |
BIN
static/images/developers/lemann.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
static/images/developers/logo_sm.png
Normal file
After Width: | Height: | Size: 7.2 KiB |
BIN
static/images/developers/www-sketch.png
Normal file
After Width: | Height: | Size: 8.7 KiB |
3
static/js/lib/raven.min.js
vendored
42
static/js/lib/react-dom.js
vendored
|
@ -1,42 +0,0 @@
|
|||
/**
|
||||
* ReactDOM v0.14.0
|
||||
*
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
// Based off https://github.com/ForbesLindesay/umd/blob/master/template.js
|
||||
;(function(f) {
|
||||
// CommonJS
|
||||
if (typeof exports === "object" && typeof module !== "undefined") {
|
||||
module.exports = f(require('react'));
|
||||
|
||||
// RequireJS
|
||||
} else if (typeof define === "function" && define.amd) {
|
||||
define(['react'], f);
|
||||
|
||||
// <script>
|
||||
} else {
|
||||
var g
|
||||
if (typeof window !== "undefined") {
|
||||
g = window;
|
||||
} else if (typeof global !== "undefined") {
|
||||
g = global;
|
||||
} else if (typeof self !== "undefined") {
|
||||
g = self;
|
||||
} else {
|
||||
// works providing we're not in "use strict";
|
||||
// needed for Java 8 Nashorn
|
||||
// see https://github.com/facebook/react/issues/3037
|
||||
g = this;
|
||||
}
|
||||
g.ReactDOM = f(g.React);
|
||||
}
|
||||
|
||||
})(function(React) {
|
||||
return React.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
});
|
12
static/js/lib/react-dom.min.js
vendored
|
@ -1,12 +0,0 @@
|
|||
/**
|
||||
* ReactDOM v0.14.0
|
||||
*
|
||||
* Copyright 2013-2015, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e(require("react"));else if("function"==typeof define&&define.amd)define(["react"],e);else{var f;f="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,f.ReactDOM=e(f.React)}}(function(e){return e.__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED});
|
4242
static/js/lib/react-intl-with-locales.js
vendored
11
static/js/lib/react-intl-with-locales.min.js
vendored
20707
static/js/lib/react.js
vendored
16
static/js/lib/react.min.js
vendored
|
@ -1,775 +0,0 @@
|
|||
(function webpackUniversalModuleDefinition(root, factory) {
|
||||
if(typeof exports === 'object' && typeof module === 'object')
|
||||
module.exports = factory();
|
||||
else if(typeof define === 'function' && define.amd)
|
||||
define([], factory);
|
||||
else if(typeof exports === 'object')
|
||||
exports["Redux"] = factory();
|
||||
else
|
||||
root["Redux"] = factory();
|
||||
})(this, function() {
|
||||
return /******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId])
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ exports: {},
|
||||
/******/ id: moduleId,
|
||||
/******/ loaded: false
|
||||
/******/ };
|
||||
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.loaded = true;
|
||||
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
|
||||
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.compose = exports.applyMiddleware = exports.bindActionCreators = exports.combineReducers = exports.createStore = undefined;
|
||||
|
||||
var _createStore = __webpack_require__(2);
|
||||
|
||||
var _createStore2 = _interopRequireDefault(_createStore);
|
||||
|
||||
var _combineReducers = __webpack_require__(7);
|
||||
|
||||
var _combineReducers2 = _interopRequireDefault(_combineReducers);
|
||||
|
||||
var _bindActionCreators = __webpack_require__(6);
|
||||
|
||||
var _bindActionCreators2 = _interopRequireDefault(_bindActionCreators);
|
||||
|
||||
var _applyMiddleware = __webpack_require__(5);
|
||||
|
||||
var _applyMiddleware2 = _interopRequireDefault(_applyMiddleware);
|
||||
|
||||
var _compose = __webpack_require__(1);
|
||||
|
||||
var _compose2 = _interopRequireDefault(_compose);
|
||||
|
||||
var _warning = __webpack_require__(3);
|
||||
|
||||
var _warning2 = _interopRequireDefault(_warning);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
/*
|
||||
* This is a dummy function to check if the function name has been altered by minification.
|
||||
* If the function has been minified and NODE_ENV !== 'production', warn the user.
|
||||
*/
|
||||
function isCrushed() {}
|
||||
|
||||
if (("development") !== 'production' && typeof isCrushed.name === 'string' && isCrushed.name !== 'isCrushed') {
|
||||
(0, _warning2["default"])('You are currently using minified code outside of NODE_ENV === \'production\'. ' + 'This means that you are running a slower development build of Redux. ' + 'You can use loose-envify (https://github.com/zertosh/loose-envify) for browserify ' + 'or DefinePlugin for webpack (http://stackoverflow.com/questions/30030031) ' + 'to ensure you have the correct code for your production build.');
|
||||
}
|
||||
|
||||
exports.createStore = _createStore2["default"];
|
||||
exports.combineReducers = _combineReducers2["default"];
|
||||
exports.bindActionCreators = _bindActionCreators2["default"];
|
||||
exports.applyMiddleware = _applyMiddleware2["default"];
|
||||
exports.compose = _compose2["default"];
|
||||
|
||||
/***/ },
|
||||
/* 1 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
"use strict";
|
||||
|
||||
exports.__esModule = true;
|
||||
exports["default"] = compose;
|
||||
/**
|
||||
* Composes single-argument functions from right to left.
|
||||
*
|
||||
* @param {...Function} funcs The functions to compose.
|
||||
* @returns {Function} A function obtained by composing functions from right to
|
||||
* left. For example, compose(f, g, h) is identical to arg => f(g(h(arg))).
|
||||
*/
|
||||
function compose() {
|
||||
for (var _len = arguments.length, funcs = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
funcs[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return function () {
|
||||
if (funcs.length === 0) {
|
||||
return arguments.length <= 0 ? undefined : arguments[0];
|
||||
}
|
||||
|
||||
var last = funcs[funcs.length - 1];
|
||||
var rest = funcs.slice(0, -1);
|
||||
|
||||
return rest.reduceRight(function (composed, f) {
|
||||
return f(composed);
|
||||
}, last.apply(undefined, arguments));
|
||||
};
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 2 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports.ActionTypes = undefined;
|
||||
exports["default"] = createStore;
|
||||
|
||||
var _isPlainObject = __webpack_require__(4);
|
||||
|
||||
var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
/**
|
||||
* These are private action types reserved by Redux.
|
||||
* For any unknown actions, you must return the current state.
|
||||
* If the current state is undefined, you must return the initial state.
|
||||
* Do not reference these action types directly in your code.
|
||||
*/
|
||||
var ActionTypes = exports.ActionTypes = {
|
||||
INIT: '@@redux/INIT'
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a Redux store that holds the state tree.
|
||||
* The only way to change the data in the store is to call `dispatch()` on it.
|
||||
*
|
||||
* There should only be a single store in your app. To specify how different
|
||||
* parts of the state tree respond to actions, you may combine several reducers
|
||||
* into a single reducer function by using `combineReducers`.
|
||||
*
|
||||
* @param {Function} reducer A function that returns the next state tree, given
|
||||
* the current state tree and the action to handle.
|
||||
*
|
||||
* @param {any} [initialState] The initial state. You may optionally specify it
|
||||
* to hydrate the state from the server in universal apps, or to restore a
|
||||
* previously serialized user session.
|
||||
* If you use `combineReducers` to produce the root reducer function, this must be
|
||||
* an object with the same shape as `combineReducers` keys.
|
||||
*
|
||||
* @param {Function} enhancer The store enhancer. You may optionally specify it
|
||||
* to enhance the store with third-party capabilities such as middleware,
|
||||
* time travel, persistence, etc. The only store enhancer that ships with Redux
|
||||
* is `applyMiddleware()`.
|
||||
*
|
||||
* @returns {Store} A Redux store that lets you read the state, dispatch actions
|
||||
* and subscribe to changes.
|
||||
*/
|
||||
function createStore(reducer, initialState, enhancer) {
|
||||
if (typeof initialState === 'function' && typeof enhancer === 'undefined') {
|
||||
enhancer = initialState;
|
||||
initialState = undefined;
|
||||
}
|
||||
|
||||
if (typeof enhancer !== 'undefined') {
|
||||
if (typeof enhancer !== 'function') {
|
||||
throw new Error('Expected the enhancer to be a function.');
|
||||
}
|
||||
|
||||
return enhancer(createStore)(reducer, initialState);
|
||||
}
|
||||
|
||||
if (typeof reducer !== 'function') {
|
||||
throw new Error('Expected the reducer to be a function.');
|
||||
}
|
||||
|
||||
var currentReducer = reducer;
|
||||
var currentState = initialState;
|
||||
var currentListeners = [];
|
||||
var nextListeners = currentListeners;
|
||||
var isDispatching = false;
|
||||
|
||||
function ensureCanMutateNextListeners() {
|
||||
if (nextListeners === currentListeners) {
|
||||
nextListeners = currentListeners.slice();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the state tree managed by the store.
|
||||
*
|
||||
* @returns {any} The current state tree of your application.
|
||||
*/
|
||||
function getState() {
|
||||
return currentState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a change listener. It will be called any time an action is dispatched,
|
||||
* and some part of the state tree may potentially have changed. You may then
|
||||
* call `getState()` to read the current state tree inside the callback.
|
||||
*
|
||||
* You may call `dispatch()` from a change listener, with the following
|
||||
* caveats:
|
||||
*
|
||||
* 1. The subscriptions are snapshotted just before every `dispatch()` call.
|
||||
* If you subscribe or unsubscribe while the listeners are being invoked, this
|
||||
* will not have any effect on the `dispatch()` that is currently in progress.
|
||||
* However, the next `dispatch()` call, whether nested or not, will use a more
|
||||
* recent snapshot of the subscription list.
|
||||
*
|
||||
* 2. The listener should not expect to see all states changes, as the state
|
||||
* might have been updated multiple times during a nested `dispatch()` before
|
||||
* the listener is called. It is, however, guaranteed that all subscribers
|
||||
* registered before the `dispatch()` started will be called with the latest
|
||||
* state by the time it exits.
|
||||
*
|
||||
* @param {Function} listener A callback to be invoked on every dispatch.
|
||||
* @returns {Function} A function to remove this change listener.
|
||||
*/
|
||||
function subscribe(listener) {
|
||||
if (typeof listener !== 'function') {
|
||||
throw new Error('Expected listener to be a function.');
|
||||
}
|
||||
|
||||
var isSubscribed = true;
|
||||
|
||||
ensureCanMutateNextListeners();
|
||||
nextListeners.push(listener);
|
||||
|
||||
return function unsubscribe() {
|
||||
if (!isSubscribed) {
|
||||
return;
|
||||
}
|
||||
|
||||
isSubscribed = false;
|
||||
|
||||
ensureCanMutateNextListeners();
|
||||
var index = nextListeners.indexOf(listener);
|
||||
nextListeners.splice(index, 1);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an action. It is the only way to trigger a state change.
|
||||
*
|
||||
* The `reducer` function, used to create the store, will be called with the
|
||||
* current state tree and the given `action`. Its return value will
|
||||
* be considered the **next** state of the tree, and the change listeners
|
||||
* will be notified.
|
||||
*
|
||||
* The base implementation only supports plain object actions. If you want to
|
||||
* dispatch a Promise, an Observable, a thunk, or something else, you need to
|
||||
* wrap your store creating function into the corresponding middleware. For
|
||||
* example, see the documentation for the `redux-thunk` package. Even the
|
||||
* middleware will eventually dispatch plain object actions using this method.
|
||||
*
|
||||
* @param {Object} action A plain object representing “what changed”. It is
|
||||
* a good idea to keep actions serializable so you can record and replay user
|
||||
* sessions, or use the time travelling `redux-devtools`. An action must have
|
||||
* a `type` property which may not be `undefined`. It is a good idea to use
|
||||
* string constants for action types.
|
||||
*
|
||||
* @returns {Object} For convenience, the same action object you dispatched.
|
||||
*
|
||||
* Note that, if you use a custom middleware, it may wrap `dispatch()` to
|
||||
* return something else (for example, a Promise you can await).
|
||||
*/
|
||||
function dispatch(action) {
|
||||
if (!(0, _isPlainObject2["default"])(action)) {
|
||||
throw new Error('Actions must be plain objects. ' + 'Use custom middleware for async actions.');
|
||||
}
|
||||
|
||||
if (typeof action.type === 'undefined') {
|
||||
throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
|
||||
}
|
||||
|
||||
if (isDispatching) {
|
||||
throw new Error('Reducers may not dispatch actions.');
|
||||
}
|
||||
|
||||
try {
|
||||
isDispatching = true;
|
||||
currentState = currentReducer(currentState, action);
|
||||
} finally {
|
||||
isDispatching = false;
|
||||
}
|
||||
|
||||
var listeners = currentListeners = nextListeners;
|
||||
for (var i = 0; i < listeners.length; i++) {
|
||||
listeners[i]();
|
||||
}
|
||||
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the reducer currently used by the store to calculate the state.
|
||||
*
|
||||
* You might need this if your app implements code splitting and you want to
|
||||
* load some of the reducers dynamically. You might also need this if you
|
||||
* implement a hot reloading mechanism for Redux.
|
||||
*
|
||||
* @param {Function} nextReducer The reducer for the store to use instead.
|
||||
* @returns {void}
|
||||
*/
|
||||
function replaceReducer(nextReducer) {
|
||||
if (typeof nextReducer !== 'function') {
|
||||
throw new Error('Expected the nextReducer to be a function.');
|
||||
}
|
||||
|
||||
currentReducer = nextReducer;
|
||||
dispatch({ type: ActionTypes.INIT });
|
||||
}
|
||||
|
||||
// When a store is created, an "INIT" action is dispatched so that every
|
||||
// reducer returns their initial state. This effectively populates
|
||||
// the initial state tree.
|
||||
dispatch({ type: ActionTypes.INIT });
|
||||
|
||||
return {
|
||||
dispatch: dispatch,
|
||||
subscribe: subscribe,
|
||||
getState: getState,
|
||||
replaceReducer: replaceReducer
|
||||
};
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 3 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports["default"] = warning;
|
||||
/**
|
||||
* Prints a warning in the console if it exists.
|
||||
*
|
||||
* @param {String} message The warning message.
|
||||
* @returns {void}
|
||||
*/
|
||||
function warning(message) {
|
||||
/* eslint-disable no-console */
|
||||
if (typeof console !== 'undefined' && typeof console.error === 'function') {
|
||||
console.error(message);
|
||||
}
|
||||
/* eslint-enable no-console */
|
||||
try {
|
||||
// This error was thrown as a convenience so that you can use this stack
|
||||
// to find the callsite that caused this warning to fire.
|
||||
throw new Error(message);
|
||||
/* eslint-disable no-empty */
|
||||
} catch (e) {}
|
||||
/* eslint-enable no-empty */
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 4 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
var isHostObject = __webpack_require__(8),
|
||||
isObjectLike = __webpack_require__(9);
|
||||
|
||||
/** `Object#toString` result references. */
|
||||
var objectTag = '[object Object]';
|
||||
|
||||
/** Used for built-in method references. */
|
||||
var objectProto = Object.prototype;
|
||||
|
||||
/** Used to resolve the decompiled source of functions. */
|
||||
var funcToString = Function.prototype.toString;
|
||||
|
||||
/** Used to infer the `Object` constructor. */
|
||||
var objectCtorString = funcToString.call(Object);
|
||||
|
||||
/**
|
||||
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
|
||||
* of values.
|
||||
*/
|
||||
var objectToString = objectProto.toString;
|
||||
|
||||
/** Built-in value references. */
|
||||
var getPrototypeOf = Object.getPrototypeOf;
|
||||
|
||||
/**
|
||||
* Checks if `value` is a plain object, that is, an object created by the
|
||||
* `Object` constructor or one with a `[[Prototype]]` of `null`.
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Lang
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
|
||||
* @example
|
||||
*
|
||||
* function Foo() {
|
||||
* this.a = 1;
|
||||
* }
|
||||
*
|
||||
* _.isPlainObject(new Foo);
|
||||
* // => false
|
||||
*
|
||||
* _.isPlainObject([1, 2, 3]);
|
||||
* // => false
|
||||
*
|
||||
* _.isPlainObject({ 'x': 0, 'y': 0 });
|
||||
* // => true
|
||||
*
|
||||
* _.isPlainObject(Object.create(null));
|
||||
* // => true
|
||||
*/
|
||||
function isPlainObject(value) {
|
||||
if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
|
||||
return false;
|
||||
}
|
||||
var proto = objectProto;
|
||||
if (typeof value.constructor == 'function') {
|
||||
proto = getPrototypeOf(value);
|
||||
}
|
||||
if (proto === null) {
|
||||
return true;
|
||||
}
|
||||
var Ctor = proto.constructor;
|
||||
return (typeof Ctor == 'function' &&
|
||||
Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString);
|
||||
}
|
||||
|
||||
module.exports = isPlainObject;
|
||||
|
||||
|
||||
/***/ },
|
||||
/* 5 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
|
||||
|
||||
exports.__esModule = true;
|
||||
exports["default"] = applyMiddleware;
|
||||
|
||||
var _compose = __webpack_require__(1);
|
||||
|
||||
var _compose2 = _interopRequireDefault(_compose);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
/**
|
||||
* Creates a store enhancer that applies middleware to the dispatch method
|
||||
* of the Redux store. This is handy for a variety of tasks, such as expressing
|
||||
* asynchronous actions in a concise manner, or logging every action payload.
|
||||
*
|
||||
* See `redux-thunk` package as an example of the Redux middleware.
|
||||
*
|
||||
* Because middleware is potentially asynchronous, this should be the first
|
||||
* store enhancer in the composition chain.
|
||||
*
|
||||
* Note that each middleware will be given the `dispatch` and `getState` functions
|
||||
* as named arguments.
|
||||
*
|
||||
* @param {...Function} middlewares The middleware chain to be applied.
|
||||
* @returns {Function} A store enhancer applying the middleware.
|
||||
*/
|
||||
function applyMiddleware() {
|
||||
for (var _len = arguments.length, middlewares = Array(_len), _key = 0; _key < _len; _key++) {
|
||||
middlewares[_key] = arguments[_key];
|
||||
}
|
||||
|
||||
return function (createStore) {
|
||||
return function (reducer, initialState, enhancer) {
|
||||
var store = createStore(reducer, initialState, enhancer);
|
||||
var _dispatch = store.dispatch;
|
||||
var chain = [];
|
||||
|
||||
var middlewareAPI = {
|
||||
getState: store.getState,
|
||||
dispatch: function dispatch(action) {
|
||||
return _dispatch(action);
|
||||
}
|
||||
};
|
||||
chain = middlewares.map(function (middleware) {
|
||||
return middleware(middlewareAPI);
|
||||
});
|
||||
_dispatch = _compose2["default"].apply(undefined, chain)(store.dispatch);
|
||||
|
||||
return _extends({}, store, {
|
||||
dispatch: _dispatch
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 6 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports["default"] = bindActionCreators;
|
||||
function bindActionCreator(actionCreator, dispatch) {
|
||||
return function () {
|
||||
return dispatch(actionCreator.apply(undefined, arguments));
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an object whose values are action creators, into an object with the
|
||||
* same keys, but with every function wrapped into a `dispatch` call so they
|
||||
* may be invoked directly. This is just a convenience method, as you can call
|
||||
* `store.dispatch(MyActionCreators.doSomething())` yourself just fine.
|
||||
*
|
||||
* For convenience, you can also pass a single function as the first argument,
|
||||
* and get a function in return.
|
||||
*
|
||||
* @param {Function|Object} actionCreators An object whose values are action
|
||||
* creator functions. One handy way to obtain it is to use ES6 `import * as`
|
||||
* syntax. You may also pass a single function.
|
||||
*
|
||||
* @param {Function} dispatch The `dispatch` function available on your Redux
|
||||
* store.
|
||||
*
|
||||
* @returns {Function|Object} The object mimicking the original object, but with
|
||||
* every action creator wrapped into the `dispatch` call. If you passed a
|
||||
* function as `actionCreators`, the return value will also be a single
|
||||
* function.
|
||||
*/
|
||||
function bindActionCreators(actionCreators, dispatch) {
|
||||
if (typeof actionCreators === 'function') {
|
||||
return bindActionCreator(actionCreators, dispatch);
|
||||
}
|
||||
|
||||
if (typeof actionCreators !== 'object' || actionCreators === null) {
|
||||
throw new Error('bindActionCreators expected an object or a function, instead received ' + (actionCreators === null ? 'null' : typeof actionCreators) + '. ' + 'Did you write "import ActionCreators from" instead of "import * as ActionCreators from"?');
|
||||
}
|
||||
|
||||
var keys = Object.keys(actionCreators);
|
||||
var boundActionCreators = {};
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var actionCreator = actionCreators[key];
|
||||
if (typeof actionCreator === 'function') {
|
||||
boundActionCreators[key] = bindActionCreator(actionCreator, dispatch);
|
||||
}
|
||||
}
|
||||
return boundActionCreators;
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 7 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
exports.__esModule = true;
|
||||
exports["default"] = combineReducers;
|
||||
|
||||
var _createStore = __webpack_require__(2);
|
||||
|
||||
var _isPlainObject = __webpack_require__(4);
|
||||
|
||||
var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
|
||||
|
||||
var _warning = __webpack_require__(3);
|
||||
|
||||
var _warning2 = _interopRequireDefault(_warning);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
||||
|
||||
function getUndefinedStateErrorMessage(key, action) {
|
||||
var actionType = action && action.type;
|
||||
var actionName = actionType && '"' + actionType.toString() + '"' || 'an action';
|
||||
|
||||
return 'Reducer "' + key + '" returned undefined handling ' + actionName + '. ' + 'To ignore an action, you must explicitly return the previous state.';
|
||||
}
|
||||
|
||||
function getUnexpectedStateShapeWarningMessage(inputState, reducers, action) {
|
||||
var reducerKeys = Object.keys(reducers);
|
||||
var argumentName = action && action.type === _createStore.ActionTypes.INIT ? 'initialState argument passed to createStore' : 'previous state received by the reducer';
|
||||
|
||||
if (reducerKeys.length === 0) {
|
||||
return 'Store does not have a valid reducer. Make sure the argument passed ' + 'to combineReducers is an object whose values are reducers.';
|
||||
}
|
||||
|
||||
if (!(0, _isPlainObject2["default"])(inputState)) {
|
||||
return 'The ' + argumentName + ' has unexpected type of "' + {}.toString.call(inputState).match(/\s([a-z|A-Z]+)/)[1] + '". Expected argument to be an object with the following ' + ('keys: "' + reducerKeys.join('", "') + '"');
|
||||
}
|
||||
|
||||
var unexpectedKeys = Object.keys(inputState).filter(function (key) {
|
||||
return !reducers.hasOwnProperty(key);
|
||||
});
|
||||
|
||||
if (unexpectedKeys.length > 0) {
|
||||
return 'Unexpected ' + (unexpectedKeys.length > 1 ? 'keys' : 'key') + ' ' + ('"' + unexpectedKeys.join('", "') + '" found in ' + argumentName + '. ') + 'Expected to find one of the known reducer keys instead: ' + ('"' + reducerKeys.join('", "') + '". Unexpected keys will be ignored.');
|
||||
}
|
||||
}
|
||||
|
||||
function assertReducerSanity(reducers) {
|
||||
Object.keys(reducers).forEach(function (key) {
|
||||
var reducer = reducers[key];
|
||||
var initialState = reducer(undefined, { type: _createStore.ActionTypes.INIT });
|
||||
|
||||
if (typeof initialState === 'undefined') {
|
||||
throw new Error('Reducer "' + key + '" returned undefined during initialization. ' + 'If the state passed to the reducer is undefined, you must ' + 'explicitly return the initial state. The initial state may ' + 'not be undefined.');
|
||||
}
|
||||
|
||||
var type = '@@redux/PROBE_UNKNOWN_ACTION_' + Math.random().toString(36).substring(7).split('').join('.');
|
||||
if (typeof reducer(undefined, { type: type }) === 'undefined') {
|
||||
throw new Error('Reducer "' + key + '" returned undefined when probed with a random type. ' + ('Don\'t try to handle ' + _createStore.ActionTypes.INIT + ' or other actions in "redux/*" ') + 'namespace. They are considered private. Instead, you must return the ' + 'current state for any unknown actions, unless it is undefined, ' + 'in which case you must return the initial state, regardless of the ' + 'action type. The initial state may not be undefined.');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns an object whose values are different reducer functions, into a single
|
||||
* reducer function. It will call every child reducer, and gather their results
|
||||
* into a single state object, whose keys correspond to the keys of the passed
|
||||
* reducer functions.
|
||||
*
|
||||
* @param {Object} reducers An object whose values correspond to different
|
||||
* reducer functions that need to be combined into one. One handy way to obtain
|
||||
* it is to use ES6 `import * as reducers` syntax. The reducers may never return
|
||||
* undefined for any action. Instead, they should return their initial state
|
||||
* if the state passed to them was undefined, and the current state for any
|
||||
* unrecognized action.
|
||||
*
|
||||
* @returns {Function} A reducer function that invokes every reducer inside the
|
||||
* passed object, and builds a state object with the same shape.
|
||||
*/
|
||||
function combineReducers(reducers) {
|
||||
var reducerKeys = Object.keys(reducers);
|
||||
var finalReducers = {};
|
||||
for (var i = 0; i < reducerKeys.length; i++) {
|
||||
var key = reducerKeys[i];
|
||||
if (typeof reducers[key] === 'function') {
|
||||
finalReducers[key] = reducers[key];
|
||||
}
|
||||
}
|
||||
var finalReducerKeys = Object.keys(finalReducers);
|
||||
|
||||
var sanityError;
|
||||
try {
|
||||
assertReducerSanity(finalReducers);
|
||||
} catch (e) {
|
||||
sanityError = e;
|
||||
}
|
||||
|
||||
return function combination() {
|
||||
var state = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
|
||||
var action = arguments[1];
|
||||
|
||||
if (sanityError) {
|
||||
throw sanityError;
|
||||
}
|
||||
|
||||
if (true) {
|
||||
var warningMessage = getUnexpectedStateShapeWarningMessage(state, finalReducers, action);
|
||||
if (warningMessage) {
|
||||
(0, _warning2["default"])(warningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
var hasChanged = false;
|
||||
var nextState = {};
|
||||
for (var i = 0; i < finalReducerKeys.length; i++) {
|
||||
var key = finalReducerKeys[i];
|
||||
var reducer = finalReducers[key];
|
||||
var previousStateForKey = state[key];
|
||||
var nextStateForKey = reducer(previousStateForKey, action);
|
||||
if (typeof nextStateForKey === 'undefined') {
|
||||
var errorMessage = getUndefinedStateErrorMessage(key, action);
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
nextState[key] = nextStateForKey;
|
||||
hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
|
||||
}
|
||||
return hasChanged ? nextState : state;
|
||||
};
|
||||
}
|
||||
|
||||
/***/ },
|
||||
/* 8 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
/**
|
||||
* Checks if `value` is a host object in IE < 9.
|
||||
*
|
||||
* @private
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is a host object, else `false`.
|
||||
*/
|
||||
function isHostObject(value) {
|
||||
// Many host objects are `Object` objects that can coerce to strings
|
||||
// despite having improperly defined `toString` methods.
|
||||
var result = false;
|
||||
if (value != null && typeof value.toString != 'function') {
|
||||
try {
|
||||
result = !!(value + '');
|
||||
} catch (e) {}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = isHostObject;
|
||||
|
||||
|
||||
/***/ },
|
||||
/* 9 */
|
||||
/***/ function(module, exports) {
|
||||
|
||||
/**
|
||||
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
||||
* and has a `typeof` result of "object".
|
||||
*
|
||||
* @static
|
||||
* @memberOf _
|
||||
* @category Lang
|
||||
* @param {*} value The value to check.
|
||||
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
||||
* @example
|
||||
*
|
||||
* _.isObjectLike({});
|
||||
* // => true
|
||||
*
|
||||
* _.isObjectLike([1, 2, 3]);
|
||||
* // => true
|
||||
*
|
||||
* _.isObjectLike(_.noop);
|
||||
* // => false
|
||||
*
|
||||
* _.isObjectLike(null);
|
||||
* // => false
|
||||
*/
|
||||
function isObjectLike(value) {
|
||||
return !!value && typeof value == 'object';
|
||||
}
|
||||
|
||||
module.exports = isObjectLike;
|
||||
|
||||
|
||||
/***/ }
|
||||
/******/ ])
|
||||
});
|
||||
;
|
1
static/js/lib/redux.min.js
vendored
|
@ -35,7 +35,16 @@ VersionPlugin.prototype.apply = function (compiler) {
|
|||
|
||||
// Prepare all entry points
|
||||
var entry = {
|
||||
init: './src/init.js'
|
||||
common: [
|
||||
// Vendor
|
||||
'raven-js',
|
||||
'react',
|
||||
'react-dom',
|
||||
'react-intl',
|
||||
'redux',
|
||||
// Init
|
||||
'./src/init.js'
|
||||
]
|
||||
};
|
||||
routes.forEach(function (route) {
|
||||
if (!route.redirect) {
|
||||
|
@ -47,13 +56,6 @@ routes.forEach(function (route) {
|
|||
module.exports = {
|
||||
entry: entry,
|
||||
devtool: 'source-map',
|
||||
externals: {
|
||||
'react': 'React',
|
||||
'react/addons': 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
'react-intl': 'ReactIntl',
|
||||
'redux': 'Redux'
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'build'),
|
||||
filename: 'js/[name].bundle.js'
|
||||
|
@ -101,6 +103,11 @@ module.exports = {
|
|||
warnings: false
|
||||
}
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env.NODE_ENV': '"' + (process.env.NODE_ENV || 'development') + '"',
|
||||
'process.env.SENTRY_DSN': '"' + (process.env.SENTRY_DSN || '') + '"'
|
||||
}),
|
||||
new webpack.optimize.CommonsChunkPlugin('common', 'js/common.bundle.js'),
|
||||
new webpack.optimize.OccurenceOrderPlugin()
|
||||
]
|
||||
};
|
||||
|
|