├── .gitattributes ├── .eslintrc ├── assets ├── logo.png └── theme │ └── parallax.css ├── icons ├── icon16.png ├── icon48.png └── icon128.png ├── fonts ├── ionicons.eot ├── ionicons.ttf ├── ionicons.woff ├── roboto-v15-latin-100.woff ├── roboto-v15-latin-300.woff ├── roboto-v15-latin-500.woff ├── roboto-v15-latin-700.woff ├── roboto-v15-latin-900.woff ├── roboto-v15-latin-100.woff2 ├── roboto-v15-latin-300.woff2 ├── roboto-v15-latin-500.woff2 ├── roboto-v15-latin-700.woff2 ├── roboto-v15-latin-900.woff2 ├── roboto-v15-latin-italic.woff ├── roboto-v15-latin-italic.woff2 ├── roboto-v15-latin-regular.woff ├── roboto-v15-latin-regular.woff2 ├── roboto-v15-latin-100italic.woff ├── roboto-v15-latin-100italic.woff2 ├── roboto-v15-latin-300italic.woff ├── roboto-v15-latin-300italic.woff2 ├── roboto-v15-latin-500italic.woff ├── roboto-v15-latin-500italic.woff2 ├── roboto-v15-latin-700italic.woff ├── roboto-v15-latin-700italic.woff2 ├── roboto-v15-latin-900italic.woff ├── roboto-v15-latin-900italic.woff2 └── roboto.css ├── readme-images ├── clone-ParallaxIDE.png ├── parallaxIDE-listed.png ├── chrome-app-launcher.png ├── enable-developer-mode.png ├── parallaxIDE-launched.png ├── select-extension-folder.png ├── load-unpacked-extensions.png └── search-chrome-app-launcher.png ├── src ├── lib │ ├── history.js │ ├── directive.js │ ├── highlighter.js │ ├── documents.js │ ├── scroller.js │ └── terminal.js ├── store.js ├── constants │ ├── queued-action-types.js │ └── action-types.js ├── creators │ ├── rx-off.js │ ├── tx-off.js │ ├── echo-on.js │ ├── connect.js │ ├── echo-off.js │ ├── disconnect.js │ ├── rx-on.js │ ├── tx-on.js │ ├── queue-new-file.js │ ├── reload-devices.js │ ├── transmit.js │ ├── rx-clear-timeout.js │ ├── tx-clear-timeout.js │ ├── reset-action-queue.js │ ├── clear-transmission.js │ ├── clear-search-status.js │ ├── enable-auto-download.js │ ├── receive.js │ ├── disable-auto-download.js │ ├── update-devices.js │ ├── reset-download-progress.js │ ├── update-duration.js │ ├── queue-change-file.js │ ├── update-search-status.js │ ├── delete-project-confirm.js │ ├── queue-overwrite-file.js │ ├── update-selected-device.js │ ├── update-download-progress.js │ └── index.js ├── views │ ├── appbar.js │ ├── editor.js │ ├── help-overlay.js │ ├── delete-project-overlay.js │ ├── overwrite-overlay.js │ ├── new-version-overlay.js │ ├── delete-file-overlay.js │ ├── terminal.js │ ├── layout.js │ ├── sidebar.js │ ├── save-overlay.js │ ├── rxtx.js │ ├── project-overlay.js │ └── download-overlay.js ├── plugins │ ├── examples.js │ ├── notifications.js │ └── keyboard-shortcuts.js ├── components │ ├── file-list.js │ ├── delete-button.js │ ├── button.js │ ├── overlay-title.js │ ├── file-operation-list-item.js │ ├── project-list-item.js │ ├── project-list.js │ ├── baud.js │ ├── file-operation-list.js │ ├── sidebar.js │ ├── overlay-footer.js │ ├── card.js │ ├── top-bar.js │ ├── progress-bar.js │ ├── projects-button.js │ ├── icon-button.js │ ├── file-list-item.js │ ├── overlay.js │ └── transmit-pane.js ├── reducers │ ├── delete-project-name.js │ ├── index.js │ ├── device-list.js │ ├── echo.js │ ├── download-progress.js │ ├── next-file.js │ ├── overlay-state.js │ ├── next-action.js │ ├── transmission.js │ ├── rxtx.js │ └── device.js ├── console-store.js └── code-mirror.js ├── zuul.config.js ├── test └── index.js ├── examples ├── HIGH_LOW.bs2 ├── PAUSE.bs2 ├── STOP.bs2 ├── SLEEP.bs2 ├── NAP.bs2 ├── DEBUG_DEBUGIN.bs2 ├── GOTO.bs2 ├── RCTIME1.bs2 ├── PULSOUT.bs2 ├── LOOKUP.bs2 ├── BRANCH.bs2 ├── ON-GOTO.bs2 ├── EXIT.bs2 ├── TOGGLE.bs2 ├── LOOKDOWN.bs2 ├── ON-GOSUB.bs2 ├── FOR-NEXT.bs2 ├── READ.bs2 ├── RETURN.bs2 ├── BUTTON.bs2 ├── IF-THEN.bs2 ├── PWM.bs2 ├── INPUT_OUTPUT.bs2 ├── WRITE.bs2 ├── REVERSE.bs2 ├── RCTIME2.bs2 ├── IF-THEN-ELSE.bs2 ├── SHIFTIN.bs2 ├── DO-LOOP.bs2 ├── AUX_TERM.bs2 ├── COUNT.bs2 ├── RANDOM.bs2 ├── PULSIN.bs2 ├── SERIN_SEROUT1.bs2 ├── SHIFTOUT.bs2 ├── LCDCMD.bs2 ├── LCDINIT.bs2 ├── SERIN_SEROUT2.bs2 ├── SELECT-CASE.bs2 ├── FREQOUT.bs2 ├── LCDIN.bs2 ├── LCDOUT.bs2 ├── GOSUB.bs2 ├── I2C.bs2 ├── XOUT.bs2 ├── DTMFOUT.bs2 ├── OWIN_OWOUT.bs2 ├── STOREALL.bs2 └── DATA.bs2 ├── _locales └── en │ └── messages.json ├── .travis.yml ├── .editorconfig ├── MakeRelease ├── .gitignore ├── manifest.json ├── background.js ├── LICENSE ├── gulpfile.babel.js ├── webpack.config.js ├── index.html ├── package.json ├── client.js └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@phated/iceddev" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/assets/logo.png -------------------------------------------------------------------------------- /icons/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/icons/icon16.png -------------------------------------------------------------------------------- /icons/icon48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/icons/icon48.png -------------------------------------------------------------------------------- /fonts/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/ionicons.eot -------------------------------------------------------------------------------- /fonts/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/ionicons.ttf -------------------------------------------------------------------------------- /fonts/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/ionicons.woff -------------------------------------------------------------------------------- /icons/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/icons/icon128.png -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-100.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-100.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-300.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-500.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-500.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-700.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-900.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-100.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-100.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-300.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-500.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-700.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-900.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-italic.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-regular.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-regular.woff2 -------------------------------------------------------------------------------- /readme-images/clone-ParallaxIDE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/clone-ParallaxIDE.png -------------------------------------------------------------------------------- /readme-images/parallaxIDE-listed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/parallaxIDE-listed.png -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-100italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-100italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-100italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-100italic.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-300italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-300italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-300italic.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-500italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-500italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-500italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-500italic.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-700italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-700italic.woff2 -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-900italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-900italic.woff -------------------------------------------------------------------------------- /fonts/roboto-v15-latin-900italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/fonts/roboto-v15-latin-900italic.woff2 -------------------------------------------------------------------------------- /readme-images/chrome-app-launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/chrome-app-launcher.png -------------------------------------------------------------------------------- /readme-images/enable-developer-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/enable-developer-mode.png -------------------------------------------------------------------------------- /readme-images/parallaxIDE-launched.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/parallaxIDE-launched.png -------------------------------------------------------------------------------- /readme-images/select-extension-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/select-extension-folder.png -------------------------------------------------------------------------------- /readme-images/load-unpacked-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/load-unpacked-extensions.png -------------------------------------------------------------------------------- /readme-images/search-chrome-app-launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/parallaxinc/Parallax-IDE/HEAD/readme-images/search-chrome-app-launcher.png -------------------------------------------------------------------------------- /src/lib/history.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const memoryHistory = require('history/lib/createMemoryHistory')(); 4 | 5 | module.exports = memoryHistory; 6 | -------------------------------------------------------------------------------- /zuul.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | builder: 'zuul-builder-webpack', 5 | webpack: require('./webpack.config'), 6 | ui: 'mocha-bdd' 7 | }; 8 | -------------------------------------------------------------------------------- /src/store.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const createStore = require('@phated/redux-create-store'); 4 | 5 | const reducers = require('./reducers'); 6 | 7 | const store = createStore(reducers); 8 | 9 | module.exports = store; 10 | -------------------------------------------------------------------------------- /src/constants/queued-action-types.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const queuedActionTypes = { 4 | NEW_FILE: 'NEW_FILE', 5 | CHANGE_FILE: 'CHANGE_FILE', 6 | OVERWRITE_FILE: 'OVERWRITE_FILE' 7 | }; 8 | 9 | module.exports = queuedActionTypes; 10 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require('expect'); 4 | 5 | describe('Parallax IDE', function(){ 6 | 7 | it('has an example test', function(done){ 8 | expect(true).toEqual(true); 9 | done(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /src/creators/rx-off.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RX_OFF 5 | } = require('../constants/action-types'); 6 | 7 | function rxOff(){ 8 | return { 9 | type: RX_OFF, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = rxOff; 15 | -------------------------------------------------------------------------------- /src/creators/tx-off.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | TX_OFF 5 | } = require('../constants/action-types'); 6 | 7 | function txOff(){ 8 | return { 9 | type: TX_OFF, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = txOff; 15 | -------------------------------------------------------------------------------- /src/creators/echo-on.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | ECHO_ON 5 | } = require('../constants/action-types'); 6 | 7 | function echoOn(){ 8 | return { 9 | type: ECHO_ON, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = echoOn; 15 | -------------------------------------------------------------------------------- /src/creators/connect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | CONNECT 5 | } = require('../constants/action-types'); 6 | 7 | function connect(){ 8 | return { 9 | type: CONNECT, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = connect; 15 | -------------------------------------------------------------------------------- /src/creators/echo-off.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | ECHO_OFF 5 | } = require('../constants/action-types'); 6 | 7 | function echoOff(){ 8 | return { 9 | type: ECHO_OFF, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = echoOff; 15 | -------------------------------------------------------------------------------- /src/creators/disconnect.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | DISCONNECT 5 | } = require('../constants/action-types'); 6 | 7 | function disconnect(){ 8 | return { 9 | type: DISCONNECT, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = disconnect; 15 | -------------------------------------------------------------------------------- /src/creators/rx-on.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RX_ON 5 | } = require('../constants/action-types'); 6 | 7 | function rxOn(timeout){ 8 | return { 9 | type: RX_ON, 10 | payload: { 11 | timeout 12 | } 13 | }; 14 | } 15 | 16 | module.exports = rxOn; 17 | -------------------------------------------------------------------------------- /src/creators/tx-on.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | TX_ON 5 | } = require('../constants/action-types'); 6 | 7 | function txOn(timeout){ 8 | return { 9 | type: TX_ON, 10 | payload: { 11 | timeout 12 | } 13 | }; 14 | } 15 | 16 | module.exports = txOn; 17 | -------------------------------------------------------------------------------- /src/creators/queue-new-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | QUEUE_NEW_FILE 5 | } = require('../constants/action-types'); 6 | 7 | function queueNewFile(){ 8 | return { 9 | type: QUEUE_NEW_FILE, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = queueNewFile; 15 | -------------------------------------------------------------------------------- /src/creators/reload-devices.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RELOAD_DEVICES 5 | } = require('../constants/action-types'); 6 | 7 | function reloadDevices(){ 8 | return { 9 | type: RELOAD_DEVICES, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = reloadDevices; 15 | -------------------------------------------------------------------------------- /src/creators/transmit.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | TRANSMIT 5 | } = require('../constants/action-types'); 6 | 7 | function transmit(input){ 8 | return { 9 | type: TRANSMIT, 10 | payload: { 11 | input 12 | } 13 | }; 14 | } 15 | 16 | module.exports = transmit; 17 | -------------------------------------------------------------------------------- /src/creators/rx-clear-timeout.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RX_CLEAR_TIMEOUT 5 | } = require('../constants/action-types'); 6 | 7 | function rxClearTimeout(){ 8 | return { 9 | type: RX_CLEAR_TIMEOUT, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = rxClearTimeout; 15 | -------------------------------------------------------------------------------- /src/creators/tx-clear-timeout.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | TX_CLEAR_TIMEOUT 5 | } = require('../constants/action-types'); 6 | 7 | function txClearTimeout(){ 8 | return { 9 | type: TX_CLEAR_TIMEOUT, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = txClearTimeout; 15 | -------------------------------------------------------------------------------- /src/creators/reset-action-queue.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RESET_ACTION_QUEUE 5 | } = require('../constants/action-types'); 6 | 7 | function resetFileQueue(){ 8 | return { 9 | type: RESET_ACTION_QUEUE, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = resetFileQueue; 15 | -------------------------------------------------------------------------------- /src/creators/clear-transmission.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | CLEAR_TRANSMISSION 5 | } = require('../constants/action-types'); 6 | 7 | function clearTransmission(){ 8 | return { 9 | type: CLEAR_TRANSMISSION, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = clearTransmission; 15 | -------------------------------------------------------------------------------- /src/views/appbar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const TopBar = require('../components/top-bar'); 6 | 7 | class AppbarView extends React.Component { 8 | render(){ 9 | return ( 10 | 11 | ); 12 | } 13 | } 14 | 15 | module.exports = AppbarView; 16 | -------------------------------------------------------------------------------- /src/creators/clear-search-status.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | CLEAR_SEARCH_STATUS 5 | } = require('../constants/action-types'); 6 | 7 | function clearSearchStatus(){ 8 | return { 9 | type: CLEAR_SEARCH_STATUS, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = clearSearchStatus; 15 | -------------------------------------------------------------------------------- /src/creators/enable-auto-download.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | ENABLE_AUTO_DOWNLOAD 5 | } = require('../constants/action-types'); 6 | 7 | function enableAutoDownload(){ 8 | return { 9 | type: ENABLE_AUTO_DOWNLOAD, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = enableAutoDownload; 15 | -------------------------------------------------------------------------------- /src/creators/receive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RECEIVE 5 | } = require('../constants/action-types'); 6 | 7 | function receive(output, offset){ 8 | return { 9 | type: RECEIVE, 10 | payload: { 11 | output, 12 | offset 13 | } 14 | }; 15 | } 16 | 17 | module.exports = receive; 18 | -------------------------------------------------------------------------------- /src/creators/disable-auto-download.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | DISABLE_AUTO_DOWNLOAD 5 | } = require('../constants/action-types'); 6 | 7 | function disableAutoDownload(){ 8 | return { 9 | type: DISABLE_AUTO_DOWNLOAD, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = disableAutoDownload; 15 | -------------------------------------------------------------------------------- /src/creators/update-devices.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | UPDATE_DEVICES 5 | } = require('../constants/action-types'); 6 | 7 | function updateDevices(devices){ 8 | return { 9 | type: UPDATE_DEVICES, 10 | payload: { 11 | devices 12 | } 13 | }; 14 | } 15 | 16 | module.exports = updateDevices; 17 | -------------------------------------------------------------------------------- /src/plugins/examples.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function examples(app, opts, done){ 4 | const { handlers } = app; 5 | 6 | handlers.ensureExampleProject(opts.examples, opts.folder || 'examples') 7 | .then(function(){ 8 | return done(); 9 | }) 10 | .catch(done); 11 | } 12 | 13 | module.exports = examples; 14 | -------------------------------------------------------------------------------- /src/creators/reset-download-progress.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RESET_DOWNLOAD_PROGRESS 5 | } = require('../constants/action-types'); 6 | 7 | function resetDownloadProgress(){ 8 | return { 9 | type: RESET_DOWNLOAD_PROGRESS, 10 | payload: {} 11 | }; 12 | } 13 | 14 | module.exports = resetDownloadProgress; 15 | -------------------------------------------------------------------------------- /src/creators/update-duration.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | UPDATE_DURATION 5 | } = require('../constants/action-types'); 6 | 7 | function updateDuration(duration){ 8 | return { 9 | type: UPDATE_DURATION, 10 | payload: { 11 | duration 12 | } 13 | }; 14 | } 15 | 16 | module.exports = updateDuration; 17 | -------------------------------------------------------------------------------- /src/lib/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function device(type){ 4 | return `'{$STAMP ${type}}`; 5 | } 6 | 7 | function pbasic(ver){ 8 | return `'{$PBASIC ${ver}}`; 9 | } 10 | 11 | function directive(board, language){ 12 | return `${device(board)}\n${pbasic(language)}\n\n`; 13 | } 14 | 15 | module.exports = directive; 16 | -------------------------------------------------------------------------------- /examples/HIGH_LOW.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: HIGH_LOW 5 | 'This simple program sets I/O pin 0 high for 1/2 second and low for 6 | '1/2 second in an endless loop. Connect an LED to P0 for a simple 7 | 'blinker. 8 | 9 | Main: 10 | DO 11 | HIGH 0 12 | PAUSE 500 13 | LOW 0 14 | PAUSE 500 15 | LOOP 16 | -------------------------------------------------------------------------------- /src/creators/queue-change-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | QUEUE_CHANGE_FILE 5 | } = require('../constants/action-types'); 6 | 7 | function queueChangeFile(filename){ 8 | return { 9 | type: QUEUE_CHANGE_FILE, 10 | payload: { 11 | filename 12 | } 13 | }; 14 | } 15 | 16 | module.exports = queueChangeFile; 17 | -------------------------------------------------------------------------------- /src/creators/update-search-status.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | UPDATE_SEARCH_STATUS 5 | } = require('../constants/action-types'); 6 | 7 | function updateSearchStatus(status){ 8 | return { 9 | type: UPDATE_SEARCH_STATUS, 10 | payload: { 11 | status 12 | } 13 | }; 14 | } 15 | 16 | module.exports = updateSearchStatus; 17 | -------------------------------------------------------------------------------- /src/creators/delete-project-confirm.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | DELETE_PROJECT_CONFIRM 5 | } = require('../constants/action-types'); 6 | 7 | function deleteProjectConfirm(name){ 8 | return { 9 | type: DELETE_PROJECT_CONFIRM, 10 | payload: { 11 | name 12 | } 13 | }; 14 | } 15 | 16 | module.exports = deleteProjectConfirm; 17 | -------------------------------------------------------------------------------- /src/creators/queue-overwrite-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | QUEUE_OVERWRITE_FILE 5 | } = require('../constants/action-types'); 6 | 7 | function queueOverwriteFile(filename){ 8 | return { 9 | type: QUEUE_OVERWRITE_FILE, 10 | payload: { 11 | filename 12 | } 13 | }; 14 | } 15 | 16 | module.exports = queueOverwriteFile; 17 | -------------------------------------------------------------------------------- /src/creators/update-selected-device.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | UPDATE_SELECTED_DEVICE 5 | } = require('../constants/action-types'); 6 | 7 | function updateSelectedDevice(device){ 8 | return { 9 | type: UPDATE_SELECTED_DEVICE, 10 | payload: { 11 | device 12 | } 13 | }; 14 | } 15 | 16 | module.exports = updateSelectedDevice; 17 | -------------------------------------------------------------------------------- /src/creators/update-download-progress.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | UPDATE_DOWNLOAD_PROGRESS 5 | } = require('../constants/action-types'); 6 | 7 | function updateDownloadProgress(progress){ 8 | return { 9 | type: UPDATE_DOWNLOAD_PROGRESS, 10 | payload: { 11 | progress 12 | } 13 | }; 14 | } 15 | 16 | module.exports = updateDownloadProgress; 17 | -------------------------------------------------------------------------------- /examples/PAUSE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: PAUSE 5 | 'This program demonstrates the PAUSE command's time delays. Once a second, 6 | 'the program will put the message, "Paused..." on the screen. 7 | 8 | Init: 9 | PAUSE 200 'short startup-pause 10 | 11 | Main: 12 | DO 13 | DEBUG "Paused...", CR 14 | PAUSE 1000 15 | LOOP -------------------------------------------------------------------------------- /src/components/file-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const List = require('react-material/components/List'); 5 | 6 | class FileList extends React.Component { 7 | render(){ 8 | const { 9 | children 10 | } = this.props; 11 | 12 | return ( 13 | 14 | {children} 15 | 16 | ); 17 | } 18 | } 19 | 20 | module.exports = FileList; 21 | -------------------------------------------------------------------------------- /_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "appName": { 3 | "message": "Parallax IDE", 4 | "description": "The name of the application" 5 | }, 6 | "appDescription": { 7 | "message": "Write, compile, and download code to your Parallax Boe-Bot Robot or custom BASIC Stamp microcontroller-based electronic creations.", 8 | "description": "The description of the application" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/delete-button.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const IconButton = require('./icon-button'); 6 | 7 | class DeleteButton extends React.Component { 8 | render(){ 9 | const { 10 | onClick 11 | } = this.props; 12 | 13 | return ( 14 | 15 | ); 16 | } 17 | } 18 | 19 | module.exports = DeleteButton; 20 | -------------------------------------------------------------------------------- /src/components/button.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const ReactStyle = require('react-style'); 5 | 6 | export default class Button extends React.Component { 7 | render(){ 8 | const { 9 | children, 10 | onClick, 11 | } = this.props 12 | 13 | return( 14 | 15 | ) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/reducers/delete-project-name.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | DELETE_PROJECT_CONFIRM 5 | } = require('../constants/action-types'); 6 | 7 | const initial = ''; 8 | 9 | function deleteProjectName(state = initial, { type, payload }){ 10 | switch(type){ 11 | case DELETE_PROJECT_CONFIRM: 12 | return payload.name; 13 | default: 14 | return state; 15 | } 16 | } 17 | 18 | module.exports = deleteProjectName; 19 | -------------------------------------------------------------------------------- /src/components/overlay-title.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const styles = { 6 | overlayTitle: { 7 | margin: 0 8 | } 9 | }; 10 | 11 | class OverlayTitle extends React.Component { 12 | render(){ 13 | const { 14 | children 15 | } = this.props; 16 | 17 | return ( 18 |

{children}

19 | ); 20 | } 21 | } 22 | 23 | module.exports = OverlayTitle; 24 | -------------------------------------------------------------------------------- /src/reducers/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const reducers = { 4 | deleteProjectName: require('./delete-project-name'), 5 | overlayState: require('./overlay-state'), 6 | transmission: require('./transmission'), 7 | device: require('./device'), 8 | deviceList: require('./device-list'), 9 | downloadProgress: require('./download-progress'), 10 | nextFile: require('./next-file'), 11 | nextAction: require('./next-action') 12 | }; 13 | 14 | module.exports = reducers; 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '6' 5 | before_install: 6 | - 'export DISPLAY=:99.0' 7 | - 'sh -e /etc/init.d/xvfb start' 8 | script: npm run ci 9 | # whenever a tag is pushed, we deploy to github releases 10 | before_deploy: npm run release 11 | deploy: 12 | provider: releases 13 | api_key: $GH_TOKEN 14 | file: "dist/parallax-ide.zip" 15 | skip_cleanup: true 16 | on: 17 | tags: true 18 | node: '6' 19 | all_branches: true 20 | -------------------------------------------------------------------------------- /examples/STOP.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: STOP 5 | 'This program is similar to END, NAP, and SLEEP except that the LED 6 | 'will not blink since the STOP command prevents the BASIC Stamp from 7 | 'entering low power mode at the end of the code. Use the circuit 8 | 'shown in the description of the SLEEP command for this example. 9 | 10 | Main: 11 | LOW 0 'turn LED on 12 | STOP 'stop program -------------------------------------------------------------------------------- /src/reducers/device-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RELOAD_DEVICES, 5 | UPDATE_DEVICES 6 | } = require('../constants/action-types'); 7 | 8 | const initial = []; 9 | 10 | function deviceList(state = initial, { type, payload }){ 11 | switch(type){ 12 | case RELOAD_DEVICES: 13 | return initial; 14 | case UPDATE_DEVICES: 15 | return payload.devices; 16 | default: 17 | return state; 18 | } 19 | } 20 | 21 | module.exports = deviceList; 22 | -------------------------------------------------------------------------------- /src/components/file-operation-list-item.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { ChildButton } = require('react-mfb-iceddev'); 5 | 6 | class FileOperationListItem extends React.Component { 7 | render(){ 8 | const { 9 | onClick, 10 | icon, 11 | label 12 | } = this.props; 13 | 14 | return ( 15 | 16 | ); 17 | } 18 | } 19 | 20 | module.exports = FileOperationListItem; 21 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /src/reducers/echo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | Don't include this in the index.js because it is used only 5 | for the console-store 6 | */ 7 | 8 | const { 9 | ECHO_OFF, 10 | ECHO_ON 11 | } = require('../constants/action-types'); 12 | 13 | const initial = false; 14 | 15 | function echo(state = initial, { type }){ 16 | switch(type){ 17 | case ECHO_OFF: 18 | return false; 19 | case ECHO_ON: 20 | return true; 21 | default: 22 | return state; 23 | } 24 | } 25 | 26 | module.exports = echo; 27 | -------------------------------------------------------------------------------- /src/components/project-list-item.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | class Project extends React.Component { 6 | render(){ 7 | const { 8 | onClick, 9 | children 10 | } = this.props; 11 | 12 | const liStyle = { 13 | listStyleType: 'none', 14 | padding: "14px 16px 15px" 15 | } 16 | 17 | return ( 18 |
  • 19 | {children} 20 |
  • 21 | ); 22 | } 23 | } 24 | 25 | module.exports = Project; 26 | -------------------------------------------------------------------------------- /src/reducers/download-progress.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | RESET_DOWNLOAD_PROGRESS, 5 | UPDATE_DOWNLOAD_PROGRESS 6 | } = require('../constants/action-types'); 7 | 8 | const initial = 0; 9 | 10 | function downloadProgress(state = initial, { type, payload }){ 11 | switch(type){ 12 | case RESET_DOWNLOAD_PROGRESS: 13 | return initial; 14 | case UPDATE_DOWNLOAD_PROGRESS: 15 | return payload.progress; 16 | default: 17 | return state; 18 | } 19 | } 20 | 21 | module.exports = downloadProgress; 22 | -------------------------------------------------------------------------------- /src/console-store.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | The terminal console is causing too many renders on components 5 | throughout the application. We could implement finer-grained 6 | subscribes through lenses but for now, just create a new store. 7 | */ 8 | 9 | const createStore = require('@phated/redux-create-store'); 10 | 11 | const reducers = { 12 | echo: require('./reducers/echo'), 13 | rxtx: require('./reducers/rxtx') 14 | }; 15 | 16 | const consoleStore = createStore(reducers); 17 | 18 | module.exports = consoleStore; 19 | -------------------------------------------------------------------------------- /src/components/project-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const List = require('react-material/components/List'); 5 | 6 | const styles = { 7 | projectList: { 8 | flex: 1, 9 | marginTop: 10 10 | } 11 | }; 12 | 13 | class ProjectsList extends React.Component { 14 | render(){ 15 | const { 16 | children 17 | } = this.props; 18 | 19 | return ( 20 | 21 | {children} 22 | 23 | ); 24 | } 25 | } 26 | 27 | module.exports = ProjectsList; 28 | -------------------------------------------------------------------------------- /src/components/baud.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const styles = { 6 | baud: { 7 | float: 'left', 8 | padding: '3px 0px 0px 10px', 9 | margin: 0 10 | }, 11 | baudRate: { 12 | paddingLeft: 8 13 | } 14 | }; 15 | 16 | class Baud extends React.Component { 17 | 18 | render() { 19 | const baudRate = 115200; 20 | 21 | return ( 22 | 23 | BAUD {baudRate} 24 | 25 | ); 26 | } 27 | } 28 | 29 | module.exports = Baud; 30 | -------------------------------------------------------------------------------- /src/components/file-operation-list.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { Menu, MainButton } = require('react-mfb-iceddev'); 5 | 6 | class FileOperationList extends React.Component { 7 | render(){ 8 | const { 9 | children 10 | } = this.props; 11 | 12 | return ( 13 | 14 | 15 | {children} 16 | 17 | ); 18 | } 19 | } 20 | 21 | module.exports = FileOperationList; 22 | -------------------------------------------------------------------------------- /src/reducers/next-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | QUEUE_CHANGE_FILE, 5 | QUEUE_OVERWRITE_FILE, 6 | RESET_ACTION_QUEUE 7 | } = require('../constants/action-types'); 8 | 9 | const initial = ''; 10 | 11 | function nextFile(state = initial, { type, payload }){ 12 | switch(type){ 13 | case QUEUE_CHANGE_FILE: 14 | return payload.filename; 15 | case QUEUE_OVERWRITE_FILE: 16 | return payload.filename; 17 | case RESET_ACTION_QUEUE: 18 | return initial; 19 | default: 20 | return state; 21 | } 22 | } 23 | 24 | module.exports = nextFile; 25 | -------------------------------------------------------------------------------- /src/components/sidebar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const Card = require('./card'); 6 | 7 | const styles = { 8 | card: { 9 | margin: 0, 10 | height: '80vh', 11 | width: '100%', 12 | display: 'flex', 13 | flexDirection: 'column' 14 | } 15 | }; 16 | 17 | class Sidebar extends React.Component { 18 | render(){ 19 | const { 20 | children 21 | } = this.props; 22 | 23 | return ( 24 | 25 | {children} 26 | 27 | ); 28 | } 29 | } 30 | 31 | module.exports = Sidebar; 32 | -------------------------------------------------------------------------------- /examples/SLEEP.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SLEEP 5 | 'This program lights an LED and then goes to sleep. Connect an LED to pin 6 | '0 as shown in the description of SLEEP in the manual and run the program. 7 | 'The LED will turn on, then the BASIC Stamp will go to sleep. During sleep, 8 | 'the LED will remain on, but will blink at intervals of approximately 2.3 9 | 'seconds due to the watchdog timeout and reset. 10 | 11 | Main: 12 | LOW 0 'turn LED on 13 | 14 | Snooze: 15 | DO 16 | SLEEP 10 'sleep for about 10 seconds 17 | LOOP -------------------------------------------------------------------------------- /examples/NAP.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: NAP 5 | 'This program lights an LED setting pin 0 low. This completes the circuit 6 | 'from +5V, through the LED and resistor, to ground. During the NAP interval, 7 | 'the LED stays lit, but blinks off for a fraction of a second. This blink 8 | 'is caused by the NAP wake-up mechanism. During wake-up, all pins briefly 9 | 'slip into input mode, effectively disconnecting them from loads. 10 | 11 | Setup: 12 | LOW 0 'turn LED on 13 | 14 | Snooze: 15 | DO 16 | NAP 4 'nap for fraction of a second 17 | LOOP -------------------------------------------------------------------------------- /src/reducers/overlay-state.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | SHOW_OVERLAY, 5 | HIDE_OVERLAY 6 | } = require('../constants/action-types'); 7 | 8 | const initial = ''; 9 | 10 | function overlayState(state = initial, { type, payload }){ 11 | switch(type){ 12 | case SHOW_OVERLAY: 13 | return payload.state; 14 | case HIDE_OVERLAY: 15 | return payload.state; 16 | default: 17 | // We only want overlay to flash once, so if any action is 18 | // dispatched that isn't an action we are watching, reset 19 | // to initial 20 | return initial; 21 | } 22 | } 23 | 24 | module.exports = overlayState; 25 | -------------------------------------------------------------------------------- /src/lib/highlighter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const cm = require('../code-mirror'); 4 | 5 | function highlighter(position, length) { 6 | const doc = cm.getDoc(); 7 | 8 | const anchor = doc.posFromIndex(position); 9 | const head = doc.posFromIndex(position + length); 10 | 11 | doc.setSelection(anchor, head, { scroll: false }); 12 | 13 | const charRect = cm.charCoords(anchor, 'local'); 14 | const halfHeight = cm.getScrollerElement().offsetHeight / 2; 15 | const halfTextHeight = Math.floor((charRect.bottom - charRect.top) / 2); 16 | cm.scrollTo(null, charRect.top - halfHeight - halfTextHeight); 17 | } 18 | 19 | module.exports = highlighter; 20 | -------------------------------------------------------------------------------- /src/components/overlay-footer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const React = require('react'); 5 | 6 | const styles = { 7 | overlayButtonContainer: { 8 | marginTop: 'auto', 9 | marginLeft: 'auto', 10 | height: '40px' 11 | } 12 | }; 13 | 14 | class OverlayFooter extends React.Component { 15 | render(){ 16 | const { 17 | children, 18 | style 19 | } = this.props; 20 | 21 | const footerStyle = _.assign({}, styles.overlayButtonContainer, style); 22 | 23 | return ( 24 |
    25 | {children} 26 |
    27 | ); 28 | } 29 | } 30 | 31 | module.exports = OverlayFooter; 32 | -------------------------------------------------------------------------------- /MakeRelease: -------------------------------------------------------------------------------- 1 | echo 2 | echo ---Making Chrome App release in ./release folder--- 3 | echo 4 | echo STEP 1 of 2: Clearing ./release folder 5 | echo 6 | # Clear release folder 7 | rm -R release/* 8 | 9 | echo 10 | echo STEP 2 of 2: Copying resources to ./release folder 11 | echo 12 | # Copy static resources 13 | cp -R assets release/assets 14 | cp -R examples release/examples 15 | cp -R fonts release/fonts 16 | cp -R icons release/icons 17 | cp -R _locales release/_locales 18 | cp background.js release/ 19 | cp bundle.js release/ 20 | cp index.html release/ 21 | cp manifest.json release/ 22 | 23 | echo Done! 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/components/card.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const React = require('react'); 5 | 6 | const defaultStyle = { 7 | boxShadow: '0 2px 2px 0 rgba(0,0,0,.14),0 3px 1px -2px rgba(0,0,0,.2),0 1px 5px 0 rgba(0,0,0,.12)', 8 | backgroundColor: 'white', 9 | padding: '16px', 10 | borderRadius: '2px' 11 | }; 12 | 13 | class Card extends React.Component { 14 | render(){ 15 | const { 16 | style = {}, 17 | children 18 | } = this.props; 19 | 20 | const styles = _.assign({}, defaultStyle, style); 21 | 22 | return ( 23 |
    24 | {children} 25 |
    26 | ); 27 | } 28 | } 29 | 30 | module.exports = Card; 31 | -------------------------------------------------------------------------------- /src/components/top-bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const AppBar = require('react-material/components/AppBar'); 5 | 6 | const styles = { 7 | appbar: { 8 | normalAppBarStyle: { 9 | backgroundColor: '#2c83d8' 10 | } 11 | }, 12 | logo: { 13 | boxSizing: 'border-box', 14 | height: '100%', 15 | position: 'absolute', 16 | right: 0, 17 | padding: 8 18 | } 19 | }; 20 | 21 | class TopBar extends React.Component { 22 | render(){ 23 | return ( 24 | 25 | 26 | 27 | ); 28 | } 29 | } 30 | 31 | module.exports = TopBar; 32 | -------------------------------------------------------------------------------- /examples/DEBUG_DEBUGIN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: DEBUG_DEBUGIN 5 | 'This program demonstrates the ability to accept user input from the 6 | 'Debug Terminal, and to accept numeric entry in any valid format. 7 | 8 | myNum VAR Word 9 | 10 | Init: 11 | PAUSE 200 'short startup-pause 12 | 13 | Main: 14 | DO 15 | DEBUG CLS, "Enter a any number: " 'prompt user 16 | DEBUGIN SNUM myNum 'retrieve number in any format 17 | 18 | DEBUG CRSRXY, 0, 2, 'display number in all formats 19 | SDEC ? myNum, 20 | SHEX ? myNum, 21 | SBIN ? myNum 22 | PAUSE 3000 23 | LOOP 'do it again -------------------------------------------------------------------------------- /examples/GOTO.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: GOTO 5 | 'This program isn't practical at all, but demonstrates the use of GOTO to 6 | 'jump around the code. This code jumps between three different routines, 7 | 'each of which print something different on the screen. The routines are 8 | 'out of order for sake of example. 9 | 10 | Init: 11 | PAUSE 200 'short startup-pause 12 | 13 | Start: 14 | GOTO Routine1 15 | 16 | Routine2: 17 | DEBUG "We're in routine #2", CR 18 | PAUSE 1000 19 | GOTO Routine3 20 | 21 | Routine1: 22 | DEBUG "We're in routine #1", CR 23 | PAUSE 1000 24 | GOTO Routine2 25 | 26 | Routine3: 27 | DEBUG "We're in routine #3", CR 28 | PAUSE 1000 29 | GOTO Routine1 -------------------------------------------------------------------------------- /src/reducers/next-action.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { 4 | QUEUE_NEW_FILE, 5 | QUEUE_CHANGE_FILE, 6 | QUEUE_OVERWRITE_FILE, 7 | RESET_ACTION_QUEUE 8 | } = require('../constants/action-types'); 9 | 10 | const { 11 | NEW_FILE, 12 | CHANGE_FILE, 13 | OVERWRITE_FILE 14 | } = require('../constants/queued-action-types'); 15 | 16 | const initial = ''; 17 | 18 | function nextAction(state = initial, { type }){ 19 | switch(type){ 20 | case QUEUE_NEW_FILE: 21 | return NEW_FILE; 22 | case QUEUE_CHANGE_FILE: 23 | return CHANGE_FILE; 24 | case QUEUE_OVERWRITE_FILE: 25 | return OVERWRITE_FILE; 26 | case RESET_ACTION_QUEUE: 27 | return initial; 28 | default: 29 | return state; 30 | } 31 | } 32 | 33 | module.exports = nextAction; 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # Compiled binary addons (http://nodejs.org/api/addons.html) 20 | build/Release 21 | 22 | # Dependency directory 23 | # Commenting this out is preferred by some people, see 24 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git- 25 | node_modules 26 | 27 | # Users Environment Variables 28 | .lock-wscript 29 | 30 | .DS_Store 31 | 32 | # Generated files 33 | /bundle.js 34 | /bundle.js.map 35 | /dist/ 36 | /release/ 37 | -------------------------------------------------------------------------------- /src/components/progress-bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const React = require('react'); 5 | 6 | const styles = { 7 | progressContainerStyle: { 8 | width: '100%', 9 | height: '8px', 10 | backgroundColor: '#b0d0ef', 11 | marginTop: 'auto' 12 | }, 13 | progressBarStyle: { 14 | height: '100%', 15 | backgroundColor: '#3a81f0' 16 | } 17 | }; 18 | 19 | class ProgressBar extends React.Component { 20 | 21 | render(){ 22 | const { 23 | percent 24 | } = this.props; 25 | 26 | const style = _.assign({}, styles.progressBarStyle, { width: `${percent}%` }); 27 | 28 | return ( 29 |
    30 |
    31 |
    32 | ); 33 | } 34 | } 35 | 36 | module.exports = ProgressBar; 37 | -------------------------------------------------------------------------------- /manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "__MSG_appName__", 3 | "description": "__MSG_appDescription__", 4 | "version": "0.14.4", 5 | "manifest_version": 2, 6 | "default_locale": "en", 7 | "permissions": [ 8 | "serial", 9 | "unlimitedStorage", 10 | "syncFileSystem", 11 | "storage", 12 | "usb", 13 | { 14 | "usbDevices": [ 15 | { 16 | "vendorId": 1027, 17 | "productId": 24577 18 | }, 19 | { 20 | "vendorId": 1027, 21 | "productId": 24597 22 | } 23 | ] 24 | } 25 | ], 26 | "icons": { 27 | "16": "icons/icon16.png", 28 | "48": "icons/icon48.png", 29 | "128": "icons/icon128.png" 30 | }, 31 | "app": { 32 | "background": { 33 | "scripts": [ 34 | "background.js" 35 | ] 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /examples/RCTIME1.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: RCTIME1 5 | 'This program shows the standard use of the RCTIME command measuring an 6 | 'RC charge/discharge time. Use the circuit in the RCTIME description 7 | '(in the manual) with R = 10K pot and C = 0.1 uF. Connect the circuit to 8 | 'pin 7 and run the program. Adjust the pot and watch the value change in 9 | 'the Debug Terminal. 10 | 11 | RC PIN 7 12 | 13 | result VAR Word 14 | 15 | Init: 16 | PAUSE 200 'short startup-pause 17 | 18 | Main: 19 | DO 20 | HIGH RC 'charge the cap 21 | PAUSE 1 ' for 1 ms 22 | RCTIME RC, 1, result 'measure RC discharge time 23 | DEBUG HOME, DEC result 'display value 24 | PAUSE 50 25 | LOOP -------------------------------------------------------------------------------- /src/components/projects-button.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { MainButton } = require('react-mfb-iceddev'); 5 | 6 | const styles = { 7 | changeFolderButton: { 8 | position: 'absolute', 9 | top: 28, 10 | margin: 0, 11 | left: 140, 12 | transform: 'none' 13 | } 14 | }; 15 | 16 | class ProjectsButton extends React.Component { 17 | render(){ 18 | const { 19 | onClick 20 | } = this.props; 21 | 22 | return ( 23 |
    24 | 29 |
    30 | ); 31 | } 32 | } 33 | 34 | module.exports = ProjectsButton; 35 | -------------------------------------------------------------------------------- /examples/PULSOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: PULSOUT 5 | 'This program blinks an LED on for 25 ms at 1-second intervals. Connect an 6 | 'LED (active-low) to I/O pin 0. 7 | 8 | #SELECT $STAMP 'Set Scale according to module type 9 | #CASE BS2, BS2E, BS2PE 10 | Scale CON 500 'to ms for 2 us per unit 11 | #CASE BS2SX, BS2P, BS2PX 12 | Scale CON 1250 'to ms for 0.8 us per unit 13 | #ENDSELECT 14 | 15 | Flash CON 25 * Scale '25 milliseconds 16 | 17 | Setup: 18 | PAUSE 200 'short startup-pause 19 | HIGH 0 'make P0 high (LED off) 20 | 21 | Main: 22 | DO 23 | PULSOUT 0, Flash 'flash LED 24 | PAUSE 1000 'one second delay 25 | LOOP -------------------------------------------------------------------------------- /examples/LOOKUP.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LOOKUP 5 | 'This program uses LOOKUP to create a Debug Terminal animation of a spinning 6 | 'propeller. The animation consists of the four ASCII characters | / - \ 7 | 'which, when printed rapidly in order at a fixed location, appears to spin. 8 | 'A little imagination helps a lot here.... 9 | 10 | idx VAR Nib 11 | frame VAR Byte 12 | 13 | Init: 14 | PAUSE 200 'short startup-pause 15 | 16 | Spinner: 17 | DO 18 | LOOKUP idx, ["|/-\"], frame 'lookup current frame character 19 | DEBUG HOME, "Spinner: ", frame 'display 20 | PAUSE 150 'pause between frames 21 | idx = idx + 1 // 4 'update frame index (0..3) 22 | LOOP 'loop forever 23 | -------------------------------------------------------------------------------- /examples/BRANCH.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: BRANCH 5 | 'This program shows how the value of an index variable (idx) controls the 6 | 'destination of the BRANCH instruction. 7 | 8 | idx VAR Byte 9 | 10 | Init: 11 | PAUSE 200 'short startup-pause 12 | 13 | Main: 14 | DEBUG "idx: ", DEC idx, " " 15 | BRANCH idx, [Task_0, Task_1, Task_2] 'branch to task 16 | DEBUG "BRANCH target error...", CR, CR '... unless out of range 17 | 18 | Next_Task: 19 | idx = idx + 1 // 4 'force idx to be 0..3 20 | PAUSE 250 21 | GOTO Main 22 | 23 | Task_0: 24 | DEBUG "BRANCHed to Task_0", CR 25 | GOTO Next_Task 26 | 27 | Task_1: 28 | DEBUG "BRANCHed to Task_1", CR 29 | GOTO Next_Task 30 | 31 | Task_2: 32 | DEBUG "BRANCHed to Task_2", CR 33 | GOTO Next_Task -------------------------------------------------------------------------------- /examples/ON-GOTO.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: ON-GOTO 5 | 'This program shows how the value of an index variable (idx) controls the 6 | 'destination of the ON...GOTO instruction. 7 | 8 | idx VAR Byte 9 | 10 | Init: 11 | PAUSE 200 'short startup-pause 12 | 13 | Main: 14 | DEBUG "idx: ", DEC idx, " " 15 | ON idx GOTO Case_0, Case_1, Case_2 'if idx = 0..2 goto label 16 | DEBUG "ON..GOTO target error.", CR 'message if idx is out of range 17 | 18 | Update: 19 | idx = idx + 1 // 4 'force idx to be 0..3 20 | PAUSE 1000 21 | GOTO Main 22 | 23 | Case_0: 24 | DEBUG "Running Case_0 routine", CR 25 | GOTO Update 26 | 27 | Case_1: 28 | DEBUG "Running Case_1 routine", CR 29 | GOTO Update 30 | 31 | Case_2: 32 | DEBUG "Running Case_2 routine", CR 33 | GOTO Update -------------------------------------------------------------------------------- /src/components/icon-button.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const Icon = require('react-material/components/Icon'); 5 | 6 | const styles = { 7 | deleteButton: { 8 | border: 0, 9 | background: 'none', 10 | padding: 0, 11 | float: 'right', 12 | position: 'relative', 13 | zIndex: 7 14 | }, 15 | buttonIcon: { 16 | display: 'inline-block', 17 | padding: 0, 18 | width: '30px', 19 | verticalAlign: 'middle', 20 | pointerEvents: 'none' 21 | } 22 | }; 23 | 24 | class IconButton extends React.Component { 25 | render(){ 26 | const { 27 | onClick, 28 | icon 29 | } = this.props; 30 | 31 | return ( 32 | 35 | ); 36 | } 37 | } 38 | 39 | module.exports = IconButton; 40 | -------------------------------------------------------------------------------- /examples/EXIT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: EXIT 5 | 'This program demonstrates the early termination of DO...LOOP and 6 | 'FOR..NEXT loop structures. IF...THEN is used to test a condition, 7 | 'and when true, EXIT will terminate the loop. 8 | 9 | col VAR Nib 10 | row VAR Nib 11 | 12 | Setup: 13 | PAUSE 200 'short startup-pause 14 | col = 0 15 | 16 | Main: 17 | DO WHILE (col < 10) 'attempt 10 iterations 18 | FOR row = 0 TO 15 'attempt 16 iterations 19 | IF (row > 9) THEN EXIT 'terminate when row > 9 20 | DEBUG CRSRXY, (col * 8), row, 'print col/row at location 21 | DEC col, "/", DEC row, CR 22 | NEXT 23 | col = col + 1 'update column 24 | IF (col = 3) THEN EXIT 'terminate when col = 3 25 | LOOP 26 | END -------------------------------------------------------------------------------- /src/code-mirror.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const CodeMirror = require('codemirror'); 4 | require('codemirror/mode/javascript/javascript'); 5 | require('codemirror/addon/search/searchcursor'); 6 | require('codemirror/addon/dialog/dialog'); 7 | require('codemirror/addon/dialog/dialog.css'); 8 | require('codemirror/addon/search/search'); 9 | require('codemirror/addon/selection/mark-selection'); 10 | require('codemirror/lib/codemirror.css'); 11 | require('../assets/theme/parallax.css'); 12 | require('./lib/pbasic')(CodeMirror); 13 | 14 | const cm = new CodeMirror(null, { 15 | mode: 'pbasic', 16 | theme: 'parallax', 17 | lineNumbers: true 18 | }); 19 | 20 | cm.setOption('styleSelectedText', true); 21 | cm.setOption('tabSize', 2); 22 | cm.setOption('extraKeys', { 23 | 'Ctrl-Up': false, 24 | 'Ctrl-Down': false, 25 | 'Tab': false, 26 | 'Shift-Tab': false, 27 | 'Ctrl-T': false 28 | }); 29 | 30 | module.exports = cm; 31 | -------------------------------------------------------------------------------- /examples/TOGGLE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: TOGGLE 5 | 'Connect LEDs to pins 0 through 3 as shown in the TOGGLE command description 6 | 'and run this program. The TOGGLE command will treat you to a light show. 7 | 'You may also run the demo without LEDs; the Debug Terminal will show you the 8 | 'states of pins 0 through 3. 9 | 10 | thePin VAR Nib 'pin 0 - 3 11 | 12 | Setup: 13 | PAUSE 200 'short startup-pause 14 | DIRA = %1111 'make LEDs output, low 15 | 16 | Main: 17 | DEBUG "LED States: " 18 | DO 19 | FOR thePin = 0 TO 3 'loop through pins 20 | TOGGLE thePin 'toggle current pin 21 | DEBUG CRSRXY, 12, 0, BIN4 OUTA 'show on Debug Terminal 22 | PAUSE 250 'short delay 23 | NEXT 24 | LOOP 'repeat forever -------------------------------------------------------------------------------- /src/views/editor.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const cm = require('../code-mirror'); 6 | 7 | class Editor extends React.Component { 8 | 9 | componentDidMount(){ 10 | const container = React.findDOMNode(this); 11 | const { handleInput } = this.props.handlers; 12 | container.style.display = 'flex'; 13 | container.style.flex = '1'; 14 | container.style.flexDirection = 'column'; 15 | container.setAttribute('id', 'editorContainer'); 16 | 17 | container.appendChild(cm.getWrapperElement()); 18 | 19 | cm.on('change', handleInput); 20 | } 21 | 22 | componentWillUnmount(){ 23 | const container = React.findDOMNode(this); 24 | container.removeAll(); 25 | } 26 | 27 | 28 | shouldComponentUpdate(){ 29 | return false; 30 | } 31 | 32 | render(){ 33 | 34 | return ( 35 |
    36 | ); 37 | } 38 | 39 | } 40 | 41 | module.exports = Editor; 42 | -------------------------------------------------------------------------------- /examples/LOOKDOWN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LOOKDOWN 5 | 'This program uses LOOKDOWN to determine the number of decimal digits in 6 | 'a number. Since LOOKDOWN uses a zero-indexed table, the output will be 7 | 'the number of digits minus one, so the DEBUG statement corrects for this. 8 | 9 | aNum VAR Word 'random number 10 | stpSz VAR Word 'FOR-NEXT step size 11 | numDig VAR Nib 'digits in aNum 12 | 13 | Setup: 14 | PAUSE 200 'short startup-pause 15 | stpSz = 2 16 | 17 | Main: 18 | FOR aNum = 0 TO 15000 STEP stpSz 19 | LOOKDOWN aNum, <[0, 10, 100, 1000, 10000, 65535], numDig 20 | 'right-justify output 21 | DEBUG "aNum = ", REP " "\(5-numDig), DEC aNum, TAB, 22 | "Digits = ", DEC numDig, CR 23 | PAUSE 150 24 | LOOKUP numDig, [2, 2, 5, 25, 250, 500, 1000], stpSz 25 | NEXT 26 | END -------------------------------------------------------------------------------- /examples/ON-GOSUB.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: ON-GOSUB 5 | 'This program demonstrates a simple task manager that can be used in 6 | 'a variety of applications. It is particularly useful in robotics and 7 | 'industrial applications. The advantage of this design is that task 8 | 'code routines may be called from other places in the program, including 9 | 'other tasks, and the overal program flow is maintained. 10 | 11 | task VAR Nib 12 | 13 | Init: 14 | PAUSE 200 'short startup-pause 15 | 16 | Main: 17 | DO 18 | ON task GOSUB Task_0, Task_1, Task_2 'run current task 19 | task = task + 1 // 3 'update task pointer 20 | PAUSE 1000 21 | LOOP 22 | 23 | Task_0: 24 | DEBUG "Running Task 0", CR 25 | RETURN 26 | 27 | Task_1: 28 | DEBUG "Running Task 1", CR 29 | RETURN 30 | 31 | Task_2: 32 | DEBUG "Running Task 2", CR 33 | RETURN -------------------------------------------------------------------------------- /src/reducers/transmission.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | const { 6 | RECEIVE, 7 | TRANSMIT, 8 | CLEAR_TRANSMISSION, 9 | CONNECT 10 | } = require('../constants/action-types'); 11 | 12 | const initial = { 13 | input: '', 14 | // output is an array of lines 15 | output: [], 16 | // offset is number of lines cleared from console buffer 17 | offset: 0 18 | }; 19 | 20 | function transmission(state = initial, { type, payload }){ 21 | switch(type){ 22 | case CONNECT: 23 | return _.assign({}, state, { input: '' }); 24 | case RECEIVE: 25 | return _.assign({}, state, { output: payload.output, offset: payload.offset }); 26 | case TRANSMIT: 27 | return _.assign({}, state, { input: payload.input }); 28 | case CLEAR_TRANSMISSION: 29 | return _.assign({}, state, { input: '', output: '' }); 30 | default: 31 | return state; 32 | } 33 | } 34 | 35 | module.exports = transmission; 36 | -------------------------------------------------------------------------------- /examples/FOR-NEXT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: FOR-NEXT 5 | 'This example uses a FOR...NEXT loop to churn out a series of sequential 6 | 'squares (numbers 1, 2, 3, 4... raised to the second power) by using a 7 | 'variable to set the FOR...NEXT's StepValue parameter, and incrementing 8 | 'StepValue within the loop. Sir Isaac Newton is generally credited with 9 | 'the discovery of this technique. 10 | 11 | square VAR Byte 'FOR/NEXT counter 12 | stepSize VAR Byte 'step size, increase by 2 each loop 13 | 14 | Setup: 15 | PAUSE 200 'short startup-pause 16 | stepSize = 1 17 | square = 1 18 | 19 | Main: 20 | FOR square = 1 TO 250 STEP stepSize 'show squares up to 250 21 | DEBUG DEC ? square 'display on screen 22 | stepSize = stepSize + 2 'add 2 to stepSize 23 | NEXT 'loop until square > 250 24 | END -------------------------------------------------------------------------------- /examples/READ.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: READ 5 | 'This program reads a string of data stored in EEPROM. The EEPROM data is 6 | 'downloaded to the BS2 at compile-time and remains there (even with the 7 | 'power off) until overwritten. Put ASCII characters into EEPROM, followed 8 | 'by 0, which will serve as the end-of-message marker. 9 | 10 | strAddr VAR Word 11 | char VAR Byte 12 | 13 | Msg1 DATA "BS2", CR, "EEPROM Storage!", 0 14 | 15 | Init: 16 | PAUSE 200 'short startup-pause 17 | 18 | Main: 19 | strAddr = Msg1 'set to start of message 20 | GOSUB String_Out 21 | END 22 | 23 | String_Out: 24 | DO 25 | READ strAddr, char 'read byte from EEPROM 26 | strAddr = strAddr + 1 'point to next character 27 | IF (char = 0) THEN EXIT 'if 0, exit routine 28 | DEBUG char 'otherwise print char 29 | LOOP 30 | RETURN -------------------------------------------------------------------------------- /background.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function noop(){} 4 | 5 | function closeSerialPorts(){ 6 | chrome.serial.getConnections(function(connections){ 7 | connections.forEach(function(connection){ 8 | chrome.serial.disconnect(connection.connectionId, noop); 9 | }); 10 | }); 11 | } 12 | 13 | // Listens for the app launching then creates the window 14 | chrome.app.runtime.onLaunched.addListener(function() { 15 | var width = 1000; 16 | var height = 500; 17 | 18 | var windowOpts = { 19 | id: 'main', 20 | state: 'maximized', 21 | bounds: { 22 | width: width, 23 | height: height, 24 | left: Math.round((screen.availWidth - width) / 2), 25 | top: Math.round((screen.availHeight - height) / 2) 26 | } 27 | }; 28 | 29 | chrome.app.window.create('index.html', windowOpts, function(win){ 30 | win.onClosed.addListener(closeSerialPorts); 31 | }); 32 | }); 33 | 34 | chrome.runtime.onInstalled.addListener(function(evt){ 35 | chrome.storage.local.set({newVersion: 'newVersion'}); 36 | }); 37 | -------------------------------------------------------------------------------- /src/components/file-list-item.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const red = '#da2100'; 6 | const green = '#159600'; 7 | const styles = { 8 | fileTempIndicator: { 9 | backgroundColor: green, 10 | height: 10, 11 | width: 10, 12 | borderRadius: '100%', 13 | marginRight: 5, 14 | display: 'inline-block' 15 | }, 16 | fileHasTemp: { 17 | backgroundColor: red 18 | } 19 | }; 20 | 21 | class FileListItem extends React.Component { 22 | render(){ 23 | const { 24 | filename, 25 | temp, 26 | onClick 27 | } = this.props; 28 | 29 | const liStyle = { 30 | listStyleType: 'none', 31 | padding: "14px 16px 15px" 32 | } 33 | 34 | const tempStyles = [styles.fileTempIndicator]; 35 | if(temp){ 36 | tempStyles.push(styles.fileHasTemp); 37 | } 38 | 39 | return ( 40 |
  • 41 | {filename} 42 |
  • 43 | ); 44 | } 45 | } 46 | 47 | module.exports = FileListItem; 48 | -------------------------------------------------------------------------------- /examples/RETURN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: RETURN 5 | 'This program demonstrates a potential bug caused by allowing a program 6 | 'to "fall into" a subroutine. The program was intented to indicate that it 7 | 'is "Starting...", then "Executing Subroutine,", then "Returned..." from 8 | 'the subroutine and then stop. Since we left out the END command (indicated 9 | 'in the comments), the program then falls into the subroutine, displays the 10 | 'message "Executing..." again and then RETURNs to the start of the program and 11 | 'runs continuously in an endless loop. 12 | 13 | Init: 14 | PAUSE 200 'short startup-pause 15 | 16 | Reset: 17 | DEBUG "Starting Program", CR 'show start-up 18 | 19 | Main: 20 | PAUSE 1000 21 | GOSUB Demo_Sub 'call the subroutine 22 | PAUSE 1000 23 | DEBUG "Returned from Subroutine", CR 'show that we're back 24 | PAUSE 1000 25 | '<-- Forgot to put END here 26 | 27 | Demo_Sub: 28 | DEBUG " Executing Subroutine", CR 'show subroutine activity 29 | RETURN -------------------------------------------------------------------------------- /examples/BUTTON.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: BUTTON 5 | 'Connect an active-low circuit (shown in the BUTTON command description) to pin P0 6 | 'of the BASIC Stamp. When you press the button, the BUTTON command will detect the 7 | 'low signal and then the DEBUG command will execute to display an asterisk (*) on 8 | 'the Debug Terminal. After the first button press, then BUTTON command will delay 9 | 'approximately one second (200 x 5 ms) before auto-repeating at a rate of 10 | 'approximately 100 ms (20 x 5 ms). 11 | 12 | Btn PIN 0 13 | btnWrk VAR Byte 14 | 15 | Init: 16 | PAUSE 200 'short startup-pause 17 | 18 | Main: 19 | 'Try changing the Delay parameter (3rd value) in BUTTON to see the effect: 20 | '0 = no delay; 1-254 = varying delays before auto-repeat; 255 = no auto-repeat 21 | '(only one action per button press) 22 | ' 23 | 'The BUTTON instruction makes the program branch to No_Press unless P0 = 0 24 | 25 | PAUSE 5 26 | BUTTON Btn, 0, 200, 20, btnWrk, 0, No_Press 27 | DEBUG "*" 28 | 29 | No_Press: 30 | GOTO Main -------------------------------------------------------------------------------- /src/views/help-overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const Button = require('../components/button'); 5 | 6 | const Overlay = require('../components/overlay'); 7 | const OverlayTitle = require('../components/overlay-title'); 8 | const OverlayFooter = require('../components/overlay-footer'); 9 | 10 | const helpStyle = { 11 | position: 'relative', 12 | marginTop: '25px' 13 | }; 14 | 15 | const helpLink = 'http://www.parallax.com/go/PBASICHelp'; 16 | 17 | class HelpOverlay extends React.Component { 18 | 19 | 20 | render(){ 21 | const { 22 | handlers 23 | } = this.props; 24 | 25 | const { 26 | hideOverlay 27 | } = handlers; 28 | 29 | return ( 30 | 31 | Help 32 |
    33 | For help with PBASIC go here: {helpLink} 34 |
    35 | 36 | 37 | 38 |
    39 | ); 40 | } 41 | } 42 | 43 | module.exports = HelpOverlay; 44 | -------------------------------------------------------------------------------- /src/lib/documents.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const CodeMirror = require('codemirror'); 4 | 5 | class Documents { 6 | constructor(editor){ 7 | this._editor = editor; 8 | 9 | this._filename = null; 10 | this._documents = {}; 11 | } 12 | 13 | focus(){ 14 | this._editor.focus(); 15 | } 16 | 17 | update(text){ 18 | if(!this._filename){ 19 | return; 20 | } 21 | 22 | return this.create(this._filename, text); 23 | } 24 | 25 | create(filename, text){ 26 | const mode = 'pbasic'; 27 | 28 | this._documents[filename] = CodeMirror.Doc(text, mode); 29 | 30 | return this.swap(filename); 31 | } 32 | 33 | remove(filename){ 34 | // TODO: remove something? 35 | delete this._documents[filename]; 36 | } 37 | 38 | swap(filename) { 39 | this._filename = filename; 40 | 41 | const doc = this._documents[filename]; 42 | 43 | if(!doc){ 44 | return; 45 | } 46 | 47 | this._editor.swapDoc(doc); 48 | return doc; 49 | } 50 | 51 | replace(filename){ 52 | this._documents[filename] = this._editor.getDoc(); 53 | } 54 | } 55 | 56 | module.exports = Documents; 57 | -------------------------------------------------------------------------------- /src/components/overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | const React = require('react'); 5 | 6 | const Card = require('./card'); 7 | 8 | const styles = { 9 | overlay: { 10 | width: 400, 11 | height: 200, 12 | margin: '100px auto 0', 13 | display: 'flex', 14 | flexDirection: 'column' 15 | }, 16 | overlayLarge: { 17 | height: 400 18 | }, 19 | backdrop:{ 20 | display: 'flex', 21 | position: 'fixed', 22 | top: 0, 23 | bottom: 0, 24 | left: 0, 25 | right: 0, 26 | backgroundColor: 'rgba(0,0,0,0.5)', 27 | zIndex: 10 28 | } 29 | }; 30 | 31 | class Overlay extends React.Component { 32 | render(){ 33 | const { 34 | large, 35 | children, 36 | style 37 | } = this.props; 38 | 39 | const cardStyle = _.assign({}, styles.overlay, style); 40 | if(large){ 41 | _.assign(cardStyle, styles.overlayLarge); 42 | } 43 | 44 | return ( 45 |
    46 | 47 | {children} 48 | 49 |
    50 | ); 51 | } 52 | } 53 | 54 | module.exports = Overlay; 55 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Parallax Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /examples/IF-THEN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: IF-THEN 5 | 'The program below generates a series of 16-bit random numbers and tests 6 | 'each to determine whether they're evenly divisible by 3. If a number is 7 | 'evenly divisible by 3, then it is printed, otherwise, the program generates 8 | 'another random number. The program quits when it's printed 10 numbers. 9 | 10 | sample VAR Word 'Random number to be tested 11 | samps VAR Nib 'Number of samples taken 12 | temp VAR Nib 'Temporary workspace 13 | 14 | 15 | Setup: 16 | PAUSE 200 'short startup-pause 17 | sample = 11500 18 | 19 | Mult3: 20 | RANDOM sample 'Put a random number into sample 21 | temp = sample // 3 22 | IF temp <> 0 THEN Mult3 'Not multiple of 3? -- try again 23 | DEBUG DEC5 sample, " divides by 3", CR 24 | samps = samps + 1 'Count multiples of 3 25 | IF samps = 10 THEN Done 'Quit with 10 samples 26 | GOTO Mult3 'keep checking 27 | 28 | Done: 29 | DEBUG CR, "All done." 30 | END -------------------------------------------------------------------------------- /examples/PWM.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: PWM 5 | 'Connect a voltmeter (such as a digital multimeter set to its voltage 6 | 'range) to the output of the circuit shown in the figure for the PWM 7 | 'command. Run the program and observe the readings on the meter. They 8 | 'should come very close to 1.96V, then decrease slightly as the capacitor 9 | 'discharges. Try varying the interval between PWM bursts (by changing the 10 | 'PAUSE value) and the number of PWM cycles to see their effect. 11 | 12 | #SELECT $stamp 'Set CycAdj according to module type 13 | #CASE BS2, BS2E 14 | CycAdj CON $100 'x 1.0, cycle adjustment (for ms) 15 | #CASE BS2SX 16 | CycAdj CON $280 'x 2.5 17 | #CASE BS2P 18 | CycAdj CON $187 'x 1.53 19 | #CASE BS2PE 20 | CycAdj CON $09E 'x 0.62 21 | #CASE BS2PX 22 | CycAdj CON $280 'x 2.5 23 | #ENDSELECT 24 | 25 | Cycles CON 50 26 | 27 | Main: 28 | DO 29 | PWM 0, 100, (Cycles */ CycAdj) 'PWM at 100/255 duty (~50 ms) 30 | PAUSE 1000 'wait one second 31 | LOOP -------------------------------------------------------------------------------- /examples/INPUT_OUTPUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: INPUT_OUTPUT 5 | 'This program demonstrates how the input/output direction of a pin is 6 | 'determined by the corresponding bit of DIRS. It also shows that the 7 | 'state of the pin itself (as reflected by the corresponding bit of INx) 8 | 'is determined by the outside world when the pin is an input, and by the 9 | 'corresponding bit of INx when it's an output. To set up the demo, 10 | 'connect a 10k resistor from +5V to P7 on the BASIC Stamp. The resistor 11 | 'to +5V puts a high (1) on the pin when it's an input. The BASIC Stamp 12 | 'can override this state by writing a low (0) to bit 7 of OUTS and 13 | 'changing the pin to output. 14 | 15 | Init: 16 | PAUSE 200 'short startup-pause 17 | 18 | Main: 19 | INPUT 7 'Make P7 an input 20 | DEBUG "State of P7: ", 21 | BIN1 IN7, CR 22 | 23 | OUT7 = 0 'Write 0 to output latch 24 | DEBUG "After 0 written to OUT7: ", 25 | BIN1 IN7, CR 26 | 27 | OUTPUT 7 'Make P7 an output 28 | DEBUG "After P7 changed to output: ", 29 | BIN1 IN7 30 | END -------------------------------------------------------------------------------- /examples/WRITE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: WRITE 5 | 'This program writes some data to EEPROM and then reads them back out 6 | 'and displays the data in the Debug Terminal. It also demonstrates 7 | 'writing both bytes and words, and the results of reading values as 8 | 'bytes or words. 9 | 10 | idx VAR Byte 'loop control 11 | value VAR Word(3) 'value(s) 12 | 13 | Init: 14 | PAUSE 200 'short startup-pause 15 | 16 | Main: 17 | WRITE 0, 100 'single byte 18 | WRITE 1, Word 1250 'single word 19 | WRITE 3, 45, 90, Word 725 'multi-value write 20 | 21 | Read_EE: 22 | 'read values as bytes only 23 | DEBUG "Values as bytes:", CR 24 | FOR idx = 0 TO 6 25 | READ idx, value 26 | DEBUG DEC1 idx, " : ", DEC value, CR 27 | NEXT 28 | DEBUG CR 29 | 30 | 'read values as stored 31 | DEBUG "Values as written:", CR 32 | READ 0, value 33 | DEBUG DEC value, CR 34 | READ 1, Word value 35 | DEBUG DEC value, CR 36 | READ 3, value(0), value(1), Word value(2) 37 | FOR idx = 0 TO 2 38 | DEBUG DEC value(idx), CR 39 | NEXT 40 | END -------------------------------------------------------------------------------- /examples/REVERSE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: REVERSE 5 | 'Connect the circuit shown in the REVERSE command description to I/O pin 6 | '0 and run this program. The LED will alternate between two states, dim 7 | 'and bright. The BASIC Stamp is using the REVERSE command to toggle I/O 8 | 'pin 0 between input and output states. When pin 0 is an input, current 9 | 'flows through R1, through the LED, through R2 to ground. Pin 0 is 10 | 'effectively disconnected and doesn't play a part in the circuit. The total 11 | 'resistance encountered by current flowing through the LED is R1 + R2 = 1220 12 | 'ohms. When pin 0 is reversed to an output, current flows through R1, through 13 | 'the LED, and into pin 0 to ground (because of the 0 written to OUT0). The 14 | 'total resistance encountered by current flowing through the LED is R1, 15 | '220 ohms. With only 20% of the resistance, the LED glows brighter. 16 | 17 | Setup: 18 | OUT0 = 0 'Put a low in the pin 0 19 | ' output driver 20 | Main: 21 | DO 22 | PAUSE 250 '1/4th second pause 23 | REVERSE 0 'reverse pin 0 I/O direction 24 | LOOP 'do forever -------------------------------------------------------------------------------- /src/constants/action-types.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const actionTypes = { 4 | SHOW_OVERLAY: 'SHOW_OVERLAY', 5 | HIDE_OVERLAY: 'HIDE_OVERLAY', 6 | DELETE_PROJECT_CONFIRM: 'DELETE_PROJECT_CONFIRM', 7 | ECHO_ON: 'ECHO_ON', 8 | ECHO_OFF: 'ECHO_OFF', 9 | RX_ON: 'RX_ON', 10 | RX_OFF: 'RX_OFF', 11 | RX_CLEAR_TIMEOUT: 'RX_CLEAR_TIMEOUT', 12 | TX_ON: 'TX_ON', 13 | TX_OFF: 'TX_OFF', 14 | TX_CLEAR_TIMEOUT: 'TX_CLEAR_TIMEOUT', 15 | RECEIVE: 'RECEIVE', 16 | TRANSMIT: 'TRANSMIT', 17 | UPDATE_DURATION: 'UPDATE_DURATION', 18 | CLEAR_TRANSMISSION: 'CLEAR_TRANSMISSION', 19 | CONNECT: 'CONNECT', 20 | DISCONNECT: 'DISCONNECT', 21 | RELOAD_DEVICES: 'RELOAD_DEVICES', 22 | UPDATE_DEVICES: 'UPDATE_DEVICES', 23 | ENABLE_AUTO_DOWNLOAD: 'ENABLE_AUTO_DOWNLOAD', 24 | DISABLE_AUTO_DOWNLOAD: 'DISABLE_AUTO_DOWNLOAD', 25 | UPDATE_SEARCH_STATUS: 'UPDATE_SEARCH_STATUS', 26 | CLEAR_SEARCH_STATUS: 'CLEAR_SEARCH_STATUS', 27 | UPDATE_SELECTED_DEVICE: 'UPDATE_SELECTED_DEVICE', 28 | RESET_DOWNLOAD_PROGRESS: 'RESET_DOWNLOAD_PROGRESS', 29 | UPDATE_DOWNLOAD_PROGRESS: 'UPDATE_DOWNLOAD_PROGRESS', 30 | QUEUE_NEW_FILE: 'QUEUE_NEW_FILE', 31 | QUEUE_CHANGE_FILE: 'QUEUE_CHANGE_FILE', 32 | QUEUE_OVERWRITE_FILE: 'QUEUE_OVERWRITE_FILE', 33 | RESET_ACTION_QUEUE: 'RESET_ACTION_QUEUE' 34 | }; 35 | 36 | module.exports = actionTypes; 37 | -------------------------------------------------------------------------------- /src/plugins/notifications.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const red = '#da2100'; 4 | const green = '#159600'; 5 | 6 | const styles = { 7 | errorToast: { 8 | backgroundColor: red 9 | }, 10 | successToast: { 11 | backgroundColor: green 12 | } 13 | }; 14 | 15 | function notifications({ workspace, toast }, opts, done){ 16 | 17 | const { 18 | SAVE_FILE_SUCCESS, 19 | SAVE_FILE_FAILURE, 20 | DELETE_FILE_SUCCESS, 21 | DELETE_FILE_FAILURE, 22 | CHANGE_FILE_FAILURE, 23 | DELETE_DIRECTORY_SUCCESS, 24 | DELETE_DIRECTORY_FAILURE, 25 | CHANGE_DIRECTORY_FAILURE 26 | } = workspace.STATUS_CONSTANTS; 27 | 28 | workspace.subscribe(() => { 29 | const { status, notification } = workspace.getState(); 30 | 31 | switch(status){ 32 | case SAVE_FILE_SUCCESS: 33 | case DELETE_FILE_SUCCESS: 34 | case DELETE_DIRECTORY_SUCCESS: 35 | toast.show(notification, { style: styles.successToast, timeout: 5000 }); 36 | break; 37 | case SAVE_FILE_FAILURE: 38 | case DELETE_FILE_FAILURE: 39 | case CHANGE_FILE_FAILURE: 40 | case DELETE_DIRECTORY_FAILURE: 41 | case CHANGE_DIRECTORY_FAILURE: 42 | toast.show(notification, { style: styles.errorToast }); 43 | break; 44 | } 45 | }); 46 | 47 | done(); 48 | } 49 | 50 | module.exports = notifications; 51 | -------------------------------------------------------------------------------- /src/views/delete-project-overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { createContainer } = require('sovereign'); 5 | const Button = require('../components/button'); 6 | 7 | const Overlay = require('../components/overlay'); 8 | const OverlayTitle = require('../components/overlay-title'); 9 | const OverlayFooter = require('../components/overlay-footer'); 10 | const history = require('../lib/history'); 11 | 12 | class DeleteProjectOverlay extends React.Component { 13 | render(){ 14 | const { 15 | name, 16 | handlers 17 | } = this.props; 18 | 19 | const { 20 | deleteProject 21 | } = handlers; 22 | 23 | return ( 24 | 25 | Are you sure you want to delete {name}? 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | module.exports = createContainer(DeleteProjectOverlay, { 36 | getStores({ store }){ 37 | return { 38 | store 39 | }; 40 | }, 41 | 42 | getPropsFromStores({ store }){ 43 | const { deleteProjectName } = store.getState(); 44 | 45 | return { 46 | name: deleteProjectName 47 | }; 48 | } 49 | }); 50 | -------------------------------------------------------------------------------- /src/views/overwrite-overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { createContainer } = require('sovereign'); 5 | const Button = require('../components/button'); 6 | 7 | const Overlay = require('../components/overlay'); 8 | const OverlayTitle = require('../components/overlay-title'); 9 | const OverlayFooter = require('../components/overlay-footer'); 10 | const history = require('../lib/history'); 11 | 12 | class OverwriteOverlay extends React.Component { 13 | 14 | render(){ 15 | const { 16 | filename, 17 | handlers 18 | } = this.props; 19 | 20 | const { 21 | overwriteFile, 22 | cancelOverwriteFile 23 | } = handlers; 24 | 25 | return ( 26 | 27 | File '{filename}' already exists. Overwrite anyway? 28 | 29 | 30 | 31 | 32 | 33 | ); 34 | } 35 | } 36 | 37 | module.exports = createContainer(OverwriteOverlay, { 38 | getStores({ store }){ 39 | return { 40 | store 41 | }; 42 | }, 43 | 44 | getPropsFromStores({ store }){ 45 | const { nextFile } = store.getState(); 46 | 47 | return { 48 | filename: nextFile 49 | }; 50 | } 51 | }); 52 | -------------------------------------------------------------------------------- /src/reducers/rxtx.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* 4 | Don't include this in the index.js because it is used only 5 | for the console-store 6 | */ 7 | 8 | const _ = require('lodash'); 9 | 10 | const { 11 | RX_ON, 12 | RX_OFF, 13 | RX_CLEAR_TIMEOUT, 14 | TX_ON, 15 | TX_OFF, 16 | TX_CLEAR_TIMEOUT, 17 | UPDATE_DURATION 18 | } = require('../constants/action-types'); 19 | 20 | const initial = { 21 | flashRx: false, 22 | rxTimeout: null, 23 | flashTx: false, 24 | txTimeout: null, 25 | duration: 100, 26 | offDuration: 50 27 | }; 28 | 29 | function rxtx(state = initial, { type, payload }){ 30 | switch(type){ 31 | case RX_ON: 32 | return _.assign({}, state, { flashRx: true, rxTimeout: payload.timeout }); 33 | case RX_OFF: 34 | return _.assign({}, state, { flashRx: false }); 35 | case RX_CLEAR_TIMEOUT: 36 | return _.assign({}, state, { flashRx: false, rxTimeout: null }); 37 | case TX_ON: 38 | return _.assign({}, state, { flashTx: true, txTimeout: payload.timeout }); 39 | case TX_OFF: 40 | return _.assign({}, state, { flashTx: false }); 41 | case TX_CLEAR_TIMEOUT: 42 | return _.assign({}, state, { flashTx: false, txTimeout: null }); 43 | case UPDATE_DURATION: 44 | return _.assign({}, state, { duration: payload.duration }); 45 | default: 46 | return state; 47 | } 48 | } 49 | 50 | module.exports = rxtx; 51 | -------------------------------------------------------------------------------- /examples/RCTIME2.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: RCTIME2 5 | 'This program illustrates the use of RCTIME as a fast stopwatch. The 6 | 'program energizes a relay coil, then measures how long it takes for the 7 | 'relay contacts to close. Use the circuit found in the RCTIME description. 8 | 'Note that RCTIME doesn't start timing instantly -- as with all PBASIC 9 | 'commands, it must be fetched from the program's EEPROM before executeing. 10 | 11 | Coil PIN 6 12 | RC PIN 7 13 | 14 | #SELECT $STAMP 'Set Adjust according to module type 15 | #CASE BS2, BS2E, BS2PE 16 | Adjust CON $200 'x 2 us per unit 17 | #CASE BS2SX 18 | Adjust CON $0CC 'x 0.8 us per unit 19 | #CASE BS2P, BS2PX 20 | Adjust CON $0C0 'x 0.75 us per unit 21 | #ENDSELECT 22 | 23 | result VAR Word 24 | 25 | Init: 26 | PAUSE 200 'short startup-pause 27 | 28 | Main: 29 | DO 30 | LOW Coil 'energize relay coil 31 | RCTIME RC, 1, result 'measure time to contact closure 32 | result = result */ Adjust 'adjust for device 33 | DEBUG "Time to close: ", DEC Result, CR 34 | HIGH Coil 'release relay 35 | PAUSE 1000 'wait one second 36 | LOOP -------------------------------------------------------------------------------- /examples/IF-THEN-ELSE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: IF-THEN-ELSE 5 | 'This program is an expansion on IF-THEN. It generates a series of 16-bit 6 | 'random numbers and tests each to determine whether they're evenly divisible 7 | 'by 3. If a number is evenly divisible by 3, then it is printed, otherwise, 8 | 'the program generates another random number. The program quits when it's 9 | 'printed 10 numbers. It also displays the tallied up Hits, Misses, and Samples. 10 | 11 | sample VAR Word 'Random number to be tested 12 | hits VAR Nib 'Number of hits 13 | misses VAR Word 'Number of misses 14 | 15 | Setup: 16 | PAUSE 200 'short startup-pause 17 | sample = 11500 18 | 19 | Main: 20 | DO 21 | RANDOM sample 'Put a random number into sample 22 | IF ((sample // 3) = 0) THEN 'divisible by 3? 23 | DEBUG DEC5 sample, '- yes, print value and message 24 | " is divisible by 3", CR 25 | hits = hits + 1 'count hits (divisble by 3) 26 | ELSE 27 | misses = misses + 1 'count misses 28 | ENDIF 29 | LOOP UNTIL (hits = 10) 'quit after 10 hits 30 | 31 | DEBUG CR, 32 | "All done.", CR, CR, 'display results 33 | "Hits: ", DEC hits, CR, 34 | "Misses: ", DEC misses, CR, 35 | "Samples: ", DEC (hits + misses) 36 | END -------------------------------------------------------------------------------- /examples/SHIFTIN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SHIFTIN 5 | 'This program uses the SHIFTIN instruction to interface with the ADC0831 6 | '8-bit analog-to-digital converter from National Semiconductor. 7 | 8 | CS PIN 0 'chip select 9 | AData PIN 1 'data pin 10 | Clk PIN 2 'clock pin 11 | 12 | adcRes VAR Byte 'ADC result 13 | 14 | Setup: 15 | PAUSE 200 'short startup-pause 16 | HIGH CS 'deselect ADC 17 | 18 | 'In the loop below, just three lines of code are required to read the 19 | 'ADC0831. The SHIFTIN command does most of the work. The mode argument in 20 | 'the SHIFTIN command specifies MSB or LSB-first and whether to sample data 21 | 'before or after the clock. In this case, we chose MSB-first, post-clock. 22 | 'The ADC0831 precedes its data output with a dummy bit, which we take care 23 | 'of by specifying 9 bits of data instead of 8. 24 | 25 | Main: 26 | DO 27 | LOW CS 'activate the ADC0831 28 | SHIFTIN AData, Clk, MSBPOST, [adcRes\9] 'shift in the data 29 | HIGH CS 'deactivate ADC0831 30 | DEBUG ? adcRes 'show conversion result 31 | PAUSE 1000 'wait one second 32 | LOOP 'repeat -------------------------------------------------------------------------------- /examples/DO-LOOP.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: DO-LOOP 5 | 'This program creates a little guessing game. It starts by creating 6 | 'a (psuedo) random number between 1 and 10. The inner loop will run 7 | 'until the answer is guessed or 3 tries have been attempted. The 8 | 'outer loop has no condition and will cause the inner loop code to 9 | 'run until the BASIC Stamp is reprogrammed. 10 | 11 | rVal VAR Word 'random value 12 | answer VAR Byte 'game answer 13 | guess VAR Byte 'player guess 14 | tries VAR Nib 'number of tries 15 | 16 | Init: 17 | PAUSE 200 'short startup-pause 18 | 19 | Main: 20 | DO 21 | RANDOM rVal 22 | answer = rVal.LOWBYTE */ 10 + 1 'create 1 - 10 answer 23 | tries = 0 24 | 25 | DO 'get answer until out of tries 26 | DEBUG CLS, "Guess a number (1 - 10). ", CLREOL 27 | DEBUGIN DEC guess 'get new guess 28 | tries = tries + 1 'update tries count 29 | IF (guess <> answer) THEN 30 | DEBUG CR, "Wrong." 31 | PAUSE 500 32 | ENDIF 33 | LOOP UNTIL ((tries = 3) OR (guess = answer)) 34 | 35 | IF (guess = answer) THEN ' test reason for loop end 36 | DEBUG CR, "You got it!" 37 | ELSE 38 | DEBUG CR, "Sorry ... the answer was ", DEC answer, "." 39 | ENDIF 40 | PAUSE 1000 41 | LOOP ' run again -------------------------------------------------------------------------------- /examples/AUX_TERM.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: AUX_MAIN_TERM 5 | 'This program demonstrates the use of the AUXIO, MAINIO and IOTERM 6 | 'commands to affect I/O pins in the auxiliary and main I/O groups. 7 | 8 | Init: 9 | PAUSE 200 'short startup-pause 10 | 11 | #SELECT $STAMP 'Notify of module requirements 12 | #CASE BS2, BS2E, BS2SX 13 | #ERROR "Program requires BS2p40" 14 | #CASE BS2P, BS2PE, BS2PX 15 | DEBUG "Note: This program is designed for the BS2p40.", CR 16 | #ENDSELECT 17 | 18 | port VAR Bit 19 | 20 | Main: 21 | DO 22 | MAINIO 'Switch to main I/O pins 23 | TOGGLE 0 'Toggle state of I/O pin P0 24 | PWM 1, 100, 40 'Generate PWM on I/O pin P1 25 | 26 | AUXIO 'Switch to auxiliary I/O pins 27 | TOGGLE 0 'Toggle state of I/O pin X0 28 | PULSOUT 1, 1000 'Generate a pulse on I/O pin X1 29 | PWM 2, 100, 40 'Generate PWM on I/O pin X2 30 | 31 | IOTERM port 'Switch to main or aux I/Os 32 | '-- depending on port 33 | TOGGLE 3 'Toggle state of I/O pin 3 34 | '-- on main and aux, alternately 35 | port = ~port 'Invert port 36 | PAUSE 1000 '1 second delay 37 | LOOP 38 | -------------------------------------------------------------------------------- /gulpfile.babel.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | 5 | const del = require('del'); 6 | const gulp = require('gulp'); 7 | const chalk = require('chalk'); 8 | const zip = require('gulp-zip'); 9 | const gutil = require('gulp-util'); 10 | const webpack = require('webpack'); 11 | 12 | const webpackConfig = require('./webpack.config'); 13 | 14 | const files = { 15 | release: [ 16 | 'manifest.json', 17 | 'index.html', 18 | 'bundle.js', 19 | 'background.js', 20 | '_locales/**', 21 | 'icons/**', 22 | 'fonts/**', 23 | 'assets/**' 24 | ] 25 | }; 26 | 27 | function js(cb){ 28 | webpack(webpackConfig, function(err){ 29 | gutil.log(chalk.green('Webpack - JS Rebuilt')); 30 | cb(err); 31 | }); 32 | } 33 | 34 | function release(){ 35 | return gulp.src(files.release, { base: __dirname }) 36 | .pipe(zip('parallax-ide.zip')) 37 | .pipe(gulp.dest('dist')); 38 | } 39 | 40 | function postinstall(cb){ 41 | // .pem files cause Chrome to show a bunch of warnings 42 | // so we remove them on postinstall 43 | del('node_modules/**/*.pem', cb); 44 | } 45 | 46 | function version(cb){ 47 | const pkg = require('./package.json'); 48 | const manifest = require('./manifest.json'); 49 | manifest.version = pkg.version; 50 | const content = `${JSON.stringify(manifest, null, 2)}\n`; 51 | fs.writeFile('./manifest.json', content, cb); 52 | } 53 | 54 | gulp.task(version); 55 | gulp.task(release); 56 | gulp.task(postinstall); 57 | 58 | gulp.task('gh-release', gulp.series(js, release)); 59 | gulp.task('default', gulp.parallel(js)); 60 | -------------------------------------------------------------------------------- /src/views/new-version-overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const Button = require('../components/button'); 5 | 6 | const Overlay = require('../components/overlay'); 7 | const OverlayTitle = require('../components/overlay-title'); 8 | const OverlayFooter = require('../components/overlay-footer'); 9 | 10 | const contentStyle = { 11 | position: 'relative', 12 | marginTop: '25px' 13 | }; 14 | 15 | const releaseNotesLink = 'https://github.com/parallaxinc/Parallax-IDE/releases'; 16 | const installationNotesLink = 'https://www.parallax.com/package/parallax-ide-for-chrome/'; 17 | 18 | class NewVersionOverlay extends React.Component { 19 | 20 | render(){ 21 | 22 | const { 23 | handlers 24 | } = this.props; 25 | 26 | const { 27 | hideOverlay 28 | } = handlers; 29 | 30 | const { 31 | name, 32 | version 33 | } = chrome.runtime.getManifest(); 34 | 35 | return ( 36 | 37 | {name} Automatically Updated to v{version} 38 |
    39 | You are now running a new release of {name}! 40 |
    41 |
    42 | See Release Notes and Installation Notes for more details. 43 |
    44 | 45 | 46 | 47 |
    48 | ); 49 | } 50 | } 51 | 52 | module.exports = NewVersionOverlay; 53 | -------------------------------------------------------------------------------- /src/creators/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const creators = { 4 | // overlay creators 5 | deleteProjectConfirm: require('./delete-project-confirm'), 6 | // terminal creators 7 | rxOn: require('./rx-on'), 8 | rxOff: require('./rx-off'), 9 | rxClearTimeout: require('./rx-clear-timeout'), 10 | txOn: require('./tx-on'), 11 | txOff: require('./tx-off'), 12 | txClearTimeout: require('./tx-clear-timeout'), 13 | receive: require('./receive'), 14 | transmit: require('./transmit'), 15 | updateDuration: require('./update-duration'), 16 | clearTransmission: require('./clear-transmission'), 17 | echoOn: require('./echo-on'), 18 | echoOff: require('./echo-off'), 19 | // device creators 20 | connect: require('./connect'), 21 | disconnect: require('./disconnect'), 22 | reloadDevices: require('./reload-devices'), 23 | updateDevices: require('./update-devices'), 24 | enableAutoDownload: require('./enable-auto-download'), 25 | disableAutoDownload: require('./disable-auto-download'), 26 | updateSearchStatus: require('./update-search-status'), 27 | clearSearchStatus: require('./clear-search-status'), 28 | updateSelectedDevice: require('./update-selected-device'), 29 | resetDownloadProgress: require('./reset-download-progress'), 30 | updateDownloadProgress: require('./update-download-progress'), 31 | // action queue creators 32 | queueNewFile: require('./queue-new-file'), 33 | queueChangeFile: require('./queue-change-file'), 34 | queueOverwriteFile: require('./queue-overwrite-file'), 35 | resetActionQueue: require('./reset-action-queue') 36 | }; 37 | 38 | module.exports = creators; 39 | -------------------------------------------------------------------------------- /examples/COUNT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: COUNT 5 | 'Connect an active-low button (shown in the BUTTON command description) to pin P0 6 | 'of the BASIC Stamp. The Debug Terminal will prompt you to press the button as 7 | 'quickly as possible for a 1-second period. When the count is done, the screen 8 | 'will display your "score," the total number of cycles registered by COUNT. Note 9 | 'that this score will almost always be greater than the actual number of presses 10 | 'because of mechanical switch contact bounce. 11 | 12 | PushBtn PIN 0 'Button on P0 13 | 14 | Capture CON 1000 '1 second 15 | 16 | #SELECT $STAMP 'Set DurAdj according to module type 17 | #CASE BS2, BS2E 18 | DurAdj CON $100 '/ 1 19 | #CASE BS2SX 20 | DurAdj CON $280 '/ 0.400 21 | #CASE BS2P, BS2PX 22 | DurAdj CON $37B '/ 0.287 23 | #CASE BS2PE 24 | DurAdj CON $163 '/ 0.720 25 | #ENDSELECT 26 | 27 | cycles VAR Word 'counted cycles 28 | 29 | Init: 30 | PAUSE 200 'short startup-pause 31 | 32 | Main: 33 | DO 34 | DEBUG CLS, "How many times can you press the button in 1 second?", CR 35 | PAUSE 1000 36 | DEBUG "Ready, set... " 37 | PAUSE 500 38 | DEBUG "GO!", CR 39 | COUNT PushBtn, (Capture */ DurAdj), cycles 40 | DEBUG CR, "Your score: ", DEC cycles, CR 41 | PAUSE 3000 42 | DEBUG "Press button to go again." 43 | DO : LOOP UNTIL (PushBtn = 0) 'wait for button press 44 | LOOP -------------------------------------------------------------------------------- /examples/RANDOM.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: RANDOM 5 | 'This program uses RANDOM to simulate a coin toss. After 100 trials, it reports 6 | 'the total number of heads and tails thrown. Connect a button to I/O pin 7 as 7 | 'shown in the RANDOM command description and run this program. 8 | 9 | Btn PIN 7 'button input 10 | 11 | flip VAR Word 'a random number 12 | coin VAR flip.BIT0 'Bit0 of the random number 13 | trials VAR Byte 'number of flips 14 | heads VAR Byte 'throws that come up heads 15 | tails VAR Byte 'throws that come up tails 16 | btnWrk VAR Byte 'workspace for BUTTON 17 | 18 | Init: 19 | PAUSE 200 'short startup-pause 20 | 21 | Start: 22 | DEBUG CLS, "Press button to start" 23 | 24 | Main: 25 | FOR trials = 1 TO 100 'flip coin 100 times 26 | 27 | Hold: 28 | RANDOM flip 'randomize while waiting 29 | BUTTON Btn, 0, 250, 100, btnWrk, 0, Hold 'wait for button press 30 | IF (coin = 0) THEN '0 = heads, 1 = tails 31 | DEBUG CR, "Heads!" 32 | heads = heads + 1 'increment heads counter 33 | ELSE 34 | DEBUG CR, "Tails..." 35 | tails = tails + 1 'increment tails counter 36 | ENDIF 37 | NEXT 38 | 39 | Done: 40 | DEBUG CR, CR, "Heads: ", DEC heads, " Tails: ", DEC tails 41 | END -------------------------------------------------------------------------------- /src/views/delete-file-overlay.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { createContainer } = require('sovereign'); 5 | const Button = require('../components/button'); 6 | 7 | const Overlay = require('../components/overlay'); 8 | const OverlayTitle = require('../components/overlay-title'); 9 | const OverlayFooter = require('../components/overlay-footer'); 10 | 11 | class DeleteFileOverlay extends React.Component { 12 | 13 | constructor(...args){ 14 | super(...args); 15 | 16 | this.delete = this.delete.bind(this); 17 | } 18 | 19 | delete(){ 20 | const { 21 | filename, 22 | handlers 23 | } = this.props; 24 | 25 | const { 26 | deleteFile, 27 | hideOverlay 28 | } = handlers; 29 | 30 | deleteFile(filename); 31 | hideOverlay(); 32 | } 33 | 34 | render(){ 35 | const { 36 | filename, 37 | handlers 38 | } = this.props; 39 | 40 | const { 41 | hideOverlay 42 | } = handlers; 43 | 44 | return ( 45 | 46 | Are you sure you want to delete {filename}? 47 | 48 | 49 | 50 | 51 | 52 | ); 53 | } 54 | } 55 | 56 | module.exports = createContainer(DeleteFileOverlay, { 57 | getStores({ workspace }){ 58 | return { 59 | workspace 60 | }; 61 | }, 62 | 63 | getPropsFromStores({ workspace }){ 64 | const { filename } = workspace.getState(); 65 | 66 | return { 67 | filename 68 | }; 69 | } 70 | }); 71 | -------------------------------------------------------------------------------- /examples/PULSIN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: PULSIN 5 | 'This program uses PULSIN to measure a pulse generated by discharging a 6 | '0.1 uF capacitor through a 1K resistor. Pressing the switch generates 7 | 'the pulse, which should ideally be approximately 120 us (60 PULSIN units 8 | 'of 2 us) long (for BS2 and BS2e). Variations in component values may 9 | 'produce results that are up to 10 units off from this value. For more 10 | 'information on calculating resistor-capacitor timing, see the RCTIME 11 | 'command. 12 | 13 | Pulse PIN 7 'pulse input pin 14 | 15 | #SELECT $STAMP 'Set Scale according to module type 16 | #CASE BS2, BS2E, BS2PE 17 | Scale CON $200 '2.0 us per unit 18 | #CASE BS2SX 19 | Scale CON $0CC '0.8 us per unit 20 | #CASE BS2P 21 | Scale CON $0C0 '0.75 us per unit 22 | #CASE BS2PX 23 | Scale CON $0CF '0.81 us per unit 24 | #ENDSELECT 25 | 26 | time VAR Word 27 | 28 | Init: 29 | PAUSE 200 'short startup-pause 30 | 31 | Main: 32 | DO 33 | PULSIN Pulse, 1, time 'measure positive pulse 34 | IF (time > 0) THEN 'if not 0 35 | DEBUG HOME, DEC time, " units ", CLREOL 'display raw input 36 | time = time */ Scale 'adjust for Stamp 37 | DEBUG CR, DEC time, " us " 'display microseconds 38 | ELSE 39 | DEBUG CLS, "Out of Range" 'else error message 40 | ENDIF 41 | PAUSE 200 42 | LOOP 43 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var path = require('path'); 5 | 6 | var webpack = require('webpack'); 7 | 8 | var shouldWatch = (process.argv.indexOf('--watch') !== -1); 9 | 10 | var examplesDir = './examples'; 11 | var examples = fs.readdirSync(examplesDir); 12 | 13 | module.exports = { 14 | devtool: 'source-map', 15 | entry: './client.js', 16 | output: { 17 | path: __dirname, 18 | filename: 'bundle.js' 19 | }, 20 | module: { 21 | noParse: [ 22 | /pbasic/i 23 | ], 24 | loaders: [ 25 | { 26 | test: /\.css$/, 27 | loader: 'style-loader!css-loader' 28 | }, 29 | { 30 | test: /\.html$/, 31 | loader: 'html-loader' 32 | }, 33 | { 34 | test: /\.json$/, 35 | loader: 'json-loader' 36 | }, 37 | { 38 | test: /\.bs2$/, 39 | loader: 'raw-loader' 40 | }, 41 | { 42 | test: /\.js$/, 43 | exclude: [ 44 | /node_modules/, 45 | /pbasic/i 46 | ], 47 | loaders: [ 48 | 'babel-loader?optional=runtime' 49 | ] 50 | } 51 | ] 52 | }, 53 | plugins: [ 54 | new webpack.optimize.DedupePlugin(), 55 | new webpack.DefinePlugin({ 56 | EXAMPLES_LIST: JSON.stringify(examples) 57 | }) 58 | ], 59 | resolveLoader: { 60 | // this is a workaround for loaders being applied 61 | // to linked modules 62 | root: path.join(__dirname, 'node_modules') 63 | }, 64 | resolve: { 65 | // this is a workaround for aliasing a top level dependency 66 | // inside a symlinked subdependency 67 | root: path.join(__dirname, 'node_modules'), 68 | alias: { 69 | memdown: 'level-js' 70 | } 71 | }, 72 | bail: true, 73 | watch: shouldWatch 74 | }; 75 | -------------------------------------------------------------------------------- /examples/SERIN_SEROUT1.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SERIN_SEROUT1 5 | 'Using two BS2-IC's, connect the circuit shown in the SERIN command 6 | 'description and run this program on the BASIC Stamp designated as the 7 | 'Sender. This program demonstrates the use of Flow Control (FPin). 8 | 'Without flow control, the sender would transmit the whole word "Hello!" 9 | 'in about 1.5 ms. The receiver would catch the first byte at most; by the 10 | 'time it got back from the first 1-second PAUSE, the rest of the data 11 | 'would be long gone. With flow control, communication is flawless since 12 | 'the sender waits for the receiver to catch up. 13 | 14 | SO PIN 1 'serial output 15 | FC PIN 0 'flow control pin 16 | 17 | #SELECT $STAMP 'Set values according to module type 18 | #CASE BS2, BS2E, BS2PE 19 | T1200 CON 813 20 | T2400 CON 396 21 | T9600 CON 84 22 | T19K2 CON 32 23 | T38K4 CON 6 24 | #CASE BS2SX, BS2P 25 | T1200 CON 2063 26 | T2400 CON 1021 27 | T9600 CON 240 28 | T19K2 CON 110 29 | T38K4 CON 45 30 | #CASE BS2PX 31 | T1200 CON 3313 32 | T2400 CON 1646 33 | T9600 CON 396 34 | T19K2 CON 188 35 | T38K4 CON 84 36 | #ENDSELECT 37 | 38 | Inverted CON $4000 39 | Open CON $8000 40 | Baud CON T9600 + Inverted 41 | 42 | Init: 43 | PAUSE 200 'short startup-pause 44 | 45 | Main: 46 | DO 47 | SEROUT SO\FC, Baud, ["Hello!", CR] 'send the greeting 48 | PAUSE 2500 'wait 2.5 seconds 49 | LOOP 'repeat forever -------------------------------------------------------------------------------- /src/reducers/device.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const _ = require('lodash'); 4 | 5 | const { 6 | CONNECT, 7 | DISCONNECT, 8 | RELOAD_DEVICES, 9 | UPDATE_DEVICES, 10 | ENABLE_AUTO_DOWNLOAD, 11 | DISABLE_AUTO_DOWNLOAD, 12 | UPDATE_SEARCH_STATUS, 13 | CLEAR_SEARCH_STATUS, 14 | UPDATE_SELECTED_DEVICE 15 | } = require('../constants/action-types'); 16 | 17 | const initial = { 18 | path: null, 19 | selected: null, 20 | searching: true, 21 | connected: false, 22 | // TODO: not sure if this should be here 23 | autoDownload: true, 24 | // TODO: I don't think search status should be in here 25 | searchStatus: null 26 | }; 27 | 28 | function device(state = initial, { type, payload }){ 29 | switch(type){ 30 | case CONNECT: 31 | return _.assign({}, state, { connected: true }); 32 | case DISCONNECT: 33 | return _.assign({}, state, { connected: false }); 34 | case RELOAD_DEVICES: 35 | return _.assign({}, state, { path: null, searching: true, searchStatus: null }); 36 | case UPDATE_DEVICES: 37 | return _.assign({}, state, { searching: false }); 38 | case ENABLE_AUTO_DOWNLOAD: 39 | return _.assign({}, state, { autoDownload: true }); 40 | case DISABLE_AUTO_DOWNLOAD: 41 | return _.assign({}, state, { autoDownload: false }); 42 | case UPDATE_SEARCH_STATUS: 43 | return _.assign({}, state, { searchStatus: payload.status }); 44 | case CLEAR_SEARCH_STATUS: 45 | return _.assign({}, state, { searchStatus: payload.status }); 46 | case UPDATE_SELECTED_DEVICE: 47 | // TODO: not sure if it is better to set searchStatus 48 | // to null when we update or dispatch a clear separately 49 | return _.assign({}, state, { selected: payload.device, path: payload.device.path, searchStatus: null }); 50 | default: 51 | return state; 52 | } 53 | } 54 | 55 | module.exports = device; 56 | -------------------------------------------------------------------------------- /examples/SHIFTOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SHIFTOUT 5 | 'This program uses the SHIFTOUT command to interface to the 74HC595 shift 6 | 'register as an 8-bit output port. The 74HC595 requires a minimum of three 7 | 'inputs: data, clock, and latch. See the figure in the SHIFTOUT command 8 | 'description for wiring information. SHIFTOUT automatically handles the data 9 | 'and clock, pulsing the clock to shift data bits into the 74HC595. An extra 10 | 'step (pulsing the latch input) is required to move the shifted bits in 11 | 'parallel onto the 74HC595's output pins. Note: this code does not control 12 | 'the output-enable or reset lines of the 74HC595. This means that before the 13 | 'BASIC Stamp first sends, the 74HC595's output latches are turned on and may 14 | 'contain random data. In critical applications, you should hold output-enable 15 | 'high (disabled) until the BASIC Stamp can take control. 16 | 17 | Dpin PIN 0 'data pin to 74HC595 18 | Clk PIN 1 'shift clock to 74HC595 19 | Latch PIN 2 'latch 74HC595 outputs 20 | 21 | counter VAR Byte 22 | 23 | Setup: 24 | LOW Latch 'initialize latch output 25 | 26 | 'This loop moves the 8-bit value 'counter' onto the output lines of the 27 | '74HC595, pauses, then increments counter and repeats. The data is shifted 28 | 'msb first so that the msb appears on pin QH and the lsb on QA. Changing 29 | 'MSBFIRST to LSBFIRST causes the data to appear backwards on the outputs. 30 | 31 | Main: 32 | DO 33 | SHIFTOUT Dpin, Clk, MSBFIRST, [counter] 'send the bits 34 | PULSOUT Latch, 1 'transfer to outputs 35 | PAUSE 100 'Wait 0.1 seconds 36 | counter = counter + 1 'increment counter 37 | LOOP -------------------------------------------------------------------------------- /examples/LCDCMD.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LCDCMD 5 | 'This program demonstrates initialization and printing on a 2 x 16 6 | 'character LCD display. The set of "LCD constants", below, are provided 7 | 'as pre-defined and useful LCD commands, though not all are actually 8 | 'used in this program. 9 | 10 | #IF ($stamp < BS2P) #THEN 'Notify of module requirements 11 | #ERROR "Program requires BS2p, BS2pe, or BS2px." 12 | #ENDIF 13 | 14 | Lcd PIN 0 15 | 16 | LcdCls CON $01 'clear the LCD 17 | LcdHome CON $02 'move cursor home 18 | LcdCrsrL CON $10 'move cursor left 19 | LcdCrsrR CON $14 'move cursor right 20 | LcdDispL CON $18 'shift chars left 21 | LcdDispR CON $1C 'shift chars right 22 | LcdDDRam CON $80 'Display Data RAM 23 | LcdCGRam CON $40 'Character Generator RAM 24 | LcdLine1 CON $80 'DDRAM address of line 1 25 | LcdLine2 CON $C0 'DDRAM address of line 2 26 | 27 | 28 | Init_LCD: 29 | PAUSE 1000 'allow LCD to self-initialize first 30 | LCDCMD Lcd, %00110000 'send wakeup sequence to LCD 31 | PAUSE 5 'pause required by LCD specs 32 | LCDCMD Lcd, %00110000 33 | PAUSE 0 'pause required by LCD specs 34 | LCDCMD Lcd, %00110000 35 | PAUSE 0 'pause required by LCD specs 36 | LCDCMD Lcd, %00100000 'set data bus to 4-bit mode 37 | LCDCMD Lcd, %00101000 'set to 2-line mode with 5x8 font 38 | LCDCMD Lcd, %00001100 'display on without cursor 39 | LCDCMD Lcd, %00000110 'auto-increment cursor 40 | 41 | Main: 42 | DO 43 | LCDOUT Lcd, LcdCls, ["Hello, World!"] 44 | LCDOUT Lcd, LcdLine2, ["How are you?"] 45 | PAUSE 3000 46 | LCDCMD Lcd, LcdCls 47 | PAUSE 500 48 | LOOP -------------------------------------------------------------------------------- /examples/LCDINIT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LCDINIT 5 | 'This program demonstrates initialization and printing on a 2 x 16 6 | 'character LCD display. The set of "LCD constants", below, are provided 7 | 'as pre-defined and useful LCD commands, though not all are actually 8 | 'used in this program. 9 | 10 | #IF ($STAMP < BS2P) #THEN 'Notify of module requirements 11 | #ERROR "Program requires BS2p, BS2pe or BS2px." 12 | #ENDIF 13 | 14 | Lcd PIN 0 15 | 16 | LcdCls CON $01 'clear the LCD 17 | LcdHome CON $02 'move cursor home 18 | LcdCrsrL CON $10 'move cursor left 19 | LcdCrsrR CON $14 'move cursor right 20 | LcdDispL CON $18 'shift chars left 21 | LcdDispR CON $1C 'shift chars right 22 | LcdDDRam CON $80 'Display Data RAM 23 | LcdCGRam CON $40 'Character Generator RAM 24 | LcdLine1 CON $80 'DDRAM address of line 1 25 | LcdLine2 CON $C0 'DDRAM address of line 2 26 | 27 | 28 | Init_LCD: 29 | PAUSE 1000 'allow LCD to self-initialize first 30 | LCDCMD Lcd, %00110000 'send wakeup sequence to LCD 31 | PAUSE 5 'pause required by LCD specs 32 | LCDCMD Lcd, %00110000 33 | PAUSE 0 'pause required by LCD specs 34 | LCDCMD Lcd, %00110000 35 | PAUSE 0 'pause required by LCD specs 36 | LCDCMD Lcd, %00100000 'set data bus to 4-bit mode 37 | LCDCMD Lcd, %00101000 'set to 2-line mode with 5x8 font 38 | LCDCMD Lcd, %00001100 'display on without cursor 39 | LCDCMD Lcd, %00000110 'auto-increment cursor 40 | 41 | Main: 42 | DO 43 | LCDOUT Lcd, LcdCls, ["Hello, World!"] 44 | LCDOUT Lcd, LcdLine2, ["How are you?"] 45 | PAUSE 3000 46 | LCDCMD Lcd, LcdCls 47 | PAUSE 500 48 | LOOP -------------------------------------------------------------------------------- /examples/SERIN_SEROUT2.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SERIN_SEROUT2 5 | 'Using two BS2-IC's, connect the circuit shown in the SERIN command 6 | 'description and run this program on the BASIC Stamp designated as the 7 | 'Receiver. This program demonstrates the use of Flow Control (FPin). 8 | 'Without flow control, the sender would transmit the whole word "Hello!" 9 | 'in about 1.5 ms. The receiver would catch the first byte at most; by the 10 | 'time it got back from the first 1-second PAUSE, the rest of the data 11 | 'would be long gone. With flow control, communication is flawless since 12 | 'the sender waits for the receiver to catch up. 13 | 14 | SI PIN 1 'serial input 15 | FC PIN 0 'flow control pin 16 | 17 | #SELECT $STAMP 'Set values according to module type 18 | #CASE BS2, BS2E, BS2PE 19 | T1200 CON 813 20 | T2400 CON 396 21 | T9600 CON 84 22 | T19K2 CON 32 23 | T38K4 CON 6 24 | #CASE BS2SX, BS2P 25 | T1200 CON 2063 26 | T2400 CON 1021 27 | T9600 CON 240 28 | T19K2 CON 110 29 | T38K4 CON 45 30 | #CASE BS2PX 31 | T1200 CON 3313 32 | T2400 CON 1646 33 | T9600 CON 396 34 | T19K2 CON 188 35 | T38K4 CON 84 36 | #ENDSELECT 37 | 38 | Inverted CON $4000 39 | Open CON $8000 40 | Baud CON T9600 + Inverted 41 | 42 | letter VAR Byte 43 | 44 | Init: 45 | PAUSE 200 'short startup-pause 46 | 47 | Main: 48 | DO 49 | SERIN SI\FC, Baud, [letter] 'receive one byte 50 | DEBUG letter 'display on screen 51 | PAUSE 1000 'wait one second 52 | LOOP 'repeat forever -------------------------------------------------------------------------------- /examples/SELECT-CASE.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: SELECT-CASE 5 | 'This program generates a series of 16-bit random numbers and tests each 6 | 'to determine odd or even, and where it falls in the possible range: 7 | 'lower third, middle third, or upper third. The program is useful for 8 | 'testing various seed values for RANDOM. 9 | 10 | test VAR Byte 'counter for tests 11 | sample VAR Word 'random number to be tested 12 | odd VAR Byte 'odd throws 13 | even VAR Byte 'even throws 14 | isLo VAR Byte 'sample in lower third 15 | isMid VAR Byte ' in middle thrid 16 | isHi VAR Byte ' in upper third 17 | 18 | Init: 19 | PAUSE 200 'short startup-pause 20 | 21 | Main: 22 | sample = 11000 'initialize seed 23 | FOR test = 1 TO 100 '"throw" 100 times 24 | RANDOM sample 'randomize 25 | 26 | IF (sample.BIT0) THEN 'check odd/even bit 27 | odd = odd + 1 'increment odd count 28 | ELSE 29 | even = even + 1 'increment even count 30 | ENDIF 31 | 32 | SELECT sample 33 | CASE <= 21845 'test lower third 34 | isLo = isLo + 1 35 | 36 | CASE 21846 TO 43691 'test middle third 37 | isMid = isMid + 1 38 | 39 | CASE ELSE 'otherwise upper third 40 | isHi = isHi + 1 41 | ENDSELECT 42 | NEXT 43 | 44 | Show_Results: 45 | DEBUG CLS, 46 | "Odd Throws.... ", DEC odd, "%", CR, 47 | "Even Throws... ", DEC even, "%", CR, 48 | "Low........... ", DEC isLo, "%", CR, 49 | "Mid........... ", DEC isMid, "%", CR, 50 | "High.......... ", DEC isHi, "%", CR 51 | END -------------------------------------------------------------------------------- /examples/FREQOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: FREQOUT 5 | 'This program demonstrates sound-effects generation by the BASIC Stamp. 6 | 'Conditional compilation sets timing and frequency adjustment factors so 7 | 'that the output will sound the same on any BS2 model. 8 | 9 | Spkr PIN 10 'output pin for FREQOUT 10 | 11 | #SELECT $STAMP 'Set TmAdj and FrAdj according to module type 12 | #CASE BS2, BS2E 13 | TmAdj CON $100 'x 1.0 (time adjust) 14 | FrAdj CON $100 'x 1.0 (freq adjust) 15 | #CASE BS2SX 16 | TmAdj CON $280 'x 2.5 17 | FrAdj CON $066 'x 0.4 18 | #CASE BS2P 19 | TmAdj CON $3C5 'x 3.77 20 | FrAdj CON $044 'x 0.265 21 | #CASE BS2PE 22 | TmAdj CON $100 'x 1.0 23 | FrAdj CON $0A9 'x 0.662 24 | #CASE BS2PX 25 | TmAdj CON $607 'x 6.03 26 | FrAdj CON $2A 'x 0.166 27 | #ENDSELECT 28 | 29 | Init: 30 | PAUSE 200 'short startup-pause 31 | 32 | Main: 33 | DEBUG "Let's make a call...", CR 34 | 'combine 350 Hz & 440 Hz 35 | FREQOUT Spkr, 2000 */ TmAdj, 350 */ FrAdj, 440 */ FrAdj 36 | 'dial number (digits 150 ms on, 25 ms off) 37 | DTMFOUT Spkr, 150 */ TmAdj, 25, [5, 5, 5, 1, 2, 1, 2] 38 | PAUSE 500 39 | 40 | 'bad connection (SIT sequence) 41 | FREQOUT Spkr, 375 */ TmAdj, 985 */ FrAdj 42 | FREQOUT Spkr, 375 */ TmAdj, 1371 */ FrAdj 43 | FREQOUT Spkr, 375 */ TmAdj, 1777 */ FrAdj 44 | 45 | DEBUG "Oops! -- try again...", CR 46 | PAUSE 1000 47 | DTMFOUT Spkr, 150 */ TmAdj, 25, [5, 5, 5, 2, 2, 2, 2] 48 | DEBUG "Ringing" 49 | FREQOUT Spkr, 2000 */ TmAdj, 440 */ FrAdj, 480 */ FrAdj 50 | PAUSE 4000 51 | FREQOUT Spkr, 2000 */ TmAdj, 440 */ FrAdj, 480 */ FrAdj 52 | INPUT Spkr 53 | END 54 | -------------------------------------------------------------------------------- /examples/LCDIN.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LCDIN 5 | 'This program demonstrates initialization, printing and reading 6 | 'from a 2 x 16 character LCD display. 7 | 8 | #IF ($STAMP < BS2P) #THEN 'Notify of module requirements 9 | #ERROR "Program requires BS2p, BS2pe or BS2px." 10 | #ENDIF 11 | 12 | Lcd PIN 0 13 | 14 | LcdCls CON $01 'clear the LCD 15 | LcdHome CON $02 'move cursor home 16 | LcdCrsrL CON $10 'move cursor left 17 | LcdCrsrR CON $14 'move cursor right 18 | LcdDispL CON $18 'shift chars left 19 | LcdDispR CON $1C 'shift chars right 20 | LcdDDRam CON $80 'Display Data RAM 21 | LcdCGRam CON $40 'Character Generator RAM 22 | LcdLine1 CON $80 'DDRAM address of line 1 23 | LcdLine2 CON $C0 'DDRAM address of line 2 24 | 25 | char VAR Byte(16) 26 | 27 | Init_LCD: 28 | PAUSE 1000 'allow LCD to self-initialize first 29 | LCDCMD Lcd, %00110000 'send wakeup sequence to LCD 30 | PAUSE 5 'pause required by LCD specs 31 | LCDCMD Lcd, %00110000 32 | PAUSE 0 'pause required by LCD specs 33 | LCDCMD Lcd, %00110000 34 | PAUSE 0 'pause required by LCD specs 35 | LCDCMD Lcd, %00100000 'set data bus to 4-bit mode 36 | LCDCMD Lcd, %00101000 'set to 2-line mode with 5x8 font 37 | LCDCMD Lcd, %00001100 'display on without cursor 38 | LCDCMD Lcd, %00000110 'auto-increment cursor 39 | 40 | Main: 41 | DO 42 | LCDOUT Lcd, LcdCls, ["Hello!"] 43 | GOSUB Read_LCD_Screen 44 | PAUSE 3000 45 | LCDOUT Lcd, LcdCls, ["I'm a 2x16 LCD!"] 46 | GOSUB Read_LCD_Screen 47 | PAUSE 3000 48 | LOOP 49 | 50 | Read_LCD_Screen: 51 | DEBUG "LCD now says: " 52 | LCDIN Lcd, LcdLine1, [STR char\16] 53 | DEBUG STR char\16, CR 54 | RETURN -------------------------------------------------------------------------------- /examples/LCDOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: LCDOUT 5 | 'This program demonstrates initialization and printing on a 2x16 6 | 'character LCD display. 7 | 8 | #IF ($STAMP < BS2P) #THEN 'Notify of module requirements 9 | #ERROR "Program requires BS2p, BS2pe or BS2px." 10 | #ENDIF 11 | 12 | Lcd PIN 0 13 | 14 | LcdCls CON $01 'clear the LCD 15 | LcdHome CON $02 'move cursor home 16 | LcdCrsrL CON $10 'move cursor left 17 | LcdCrsrR CON $14 'move cursor right 18 | LcdDispL CON $18 'shift chars left 19 | LcdDispR CON $1C 'shift chars right 20 | LcdDDRam CON $80 'Display Data RAM 21 | LcdCGRam CON $40 'Character Generator RAM 22 | LcdLine1 CON $80 'DDRAM address of line 1 23 | LcdLine2 CON $C0 'DDRAM address of line 2 24 | 25 | 26 | Init_LCD: 27 | PAUSE 1000 'allow LCD to self-initialize first 28 | LCDCMD Lcd, %00110000 'send wakeup sequence to LCD 29 | PAUSE 5 'pause required by LCD specs 30 | LCDCMD Lcd, %00110000 31 | PAUSE 0 'pause required by LCD specs 32 | LCDCMD Lcd, %00110000 33 | PAUSE 0 'pause required by LCD specs 34 | LCDCMD Lcd, %00100000 'set data bus to 4-bit mode 35 | LCDCMD Lcd, %00101000 'set to 2-line mode with 5x8 font 36 | LCDCMD Lcd, %00001100 'display on without cursor 37 | LCDCMD Lcd, %00000110 'auto-increment cursor 38 | 39 | LCDOUT Lcd, LcdCGRam, 'load custom character map 40 | [$00, $0A, $0A, $00, $11, $0E, $06, $00] 41 | 42 | Main: 43 | DO 44 | LCDOUT Lcd, LcdCls, ["Hello my friend."] 45 | PAUSE 750 46 | LCDOUT Lcd, LcdLine2, ["How are you?"] 47 | PAUSE 1500 48 | LCDCMD Lcd, LcdCls 49 | LCDOUT Lcd, LcdLine1 + 1, ["I'm doing just"] 50 | LCDOUT Lcd, LcdLine2 + 4, ["fine! ", 0] 51 | PAUSE 2000 52 | LOOP -------------------------------------------------------------------------------- /examples/GOSUB.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: GOSUB 5 | 'This program is a guessing game that generates a random number in a 6 | 'subroutine called Pick_A_Number. It is written to stop after three 7 | 'guesses. To see a common bug associated with GOSUB, delete or comment 8 | 'out the line beginning with END after the FOR-NEXT loop. This means 9 | 'that after the loop is finished, the program will wander into the 10 | 'Pick_A_Number subroutine. When the RETURN at the source's end executes, 11 | 'the program will go back to the beginning. This will cause the program 12 | 'to execute endlessly. Make sure that your programs can't accidentally 13 | 'execute subroutines! 14 | 15 | rounds VAR Byte 'number of reps 16 | numGen VAR Word 'random number holder 17 | myNum VAR Byte 'random number, 1-10 18 | 19 | Setup: 20 | PAUSE 200 'short startup-pause 21 | numGen = 11500 'initialize random "seed" 22 | 23 | Main: 24 | FOR rounds = 1 TO 3 25 | DEBUG CLS, "Think of a number from 1 to 10", CR 26 | GOSUB Pick_A_Number 27 | PAUSE 2000 'dramatic pause 28 | DEBUG "My number was: ", DEC myNum 'show the number 29 | PAUSE 1000 'another pause. 30 | NEXT 31 | DEBUG CLS, "Done" 32 | END 'end program 33 | 34 | 'Random-number subroutine. A subroutine is just a piece of code with 35 | 'the RETURN instruction at the end. Always make sure your program enters 36 | 'subroutines with a GOSUB. If you don't, the RETURN won't have the 37 | 'correct address, and your program will have a bug! 38 | 39 | Pick_A_Number: 40 | RANDOM numGen 'stir up the bits of NumGen. 41 | DEBUG " (random value = ", DEC numGen, ")", CR, CR 42 | myNum = numGen / 6550 MIN 1 'scale to fit 1-10 range. 43 | RETURN 'go back to instruction after 44 | 'the GOSUB that got us here -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Parallax IDE 6 | 7 | 8 | 9 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /examples/I2C.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: I2C 5 | 'This program demonstrates writing and reading every location in a 24LC16B 6 | 'EEPROM using the BS2p/BS2pe's I2C commands. Connect the BS2p, BS2pe, or 7 | 'BS2px to the 24LC16B DIP EEPROM as shown in the diagram in the I2CIN OR 8 | 'I2COUT command description. 9 | 10 | #IF ($STAMP < BS2P) #THEN 'Notify of module requirements 11 | #ERROR "Program requires BS2p, BS2pe, or BS2px." 12 | #ENDIF 13 | 14 | SDA PIN 0 'I2C SDA pin 15 | SCL PIN SDA + 1 16 | 17 | addr VAR Word 'internal address 18 | block VAR Nib 'block address in 24LC16 19 | value VAR Byte 'value to write 20 | check VAR Nib 'for checking retuned values 21 | result VAR Byte(16) 'array for returned value 22 | 23 | Init: 24 | PAUSE 200 'short startup-pause 25 | 26 | Write_To_EEPROM: 27 | DEBUG "Writing...", CR 28 | PAUSE 2000 29 | FOR addr = 0 TO 2047 STEP 16 'loop through all addresses 30 | block = addr.NIB2 << 1 'calculate block address 31 | value = addr >> 4 'create value from upper 8 bits 32 | 'write 16 bytes 33 | I2COUT SDA, $A0 | block, addr, [REP value\16] 34 | PAUSE 5 35 | DEBUG "Addr: ", DEC4 addr, "-", DEC4 addr + 15, " ", 36 | "Value: ", DEC3 value, CR 37 | NEXT 38 | PAUSE 2000 39 | 40 | Read_From_EEPROM: 41 | DEBUG CR, "Reading...", CR 42 | PAUSE 2000 43 | FOR addr = 0 TO 2047 STEP 16 44 | block = addr.NIB2 << 1 45 | value = addr >> 4 46 | I2CIN SDA, $A1 | block, addr, [STR result\16] 47 | FOR check = 0 TO 15 48 | IF (result(check) <> value) THEN Error 49 | NEXT 50 | DEBUG "Addr: ", DEC4 addr, "-", DEC4 addr + 15, " ", 51 | "Value: ", DEC3 result, CR 52 | NEXT 53 | PAUSE 100 54 | DEBUG CR, "All locations passed" 55 | END 56 | 57 | Error: 58 | DEBUG "Error at location: ", DEC4 addr + check, CR, 59 | "Found: ", DEC3 result(check), ", Expected: ", DEC3 value -------------------------------------------------------------------------------- /examples/XOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: XOUT 5 | 'This program--really two program fragments--demonstrates the syntax and 6 | 'use of the XOUT command. XOUT works like pressing the buttons on an X-10 7 | 'control box; first you press one of 16 keys to identify the unit you want 8 | 'to control, then you press the key for the action you want that unit to 9 | 'take (turn ON, OFF, Bright, or Dim). There are also two group-action keys, 10 | 'Lights ON and All OFF. Lights ON turns all lamp modules on without 11 | 'affecting appliance modules. All OFF turns off all modules, both lamp and 12 | 'appliance types. Connect the BASIC Stamp to a power-line interface as 13 | 'shown in the XOUT command description in the manual. 14 | 15 | Mpin PIN 1 'modulation pin 16 | Zpin PIN 0 'zero-cross input 17 | 18 | HouseA CON 0 'House code A = 0 19 | Unit1 CON 0 'Unit code 1 = 0 20 | Unit2 CON 1 'Unit code 2 = 1 21 | 22 | 'This first example turns a standard (appliance or non-dimmer lamp) module 23 | 'ON, then OFF. Note that once the Unit code is sent, it need not be repeated 24 | '--subsequent instructions are understood to be addressed to that unit. 25 | 26 | Main: 27 | XOUT Mpin, Zpin, [HouseA\Unit1\2] 'select Unit1 (appliance module) 28 | XOUT Mpin, Zpin, [HouseA\UNITON] 'turn it on 29 | 30 | PAUSE 1000 'wait one second 31 | 32 | XOUT Mpin, Zpin, [HouseA\UNITOFF] 'then turn it off 33 | 34 | 'The next example talks to a lamp module using the dimmer feature. Dimmers 35 | 'go from full ON to dimmed OFF in 19 steps. Because dimming is relative to 36 | 'the current state of the lamp, the only guaranteed way to set a predefined 37 | 'brightness level is to turn the dimmer fully OFF, then ON, then dim to the 38 | 'desired level. 39 | 40 | XOUT Mpin, Zpin, [HouseA\Unit2\2] 'select Unit2 (lamp module) 41 | 42 | 'This example shows the use of the optional Cycles argument. Here we DIM 43 | 'for 10 cycles. 44 | 45 | XOUT Mpin, Zpin, [HouseA\UNITOFF\2, HouseA\DIM\10] 46 | STOP -------------------------------------------------------------------------------- /src/views/terminal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | const { createContainer } = require('sovereign'); 5 | 6 | const Scroller = require('../lib/scroller'); 7 | 8 | const TransmitPane = require('../components/transmit-pane'); 9 | 10 | const styles = { 11 | outputConsole: { 12 | height: '200px', 13 | boxShadow: 'inset 0 5px 10px -5px rgba(0, 0, 0, 0.26)', 14 | backgroundColor: 'white', 15 | padding: '10px', 16 | margin: '0', 17 | overflow: 'auto', 18 | whiteSpace: 'pre' 19 | } 20 | }; 21 | 22 | class TermnialView extends React.Component { 23 | 24 | componentWillReceiveProps(nextProps){ 25 | const { output, offset } = nextProps; 26 | this.scroller.setLines(output, offset); 27 | this.scroller.requestRefresh(); 28 | } 29 | 30 | componentDidMount() { 31 | const outputElement = React.findDOMNode(this.outputConsole); 32 | this.scroller = new Scroller(outputElement); 33 | outputElement.addEventListener('scroll', this.scroller.scroll, false); 34 | } 35 | 36 | componentWillUnmount() { 37 | const outputElement = React.findDOMNode(this.outputConsole); 38 | outputElement.removeEventListener('scroll', this.scroller.scroll, false); 39 | } 40 | 41 | shouldComponentUpdate(nextProps){ 42 | const { connected, input } = this.props; 43 | return (connected !== nextProps.connected || input !== nextProps.input); 44 | } 45 | 46 | render(){ 47 | const { 48 | handlers, 49 | connected, 50 | input 51 | } = this.props; 52 | 53 | const { 54 | transmitInput 55 | } = handlers; 56 | 57 | return ( 58 |
    59 | 60 |
     this.outputConsole = ref} style={styles.outputConsole} />
    61 |       
    62 | ); 63 | } 64 | } 65 | 66 | module.exports = createContainer(TermnialView, { 67 | getStores({ store }){ 68 | return { 69 | store 70 | }; 71 | }, 72 | 73 | getPropsFromStores({ store }){ 74 | const { transmission, device } = store.getState(); 75 | const { input, output, offset } = transmission; 76 | const { connected } = device; 77 | 78 | return { 79 | connected, 80 | input, 81 | output, 82 | offset 83 | }; 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /examples/DTMFOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: DTMFOUT 5 | 'This demo program is a rudimentary memory dialer. Since DTMF digits fit 6 | 'within a nibble (four bits), the program below packs two DTMF digits into 7 | 'each byte of three EEPROM data tables. The end of phone number is marked 8 | 'by the nibble $F, since this is not a valid phone-dialing digit. 9 | 'Conditional compilation sets the timing adjustment factor so that the 10 | 'output will sound the same on any BS2 model. 11 | 12 | Spkr PIN 10 'DTMF output on pin 10 13 | 14 | #SELECT $STAMP 'Set TmAdj according to module type 15 | #CASE BS2, BS2E, BS2PE 16 | TmAdj CON $100 'x 1.0 (time adjust) 17 | #CASE BS2SX 18 | TmAdj CON $280 'x 2.5 19 | #CASE BS2P 20 | TmAdj CON $3C5 'x 3.77 21 | #CASE BS2PX 22 | TmAdj CON $607 'x 6.03 23 | #ENDSELECT 24 | 25 | eeLoc VAR Byte 'EEPROM address of stored number 26 | eeByte VAR Byte 'Byte containing two DTMF digits 27 | dtDig VAR eeByte.NIB1 'Digit to dial 28 | phone VAR Nib 'Pick a phone # 29 | hiLo VAR Bit 'Bit to select upper and lower nib 30 | 31 | Parallax DATA $19,$16,$62,$48,$33,$3F 'Phone: 1-916-624-8333 32 | ParallaxFax DATA $19,$16,$62,$48,$00,$3F 'Phone: 1-916-624-8003 33 | Information DATA $15,$20,$55,$51,$21,$2F 'Phone: 1-520-555-1212 34 | 35 | Main: 36 | FOR phone = 0 TO 2 37 | 'retrieve address 38 | LOOKUP phone, [Parallax, ParallaxFax, Information], eeLoc 39 | GOSUB Dial_Number 40 | PAUSE 2000 41 | NEXT 42 | END 43 | 44 | Dial_Number: 45 | DO 46 | READ eeLoc, eeByte 'Retrieve byte from EEPROM 47 | eeLoc = eeLoc + 1 'point to next pair of digits 48 | FOR hiLo = 0 TO 1 'Dial upper and lower digits 49 | IF (dtDig = $F) THEN EXIT 'Hex $F is end-of-number flag 50 | DTMFOUT Spkr, 'dial digit 51 | 150 */ TmAdj, 25, [dtDig] '150 ms on, 25 ms off 52 | eeByte = eeByte << 4 'Shift in next digit 53 | NEXT 54 | LOOP UNTIL (dtDig = $F) 55 | RETURN 56 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "parallax-ide", 3 | "version": "0.14.4", 4 | "description": "Write, compile, and download code to your Parallax Boe-Bot Robot or custom BASIC Stamp microcontroller-based electronic creations.", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "dependencies": { 10 | "@phated/redux-create-store": "^0.3.0", 11 | "acorn": "^6.4.2", 12 | "bs2-serial": "^0.15.0", 13 | "codemirror": "^4.13.0", 14 | "express": "^3.21.2", 15 | "frylord": "^0.7.4", 16 | "history": "^1.12.5", 17 | "iggins": "^0.4.0", 18 | "invariant": "^2.1.1", 19 | "irken": "^0.9.0", 20 | "lodash": "^4.17.19", 21 | "raw-loader": "^0.5.1", 22 | "react": "^0.13.1", 23 | "react-loader": "^1.2.0", 24 | "react-material": "git://github.com/PropGit/react-material#0.14", 25 | "react-mfb-iceddev": "^0.1.0", 26 | "react-router": "^1.0.0-rc1", 27 | "react-style": "^0.4.0", 28 | "skrim": "0.0.3", 29 | "snacks": "^0.3.1", 30 | "sovereign": "^0.3.0", 31 | "when": "^3.7.2" 32 | }, 33 | "devDependencies": { 34 | "@phated/eslint-config-iceddev": "^0.2.1", 35 | "babel-core": "^4.5.1", 36 | "babel-loader": "^4.0.0", 37 | "babel-runtime": "^4.7.16", 38 | "chalk": "^1.0.0", 39 | "css-loader": "^0.9.1", 40 | "del": "^1.1.1", 41 | "electron-prebuilt": "^0.30.2", 42 | "eslint": "^1.2.1", 43 | "eslint-plugin-mocha": "^0.5.1", 44 | "eslint-plugin-react": "^3.2.3", 45 | "expect": "^1.8.0", 46 | "gulp": "^4.0.1", 47 | "gulp-util": "^3.0.4", 48 | "gulp-zip": "^2.0.3", 49 | "html-loader": "^0.2.3", 50 | "json-loader": "^0.5.1", 51 | "level-js": "^2.1.6", 52 | "style-loader": "^0.8.3", 53 | "webpack": "^1.7.2", 54 | "webpack-dev-server": "^1.7.0", 55 | "zuul": "^3.2.0", 56 | "zuul-builder-webpack": "^1.1.0" 57 | }, 58 | "scripts": { 59 | "test": "zuul test/*.js --local --open", 60 | "ci": "zuul test/*.js --electron", 61 | "build": "gulp", 62 | "version": "gulp version && git add manifest.json", 63 | "release": "gulp gh-release", 64 | "postinstall": "gulp postinstall", 65 | "serve": "webpack-dev-server" 66 | }, 67 | "repository": { 68 | "type": "git", 69 | "url": "https://github.com/parallaxinc/Parallax-IDE" 70 | }, 71 | "license": "MIT", 72 | "bugs": { 73 | "url": "https://github.com/parallaxinc/Parallax-IDE/issues" 74 | }, 75 | "homepage": "https://github.com/parallaxinc/Parallax-IDE" 76 | } 77 | -------------------------------------------------------------------------------- /examples/OWIN_OWOUT.bs2: -------------------------------------------------------------------------------- 1 | '{$STAMP BS2p} 2 | '{$PBASIC 2.5} 3 | 4 | 'SOURCE: OWIN_OWOUT 5 | 'This program demonstrates interfacing to a Dallas Semiconductor DS1822 6 | '1-Wire Digital Thermometer chip using the BS2p's 1-Wire commands. Connect 7 | 'the BS2p, BS2pe, or BS2px to the DS1822 as shown in the diagram in the 8 | 'OWIN or OWOUT command description. This program uses a simplified 9 | 'approach that ignores the fractional portion of the temperature. 10 | 11 | #IF ($STAMP < BS2P) #THEN 'Notify of module requirements 12 | #ERROR "Program requires BS2p, BS2pe or BS2px." 13 | #ENDIF 14 | 15 | DQ PIN 0 '1-Wire buss pin 16 | 17 | RdROM CON $33 'read serial number 18 | MatchROM CON $55 'match SN -- for multiple devices 19 | SkipROM CON $CC 'ignore SN -- use for one device 20 | CvrtTmp CON $44 'start temperature conversion 21 | RdSP CON $BE 'read DS1822 scratch pad 22 | 23 | tempIn VAR Word 'raw temperature 24 | sign VAR tempIn.BIT11 '1 = negative temperature 25 | tLo VAR tempIn.BYTE0 26 | tHi VAR tempIn.BYTE1 27 | tSign VAR Bit 'saved sign bit 28 | tempC VAR Word 'final Celsius temp 29 | tempF VAR Word 'final Fahrenheit temp 30 | 31 | Init: 32 | PAUSE 200 'short startup-pause 33 | 34 | Main: 35 | DO 36 | GOSUB Get_Temperature 'read temperature from DS1822 37 | DEBUG HOME, 'display 38 | "DS1822", CR, 39 | "------", CR, 40 | SDEC tempC, " C ", CR, 41 | SDEC tempF, " F " 42 | PAUSE 1000 43 | LOOP 44 | END 45 | 46 | Get_Temperature: 47 | OWOUT DQ, 1, [SkipROM, CvrtTmp] 'send convert temperature command 48 | DO 'wait on conversion 49 | PAUSE 25 'small loop pad 50 | OWIN DQ, 4, [tempIn] 'check status (bit transfer) 51 | LOOP UNTIL (tempIn) '1 when complete 52 | OWOUT DQ, 1, [SkipROM, RdSP] 'read DS1822 scratch pad 53 | OWIN DQ, 2, [tLo, tHi] 'get raw temp data 54 | tSign = sign 'save sign bit 55 | tempC = tempIn >> 4 'round to whole degrees 56 | tempC.BYTE1 = $FF * tSign 'correct twos complement bits 57 | tempF = (ABS tempC) * 9 / 5 'start F conversion 58 | IF (tSign) THEN 'finish F conversion 59 | tempF = 32 - tempF 'C was negative 60 | ELSE 61 | tempF = tempF + 32 'C was positive 62 | ENDIF 63 | RETURN -------------------------------------------------------------------------------- /src/components/transmit-pane.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const React = require('react'); 4 | 5 | const styles = { 6 | transmit: { 7 | margin: 0, 8 | height: '32px', 9 | backgroundColor: 'white', 10 | boxShadow: 'inset 0px 5px 10px -5px rgba(0, 0, 0, 0.26)' 11 | }, 12 | transmitInput: { 13 | border: '0px', 14 | backgroundColor: 'transparent', 15 | outline: 'none', 16 | resize: 'none', 17 | width: '100%', 18 | padding: '5px 10px', 19 | fontSize: 'inherit', 20 | fontFamily: 'inherit', 21 | boxSizing: 'border-box' 22 | } 23 | }; 24 | 25 | const ignore = [16, 17, 18, 20]; 26 | 27 | class TransmitPane extends React.Component { 28 | 29 | constructor(...args){ 30 | super(...args); 31 | 32 | this.handleKeyDown = this.handleKeyDown.bind(this); 33 | this.handleKeyPress = this.handleKeyPress.bind(this); 34 | this.handlePaste = this.handlePaste.bind(this); 35 | } 36 | 37 | handleKeyDown(event) { 38 | const { onChange } = this.props; 39 | 40 | const { keyCode } = event.nativeEvent; 41 | 42 | if (ignore.indexOf(keyCode) > -1) { 43 | return; 44 | } 45 | 46 | if (keyCode < 32 || (keyCode > 127 && keyCode < 160)) { 47 | // TODO: pass the whole event? 48 | onChange(keyCode); 49 | } 50 | } 51 | 52 | handleKeyPress(event) { 53 | const { onChange } = this.props; 54 | 55 | const { keyCode } = event.nativeEvent; 56 | 57 | if ((keyCode >= 32 && keyCode <= 127) || 58 | (keyCode >= 160 && keyCode <= 255)) { 59 | // TODO: pass the whole event? 60 | onChange(keyCode); 61 | } 62 | } 63 | 64 | handlePaste(event) { 65 | const { onChange } = this.props; 66 | 67 | const { clipboardData } = event; 68 | const data = clipboardData.getData('text/plain'); 69 | 70 | onChange(data); 71 | } 72 | 73 | shouldComponentUpdate(nextProps){ 74 | const { connected, text } = this.props; 75 | return (connected !== nextProps.connected || text !== nextProps.text); 76 | } 77 | 78 | render() { 79 | const { connected, text } = this.props; 80 | return ( 81 |
    82 |