diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..b34309e15 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +node_modules/* +static/* +build/* +intl/* +**/*.min.js diff --git a/.eslintrc b/.eslintrc index ca3e7f389..853e777b4 100644 --- a/.eslintrc +++ b/.eslintrc @@ -25,7 +25,8 @@ "jsx": true }, "plugins": [ - "react" + "react", + "json" ], "extends": "eslint:recommended" } diff --git a/.travis.yml b/.travis.yml index 6267fb4a6..f0faf2485 100644 --- a/.travis.yml +++ b/.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 diff --git a/Makefile b/Makefile index 8cfececd8..be8b6ccfd 100644 --- a/Makefile +++ b/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 diff --git a/bin/configure-fastly.js b/bin/configure-fastly.js index bf5e8f5f6..6d92b3bf8 100644 --- a/bin/configure-fastly.js +++ b/bin/configure-fastly.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, diff --git a/package.json b/package.json index 6f922e101..ca92315d2 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/components/footer/www/footer.jsx b/src/components/footer/www/footer.jsx index 3b4cb2278..d36023f79 100644 --- a/src/components/footer/www/footer.jsx +++ b/src/components/footer/www/footer.jsx @@ -14,201 +14,145 @@ var Footer = React.createClass({
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
- +
@@ -218,11 +162,7 @@ var Footer = React.createClass({

- +

diff --git a/src/components/subnavigation/subnavigation.scss b/src/components/subnavigation/subnavigation.scss index 7e0ead35a..d6ed0446d 100644 --- a/src/components/subnavigation/subnavigation.scss +++ b/src/components/subnavigation/subnavigation.scss @@ -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 { diff --git a/src/init.js b/src/init.js index 3700537f1..d97d79646 100644 --- a/src/init.js +++ b/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(); + } +})(); /** * ----------------------------------------------------------------------------- diff --git a/src/l10n.json b/src/l10n.json index 9f2763296..4ab1fa552 100644 --- a/src/l10n.json +++ b/src/l10n.json @@ -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", diff --git a/src/lib/intl.jsx b/src/lib/intl.jsx index fe35df4ea..12a76eb46 100644 --- a/src/lib/intl.jsx +++ b/src/lib/intl.jsx @@ -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; diff --git a/src/lib/render.jsx b/src/lib/render.jsx index badf22a29..5706f3197 100644 --- a/src/lib/render.jsx +++ b/src/lib/render.jsx @@ -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; diff --git a/src/lib/require-all.js b/src/lib/require-all.js new file mode 100644 index 000000000..028a18028 --- /dev/null +++ b/src/lib/require-all.js @@ -0,0 +1,5 @@ +var requireAll = function (requireContext) { + return requireContext.keys().map(requireContext); +}; + +module.exports = requireAll; diff --git a/src/routes.json b/src/routes.json index 6bc5b2014..802cbbfaf 100644 --- a/src/routes.json +++ b/src/routes.json @@ -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" } ] diff --git a/src/template-config.js b/src/template-config.js index 5a1ce4296..af9ee0050 100644 --- a/src/template-config.js +++ b/src/template-config.js @@ -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 || '' }; diff --git a/src/template.html b/src/template.html index 91700e759..d389b2d47 100644 --- a/src/template.html +++ b/src/template.html @@ -38,31 +38,19 @@ }; - - - + +
+ + - - - - - - - - - + + + diff --git a/src/views/conference/expect/expect.scss b/src/views/conference/expect/expect.scss index 5d2004b89..498b6a760 100644 --- a/src/views/conference/expect/expect.scss +++ b/src/views/conference/expect/expect.scss @@ -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; + } } } } diff --git a/src/views/conference/index/index.scss b/src/views/conference/index/index.scss index 759b25472..a0244cd78 100644 --- a/src/views/conference/index/index.scss +++ b/src/views/conference/index/index.scss @@ -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; diff --git a/src/views/conference/plan/plan.scss b/src/views/conference/plan/plan.scss index fec4598fc..bc00340b9 100644 --- a/src/views/conference/plan/plan.scss +++ b/src/views/conference/plan/plan.scss @@ -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; - } - } -} diff --git a/src/views/developers/developers.jsx b/src/views/developers/developers.jsx new file mode 100644 index 000000000..71fd754f8 --- /dev/null +++ b/src/views/developers/developers.jsx @@ -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 ( +
+ +
+

Scratch for Developers

+

+ On this page, you’ll find information about open source projects created and maintained{' '} + by the Scratch Team at MIT, as well{' '} + as our thoughts on best practices for designing learning experiences for children. +

+
+
+ + +
  • + Projects +
  • +
    + +
  • + Principles +
  • +
    + +
  • + Donate +
  • +
    + +
  • + Partners +
  • +
    + +
  • + FAQ +
  • +
    +
    +
    +
    + +
    +
    + +

    Projects

    +

    + The following projects are open source and available for any purpose. +

    + +
    +

    Scratch Blocks

    +

    + 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{' '} + Blockly technology{' '} + 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{' '} + here. +

    +

    + 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. +

    +
    + blocks +
    + +
    +

    Scratch WWW

    +

    + Scratch-www is a standalone web client for the Scratch Community, built{' '} + using React and Redux. Access the code and documentation{' '} + here. +

    +
    + + www +
    +
    + +
    + +

    Principles

    +

    + We created Scratch to empower young people to think creatively, reason systematically,{' '} + and work collaboratively. We are guided by a set of Learning Principles and{' '} + Design Principles that we hope you will follow as you develop new tools and{' '} + technologies with Scratch Blocks. +

    + + +
    +

    Learning Principles

    +
    +
    Projects
    +
    + People learn best when they are actively working on projects — generating{' '} + new ideas, designing prototypes, making improvements and creating final{' '} + products. +
    +
    Passion
    +
    + 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. +
    +
    Peers
    +
    + Learning flourishes as a social activity, with people sharing ideas,{' '} + collaborating on projects, and building on one another's work. +
    +
    Play
    +
    + Learning involves playful experimentation — trying new things, tinkering{' '} + with materials, testing boundaries, taking risks, iterating again and again. +
    +
    +
    +
    + + +
    +

    Design Principles

    +
    +
    Low Floor & Wide Walls
    +
    + 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). +
    +
    Make it as Simple as Possible — And Maybe Even Simpler
    +
    + 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. +
    +
    Many Paths, Many Styles
    +
    + 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. +
    +
    Design for Tinkerability
    +
    + 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. +
    +
    +
    +
    +
    + + + +
    + +

    Partners

    +

    + The creation and maintenance of this open source code would not be possible without{' '} + generous technical and financial support from our partners: +

    + + + google + intel + cartoon network + lemann foundation + +
    +
    + + +
    +
    + +

    FAQ

    + +
    +

    Where can I learn more about Scratch?

    +

    + 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{' '} + Lifelong Kindergarten{' '} + Group at the MIT Media Lab.{' '} + You can learn more about Scratch{' '} + here. +

    +
    +
    +

    Are there rules to using this code in my application?

    +

    + You may use this code in accordance with the{' '} + Apache 2.0 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. +

    +
    +
    +

    + Am I allowed to use the name "Scratch Blocks" in the description of my{' '} + app and other public messaging? +

    +

    + 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. +

    +
    +
    +

    Are you releasing more code and when?

    +

    + We plan to open source additional code relating to the Scratch programming{' '} + language over the next few months. Keep an eye on this page! +

    +
    +
    +

    What’s the difference between Blockly and Scratch Blocks?

    +

    + Scratch Blocks builds upon the Blockly code base, and is specifically{' '} + designed with our principles in mind to support creative learning experiences. +

    +
    +
    +

    I’d like to collaborate. How do I get in touch?

    +

    + You can reach us over on github or{' '} + you can send an email to{' '} + help@scratch.mit.edu.{' '} + We look forward to hearing from you! +

    +
    +
    +
    +
    +
    +
    + ); + } +}); + +render(, document.getElementById('app')); diff --git a/src/views/developers/developers.scss b/src/views/developers/developers.scss new file mode 100644 index 000000000..ea706de08 --- /dev/null +++ b/src/views/developers/developers.scss @@ -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%; + } + } +} + + + + diff --git a/src/views/developers/l10n.json b/src/views/developers/l10n.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/src/views/developers/l10n.json @@ -0,0 +1 @@ +{} diff --git a/src/views/privacypolicy/privacypolicy.jsx b/src/views/privacypolicy/privacypolicy.jsx new file mode 100644 index 000000000..e1e75a44a --- /dev/null +++ b/src/views/privacypolicy/privacypolicy.jsx @@ -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 ( +
    + +

    + 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{' '} + contact us. +

    +

    + 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. +

    +

    What information does the Scratch Team collect about me?

    +

    + Account Information: + 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. +

    +

    + User-generated Content: + 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 Scratch 2 offline editor{' '} + or Scratch 1.4. +

    +

    + Usage Information: + 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. +

    +

    + Google Analytics: + 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. +

    +

    + Cookies: + 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. +

    +

    How does the Scratch Team use my information?

    +
      +
    • + We collect age and gender data so that we know who is using our + website. +
    • +
    • + 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. +
    • +
    • + 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. +
    • +
    • + 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. +
    • +
    • + Parents and guardians who register their under-13 year olds for + Scratch may also receive additional updates from the{' '} + Scratch Foundation, + 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. +
    • +
    • + 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). +
    • +
    • + 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{' '} + Research page. +
    • +
    • + 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. +
    • +
    • + Other than as described above, we will never share personally + identifiable information about you with any other person, + company, or organization, except: +
        +
      • + As required to comply with our obligations under the law. +
      • +
      • + For technical reasons, if we are required to transfer the + data on our servers to another location or organization. +
      • +
      +
    • +
    +

    How can I update my personal information?

    +

    + You can update your password, email address, and country through + the Account Settings page. + You can also reset your password through the{' '} + Account Reset{' '} + page. You cannot change your username, but you can make a new + account and manually copy your projects to the new account. +

    +

    + 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. +

    +

    How does the Scratch Team protect my information?

    +

    + 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. +

    +

    Notifications of Changes to the Privacy Policy

    +

    + 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. +

    +
    +
    + ); + } +}); + +render(, document.getElementById('app')); diff --git a/src/views/splash/splash.jsx b/src/views/splash/splash.jsx index 389d8f029..7dbce5ef6 100644 --- a/src/views/splash/splash.jsx +++ b/src/views/splash/splash.jsx @@ -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'); diff --git a/static/images/developers/block-sketch.png b/static/images/developers/block-sketch.png new file mode 100644 index 000000000..80cf39996 Binary files /dev/null and b/static/images/developers/block-sketch.png differ diff --git a/static/images/developers/cn.png b/static/images/developers/cn.png new file mode 100644 index 000000000..565c58412 Binary files /dev/null and b/static/images/developers/cn.png differ diff --git a/static/images/developers/google.png b/static/images/developers/google.png new file mode 100644 index 000000000..563d9e637 Binary files /dev/null and b/static/images/developers/google.png differ diff --git a/static/images/developers/intel.png b/static/images/developers/intel.png new file mode 100644 index 000000000..f01e5fb0e Binary files /dev/null and b/static/images/developers/intel.png differ diff --git a/static/images/developers/lemann.png b/static/images/developers/lemann.png new file mode 100644 index 000000000..2448a965a Binary files /dev/null and b/static/images/developers/lemann.png differ diff --git a/static/images/developers/logo_sm.png b/static/images/developers/logo_sm.png new file mode 100644 index 000000000..7f4e7353a Binary files /dev/null and b/static/images/developers/logo_sm.png differ diff --git a/static/images/developers/www-sketch.png b/static/images/developers/www-sketch.png new file mode 100644 index 000000000..63546033d Binary files /dev/null and b/static/images/developers/www-sketch.png differ diff --git a/static/js/lib/raven.min.js b/static/js/lib/raven.min.js deleted file mode 100644 index 3b399e359..000000000 --- a/static/js/lib/raven.min.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! Raven.js 1.2.0 (feb5e65) | github.com/getsentry/raven-js */ -!function(a,b){"use strict";function c(){return"undefined"==typeof document?"":document.location.href}function d(a,b){var c,d;if(Q){b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),document.createEvent?(c=document.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=document.createEventObject(),c.eventType=a);for(d in b)m(b,d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}}function e(a){this.name="RavenConfigError",this.message=a}function f(a){var b=aa.exec(a),c={},d=7;try{for(;d--;)c[_[d]]=b[d]||""}catch(f){throw new e("Invalid DSN: "+a)}if(c.pass)throw new e("Do not specify your private key in the DSN!");return c}function g(a){return void 0===a}function h(a){return"function"==typeof a}function i(a){return"[object String]"===U.toString.call(a)}function j(a){return"object"==typeof a&&null!==a}function k(a){for(var b in a)return!1;return!0}function l(a){return j(a)&&"[object Error]"===U.toString.call(a)||a instanceof Error}function m(a,b){return U.hasOwnProperty.call(a,b)}function n(a,b){var c,d;if(g(a.length))for(c in a)m(a,c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;d>c;c++)b.call(null,c,a[c])}function o(a,b){var c=[];a.stack&&a.stack.length&&n(a.stack,function(a,b){var d=p(b);d&&c.push(d)}),d("handle",{stackInfo:a,options:b}),r(a.name,a.message,a.url,a.lineno,c,b)}function p(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=q(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(S.includePaths.test&&!S.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}}function q(a){if(a.context&&S.fetchContext){for(var b=a.context,c=~~(b.length/2),d=b.length,e=!1;d--;)if(b[d].length>300){e=!0;break}if(e){if(g(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}}function r(a,b,c,d,e,f){var g,h;S.ignoreErrors.test&&S.ignoreErrors.test(b)||(b+="",b=t(b,S.maxMessageLength),h=a+": "+b,h=t(h,S.maxMessageLength),e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),S.ignoreUrls.test&&S.ignoreUrls.test(c)||(!S.whitelistUrls.test||S.whitelistUrls.test(c))&&w(s({exception:{type:a,value:b},stacktrace:g,culprit:c,message:h},f)))}function s(a,b){return b?(n(b,function(b,c){a[b]=c}),a):a}function t(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function u(){return+new Date}function v(){if(Q&&document.location&&document.location.href){var a={headers:{"User-Agent":navigator.userAgent}};return a.url=document.location.href,document.referrer&&(a.headers.Referer=document.referrer),a}}function w(a){var b={project:N,logger:S.logger,platform:"javascript"},c=v();c&&(b.request=c),a=s(b,a),a.tags=s(s({},R.tags),a.tags),a.extra=s(s({},R.extra),a.extra),a.extra=s({"session:duration":u()-Y},a.extra),k(a.tags)&&delete a.tags,R.user&&(a.user=R.user),S.release&&(a.release=S.release),h(S.dataCallback)&&(a=S.dataCallback(a)||a),a&&!k(a)&&(!h(S.shouldSendCallback)||S.shouldSendCallback(a))&&(K=a.event_id||(a.event_id=B()),C("debug","Raven about to send:",a),z()&&(S.transport||x)({url:L,auth:{sentry_version:"4",sentry_client:"raven-js/"+$.VERSION,sentry_key:M},data:a,options:S,onSuccess:function(){d("success",{data:a,src:L})},onError:function(){d("failure",{data:a,src:L})}}))}function x(a){a.auth.sentry_data=JSON.stringify(a.data);var b=y(),c=a.url+"?"+E(a.auth);(a.options.crossOrigin||""===a.options.crossOrigin)&&(b.crossOrigin=a.options.crossOrigin),b.onload=a.onSuccess,b.onerror=b.onabort=a.onError,b.src=c}function y(){return document.createElement("img")}function z(){return P?L?!0:(ba||C("error","Error: Raven has not been configured."),ba=!0,!1):!1}function A(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],i(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function B(){var b=a.crypto||a.msCrypto;if(!g(b)&&b.getRandomValues){var c=new Uint16Array(8);b.getRandomValues(c),c[3]=4095&c[3]|16384,c[4]=16383&c[4]|32768;var d=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return d(c[0])+d(c[1])+d(c[2])+d(c[3])+d(c[4])+d(c[5])+d(c[6])+d(c[7])}return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function C(a){W[a]&&$.debug&&W[a].apply(V,H.call(arguments,1))}function D(){var b=a.RavenConfig;b&&$.config(b.dsn,b.config).install()}function E(a){var b=[];return n(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function F(a,b){g(b)?delete R[a]:R[a]=s(R[a]||{},b)}var G={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7,debug:!1},H=[].slice,I="?";G.wrap=function(a){function b(){try{return a.apply(this,arguments)}catch(b){throw G.report(b),b}}return b},G.report=function(){function d(a){i(),p.push(a)}function e(a){for(var b=p.length-1;b>=0;--b)p[b]===a&&p.splice(b,1)}function f(){j(),p=[]}function g(a,b){var c=null;if(!b||G.collectWindowErrors){for(var d in p)if(m(p,d))try{p[d].apply(null,[a].concat(H.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function h(a,b,d,e,f){var h=null;if(s)G.computeStackTrace.augmentStackTraceWithInitialElement(s,b,d,a),k();else if(f)h=G.computeStackTrace(f),g(h,!0);else{var i={url:b,line:d,column:e};i.func=G.computeStackTrace.guessFunctionName(i.url,i.line),i.context=G.computeStackTrace.gatherContext(i.url,i.line),h={message:a,url:c(),stack:[i]},g(h,!0)}return n?n.apply(this,arguments):!1}function i(){o||(n=a.onerror,a.onerror=h,o=!0)}function j(){o&&(a.onerror=n,o=!1,n=b)}function k(){var a=s,b=q;q=null,s=null,r=null,g.apply(null,[a,!1].concat(b))}function l(b,c){var d=H.call(arguments,1);if(s){if(r===b)return;k()}var e=G.computeStackTrace(b);if(s=e,r=b,q=d,a.setTimeout(function(){r===b&&k()},e.incomplete?2e3:0),c!==!1)throw b}var n,o,p=[],q=null,r=null,s=null;return l.subscribe=d,l.unsubscribe=e,l.uninstall=f,l}(),G.computeStackTrace=function(){function b(b){if(!G.remoteFetching)return"";try{var c=function(){try{return new a.XMLHttpRequest}catch(b){return new a.ActiveXObject("Microsoft.XMLHTTP")}},d=c();return d.open("GET",b,!1),d.send(""),d.responseText}catch(e){return""}}function d(a){if(!i(a))return[];if(!m(u,a)){var c="",d="";try{d=document.domain}catch(e){}-1!==a.indexOf(d)&&(c=b(a)),u[a]=c?c.split("\n"):[]}return u[a]}function e(a,b){var c,e=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,h="",i=10,j=d(a);if(!j.length)return I;for(var k=0;i>k;++k)if(h=j[b-k]+h,!g(h)){if(c=f.exec(h))return c[1];if(c=e.exec(h))return c[1]}return I}function f(a,b){var c=d(a);if(!c.length)return null;var e=[],f=Math.floor(G.linesOfContext/2),h=f+G.linesOfContext%2,i=Math.max(0,b-f-1),j=Math.min(c.length,b+h-1);b-=1;for(var k=i;j>k;++k)g(c[k])||e.push(c[k]);return e.length>0?e:null}function h(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function j(a){return h(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function k(a,b){for(var c,e,f=0,g=b.length;g>f;++f)if((c=d(b[f])).length&&(c=c.join("\n"),e=a.exec(c)))return{url:b[f],line:c.substring(0,e.index).split("\n").length,column:e.index-c.lastIndexOf("\n",e.index)-1};return null}function l(a,b,c){var e,f=d(b),g=new RegExp("\\b"+h(a)+"\\b");return c-=1,f&&f.length>c&&(e=g.exec(f[c]))?e.index:null}function n(b){if("undefined"!=typeof document){for(var c,d,e,f,g=[a.location.href],i=document.getElementsByTagName("script"),l=""+b,m=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=0;o):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,j=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,k=a.stack.split("\n"),m=[],n=/^(.*) is undefined$/.exec(a.message),o=0,p=k.length;p>o;++o){if(b=i.exec(k[o]))d={url:b[3],func:b[1]||I,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else if(b=h.exec(k[o]))d={url:b[2],func:b[1]||I,line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=j.exec(k[o])))continue;d={url:b[2],func:b[1]||I,line:+b[3],column:b[4]?+b[4]:null}}!d.func&&d.line&&(d.func=e(d.url,d.line)),d.line&&(d.context=f(d.url,d.line)),m.push(d)}return m.length?(m[0].line&&!m[0].column&&n?m[0].column=l(n[1],m[0].url,m[0].line):m[0].column||g(a.columnNumber)||(m[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:c(),stack:m}):null}}function p(a){var b=a.stacktrace;if(!g(a.stacktrace)&&a.stacktrace){for(var d,h=/ line (\d+), column (\d+) in (?:]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,i=b.split("\n"),j=[],k=0,l=i.length;l>k;k+=2)if(d=h.exec(i[k])){var m={line:+d[1],column:+d[2],func:d[3]||d[4],args:d[5]?d[5].split(","):[],url:d[6]};if(!m.func&&m.line&&(m.func=e(m.url,m.line)),m.line)try{m.context=f(m.url,m.line)}catch(n){}m.context||(m.context=[i[k+1]]),j.push(m)}return j.length?{name:a.name,message:a.message,url:c(),stack:j}:null}}function q(b){var g=b.message.split("\n");if(g.length<4)return null;var h,i,l,n,o=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,q=/^\s*Line (\d+) of function script\s*$/i,r=[],s=document.getElementsByTagName("script"),t=[];for(i in s)m(s,i)&&!s[i].src&&t.push(s[i]);for(i=2,l=g.length;l>i;i+=2){var u=null;if(h=o.exec(g[i]))u={url:h[2],func:h[3],line:+h[1]};else if(h=p.exec(g[i])){u={url:h[3],func:h[4]};var v=+h[1],w=t[h[2]-1];if(w&&(n=d(u.url))){n=n.join("\n");var x=n.indexOf(w.innerText);x>=0&&(u.line=v+n.substring(0,x).split("\n").length)}}else if(h=q.exec(g[i])){var y=a.location.href.replace(/#.*$/,""),z=h[1],A=new RegExp(j(g[i+1]));n=k(A,[y]),u={url:y,line:n?n.line:z,func:""}}if(u){u.func||(u.func=e(u.url,u.line));var B=f(u.url,u.line),C=B?B[Math.floor(B.length/2)]:null;B&&C.replace(/^\s*/,"")===g[i+1].replace(/^\s*/,"")?u.context=B:u.context=[g[i+1]],r.push(u)}}return r.length?{name:b.name,message:g[0],url:c(),stack:r}:null}function r(a,b,c,d){var g={url:b,line:c};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=e(g.url,g.line)),g.context||(g.context=f(g.url,g.line));var h=/ '([^']+)' /.exec(d);if(h&&(g.column=l(h[1],g.url,g.line)),a.stack.length>0&&a.stack[0].url===g.url){if(a.stack[0].line===g.line)return!1;if(!a.stack[0].line&&a.stack[0].func===g.func)return a.stack[0].line=g.line,a.stack[0].context=g.context,!1}return a.stack.unshift(g),a.partial=!0,!0}return a.incomplete=!0,!1}function s(a,b){for(var d,f,g,h=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,i=[],j={},k=!1,m=s.caller;m&&!k;m=m.caller)if(m!==t&&m!==G.report){if(f={url:null,func:I,line:null,column:null},m.name?f.func=m.name:(d=h.exec(m.toString()))&&(f.func=d[1]),"undefined"==typeof f.func)try{f.func=d.input.substring(0,d.input.indexOf("{"))}catch(o){}if(g=n(m)){f.url=g.url,f.line=g.line,f.func===I&&(f.func=e(f.url,f.line));var p=/ '([^']+)' /.exec(a.message||a.description);p&&(f.column=l(p[1],g.url,g.line))}j[""+m]?k=!0:j[""+m]=!0,i.push(f)}b&&i.splice(0,b);var q={name:a.name,message:a.message,url:c(),stack:i};return r(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function t(a,b){var d=null;b=null==b?0:+b;try{if(d=p(a))return d}catch(e){if(G.debug)throw e}try{if(d=o(a))return d}catch(e){if(G.debug)throw e}try{if(d=q(a))return d}catch(e){if(G.debug)throw e}try{if(d=s(a,b+1))return d}catch(e){if(G.debug)throw e}return{name:a.name,message:a.message,url:c()}}var u={};return t.augmentStackTraceWithInitialElement=r,t.computeStackTraceFromStackProp=o,t.guessFunctionName=e,t.gatherContext=f,t}();var J,K,L,M,N,O=a.Raven,P=!("object"!=typeof JSON||!JSON.stringify),Q="undefined"!=typeof document,R={},S={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],crossOrigin:"anonymous",collectWindowErrors:!0,maxMessageLength:100},T=!1,U=Object.prototype,V=a.console||{},W={},X=[],Y=u();for(var Z in V)W[Z]=V[Z];var $={VERSION:"1.2.0",debug:!0,noConflict:function(){return a.Raven=O,$},config:function(a,b){if(L)return C("error","Error: Raven has already been configured"),$;if(!a)return $;var c=f(a),d=c.path.lastIndexOf("/"),e=c.path.substr(1,d);return b&&n(b,function(a,b){"tags"==a||"extra"==a?R[a]=b:S[a]=b}),S.ignoreErrors.push(/^Script error\.?$/),S.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),S.ignoreErrors=A(S.ignoreErrors),S.ignoreUrls=S.ignoreUrls.length?A(S.ignoreUrls):!1,S.whitelistUrls=S.whitelistUrls.length?A(S.whitelistUrls):!1,S.includePaths=A(S.includePaths),M=c.user,N=c.path.substr(d+1),L="//"+c.host+(c.port?":"+c.port:"")+"/"+e+"api/"+N+"/store/",c.protocol&&(L=c.protocol+":"+L),S.fetchContext&&(G.remoteFetching=!0),S.linesOfContext&&(G.linesOfContext=S.linesOfContext),G.collectWindowErrors=!!S.collectWindowErrors,$},install:function(){return z()&&!T&&(G.report.subscribe(o),n(X,function(a,b){b()}),T=!0),$},context:function(a,c,d){return h(a)&&(d=c||[],c=a,a=b),$.wrap(a,c).apply(this,d)},wrap:function(a,c){function d(){for(var b=[],d=arguments.length,e=!a||a&&a.deep!==!1;d--;)b[d]=e?$.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw $.captureException(f,a),f}}if(g(c)&&!h(a))return a;if(h(a)&&(c=a,a=b),!h(c))return c;if(c.__raven__)return c;for(var e in c)m(c,e)&&(d[e]=c[e]);return d.__raven__=!0,d.__inner__=c,d},uninstall:function(){return G.report.uninstall(),T=!1,$},captureException:function(a,b){if(!l(a))return $.captureMessage(a,b);J=a;try{var c=G.computeStackTrace(a);o(c,b)}catch(d){if(a!==d)throw d}return $},captureMessage:function(a,b){return S.ignoreErrors.test&&S.ignoreErrors.test(a)?void 0:(w(s({message:a+""},b)),$)},addPlugin:function(a){return X.push(a),T&&a(),$},setUserContext:function(a){return R.user=a,$},setExtraContext:function(a){return F("extra",a),$},setTagsContext:function(a){return F("tags",a),$},clearContext:function(){return R={},$},getContext:function(){return JSON.parse(JSON.stringify(R))},setRelease:function(a){return S.release=a,$},setDataCallback:function(a){return S.dataCallback=a,$},setShouldSendCallback:function(a){return S.shouldSendCallback=a,$},setTransport:function(a){return S.transport=a,$},lastException:function(){return J},lastEventId:function(){return K},isSetup:function(){return z()}};$.setUser=$.setUserContext,$.setReleaseContext=$.setRelease;var _="source protocol user pass host port path".split(" "),aa=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;e.prototype=new Error,e.prototype.constructor=e;var ba;D(),a.Raven=$,"function"==typeof define&&define.amd?define("raven",[],function(){return $}):"object"==typeof module?module.exports=$:"object"==typeof exports&&(exports=$)}("undefined"!=typeof window?window:this),function(a){"use strict";a.Raven&&Raven.addPlugin(function(){var b=a.jQuery;if(b){var c=b.event.add;b.event.add=function(a,d,e,f,g){var h;return e&&e.handler?(h=e.handler,e.handler=Raven.wrap(e.handler)):(h=e,e=Raven.wrap(e)),h.guid?e.guid=h.guid:e.guid=h.guid=b.guid++,c.call(this,a,d,e,f,g)};var d=b.fn.ready;b.fn.ready=function(a){return d.call(this,Raven.wrap(a))};var e=b.ajax;b.ajax=function(a,c){var d,f=["complete","error","success"];for("object"==typeof a&&(c=a,a=void 0),c=c||{};d=f.pop();)b.isFunction(c[d])&&(c[d]=Raven.wrap(c[d]));try{var g=e.call(this,a,c);return b.isFunction(g.complete)&&(g.complete=Raven.wrap(g.complete)),g}catch(h){throw Raven.captureException(h),h}};var f=b.Deferred;b.Deferred=function(a){return f?f(function(c){for(var d,e=["resolve","reject","notify","resolveWith","rejectWith","notifyWith"];d=e.pop();)b.isFunction(c[d])&&(c[d]=Raven.wrap(c[d]));a&&a.call(c,c)}):null}}})}("undefined"!=typeof window?window:this),function(a){"use strict";a.Raven&&Raven.addPlugin(function(){var b=function(b){var c=a[b];a[b]=function(){var a=[].slice.call(arguments),b=a[0];return"function"==typeof b&&(a[0]=Raven.wrap(b)),c.apply?c.apply(this,a):c(a[0],a[1])}};b("setTimeout"),b("setInterval")})}("undefined"!=typeof window?window:this); -//# sourceMappingURL=raven.min.map \ No newline at end of file diff --git a/static/js/lib/react-dom.js b/static/js/lib/react-dom.js deleted file mode 100644 index 8f54ea727..000000000 --- a/static/js/lib/react-dom.js +++ /dev/null @@ -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); - - //