├── .gitignore ├── deck-layers-map ├── .storybook │ ├── main.js │ └── preview.js ├── README.md ├── config │ ├── env.js │ ├── getHttpsConfig.js │ ├── jest │ │ ├── babelTransform.js │ │ ├── cssTransform.js │ │ └── fileTransform.js │ ├── modules.js │ ├── paths.js │ ├── pnpTs.js │ ├── webpack.config.js │ └── webpackDevServer.config.js ├── foss4g-react-mapbox.code-workspace ├── generate-react-cli.json ├── package-lock.json ├── package.json ├── public │ ├── data │ │ └── hex_radio_coverage.json │ ├── favicon.ico │ ├── index.html │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── scripts │ ├── build.js │ ├── start.js │ └── test.js ├── src │ ├── App.css │ ├── App.test.tsx │ ├── App.tsx │ ├── components │ │ ├── BackdropMap │ │ │ ├── BackdropMap.module.css │ │ │ ├── BackdropMap.stories.tsx │ │ │ ├── BackdropMap.test.tsx │ │ │ └── BackdropMap.tsx │ │ └── MbxHomeControl │ │ │ ├── MbxHomeControl.module.css │ │ │ ├── MbxHomeControl.stories.tsx │ │ │ ├── MbxHomeControl.test.tsx │ │ │ └── MbxHomeControl.tsx │ ├── deckgl.d.ts │ ├── index.css │ ├── index.tsx │ ├── logo.svg │ ├── react-app-env.d.ts │ ├── reportWebVitals.ts │ ├── setupTests.ts │ └── stories │ │ ├── Button.stories.tsx │ │ ├── Button.tsx │ │ ├── Header.stories.tsx │ │ ├── Header.tsx │ │ ├── Introduction.stories.mdx │ │ ├── Page.stories.tsx │ │ ├── Page.tsx │ │ ├── assets │ │ ├── code-brackets.svg │ │ ├── colors.svg │ │ ├── comments.svg │ │ ├── direction.svg │ │ ├── flow.svg │ │ ├── plugin.svg │ │ ├── repo.svg │ │ └── stackalt.svg │ │ ├── button.css │ │ ├── header.css │ │ └── page.css └── tsconfig.json ├── foss4g-react-mapbox.code-workspace ├── rmg-component-lib ├── package-lock.json ├── package.json ├── src │ ├── components │ │ ├── LayerDrawer │ │ │ └── LayerDrawer.tsx │ │ └── MbxHomeControl │ │ │ ├── MbxHomeControl.css │ │ │ ├── MbxHomeControl.stories │ │ │ ├── MbxHomeControl.test │ │ │ └── MbxHomeControl.tsx │ └── index.tsx └── tsconfig.json └── web-component-playground ├── .babelrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .htaccess ├── 404.html ├── LICENSE.txt ├── browserconfig.xml ├── css ├── main.css └── normalize.css ├── doc ├── TOC.md ├── css.md ├── extend.md ├── faq.md ├── html.md ├── js.md ├── misc.md └── usage.md ├── favicon.ico ├── humans.txt ├── icon.png ├── img └── .gitignore ├── index.html ├── js ├── main.js ├── plugins.js └── vendor │ └── modernizr-3.11.2.min.js ├── package-lock.json ├── package.json ├── robots.txt ├── site.webmanifest ├── tile-wide.png └── tile.png /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | build 13 | lib 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | -------------------------------------------------------------------------------- /deck-layers-map/.storybook/main.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"], 3 | addons: ["@storybook/addon-links", "@storybook/addon-essentials"], 4 | webpackFinal: async (config) => { 5 | const path = require("path"); 6 | // add SCSS support for CSS Modules 7 | config.module.rules.push({ 8 | test: /\.scss$/, 9 | use: ["style-loader", "css-loader?modules&importLoaders", "sass-loader"], 10 | include: path.resolve(__dirname, "../"), 11 | }); 12 | 13 | return config; 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /deck-layers-map/.storybook/preview.js: -------------------------------------------------------------------------------- 1 | export const parameters = { 2 | actions: { argTypesRegex: "^on[A-Z].*" }, 3 | controls: { 4 | matchers: { 5 | color: /(background|color)$/i, 6 | date: /Date$/, 7 | }, 8 | }, 9 | } -------------------------------------------------------------------------------- /deck-layers-map/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Create React App 2 | 3 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 4 | 5 | ## Available Scripts 6 | 7 | In the project directory, you can run: 8 | 9 | ### `npm start` 10 | 11 | Runs the app in the development mode.\ 12 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 13 | 14 | The page will reload if you make edits.\ 15 | You will also see any lint errors in the console. 16 | 17 | ### `npm test` 18 | 19 | Launches the test runner in the interactive watch mode.\ 20 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 21 | 22 | ### `npm run build` 23 | 24 | Builds the app for production to the `build` folder.\ 25 | It correctly bundles React in production mode and optimizes the build for the best performance. 26 | 27 | The build is minified and the filenames include the hashes.\ 28 | Your app is ready to be deployed! 29 | 30 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 31 | 32 | ### `npm run eject` 33 | 34 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 35 | 36 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 37 | 38 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 39 | 40 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 41 | 42 | ## Learn More 43 | 44 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 45 | 46 | To learn React, check out the [React documentation](https://reactjs.org/). 47 | -------------------------------------------------------------------------------- /deck-layers-map/config/env.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const paths = require('./paths'); 6 | 7 | // Make sure that including paths.js after env.js will read .env variables. 8 | delete require.cache[require.resolve('./paths')]; 9 | 10 | const NODE_ENV = process.env.NODE_ENV; 11 | if (!NODE_ENV) { 12 | throw new Error( 13 | 'The NODE_ENV environment variable is required but was not specified.' 14 | ); 15 | } 16 | 17 | // https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use 18 | const dotenvFiles = [ 19 | `${paths.dotenv}.${NODE_ENV}.local`, 20 | // Don't include `.env.local` for `test` environment 21 | // since normally you expect tests to produce the same 22 | // results for everyone 23 | NODE_ENV !== 'test' && `${paths.dotenv}.local`, 24 | `${paths.dotenv}.${NODE_ENV}`, 25 | paths.dotenv, 26 | ].filter(Boolean); 27 | 28 | // Load environment variables from .env* files. Suppress warnings using silent 29 | // if this file is missing. dotenv will never modify any environment variables 30 | // that have already been set. Variable expansion is supported in .env files. 31 | // https://github.com/motdotla/dotenv 32 | // https://github.com/motdotla/dotenv-expand 33 | dotenvFiles.forEach(dotenvFile => { 34 | if (fs.existsSync(dotenvFile)) { 35 | require('dotenv-expand')( 36 | require('dotenv').config({ 37 | path: dotenvFile, 38 | }) 39 | ); 40 | } 41 | }); 42 | 43 | // We support resolving modules according to `NODE_PATH`. 44 | // This lets you use absolute paths in imports inside large monorepos: 45 | // https://github.com/facebook/create-react-app/issues/253. 46 | // It works similar to `NODE_PATH` in Node itself: 47 | // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders 48 | // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored. 49 | // Otherwise, we risk importing Node.js core modules into an app instead of webpack shims. 50 | // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421 51 | // We also resolve them to make sure all tools using them work consistently. 52 | const appDirectory = fs.realpathSync(process.cwd()); 53 | process.env.NODE_PATH = (process.env.NODE_PATH || '') 54 | .split(path.delimiter) 55 | .filter(folder => folder && !path.isAbsolute(folder)) 56 | .map(folder => path.resolve(appDirectory, folder)) 57 | .join(path.delimiter); 58 | 59 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 60 | // injected into the application via DefinePlugin in webpack configuration. 61 | const REACT_APP = /^REACT_APP_/i; 62 | 63 | function getClientEnvironment(publicUrl) { 64 | const raw = Object.keys(process.env) 65 | .filter(key => REACT_APP.test(key)) 66 | .reduce( 67 | (env, key) => { 68 | env[key] = process.env[key]; 69 | return env; 70 | }, 71 | { 72 | // Useful for determining whether we’re running in production mode. 73 | // Most importantly, it switches React into the correct mode. 74 | NODE_ENV: process.env.NODE_ENV || 'development', 75 | // Useful for resolving the correct path to static assets in `public`. 76 | // For example, . 77 | // This should only be used as an escape hatch. Normally you would put 78 | // images into the `src` and `import` them in code to get their paths. 79 | PUBLIC_URL: publicUrl, 80 | // We support configuring the sockjs pathname during development. 81 | // These settings let a developer run multiple simultaneous projects. 82 | // They are used as the connection `hostname`, `pathname` and `port` 83 | // in webpackHotDevClient. They are used as the `sockHost`, `sockPath` 84 | // and `sockPort` options in webpack-dev-server. 85 | WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST, 86 | WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH, 87 | WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT, 88 | // Whether or not react-refresh is enabled. 89 | // react-refresh is not 100% stable at this time, 90 | // which is why it's disabled by default. 91 | // It is defined here so it is available in the webpackHotDevClient. 92 | FAST_REFRESH: process.env.FAST_REFRESH !== 'false', 93 | } 94 | ); 95 | // Stringify all values so we can feed into webpack DefinePlugin 96 | const stringified = { 97 | 'process.env': Object.keys(raw).reduce((env, key) => { 98 | env[key] = JSON.stringify(raw[key]); 99 | return env; 100 | }, {}), 101 | }; 102 | 103 | return { raw, stringified }; 104 | } 105 | 106 | module.exports = getClientEnvironment; 107 | -------------------------------------------------------------------------------- /deck-layers-map/config/getHttpsConfig.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const crypto = require('crypto'); 6 | const chalk = require('react-dev-utils/chalk'); 7 | const paths = require('./paths'); 8 | 9 | // Ensure the certificate and key provided are valid and if not 10 | // throw an easy to debug error 11 | function validateKeyAndCerts({ cert, key, keyFile, crtFile }) { 12 | let encrypted; 13 | try { 14 | // publicEncrypt will throw an error with an invalid cert 15 | encrypted = crypto.publicEncrypt(cert, Buffer.from('test')); 16 | } catch (err) { 17 | throw new Error( 18 | `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}` 19 | ); 20 | } 21 | 22 | try { 23 | // privateDecrypt will throw an error with an invalid key 24 | crypto.privateDecrypt(key, encrypted); 25 | } catch (err) { 26 | throw new Error( 27 | `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${ 28 | err.message 29 | }` 30 | ); 31 | } 32 | } 33 | 34 | // Read file and throw an error if it doesn't exist 35 | function readEnvFile(file, type) { 36 | if (!fs.existsSync(file)) { 37 | throw new Error( 38 | `You specified ${chalk.cyan( 39 | type 40 | )} in your env, but the file "${chalk.yellow(file)}" can't be found.` 41 | ); 42 | } 43 | return fs.readFileSync(file); 44 | } 45 | 46 | // Get the https config 47 | // Return cert files if provided in env, otherwise just true or false 48 | function getHttpsConfig() { 49 | const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env; 50 | const isHttps = HTTPS === 'true'; 51 | 52 | if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) { 53 | const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE); 54 | const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE); 55 | const config = { 56 | cert: readEnvFile(crtFile, 'SSL_CRT_FILE'), 57 | key: readEnvFile(keyFile, 'SSL_KEY_FILE'), 58 | }; 59 | 60 | validateKeyAndCerts({ ...config, keyFile, crtFile }); 61 | return config; 62 | } 63 | return isHttps; 64 | } 65 | 66 | module.exports = getHttpsConfig; 67 | -------------------------------------------------------------------------------- /deck-layers-map/config/jest/babelTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const babelJest = require('babel-jest'); 4 | 5 | const hasJsxRuntime = (() => { 6 | if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') { 7 | return false; 8 | } 9 | 10 | try { 11 | require.resolve('react/jsx-runtime'); 12 | return true; 13 | } catch (e) { 14 | return false; 15 | } 16 | })(); 17 | 18 | module.exports = babelJest.createTransformer({ 19 | presets: [ 20 | [ 21 | require.resolve('babel-preset-react-app'), 22 | { 23 | runtime: hasJsxRuntime ? 'automatic' : 'classic', 24 | }, 25 | ], 26 | ], 27 | babelrc: false, 28 | configFile: false, 29 | }); 30 | -------------------------------------------------------------------------------- /deck-layers-map/config/jest/cssTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // This is a custom Jest transformer turning style imports into empty objects. 4 | // http://facebook.github.io/jest/docs/en/webpack.html 5 | 6 | module.exports = { 7 | process() { 8 | return 'module.exports = {};'; 9 | }, 10 | getCacheKey() { 11 | // The output is always the same. 12 | return 'cssTransform'; 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /deck-layers-map/config/jest/fileTransform.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const camelcase = require('camelcase'); 5 | 6 | // This is a custom Jest transformer turning file imports into filenames. 7 | // http://facebook.github.io/jest/docs/en/webpack.html 8 | 9 | module.exports = { 10 | process(src, filename) { 11 | const assetFilename = JSON.stringify(path.basename(filename)); 12 | 13 | if (filename.match(/\.svg$/)) { 14 | // Based on how SVGR generates a component name: 15 | // https://github.com/smooth-code/svgr/blob/01b194cf967347d43d4cbe6b434404731b87cf27/packages/core/src/state.js#L6 16 | const pascalCaseFilename = camelcase(path.parse(filename).name, { 17 | pascalCase: true, 18 | }); 19 | const componentName = `Svg${pascalCaseFilename}`; 20 | return `const React = require('react'); 21 | module.exports = { 22 | __esModule: true, 23 | default: ${assetFilename}, 24 | ReactComponent: React.forwardRef(function ${componentName}(props, ref) { 25 | return { 26 | $$typeof: Symbol.for('react.element'), 27 | type: 'svg', 28 | ref: ref, 29 | key: null, 30 | props: Object.assign({}, props, { 31 | children: ${assetFilename} 32 | }) 33 | }; 34 | }), 35 | };`; 36 | } 37 | 38 | return `module.exports = ${assetFilename};`; 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /deck-layers-map/config/modules.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const paths = require('./paths'); 6 | const chalk = require('react-dev-utils/chalk'); 7 | const resolve = require('resolve'); 8 | 9 | /** 10 | * Get additional module paths based on the baseUrl of a compilerOptions object. 11 | * 12 | * @param {Object} options 13 | */ 14 | function getAdditionalModulePaths(options = {}) { 15 | const baseUrl = options.baseUrl; 16 | 17 | if (!baseUrl) { 18 | return ''; 19 | } 20 | 21 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl); 22 | 23 | // We don't need to do anything if `baseUrl` is set to `node_modules`. This is 24 | // the default behavior. 25 | if (path.relative(paths.appNodeModules, baseUrlResolved) === '') { 26 | return null; 27 | } 28 | 29 | // Allow the user set the `baseUrl` to `appSrc`. 30 | if (path.relative(paths.appSrc, baseUrlResolved) === '') { 31 | return [paths.appSrc]; 32 | } 33 | 34 | // If the path is equal to the root directory we ignore it here. 35 | // We don't want to allow importing from the root directly as source files are 36 | // not transpiled outside of `src`. We do allow importing them with the 37 | // absolute path (e.g. `src/Components/Button.js`) but we set that up with 38 | // an alias. 39 | if (path.relative(paths.appPath, baseUrlResolved) === '') { 40 | return null; 41 | } 42 | 43 | // Otherwise, throw an error. 44 | throw new Error( 45 | chalk.red.bold( 46 | "Your project's `baseUrl` can only be set to `src` or `node_modules`." + 47 | ' Create React App does not support other values at this time.' 48 | ) 49 | ); 50 | } 51 | 52 | /** 53 | * Get webpack aliases based on the baseUrl of a compilerOptions object. 54 | * 55 | * @param {*} options 56 | */ 57 | function getWebpackAliases(options = {}) { 58 | const baseUrl = options.baseUrl; 59 | 60 | if (!baseUrl) { 61 | return {}; 62 | } 63 | 64 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl); 65 | 66 | if (path.relative(paths.appPath, baseUrlResolved) === '') { 67 | return { 68 | src: paths.appSrc, 69 | }; 70 | } 71 | } 72 | 73 | /** 74 | * Get jest aliases based on the baseUrl of a compilerOptions object. 75 | * 76 | * @param {*} options 77 | */ 78 | function getJestAliases(options = {}) { 79 | const baseUrl = options.baseUrl; 80 | 81 | if (!baseUrl) { 82 | return {}; 83 | } 84 | 85 | const baseUrlResolved = path.resolve(paths.appPath, baseUrl); 86 | 87 | if (path.relative(paths.appPath, baseUrlResolved) === '') { 88 | return { 89 | '^src/(.*)$': '/src/$1', 90 | }; 91 | } 92 | } 93 | 94 | function getModules() { 95 | // Check if TypeScript is setup 96 | const hasTsConfig = fs.existsSync(paths.appTsConfig); 97 | const hasJsConfig = fs.existsSync(paths.appJsConfig); 98 | 99 | if (hasTsConfig && hasJsConfig) { 100 | throw new Error( 101 | 'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.' 102 | ); 103 | } 104 | 105 | let config; 106 | 107 | // If there's a tsconfig.json we assume it's a 108 | // TypeScript project and set up the config 109 | // based on tsconfig.json 110 | if (hasTsConfig) { 111 | const ts = require(resolve.sync('typescript', { 112 | basedir: paths.appNodeModules, 113 | })); 114 | config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config; 115 | // Otherwise we'll check if there is jsconfig.json 116 | // for non TS projects. 117 | } else if (hasJsConfig) { 118 | config = require(paths.appJsConfig); 119 | } 120 | 121 | config = config || {}; 122 | const options = config.compilerOptions || {}; 123 | 124 | const additionalModulePaths = getAdditionalModulePaths(options); 125 | 126 | return { 127 | additionalModulePaths: additionalModulePaths, 128 | webpackAliases: getWebpackAliases(options), 129 | jestAliases: getJestAliases(options), 130 | hasTsConfig, 131 | }; 132 | } 133 | 134 | module.exports = getModules(); 135 | -------------------------------------------------------------------------------- /deck-layers-map/config/paths.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath'); 6 | 7 | // Make sure any symlinks in the project folder are resolved: 8 | // https://github.com/facebook/create-react-app/issues/637 9 | const appDirectory = fs.realpathSync(process.cwd()); 10 | const resolveApp = relativePath => path.resolve(appDirectory, relativePath); 11 | 12 | // We use `PUBLIC_URL` environment variable or "homepage" field to infer 13 | // "public path" at which the app is served. 14 | // webpack needs to know it to put the right 169 | 170 | 171 | 172 | 173 | ``` 174 | 175 | If you like to just include the polyfills yourself, you could include them in 176 | `js/plugins.js`. When you have a bunch of polyfills to load in, you could also 177 | create a `polyfills.js` file in the `js/vendor` directory or include the files 178 | individually and combine them using a build tool. Always ensure that the 179 | polyfills are all loaded before any other JavaScript. 180 | 181 | There are some misconceptions about Modernizr and polyfills. It's important to 182 | understand that Modernizr just handles feature checking, not polyfilling itself. 183 | The only thing Modernizr does regarding polyfills is that the team maintains [a 184 | huge list of cross Browser 185 | polyfills](https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills). 186 | 187 | ### jQuery 188 | 189 | As of v8.0.0 we no longer include jQuery by default. Web development has 190 | changed a lot since we started this project and while many millions of sites 191 | still use jQuery there are many sites and applications that don't. 10 years ago 192 | jQuery _was_ JavaScript for most developers. That's not the case any more so 193 | we've made the decision to remove jQuery from the project. 194 | 195 | If you're interested in including it, you can easily install jQuery using the 196 | following command: 197 | 198 | ``` 199 | npm install jQuery 200 | ``` 201 | 202 | You can then copy the minified file into the `vendor` folder and add jQuery 203 | to the `index.html` manually. 204 | 205 | To load jQuery from a CDN with a local fallback you can use the following: 206 | 207 | ``` html 208 | 209 | 210 | ``` 211 | 212 | ### Google Universal Analytics Tracking Code 213 | 214 | Finally, an optimized version of the Google Universal Analytics tracking code is 215 | included. 216 | 217 | We use `analytics.js` rather than the newer `gtag.js` as [it's faster and 218 | supports tasks and 219 | plugins](https://github.com/philipwalton/analyticsjs-boilerplate/issues/19#issuecomment-333714370) 220 | 221 | Starting with version 8.0.0 we, by default, [anonymize IP 222 | addresses](https://support.google.com/analytics/answer/2763052). By 223 | default Google Analytics records the full IP address of a user visiting the 224 | site, but that full IP address is never available to the Google Analytics 225 | property admin. By anonymizing the IP address you can make your site more 226 | GDPR-compliant as a full IP address can be defined as PII (personally 227 | identifiable information.) 228 | 229 | The beacon transport mechanism is used to send all hits [which saves HTTP 230 | requests and improves 231 | performance](https://philipwalton.com/articles/the-google-analytics-setup-i-use-on-every-site-i-build/#loading-analytics.js). 232 | 233 | Google recommends that this script be placed at the top of the page. Factors to 234 | consider: if you place this script at the top of the page, you’ll be able to 235 | count users who don’t fully load the page, and you’ll incur the max number of 236 | simultaneous connections of the browser. 237 | 238 | Please be aware that while Google [states that it is fully GDPR compliant](https://privacy.google.com/businesses/compliance/), 239 | it is still possible to use analytics to violate GDPR. 240 | 241 | Further information: 242 | 243 | * [Introduction to 244 | Analytics.js](https://developers.google.com/analytics/devguides/collection/analyticsjs/) 245 | * [Google Analytics Demos & Tools](https://ga-dev-tools.appspot.com/) 246 | * [Privacy Controls in Google Analytics](https://support.google.com/analytics/answer/9019185) 247 | 248 | **N.B.** The Google Analytics snippet is included by default mainly because 249 | Google Analytics is [currently one of the most popular tracking 250 | solutions](https://trends.builtwith.com/analytics/Google-Analytics) out there. 251 | However, its usage isn't set in stone, and you SHOULD consider exploring the 252 | [alternatives](https://en.wikipedia.org/wiki/List_of_web_analytics_software) and 253 | use whatever suits your needs best. 254 | -------------------------------------------------------------------------------- /web-component-playground/doc/js.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) | [Documentation 2 | table of contents](TOC.md) 3 | 4 | # The JavaScript 5 | 6 | Information about the default JavaScript included in the project. 7 | 8 | ## main.js 9 | 10 | This file can be used to contain or reference your site/app JavaScript code. If 11 | you're working on something more advanced you might replace this file entirely. 12 | That's cool. 13 | 14 | ## plugins.js 15 | 16 | This file can be used to contain all your plugins, such as jQuery plugins and 17 | other 3rd party scripts for a simple site. 18 | 19 | One approach is to put jQuery plugins inside of a `(function($){ ...})(jQuery);` 20 | closure to make sure they're in the jQuery namespace safety blanket. Read more 21 | about [jQuery plugin authoring](https://learn.jquery.com/plugins/). 22 | 23 | By default the `plugins.js` file contains a small script to avoid `console` 24 | errors in browsers that lack a `console`. The script will make sure that, if a 25 | console method isn't available, that method will have the value of empty 26 | function, thus, preventing the browser from throwing an error. 27 | 28 | ## vendor 29 | 30 | This directory can be used to contain all 3rd party library code. 31 | 32 | Our custom build of the Modernizr library is included by 33 | default. You may wish to create your own [custom Modernizr build with the online 34 | builder](https://modernizr.com/download/) or [command line 35 | tool](https://modernizr.com/docs#command-line-config). 36 | -------------------------------------------------------------------------------- /web-component-playground/doc/misc.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) | [Documentation 2 | table of contents](TOC.md) 3 | 4 | # Miscellaneous 5 | 6 | * [.gitignore](#gitignore) 7 | * [.editorconfig](#editorconfig) 8 | * [Server Configuration](#server-configuration) 9 | * [robots.txt](#robotstxt) 10 | * [humans.txt](#humanstxt) 11 | * [browserconfig.xml](#browserconfigxml) 12 | * [package.json](#packagejson) 13 | 14 | -- 15 | 16 | ## .gitignore 17 | 18 | HTML5 Boilerplate includes a basic project-level `.gitignore`. This should 19 | primarily be used to avoid certain project-level files and directories from 20 | being kept under source control. Different development-environments will 21 | benefit from different collections of ignores. 22 | 23 | OS-specific and editor-specific files should be ignored using a "global 24 | ignore" that applies to all repositories on your system. 25 | 26 | For example, add the following to your `~/.gitconfig`, where the `.gitignore` 27 | in your HOME directory contains the files and directories you'd like to 28 | globally ignore: 29 | 30 | ```gitignore 31 | [core] 32 | excludesfile = ~/.gitignore 33 | ``` 34 | 35 | * More on global ignores: [https://help.github.com/articles/ignoring-files/](https://help.github.com/en/github/using-git/ignoring-files) 36 | * Comprehensive set of ignores on GitHub: https://github.com/github/gitignore 37 | 38 | ## .editorconfig 39 | 40 | The `.editorconfig` file is provided in order to encourage and help you and 41 | your team define and maintain consistent coding styles between different 42 | editors and IDEs. 43 | 44 | By default, `.editorconfig` includes some basic 45 | [properties](https://editorconfig.org/#supported-properties) that reflect the 46 | coding styles from the files provided by default, but you can easily change 47 | them to better suit your needs. 48 | 49 | In order for your editor/IDE to apply the 50 | [properties](https://editorconfig.org/#supported-properties) from the 51 | `.editorconfig` file, you may need to [install a 52 | plugin]( https://editorconfig.org/#download). 53 | 54 | __N.B.__ If you aren't using the server configurations provided by HTML5 55 | Boilerplate, we highly encourage you to configure your server to block 56 | access to `.editorconfig` files, as they can disclose sensitive information! 57 | 58 | For more details, please refer to the [EditorConfig 59 | project](https://editorconfig.org/). 60 | 61 | ## Server Configuration 62 | 63 | H5BP includes a [`.htaccess`](#htaccess) file for the [Apache HTTP 64 | server](https://httpd.apache.org/docs/). If you are not using Apache 65 | as your web server, then you are encouraged to download a 66 | [server configuration](https://github.com/h5bp/server-configs) that 67 | corresponds to your web server and environment. 68 | 69 | A `.htaccess` (hypertext access) file is an [Apache HTTP server 70 | configuration file](https://github.com/h5bp/server-configs-apache). 71 | The `.htaccess` file is mostly used for: 72 | 73 | * Rewriting URLs 74 | * Controlling cache 75 | * Authentication 76 | * Server-side includes 77 | * Redirects 78 | * Gzipping 79 | 80 | If you have access to the main server configuration file (usually called 81 | `httpd.conf`), you should add the logic from the `.htaccess` file in, for 82 | example, a `` section in the main configuration file. This is usually 83 | the recommended way, as using .htaccess files slows down Apache! 84 | 85 | To enable Apache modules locally, please see [the Apache modules documentation](https://github.com/h5bp/server-configs-apache#enable-apache-httpd-modules) 86 | 87 | In the repo the `.htaccess` is used for: 88 | 89 | * Allowing cross-origin access to web fonts 90 | * CORS header for images when browsers request it 91 | * Enable `404.html` as 404 error document 92 | * Making the website experience better for IE users better 93 | * Media UTF-8 as character encoding for `text/html` and `text/plain` 94 | * Enabling the rewrite URLs engine 95 | * Forcing or removing the `www.` at the begin of a URL 96 | * It blocks access to directories without a default document 97 | * It blocks access to files that can expose sensitive information. 98 | * It reduces MIME type security risks 99 | * It forces compressing (gzipping) 100 | * It tells the browser whether they should request a specific file from the 101 | server or whether they should grab it from the browser's cache 102 | 103 | When using `.htaccess` we recommend reading all inline comments (the rules after 104 | a `#`) in the file once. There is a bunch of optional stuff in it. 105 | 106 | If you want to know more about the `.htaccess` file check out the 107 | [Apache HTTP server docs](https://httpd.apache.org/docs/) or more 108 | specifically the [htaccess 109 | section](https://httpd.apache.org/docs/current/howto/htaccess.html). 110 | 111 | Notice that the original repo for the `.htaccess` file is [this 112 | one](https://github.com/h5bp/server-configs-apache). 113 | 114 | ## robots.txt 115 | 116 | The `robots.txt` file is used to give instructions to web robots on what can 117 | be crawled from the website. 118 | 119 | By default, the file provided by this project includes the next two lines: 120 | 121 | * `User-agent: *` - the following rules apply to all web robots 122 | * `Disallow:` - everything on the website is allowed to be crawled 123 | 124 | If you want to disallow certain pages you will need to specify the path in a 125 | `Disallow` directive (e.g.: `Disallow: /path`) or, if you want to disallow 126 | crawling of all content, use `Disallow: /`. 127 | 128 | The `/robots.txt` file is not intended for access control, so don't try to 129 | use it as such. Think of it as a "No Entry" sign, rather than a locked door. 130 | URLs disallowed by the `robots.txt` file might still be indexed without being 131 | crawled, and the content from within the `robots.txt` file can be viewed by 132 | anyone, potentially disclosing the location of your private content! So, if 133 | you want to block access to private content, use proper authentication instead. 134 | 135 | For more information about `robots.txt`, please see: 136 | 137 | * [robotstxt.org](https://www.robotstxt.org/) 138 | * [How Google handles the `robots.txt` file](https://developers.google.com/search/reference/robots_txt) 139 | 140 | ## humans.txt 141 | 142 | The `humans.txt` file is used to provide information about people involved with 143 | the website. 144 | 145 | The provided file contains three sections: 146 | 147 | * `TEAM` - this is intended to list the group of people responsible for the website 148 | * `THANKS` - this is intended to list the group of people that have contributed 149 | to the website 150 | * `TECHNOLOGY COLOPHON` - the section lists technologies used to make the website 151 | 152 | For more information about `humans.txt`, please see: http://humanstxt.org/ 153 | 154 | ## browserconfig.xml 155 | 156 | The `browserconfig.xml` file is used to customize the tile displayed when users 157 | pin your site to the Windows 8.1 start screen. In there you can define custom 158 | tile colors, custom images or even [live tiles](https://docs.microsoft.com/previous-versions/windows/internet-explorer/ie-developer/samples/dn455106(v=vs.85)). 159 | 160 | By default, the file points to 2 placeholder tile images: 161 | 162 | * `tile.png` (558x558px): used for `Small`, `Medium` and `Large` tiles. 163 | This image resizes automatically when necessary. 164 | * `tile-wide.png` (558x270px): user for `Wide` tiles. 165 | 166 | Notice that IE11 uses the same images when adding a site to the `favorites`. 167 | 168 | For more in-depth information about the `browserconfig.xml` file, please 169 | see [MSDN](https://docs.microsoft.com/previous-versions/windows/internet-explorer/ie-developer/platform-apis/dn320426(v=vs.85)). 170 | 171 | ## package.json 172 | 173 | `package.json` is used to define attributes of your site or application for 174 | use in modern JavaScript development. [The full documentation is available](https://docs.npmjs.com/files/package.json) 175 | if you're interested. The fields we provide are as follows: 176 | 177 | * `title` - the title of your project. If you expect to publish your application 178 | to npm, then the name needs to follow [certain guidelines](https://docs.npmjs.com/files/package.json#name) 179 | and be unique. 180 | * `version` - indicates the version of your site application using semantic 181 | versioning ([semver](https://docs.npmjs.com/misc/semver)) 182 | * `description` - describes your site. 183 | * `scripts` - is a JavaScript object containing commands that can be run in a 184 | node environment. There are many [built-in keys](https://docs.npmjs.com/misc/scripts) 185 | related to the package lifecycle that node understands automatically. You can 186 | also define custom scripts for use with your application development. We 187 | provide three custom scripts that work with Parcel to get you up and running 188 | quickly with a bundler for your assets and a simple development server. 189 | 190 | * `start` builds your site and starts a server 191 | * `build` builds your `index.html` using Parcel 192 | * `dev` serves your `index.html` with a simple development server 193 | 194 | * `keywords` - an array of keywords used to discover your app in the npm 195 | registry 196 | * `author` - defines the author of a package. There is also an alternative 197 | [contributors](https://docs.npmjs.com/files/package.json#people-fields-author-contributors) 198 | field if there's more than one author. 199 | * `license` - the license for your application. Must conform to 200 | [specific rules](https://docs.npmjs.com/files/package.json#license) 201 | * `devDependencies` - development dependencies for your package. In our case 202 | it's a single dependency, Parcel, which we use to bundle files and run a 203 | simple web server. 204 | -------------------------------------------------------------------------------- /web-component-playground/doc/usage.md: -------------------------------------------------------------------------------- 1 | [HTML5 Boilerplate homepage](https://html5boilerplate.com/) | [Documentation 2 | table of contents](TOC.md) 3 | 4 | # Usage 5 | 6 | The most basic usage of HTML5 Boilerplate is to create a static site or simple 7 | app. Once you've downloaded or cloned the project, that process looks something 8 | like this: 9 | 10 | 1. Set up the basic structure of the site. 11 | 2. Add some content, style, and functionality. 12 | 3. Run your site locally to see how it looks. 13 | 4. Deploy your site. 14 | 15 | Cool, right? _It is_. That said, the smart defaults, baseline elements, default 16 | attribute values and various other utilities that HTML5 Boilerplate offers can 17 | serve as the foundation for whatever you're interested in building. 18 | 19 | Even the basic use-case of a simple static site can be enhanced by manipulating 20 | the code through an automated build process. Moving up in complexity HTML5 21 | Boilerplate can be integrated with whatever front-end framework, CMS or 22 | e-commerce platform you're working with. Mix-and-match to your heart's content. 23 | Use what you need (toss it in a blender if you need to) and discard the rest. 24 | HTML5 Boilerplate is a starting point, not a destination. 25 | 26 | ## Basic structure 27 | 28 | A basic HTML5 Boilerplate site initially looks something like this: 29 | 30 | ``` 31 | . 32 | ├── css 33 | │ ├── main.css 34 | │ └── normalize.css 35 | ├── doc 36 | ├── img 37 | ├── js 38 | │ ├── main.js 39 | │ ├── plugins.js 40 | │ └── vendor 41 | │ └── modernizr.min.js 42 | ├── .editorconfig 43 | ├── .htaccess 44 | ├── 404.html 45 | ├── browserconfig.xml 46 | ├── favicon.ico 47 | ├── humans.txt 48 | ├── icon.png 49 | ├── index.html 50 | ├── package.json 51 | ├── robots.txt 52 | ├── site.webmanifest 53 | ├── tile.png 54 | └── tile-wide.png 55 | ``` 56 | 57 | What follows is a general overview of each major part and how to use them. 58 | 59 | ### css 60 | 61 | This directory should contain all your project's CSS files. It includes some 62 | initial CSS to help get you started from a solid foundation. [About the 63 | CSS](css.md). 64 | 65 | ### doc 66 | 67 | This directory contains all the HTML5 Boilerplate documentation. You can use it 68 | as the location and basis for your own project's documentation. 69 | 70 | ### js 71 | 72 | This directory should contain all your project's JS files. Libraries, plugins, 73 | and custom code can all be included here. It includes some initial JS to help 74 | get you started. [About the JavaScript](js.md). 75 | 76 | ### .htaccess 77 | 78 | The default web server configs are for Apache. For more information, please 79 | refer to the [Apache Server Configs 80 | repository](https://github.com/h5bp/server-configs-apache). 81 | 82 | Host your site on a server other than Apache? You're likely to find the 83 | corresponding server configs project listed in our [Server 84 | Configs](https://github.com/h5bp/server-configs/blob/master/README.md) 85 | repository. 86 | 87 | ### 404.html 88 | 89 | A helpful custom 404 to get you started. 90 | 91 | ### browserconfig.xml 92 | 93 | This file contains all settings regarding custom tiles for IE11 and Edge. 94 | 95 | For more info on this topic, please refer to [Microsoft's 96 | Docs](https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/platform-apis/dn320426(v=vs.85)). 97 | 98 | ### .editorconfig 99 | 100 | The `.editorconfig` file is provided in order to encourage and help you and your 101 | team to maintain consistent coding styles between different editors and IDEs. 102 | [Read more about the `.editorconfig` file](misc.md#editorconfig). 103 | 104 | ### index.html 105 | 106 | This is the default HTML skeleton that should form the basis of all pages on 107 | your site. If you are using a server-side templating framework, then you will 108 | need to integrate this starting HTML with your setup. 109 | 110 | Make sure that you update the URLs for the referenced CSS and JavaScript if you 111 | modify the directory structure at all. 112 | 113 | If you are using Google Universal Analytics, make sure that you edit the 114 | corresponding snippet at the bottom to include your analytics ID. 115 | 116 | ### humans.txt 117 | 118 | Edit this file to include the team that worked on your site/app, and the 119 | technology powering it. 120 | 121 | ### package.json 122 | 123 | Edit this file to describe your application, add dependencies, scripts and 124 | other properties related to node based development and the npm registry 125 | 126 | ### robots.txt 127 | 128 | Edit this file to include any pages you need hidden from search engines. 129 | 130 | ### Icons 131 | 132 | Replace the default `favicon.ico`, `tile.png`, `tile-wide.png` and Apple Touch 133 | Icon with your own. 134 | 135 | If you want to use different Apple Touch Icons for different resolutions please 136 | refer to the [according documentation](extend.md#apple-touch-icons). 137 | -------------------------------------------------------------------------------- /web-component-playground/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriszrc/foss4g-2021-react-mapbox/df4f8a4bcb2d2e0324155adc7fe124e1b8b2c091/web-component-playground/favicon.ico -------------------------------------------------------------------------------- /web-component-playground/humans.txt: -------------------------------------------------------------------------------- 1 | # humanstxt.org/ 2 | # The humans responsible & technology colophon 3 | 4 | # TEAM 5 | 6 | -- -- 7 | 8 | # THANKS 9 | 10 | 11 | 12 | # TECHNOLOGY COLOPHON 13 | 14 | CSS3, HTML5 15 | Apache Server Configs, jQuery, Modernizr, Normalize.css 16 | -------------------------------------------------------------------------------- /web-component-playground/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriszrc/foss4g-2021-react-mapbox/df4f8a4bcb2d2e0324155adc7fe124e1b8b2c091/web-component-playground/icon.png -------------------------------------------------------------------------------- /web-component-playground/img/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chriszrc/foss4g-2021-react-mapbox/df4f8a4bcb2d2e0324155adc7fe124e1b8b2c091/web-component-playground/img/.gitignore -------------------------------------------------------------------------------- /web-component-playground/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 31 |

Hello world! This is HTML5 Boilerplate.

32 |
33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /web-component-playground/js/main.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import retargetEvents from "react-shadow-dom-retarget-events"; 4 | import { StylesProvider, jssPreset } from "@material-ui/styles"; 5 | import { create } from "jss"; 6 | import { LayerDrawer } from "rmg-component-lib"; 7 | 8 | export default class LayerDrawerWc extends HTMLElement { 9 | mountPoint; //: HTMLSpanElement; 10 | reactRoot; 11 | // title; //: string; 12 | 13 | constructor() { 14 | super(); 15 | this.mountPoint = document.createElement("div"); 16 | this.reactRoot = this.appendChild(this.mountPoint); 17 | 18 | // const shadowRoot = this.attachShadow({ mode: "open" }); 19 | // this.mountPoint = document.createElement("span"); 20 | // this.reactRoot = shadowRoot.appendChild(this.mountPoint); 21 | } 22 | 23 | createCollapsed(props, reactRoot) { 24 | const layerDrawer = React.createElement( 25 | LayerDrawer, 26 | { 27 | // layers: [ 28 | // { 29 | // id: "Airports", 30 | // getFillColor: [200, 0, 80, 180], 31 | // }, 32 | // { 33 | // id: "Arcs", 34 | // getSourceColor: [0, 128, 200], 35 | // }, 36 | // { 37 | // id: "H3 Radio Sources", 38 | // getFillColor: (d) => [255, (1 - d.count / 50) * 255, 0], 39 | // }, 40 | // ], 41 | // activeLayerIds: ["H3 Radio Sources"], 42 | layers: props.layers, 43 | activeLayerIds: props["active-layer-ids"], 44 | onActiveLayerChange: (activeLayerIds) => console.log(activeLayerIds), 45 | }, 46 | React.createElement("slot") 47 | ); 48 | 49 | // now we use that saved reference to create a JSS configuration 50 | const jss = create({ 51 | ...jssPreset(), 52 | insertionPoint: reactRoot, 53 | }); 54 | 55 | //TODO but now how to we pass children elements to the react slot of layer drawer? 56 | const styleProvider = React.createElement( 57 | StylesProvider, 58 | { jss }, 59 | layerDrawer 60 | ); 61 | // return layerDrawer; 62 | return styleProvider; 63 | } 64 | 65 | getJsonAttributes(observedAttributes) { 66 | return observedAttributes.reduce((acc, cur) => { 67 | acc[cur] = JSON.parse(this.getAttribute(cur)); 68 | return acc; 69 | }, {}); 70 | } 71 | 72 | connectedCallback() { 73 | //TODO how to get the styles injected into the shadowroot? 74 | // const shadowRoot = this.attachShadow({ mode: "open" }); 75 | // const reactRoot = shadowRoot.appendChild(this.mountPoint); 76 | 77 | const props = this.getJsonAttributes(LayerDrawerWc.observedAttributes); 78 | 79 | ReactDOM.render( 80 | this.createCollapsed(props, this.reactRoot), 81 | this.mountPoint 82 | ); 83 | // retargetEvents(shadowRoot); 84 | } 85 | 86 | /** 87 | * NOTE only called for attributes listed in the #observedAttributes 88 | * @param {*} name 89 | * @param {*} oldValue 90 | * @param {*} newValue 91 | */ 92 | attributeChangedCallback(name, oldValue, newValue) { 93 | if (LayerDrawerWc.observedAttributes.includes(name)) { 94 | const props = this.getJsonAttributes(LayerDrawerWc.observedAttributes); 95 | ReactDOM.render( 96 | this.createCollapsed(props, this.reactRoot), 97 | this.mountPoint 98 | ); 99 | } 100 | } 101 | 102 | /** 103 | * List the attributes here for which we want to listen for changes 104 | */ 105 | static get observedAttributes() { 106 | return ["active-layer-ids", "layers"]; 107 | } 108 | } 109 | 110 | window.customElements.define("layer-drawer", LayerDrawerWc); 111 | 112 | // ReactDOM.render(, document.getElementById("root")); 113 | -------------------------------------------------------------------------------- /web-component-playground/js/plugins.js: -------------------------------------------------------------------------------- 1 | // Avoid `console` errors in browsers that lack a console. 2 | (function() { 3 | var method; 4 | var noop = function () {}; 5 | var methods = [ 6 | 'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error', 7 | 'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 8 | 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 9 | 'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn' 10 | ]; 11 | var length = methods.length; 12 | var console = (window.console = window.console || {}); 13 | 14 | while (length--) { 15 | method = methods[length]; 16 | 17 | // Only stub undefined methods. 18 | if (!console[method]) { 19 | console[method] = noop; 20 | } 21 | } 22 | }()); 23 | 24 | // Place any jQuery/helper plugins in here. 25 | -------------------------------------------------------------------------------- /web-component-playground/js/vendor/modernizr-3.11.2.min.js: -------------------------------------------------------------------------------- 1 | /*! modernizr 3.11.2 (Custom Build) | MIT * 2 | * https://modernizr.com/download/?-cssanimations-csscolumns-customelements-flexbox-history-picture-pointerevents-postmessage-sizes-srcset-webgl-websockets-webworkers-addtest-domprefixes-hasevent-mq-prefixedcssvalue-prefixes-setclasses-testallprops-testprop-teststyles !*/ 3 | !function(e,t,n,r){function o(e,t){return typeof e===t}function i(e){var t=_.className,n=Modernizr._config.classPrefix||"";if(S&&(t=t.baseVal),Modernizr._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}Modernizr._config.enableClasses&&(e.length>0&&(t+=" "+n+e.join(" "+n)),S?_.className.baseVal=t:_.className=t)}function s(e,t){if("object"==typeof e)for(var n in e)k(e,n)&&s(n,e[n]);else{e=e.toLowerCase();var r=e.split("."),o=Modernizr[r[0]];if(2===r.length&&(o=o[r[1]]),void 0!==o)return Modernizr;t="function"==typeof t?t():t,1===r.length?Modernizr[r[0]]=t:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=t),i([(t&&!1!==t?"":"no-")+r.join("-")]),Modernizr._trigger(e,t)}return Modernizr}function a(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):S?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function l(){var e=n.body;return e||(e=a(S?"svg":"body"),e.fake=!0),e}function u(e,t,r,o){var i,s,u,f,c="modernizr",d=a("div"),p=l();if(parseInt(r,10))for(;r--;)u=a("div"),u.id=o?o[r]:c+(r+1),d.appendChild(u);return i=a("style"),i.type="text/css",i.id="s"+c,(p.fake?p:d).appendChild(i),p.appendChild(d),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(n.createTextNode(e)),d.id=c,p.fake&&(p.style.background="",p.style.overflow="hidden",f=_.style.overflow,_.style.overflow="hidden",_.appendChild(p)),s=t(d,e),p.fake?(p.parentNode.removeChild(p),_.style.overflow=f,_.offsetHeight):d.parentNode.removeChild(d),!!s}function f(e,n,r){var o;if("getComputedStyle"in t){o=getComputedStyle.call(t,e,n);var i=t.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(i){var s=i.error?"error":"log";i[s].call(i,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else o=!n&&e.currentStyle&&e.currentStyle[r];return o}function c(e,t){return!!~(""+e).indexOf(t)}function d(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function p(e,n){var o=e.length;if("CSS"in t&&"supports"in t.CSS){for(;o--;)if(t.CSS.supports(d(e[o]),n))return!0;return!1}if("CSSSupportsRule"in t){for(var i=[];o--;)i.push("("+d(e[o])+":"+n+")");return i=i.join(" or "),u("@supports ("+i+") { #modernizr { position: absolute; } }",function(e){return"absolute"===f(e,null,"position")})}return r}function m(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function h(e,t,n,i){function s(){u&&(delete N.style,delete N.modElem)}if(i=!o(i,"undefined")&&i,!o(n,"undefined")){var l=p(e,n);if(!o(l,"undefined"))return l}for(var u,f,d,h,A,v=["modernizr","tspan","samp"];!N.style&&v.length;)u=!0,N.modElem=a(v.shift()),N.style=N.modElem.style;for(d=e.length,f=0;f