aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Finlay <dan@danfinlay.com>2017-07-25 08:04:13 +0800
committerDan Finlay <dan@danfinlay.com>2017-07-25 08:05:07 +0800
commita22adec66fd0c541eb350ea424a6b00d179eedaf (patch)
tree684b5ffca43944b0aaf33a99dbb6edcdc04e620e
parentfcde52f39070160623be5a03455d9d5c84a99f36 (diff)
downloadtangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar.gz
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar.bz2
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar.lz
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar.xz
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.tar.zst
tangerine-wallet-browser-a22adec66fd0c541eb350ea424a6b00d179eedaf.zip
Replace ui with responsive-ui
-rw-r--r--app/home.html11
-rw-r--r--app/scripts/responsive-core.js54
-rw-r--r--app/scripts/responsive.js30
-rw-r--r--responsive-ui/app/account-detail.js297
-rw-r--r--responsive-ui/app/accounts/import/index.js100
-rw-r--r--responsive-ui/app/accounts/import/json.js100
-rw-r--r--responsive-ui/app/accounts/import/private-key.js67
-rw-r--r--responsive-ui/app/accounts/import/seed.js30
-rw-r--r--responsive-ui/app/actions.js1031
-rw-r--r--responsive-ui/app/add-token.js219
-rw-r--r--responsive-ui/app/app.js591
-rw-r--r--responsive-ui/app/components/account-export.js122
-rw-r--r--responsive-ui/app/components/account-panel.js86
-rw-r--r--responsive-ui/app/components/balance.js89
-rw-r--r--responsive-ui/app/components/binary-renderer.js46
-rw-r--r--responsive-ui/app/components/bn-as-decimal-input.js174
-rw-r--r--responsive-ui/app/components/buy-button-subview.js197
-rw-r--r--responsive-ui/app/components/coinbase-form.js63
-rw-r--r--responsive-ui/app/components/copyButton.js59
-rw-r--r--responsive-ui/app/components/copyable.js46
-rw-r--r--responsive-ui/app/components/custom-radio-list.js60
-rw-r--r--responsive-ui/app/components/editable-label.js56
-rw-r--r--responsive-ui/app/components/ens-input.js170
-rw-r--r--responsive-ui/app/components/eth-balance.js89
-rw-r--r--responsive-ui/app/components/fiat-value.js63
-rw-r--r--responsive-ui/app/components/hex-as-decimal-input.js154
-rw-r--r--responsive-ui/app/components/identicon.js72
-rw-r--r--responsive-ui/app/components/loading.js53
-rw-r--r--responsive-ui/app/components/mascot.js59
-rw-r--r--responsive-ui/app/components/mini-account-panel.js74
-rw-r--r--responsive-ui/app/components/network.js124
-rw-r--r--responsive-ui/app/components/notice.js126
-rw-r--r--responsive-ui/app/components/pending-msg-details.js50
-rw-r--r--responsive-ui/app/components/pending-msg.js56
-rw-r--r--responsive-ui/app/components/pending-personal-msg-details.js60
-rw-r--r--responsive-ui/app/components/pending-personal-msg.js47
-rw-r--r--responsive-ui/app/components/pending-tx.js480
-rw-r--r--responsive-ui/app/components/qr-code.js79
-rw-r--r--responsive-ui/app/components/range-slider.js58
-rw-r--r--responsive-ui/app/components/shapeshift-form.js306
-rw-r--r--responsive-ui/app/components/shift-list-item.js204
-rw-r--r--responsive-ui/app/components/tab-bar.js36
-rw-r--r--responsive-ui/app/components/template.js18
-rw-r--r--responsive-ui/app/components/token-cell.js72
-rw-r--r--responsive-ui/app/components/token-list.js192
-rw-r--r--responsive-ui/app/components/tooltip.js22
-rw-r--r--responsive-ui/app/components/transaction-list-item-icon.js68
-rw-r--r--responsive-ui/app/components/transaction-list-item.js165
-rw-r--r--responsive-ui/app/components/transaction-list.js83
-rw-r--r--responsive-ui/app/conf-tx.js213
-rw-r--r--responsive-ui/app/config.js211
-rw-r--r--responsive-ui/app/conversion.json207
-rw-r--r--responsive-ui/app/css/debug.css21
-rw-r--r--responsive-ui/app/css/fonts.css36
-rw-r--r--responsive-ui/app/css/index.css676
-rw-r--r--responsive-ui/app/css/lib.css272
-rw-r--r--responsive-ui/app/css/reset.css48
-rw-r--r--responsive-ui/app/css/transitions.css42
-rw-r--r--responsive-ui/app/first-time/init-menu.js179
-rw-r--r--responsive-ui/app/img/identicon-tardigrade.pngbin141119 -> 0 bytes
-rw-r--r--responsive-ui/app/img/identicon-walrus.pngbin388973 -> 0 bytes
-rw-r--r--responsive-ui/app/info.js154
-rw-r--r--responsive-ui/app/keychains/hd/create-vault-complete.js76
-rw-r--r--responsive-ui/app/keychains/hd/recover-seed/confirmation.js118
-rw-r--r--responsive-ui/app/keychains/hd/restore-vault.js152
-rw-r--r--responsive-ui/app/new-keychain.js29
-rw-r--r--responsive-ui/app/reducers.js52
-rw-r--r--responsive-ui/app/reducers/app.js585
-rw-r--r--responsive-ui/app/reducers/identities.js15
-rw-r--r--responsive-ui/app/reducers/metamask.js137
-rw-r--r--responsive-ui/app/root.js22
-rw-r--r--responsive-ui/app/send.js288
-rw-r--r--responsive-ui/app/settings.js59
-rw-r--r--responsive-ui/app/store.js21
-rw-r--r--responsive-ui/app/template.js30
-rw-r--r--responsive-ui/app/unlock.js118
-rw-r--r--responsive-ui/app/util.js217
-rw-r--r--responsive-ui/css.js29
-rw-r--r--responsive-ui/design/00-metamask-SignIn.jpgbin57848 -> 0 bytes
-rw-r--r--responsive-ui/design/01-metamask-SelectAcc.jpgbin76063 -> 0 bytes
-rw-r--r--responsive-ui/design/02-metamask-AccDetails.jpgbin75780 -> 0 bytes
-rw-r--r--responsive-ui/design/02a-metamask-AccDetails-OverToken.jpgbin121847 -> 0 bytes
-rw-r--r--responsive-ui/design/02a-metamask-AccDetails-OverTransaction.jpgbin122075 -> 0 bytes
-rw-r--r--responsive-ui/design/02a-metamask-AccDetails.jpgbin117570 -> 0 bytes
-rw-r--r--responsive-ui/design/02b-metamask-AccDetails-Send.jpgbin110143 -> 0 bytes
-rw-r--r--responsive-ui/design/03-metamask-Qr.jpgbin66052 -> 0 bytes
-rw-r--r--responsive-ui/design/05-metamask-Menu.jpgbin130264 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/final_screen_dao_accounts.pngbin249708 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/final_screen_dao_locked.pngbin220295 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/final_screen_dao_notification.pngbin214405 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/final_screen_wei_account.pngbin253382 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/final_screen_wei_notification.pngbin193865 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/icon-128.pngbin5770 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/icon-64.pngbin3573 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/metamask_icon.ai2383
-rw-r--r--responsive-ui/design/chromeStorePics/promo1400560.pngbin261644 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/promo440280.pngbin57471 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/promo920680.pngbin206713 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/screen_dao_accounts.pngbin517598 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/screen_dao_locked.pngbin287108 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/screen_dao_notification.pngbin296498 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/screen_wei_account.pngbin653633 -> 0 bytes
-rw-r--r--responsive-ui/design/chromeStorePics/screen_wei_notification.pngbin402486 -> 0 bytes
-rw-r--r--responsive-ui/design/metamask-logo-eyes.pngbin146076 -> 0 bytes
-rw-r--r--responsive-ui/design/wireframes/1st_time_use.pngbin937556 -> 0 bytes
-rw-r--r--responsive-ui/design/wireframes/metamask_wfs_jan_13.pdfbin452413 -> 0 bytes
-rw-r--r--responsive-ui/design/wireframes/metamask_wfs_jan_13.pngbin419066 -> 0 bytes
-rw-r--r--responsive-ui/design/wireframes/metamask_wfs_jan_18.pdfbin612778 -> 0 bytes
-rw-r--r--responsive-ui/example.js123
-rw-r--r--responsive-ui/index.html20
-rw-r--r--responsive-ui/index.js58
-rw-r--r--responsive-ui/lib/account-link.js26
-rw-r--r--responsive-ui/lib/contract-namer.js33
-rw-r--r--responsive-ui/lib/etherscan-prefix-for-network.js21
-rw-r--r--responsive-ui/lib/explorer-link.js6
-rw-r--r--responsive-ui/lib/icon-factory.js65
-rw-r--r--responsive-ui/lib/lost-accounts-notice.js23
-rw-r--r--responsive-ui/lib/persistent-form.js61
-rw-r--r--responsive-ui/lib/tx-helper.js17
-rw-r--r--test/unit/responsive/components/dropdown-test.js4
-rw-r--r--ui/.gitignore (renamed from responsive-ui/.gitignore)0
-rw-r--r--ui/app/account-detail.js120
-rw-r--r--ui/app/accounts/account-list-item.js91
-rw-r--r--ui/app/accounts/index.js164
-rw-r--r--ui/app/add-token.js2
-rw-r--r--ui/app/app.js272
-rw-r--r--ui/app/components/account-dropdowns.js (renamed from responsive-ui/app/components/account-dropdowns.js)0
-rw-r--r--ui/app/components/account-info-link.js41
-rw-r--r--ui/app/components/drop-menu-item.js59
-rw-r--r--ui/app/components/dropdown.js (renamed from responsive-ui/app/components/dropdown.js)0
-rw-r--r--ui/app/components/editable-label.js7
-rw-r--r--ui/app/components/pending-tx.js2
-rw-r--r--ui/app/components/transaction-list.js8
-rw-r--r--ui/app/css/index.css15
-rw-r--r--ui/app/css/lib.css4
-rw-r--r--ui/app/info.js10
-rw-r--r--ui/app/keychains/hd/create-vault-complete.js2
-rw-r--r--ui/lib/tx-helper.js6
138 files changed, 224 insertions, 13934 deletions
diff --git a/app/home.html b/app/home.html
deleted file mode 100644
index b7b8adbeb..000000000
--- a/app/home.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>MetaMask Plugin</title>
- </head>
- <body>
- <div id="app-content"></div>
- <script src="./scripts/responsive.js" type="text/javascript" charset="utf-8"></script>
- </body>
-</html>
diff --git a/app/scripts/responsive-core.js b/app/scripts/responsive-core.js
deleted file mode 100644
index c3fa6700d..000000000
--- a/app/scripts/responsive-core.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const EventEmitter = require('events').EventEmitter
-const async = require('async')
-const Dnode = require('dnode')
-const EthQuery = require('eth-query')
-const launchMetamaskUi = require('../../responsive-ui')
-const StreamProvider = require('web3-stream-provider')
-const setupMultiplex = require('./lib/stream-utils.js').setupMultiplex
-
-
-module.exports = initializePopup
-
-
-function initializePopup ({ container, connectionStream }, cb) {
- // setup app
- async.waterfall([
- (cb) => connectToAccountManager(connectionStream, cb),
- (accountManager, cb) => launchMetamaskUi({ container, accountManager }, cb),
- ], cb)
-}
-
-function connectToAccountManager (connectionStream, cb) {
- // setup communication with background
- // setup multiplexing
- var mx = setupMultiplex(connectionStream)
- // connect features
- setupControllerConnection(mx.createStream('controller'), cb)
- setupWeb3Connection(mx.createStream('provider'))
-}
-
-function setupWeb3Connection (connectionStream) {
- var providerStream = new StreamProvider()
- providerStream.pipe(connectionStream).pipe(providerStream)
- connectionStream.on('error', console.error.bind(console))
- providerStream.on('error', console.error.bind(console))
- global.ethereumProvider = providerStream
- global.ethQuery = new EthQuery(providerStream)
-}
-
-function setupControllerConnection (connectionStream, cb) {
- // this is a really sneaky way of adding EventEmitter api
- // to a bi-directional dnode instance
- var eventEmitter = new EventEmitter()
- var accountManagerDnode = Dnode({
- sendUpdate: function (state) {
- eventEmitter.emit('update', state)
- },
- })
- connectionStream.pipe(accountManagerDnode).pipe(connectionStream)
- accountManagerDnode.once('remote', function (accountManager) {
- // setup push events
- accountManager.on = eventEmitter.on.bind(eventEmitter)
- cb(null, accountManager)
- })
-}
diff --git a/app/scripts/responsive.js b/app/scripts/responsive.js
deleted file mode 100644
index 6525b833b..000000000
--- a/app/scripts/responsive.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const injectCss = require('inject-css')
-const startPopup = require('./responsive-core')
-const MetaMaskUiCss = require('../../responsive-ui/css')
-const PortStream = require('./lib/port-stream.js')
-const ExtensionPlatform = require('./platforms/extension')
-const extension = require('extensionizer')
-
-// create platform global
-global.platform = new ExtensionPlatform()
-
-// inject css
-const css = MetaMaskUiCss()
-injectCss(css)
-
-// setup stream to background
-const extensionPort = extension.runtime.connect({ name: 'ui' })
-const connectionStream = new PortStream(extensionPort)
-
-// start ui
-const container = document.getElementById('app-content')
-startPopup({ container, connectionStream }, (err, store) => {
- if (err) return displayCriticalError(err)
-})
-
-function displayCriticalError (err) {
- container.innerHTML = '<div class="critical-error">The MetaMask app failed to load: please open and close MetaMask again to restart.</div>'
- container.style.height = '80px'
- log.error(err.stack)
- throw err
-}
diff --git a/responsive-ui/app/account-detail.js b/responsive-ui/app/account-detail.js
deleted file mode 100644
index 18c867153..000000000
--- a/responsive-ui/app/account-detail.js
+++ /dev/null
@@ -1,297 +0,0 @@
-const inherits = require('util').inherits
-const extend = require('xtend')
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
-const valuesFor = require('./util').valuesFor
-const Identicon = require('./components/identicon')
-const EthBalance = require('./components/eth-balance')
-const TransactionList = require('./components/transaction-list')
-const ExportAccountView = require('./components/account-export')
-const ethUtil = require('ethereumjs-util')
-const EditableLabel = require('./components/editable-label')
-const TabBar = require('./components/tab-bar')
-const TokenList = require('./components/token-list')
-const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
-
-module.exports = connect(mapStateToProps)(AccountDetailScreen)
-
-function mapStateToProps (state) {
- return {
- metamask: state.metamask,
- identities: state.metamask.identities,
- accounts: state.metamask.accounts,
- address: state.metamask.selectedAddress,
- accountDetail: state.appState.accountDetail,
- network: state.metamask.network,
- unapprovedMsgs: valuesFor(state.metamask.unapprovedMsgs),
- shapeShiftTxList: state.metamask.shapeShiftTxList,
- transactions: state.metamask.selectedAddressTxList || [],
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- currentAccountTab: state.metamask.currentAccountTab,
- tokens: state.metamask.tokens,
- }
-}
-
-inherits(AccountDetailScreen, Component)
-function AccountDetailScreen () {
- Component.call(this)
-}
-
-AccountDetailScreen.prototype.render = function () {
- var props = this.props
- var selected = props.address || Object.keys(props.accounts)[0]
- var checksumAddress = selected && ethUtil.toChecksumAddress(selected)
- var identity = props.identities[selected]
- var account = props.accounts[selected]
- const { network, conversionRate, currentCurrency } = props
-
- return (
-
- h('.account-detail-section', {
- style: {
- height: '100%',
- maxWidth: '850px',
- },
- }, [
-
- // identicon, label, balance, etc
- h('.account-data-subsection', {
- style: {
- margin: '0 20px',
- flex: '1 0 auto',
- },
- }, [
-
- // header - identicon + nav
- h('div', {
- style: {
- paddingTop: '20px',
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'flex-start',
- },
- }, [
-
- // large identicon and addresses
- h('.identicon-wrapper.select-none', [
- h(Identicon, {
- diameter: 62,
- address: selected,
- }),
- ]),
- h('flex-column', {
- style: {
- lineHeight: '10px',
- marginLeft: '15px',
- width: '100%',
- },
- }, [
- h(EditableLabel, {
- textValue: identity ? identity.name : '',
- state: {
- isEditingLabel: false,
- },
- saveText: (text) => {
- props.dispatch(actions.saveAccountLabel(selected, text))
- },
- }, [
-
- // What is shown when not editing + edit text:
- h('label.editing-label', [h('.edit-text', 'edit')]),
- h(
- 'div',
- {
- style: {
- display: 'flex',
- justifyContent: 'flex-start',
- alignItems: 'center',
- },
- },
- [
- h(
- 'h2.font-medium.color-forest',
- {
- name: 'edit',
- style: {
- },
- },
- [
- identity && identity.name,
- ]
- ),
- h(
- AccountDropdowns,
- {
- style: {
- marginRight: '8px',
- marginLeft: 'auto',
- cursor: 'pointer',
- },
- selected,
- network,
- identities: props.identities,
- },
- ),
- ]
- ),
- ]),
- h('.flex-row', {
- style: {
- width: '15em',
- justifyContent: 'space-between',
- alignItems: 'baseline',
- },
- }, [
-
- // address
-
- h('div', {
- style: {
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- paddingTop: '3px',
- width: '5em',
- fontSize: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- marginTop: '10px',
- marginBottom: '15px',
- color: '#AEAEAE',
- },
- }, checksumAddress),
- ]),
-
- // account ballence
-
- ]),
- ]),
- h('.flex-row', {
- style: {
- justifyContent: 'space-between',
- alignItems: 'flex-start',
- },
- }, [
-
- h(EthBalance, {
- value: account && account.balance,
- conversionRate,
- currentCurrency,
- style: {
- lineHeight: '7px',
- marginTop: '10px',
- },
- }),
-
- h('.flex-grow'),
-
- h('button', {
- onClick: () => props.dispatch(actions.buyEthView(selected)),
- style: { marginRight: '10px' },
- }, 'BUY'),
-
- h('button', {
- onClick: () => props.dispatch(actions.showSendPage()),
- style: {
- marginBottom: '20px',
- marginRight: '8px',
- },
- }, 'SEND'),
-
- ]),
- ]),
-
- // subview (tx history, pk export confirm, buy eth warning)
- h(ReactCSSTransitionGroup, {
- className: 'css-transition-group',
- transitionName: 'main',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 300,
- }, [
- this.subview(),
- ]),
-
- ])
- )
-}
-
-AccountDetailScreen.prototype.subview = function () {
- var subview
- try {
- subview = this.props.accountDetail.subview
- } catch (e) {
- subview = null
- }
-
- switch (subview) {
- case 'transactions':
- return this.tabSections()
- case 'export':
- var state = extend({key: 'export'}, this.props)
- return h(ExportAccountView, state)
- default:
- return this.tabSections()
- }
-}
-
-AccountDetailScreen.prototype.tabSections = function () {
- const { currentAccountTab } = this.props
-
- return h('section.tabSection', {
- style: {
- height: '100%',
- },
- }, [
-
- h(TabBar, {
- tabs: [
- { content: 'Sent', key: 'history' },
- { content: 'Tokens', key: 'tokens' },
- ],
- defaultTab: currentAccountTab || 'history',
- tabSelected: (key) => {
- this.props.dispatch(actions.setCurrentAccountTab(key))
- },
- }),
-
- this.tabSwitchView(),
- ])
-}
-
-AccountDetailScreen.prototype.tabSwitchView = function () {
- const props = this.props
- const { address, network } = props
- const { currentAccountTab, tokens } = this.props
-
- switch (currentAccountTab) {
- case 'tokens':
- return h(TokenList, {
- userAddress: address,
- network,
- tokens,
- addToken: () => this.props.dispatch(actions.showAddTokenPage()),
- })
- default:
- return this.transactionList()
- }
-}
-
-AccountDetailScreen.prototype.transactionList = function () {
- const {transactions, unapprovedMsgs, address,
- network, shapeShiftTxList, conversionRate } = this.props
-
- return h(TransactionList, {
- transactions: transactions.sort((a, b) => b.time - a.time),
- network,
- unapprovedMsgs,
- conversionRate,
- address,
- shapeShiftTxList,
- viewPendingTx: (txId) => {
- this.props.dispatch(actions.viewPendingTx(txId))
- },
- })
-}
diff --git a/responsive-ui/app/accounts/import/index.js b/responsive-ui/app/accounts/import/index.js
deleted file mode 100644
index 97b387229..000000000
--- a/responsive-ui/app/accounts/import/index.js
+++ /dev/null
@@ -1,100 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../../actions')
-import Select from 'react-select'
-
-// Subviews
-const JsonImportView = require('./json.js')
-const PrivateKeyImportView = require('./private-key.js')
-
-const menuItems = [
- 'Private Key',
- 'JSON File',
-]
-
-module.exports = connect(mapStateToProps)(AccountImportSubview)
-
-function mapStateToProps (state) {
- return {
- menuItems,
- }
-}
-
-inherits(AccountImportSubview, Component)
-function AccountImportSubview () {
- Component.call(this)
-}
-
-AccountImportSubview.prototype.render = function () {
- const props = this.props
- const state = this.state || {}
- const { menuItems } = props
- const { type } = state
-
- return (
- h('div', {
- style: {
- },
- }, [
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- props.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Import Accounts'),
- ]),
- h('div', {
- style: {
- padding: '10px',
- color: 'rgb(174, 174, 174)',
- },
- }, [
-
- h('h3', { style: { padding: '3px' } }, 'SELECT TYPE'),
-
- h('style', `
- .has-value.Select--single > .Select-control .Select-value .Select-value-label, .Select-value-label {
- color: rgb(174,174,174);
- }
- `),
-
- h(Select, {
- name: 'import-type-select',
- clearable: false,
- value: type || menuItems[0],
- options: menuItems.map((type) => {
- return {
- value: type,
- label: type,
- }
- }),
- onChange: (opt) => {
- this.setState({ type: opt.value })
- },
- }),
- ]),
-
- this.renderImportView(),
- ])
- )
-}
-
-AccountImportSubview.prototype.renderImportView = function () {
- const props = this.props
- const state = this.state || {}
- const { type } = state
- const { menuItems } = props
- const current = type || menuItems[0]
-
- switch (current) {
- case 'Private Key':
- return h(PrivateKeyImportView)
- case 'JSON File':
- return h(JsonImportView)
- default:
- return h(JsonImportView)
- }
-}
diff --git a/responsive-ui/app/accounts/import/json.js b/responsive-ui/app/accounts/import/json.js
deleted file mode 100644
index 158a3c923..000000000
--- a/responsive-ui/app/accounts/import/json.js
+++ /dev/null
@@ -1,100 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../../actions')
-const FileInput = require('react-simple-file-input').default
-
-const HELP_LINK = 'https://github.com/MetaMask/faq/blob/master/README.md#q-i-cant-use-the-import-feature-for-uploading-a-json-file-the-window-keeps-closing-when-i-try-to-select-a-file'
-
-module.exports = connect(mapStateToProps)(JsonImportSubview)
-
-function mapStateToProps (state) {
- return {
- error: state.appState.warning,
- }
-}
-
-inherits(JsonImportSubview, Component)
-function JsonImportSubview () {
- Component.call(this)
-}
-
-JsonImportSubview.prototype.render = function () {
- const { error } = this.props
-
- return (
- h('div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- padding: '5px 15px 0px 15px',
- },
- }, [
-
- h('p', 'Used by a variety of different clients'),
- h('a.warning', { href: HELP_LINK, target: '_blank' }, 'File import not working? Click here!'),
-
- h(FileInput, {
- readAs: 'text',
- onLoad: this.onLoad.bind(this),
- style: {
- margin: '20px 0px 12px 20px',
- fontSize: '15px',
- },
- }),
-
- h('input.large-input.letter-spacey', {
- type: 'password',
- placeholder: 'Enter password',
- id: 'json-password-box',
- onKeyPress: this.createKeyringOnEnter.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- h('button.primary', {
- onClick: this.createNewKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Import'),
-
- error ? h('span.error', error) : null,
- ])
- )
-}
-
-JsonImportSubview.prototype.onLoad = function (event, file) {
- this.setState({file: file, fileContents: event.target.result})
-}
-
-JsonImportSubview.prototype.createKeyringOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewKeychain()
- }
-}
-
-JsonImportSubview.prototype.createNewKeychain = function () {
- const state = this.state
- const { fileContents } = state
-
- if (!fileContents) {
- const message = 'You must select a file to import.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- const passwordInput = document.getElementById('json-password-box')
- const password = passwordInput.value
-
- if (!password) {
- const message = 'You must enter a password for the selected file.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- this.props.dispatch(actions.importNewAccount('JSON File', [ fileContents, password ]))
-}
diff --git a/responsive-ui/app/accounts/import/private-key.js b/responsive-ui/app/accounts/import/private-key.js
deleted file mode 100644
index 68ccee58e..000000000
--- a/responsive-ui/app/accounts/import/private-key.js
+++ /dev/null
@@ -1,67 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../../actions')
-
-module.exports = connect(mapStateToProps)(PrivateKeyImportView)
-
-function mapStateToProps (state) {
- return {
- error: state.appState.warning,
- }
-}
-
-inherits(PrivateKeyImportView, Component)
-function PrivateKeyImportView () {
- Component.call(this)
-}
-
-PrivateKeyImportView.prototype.render = function () {
- const { error } = this.props
-
- return (
- h('div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- padding: '5px 15px 0px 15px',
- },
- }, [
- h('span', 'Paste your private key string here'),
-
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'private-key-box',
- onKeyPress: this.createKeyringOnEnter.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- h('button.primary', {
- onClick: this.createNewKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Import'),
-
- error ? h('span.error', error) : null,
- ])
- )
-}
-
-PrivateKeyImportView.prototype.createKeyringOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewKeychain()
- }
-}
-
-PrivateKeyImportView.prototype.createNewKeychain = function () {
- const input = document.getElementById('private-key-box')
- const privateKey = input.value
- this.props.dispatch(actions.importNewAccount('Private Key', [ privateKey ]))
-}
diff --git a/responsive-ui/app/accounts/import/seed.js b/responsive-ui/app/accounts/import/seed.js
deleted file mode 100644
index b4a7c0afa..000000000
--- a/responsive-ui/app/accounts/import/seed.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-
-module.exports = connect(mapStateToProps)(SeedImportSubview)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(SeedImportSubview, Component)
-function SeedImportSubview () {
- Component.call(this)
-}
-
-SeedImportSubview.prototype.render = function () {
- return (
- h('div', {
- style: {
- },
- }, [
- `Paste your seed phrase here!`,
- h('textarea'),
- h('br'),
- h('button', 'Submit'),
- ])
- )
-}
-
diff --git a/responsive-ui/app/actions.js b/responsive-ui/app/actions.js
deleted file mode 100644
index d99291e46..000000000
--- a/responsive-ui/app/actions.js
+++ /dev/null
@@ -1,1031 +0,0 @@
-const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url')
-
-var actions = {
- _setBackgroundConnection: _setBackgroundConnection,
-
- GO_HOME: 'GO_HOME',
- goHome: goHome,
- // menu state
- getNetworkStatus: 'getNetworkStatus',
- // transition state
- TRANSITION_FORWARD: 'TRANSITION_FORWARD',
- TRANSITION_BACKWARD: 'TRANSITION_BACKWARD',
- transitionForward,
- transitionBackward,
- // remote state
- UPDATE_METAMASK_STATE: 'UPDATE_METAMASK_STATE',
- updateMetamaskState: updateMetamaskState,
- // notices
- MARK_NOTICE_READ: 'MARK_NOTICE_READ',
- markNoticeRead: markNoticeRead,
- SHOW_NOTICE: 'SHOW_NOTICE',
- showNotice: showNotice,
- CLEAR_NOTICES: 'CLEAR_NOTICES',
- clearNotices: clearNotices,
- markAccountsFound,
- // intialize screen
- CREATE_NEW_VAULT_IN_PROGRESS: 'CREATE_NEW_VAULT_IN_PROGRESS',
- SHOW_CREATE_VAULT: 'SHOW_CREATE_VAULT',
- SHOW_RESTORE_VAULT: 'SHOW_RESTORE_VAULT',
- FORGOT_PASSWORD: 'FORGOT_PASSWORD',
- forgotPassword: forgotPassword,
- SHOW_INIT_MENU: 'SHOW_INIT_MENU',
- SHOW_NEW_VAULT_SEED: 'SHOW_NEW_VAULT_SEED',
- SHOW_INFO_PAGE: 'SHOW_INFO_PAGE',
- SHOW_IMPORT_PAGE: 'SHOW_IMPORT_PAGE',
- unlockMetamask: unlockMetamask,
- unlockFailed: unlockFailed,
- showCreateVault: showCreateVault,
- showRestoreVault: showRestoreVault,
- showInitializeMenu: showInitializeMenu,
- showImportPage,
- createNewVaultAndKeychain: createNewVaultAndKeychain,
- createNewVaultAndRestore: createNewVaultAndRestore,
- createNewVaultInProgress: createNewVaultInProgress,
- addNewKeyring,
- importNewAccount,
- addNewAccount,
- NEW_ACCOUNT_SCREEN: 'NEW_ACCOUNT_SCREEN',
- navigateToNewAccountScreen,
- showNewVaultSeed: showNewVaultSeed,
- showInfoPage: showInfoPage,
- // seed recovery actions
- REVEAL_SEED_CONFIRMATION: 'REVEAL_SEED_CONFIRMATION',
- revealSeedConfirmation: revealSeedConfirmation,
- requestRevealSeed: requestRevealSeed,
- // unlock screen
- UNLOCK_IN_PROGRESS: 'UNLOCK_IN_PROGRESS',
- UNLOCK_FAILED: 'UNLOCK_FAILED',
- UNLOCK_METAMASK: 'UNLOCK_METAMASK',
- LOCK_METAMASK: 'LOCK_METAMASK',
- tryUnlockMetamask: tryUnlockMetamask,
- lockMetamask: lockMetamask,
- unlockInProgress: unlockInProgress,
- // error handling
- displayWarning: displayWarning,
- DISPLAY_WARNING: 'DISPLAY_WARNING',
- HIDE_WARNING: 'HIDE_WARNING',
- hideWarning: hideWarning,
- // accounts screen
- SET_SELECTED_ACCOUNT: 'SET_SELECTED_ACCOUNT',
- SHOW_ACCOUNT_DETAIL: 'SHOW_ACCOUNT_DETAIL',
- SHOW_ACCOUNTS_PAGE: 'SHOW_ACCOUNTS_PAGE',
- SHOW_CONF_TX_PAGE: 'SHOW_CONF_TX_PAGE',
- SHOW_CONF_MSG_PAGE: 'SHOW_CONF_MSG_PAGE',
- SET_CURRENT_FIAT: 'SET_CURRENT_FIAT',
- setCurrentCurrency: setCurrentCurrency,
- setCurrentAccountTab,
- // account detail screen
- SHOW_SEND_PAGE: 'SHOW_SEND_PAGE',
- showSendPage: showSendPage,
- ADD_TO_ADDRESS_BOOK: 'ADD_TO_ADDRESS_BOOK',
- addToAddressBook: addToAddressBook,
- REQUEST_ACCOUNT_EXPORT: 'REQUEST_ACCOUNT_EXPORT',
- requestExportAccount: requestExportAccount,
- EXPORT_ACCOUNT: 'EXPORT_ACCOUNT',
- exportAccount: exportAccount,
- SHOW_PRIVATE_KEY: 'SHOW_PRIVATE_KEY',
- showPrivateKey: showPrivateKey,
- SAVE_ACCOUNT_LABEL: 'SAVE_ACCOUNT_LABEL',
- saveAccountLabel: saveAccountLabel,
- // tx conf screen
- COMPLETED_TX: 'COMPLETED_TX',
- TRANSACTION_ERROR: 'TRANSACTION_ERROR',
- NEXT_TX: 'NEXT_TX',
- PREVIOUS_TX: 'PREV_TX',
- signMsg: signMsg,
- cancelMsg: cancelMsg,
- signPersonalMsg,
- cancelPersonalMsg,
- sendTx: sendTx,
- signTx: signTx,
- updateAndApproveTx,
- cancelTx: cancelTx,
- completedTx: completedTx,
- txError: txError,
- nextTx: nextTx,
- previousTx: previousTx,
- viewPendingTx: viewPendingTx,
- VIEW_PENDING_TX: 'VIEW_PENDING_TX',
- // app messages
- confirmSeedWords: confirmSeedWords,
- showAccountDetail: showAccountDetail,
- BACK_TO_ACCOUNT_DETAIL: 'BACK_TO_ACCOUNT_DETAIL',
- backToAccountDetail: backToAccountDetail,
- showAccountsPage: showAccountsPage,
- showConfTxPage: showConfTxPage,
- // config screen
- SHOW_CONFIG_PAGE: 'SHOW_CONFIG_PAGE',
- SET_RPC_TARGET: 'SET_RPC_TARGET',
- SET_DEFAULT_RPC_TARGET: 'SET_DEFAULT_RPC_TARGET',
- SET_PROVIDER_TYPE: 'SET_PROVIDER_TYPE',
- USE_ETHERSCAN_PROVIDER: 'USE_ETHERSCAN_PROVIDER',
- useEtherscanProvider: useEtherscanProvider,
- showConfigPage,
- SHOW_ADD_TOKEN_PAGE: 'SHOW_ADD_TOKEN_PAGE',
- showAddTokenPage,
- addToken,
- setRpcTarget: setRpcTarget,
- setDefaultRpcTarget: setDefaultRpcTarget,
- setProviderType: setProviderType,
- // loading overlay
- SHOW_LOADING: 'SHOW_LOADING_INDICATION',
- HIDE_LOADING: 'HIDE_LOADING_INDICATION',
- showLoadingIndication: showLoadingIndication,
- hideLoadingIndication: hideLoadingIndication,
- // buy Eth with coinbase
- BUY_ETH: 'BUY_ETH',
- buyEth: buyEth,
- buyEthView: buyEthView,
- BUY_ETH_VIEW: 'BUY_ETH_VIEW',
- COINBASE_SUBVIEW: 'COINBASE_SUBVIEW',
- coinBaseSubview: coinBaseSubview,
- SHAPESHIFT_SUBVIEW: 'SHAPESHIFT_SUBVIEW',
- shapeShiftSubview: shapeShiftSubview,
- PAIR_UPDATE: 'PAIR_UPDATE',
- pairUpdate: pairUpdate,
- coinShiftRquest: coinShiftRquest,
- SHOW_SUB_LOADING_INDICATION: 'SHOW_SUB_LOADING_INDICATION',
- showSubLoadingIndication: showSubLoadingIndication,
- HIDE_SUB_LOADING_INDICATION: 'HIDE_SUB_LOADING_INDICATION',
- hideSubLoadingIndication: hideSubLoadingIndication,
-// QR STUFF:
- SHOW_QR: 'SHOW_QR',
- showQrView: showQrView,
- reshowQrCode: reshowQrCode,
- SHOW_QR_VIEW: 'SHOW_QR_VIEW',
-// FORGOT PASSWORD:
- BACK_TO_INIT_MENU: 'BACK_TO_INIT_MENU',
- goBackToInitView: goBackToInitView,
- RECOVERY_IN_PROGRESS: 'RECOVERY_IN_PROGRESS',
- BACK_TO_UNLOCK_VIEW: 'BACK_TO_UNLOCK_VIEW',
- backToUnlockView: backToUnlockView,
- // SHOWING KEYCHAIN
- SHOW_NEW_KEYCHAIN: 'SHOW_NEW_KEYCHAIN',
- showNewKeychain: showNewKeychain,
-
- callBackgroundThenUpdate,
- forceUpdateMetamaskState,
-}
-
-module.exports = actions
-
-var background = null
-function _setBackgroundConnection (backgroundConnection) {
- background = backgroundConnection
-}
-
-function goHome () {
- return {
- type: actions.GO_HOME,
- }
-}
-
-// async actions
-
-function tryUnlockMetamask (password) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- dispatch(actions.unlockInProgress())
- log.debug(`background.submitPassword`)
- background.submitPassword(password, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.unlockFailed(err.message))
- } else {
- dispatch(actions.transitionForward())
- forceUpdateMetamaskState(dispatch)
- }
- })
- }
-}
-
-function transitionForward () {
- return {
- type: this.TRANSITION_FORWARD,
- }
-}
-
-function transitionBackward () {
- return {
- type: this.TRANSITION_BACKWARD,
- }
-}
-
-function confirmSeedWords () {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.clearSeedWordCache`)
- background.clearSeedWordCache((err, account) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
-
- log.info('Seed word cache cleared. ' + account)
- dispatch(actions.showAccountDetail(account))
- })
- }
-}
-
-function createNewVaultAndRestore (password, seed) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.createNewVaultAndRestore`)
- background.createNewVaultAndRestore(password, seed, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.showAccountsPage())
- })
- }
-}
-
-function createNewVaultAndKeychain (password) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.createNewVaultAndKeychain`)
- background.createNewVaultAndKeychain(password, (err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- log.debug(`background.placeSeedWords`)
- background.placeSeedWords((err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch(actions.hideLoadingIndication())
- forceUpdateMetamaskState(dispatch)
- })
- })
- }
-}
-
-function revealSeedConfirmation () {
- return {
- type: this.REVEAL_SEED_CONFIRMATION,
- }
-}
-
-function requestRevealSeed (password) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.submitPassword`)
- background.submitPassword(password, (err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- log.debug(`background.placeSeedWords`)
- background.placeSeedWords((err, result) => {
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.hideLoadingIndication())
- dispatch(actions.showNewVaultSeed(result))
- })
- })
- }
-}
-
-function addNewKeyring (type, opts) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.addNewKeyring`)
- background.addNewKeyring(type, opts, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.showAccountsPage())
- })
- }
-}
-
-function importNewAccount (strategy, args) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication('This may take a while, be patient.'))
- log.debug(`background.importAccountWithStrategy`)
- background.importAccountWithStrategy(strategy, args, (err) => {
- if (err) return dispatch(actions.displayWarning(err.message))
- log.debug(`background.getState`)
- background.getState((err, newState) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch(actions.updateMetamaskState(newState))
- dispatch({
- type: actions.SHOW_ACCOUNT_DETAIL,
- value: newState.selectedAddress,
- })
- })
- })
- }
-}
-
-function navigateToNewAccountScreen () {
- return {
- type: this.NEW_ACCOUNT_SCREEN,
- }
-}
-
-function addNewAccount () {
- log.debug(`background.addNewAccount`)
- return callBackgroundThenUpdate(background.addNewAccount)
-}
-
-function showInfoPage () {
- return {
- type: actions.SHOW_INFO_PAGE,
- }
-}
-
-function setCurrentCurrency (currencyCode) {
- return (dispatch) => {
- dispatch(this.showLoadingIndication())
- log.debug(`background.setCurrentCurrency`)
- background.setCurrentCurrency(currencyCode, (err, data) => {
- dispatch(this.hideLoadingIndication())
- if (err) {
- log.error(err.stack)
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch({
- type: this.SET_CURRENT_FIAT,
- value: {
- currentCurrency: data.currentCurrency,
- conversionRate: data.conversionRate,
- conversionDate: data.conversionDate,
- },
- })
- })
- }
-}
-
-function signMsg (msgData) {
- log.debug('action - signMsg')
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
-
- log.debug(`actions calling background.signMessage`)
- background.signMessage(msgData, (err, newState) => {
- log.debug('signMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
-
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
-
- dispatch(actions.completedTx(msgData.metamaskId))
- })
- }
-}
-
-function signPersonalMsg (msgData) {
- log.debug('action - signPersonalMsg')
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
-
- log.debug(`actions calling background.signPersonalMessage`)
- background.signPersonalMessage(msgData, (err, newState) => {
- log.debug('signPersonalMessage called back')
- dispatch(actions.updateMetamaskState(newState))
- dispatch(actions.hideLoadingIndication())
-
- if (err) log.error(err)
- if (err) return dispatch(actions.displayWarning(err.message))
-
- dispatch(actions.completedTx(msgData.metamaskId))
- })
- }
-}
-
-function signTx (txData) {
- return (dispatch) => {
- global.ethQuery.sendTransaction(txData, (err, data) => {
- dispatch(actions.hideLoadingIndication())
- if (err) return dispatch(actions.displayWarning(err.message))
- dispatch(actions.hideWarning())
- })
- dispatch(this.showConfTxPage())
- }
-}
-
-function sendTx (txData) {
- log.info(`actions - sendTx: ${JSON.stringify(txData.txParams)}`)
- return (dispatch) => {
- log.debug(`actions calling background.approveTransaction`)
- background.approveTransaction(txData.id, (err) => {
- if (err) {
- dispatch(actions.txError(err))
- return log.error(err.message)
- }
- dispatch(actions.completedTx(txData.id))
- })
- }
-}
-
-function updateAndApproveTx (txData) {
- log.info('actions: updateAndApproveTx: ' + JSON.stringify(txData))
- return (dispatch) => {
- log.debug(`actions calling background.updateAndApproveTx`)
- background.updateAndApproveTransaction(txData, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- dispatch(actions.txError(err))
- return log.error(err.message)
- }
- dispatch(actions.completedTx(txData.id))
- })
- }
-}
-
-function completedTx (id) {
- return {
- type: actions.COMPLETED_TX,
- value: id,
- }
-}
-
-function txError (err) {
- return {
- type: actions.TRANSACTION_ERROR,
- message: err.message,
- }
-}
-
-function cancelMsg (msgData) {
- log.debug(`background.cancelMessage`)
- background.cancelMessage(msgData.id)
- return actions.completedTx(msgData.id)
-}
-
-function cancelPersonalMsg (msgData) {
- const id = msgData.id
- background.cancelPersonalMessage(id)
- return actions.completedTx(id)
-}
-
-function cancelTx (txData) {
- log.debug(`background.cancelTransaction`)
- background.cancelTransaction(txData.id)
- return actions.completedTx(txData.id)
-}
-
-//
-// initialize screen
-//
-
-function showCreateVault () {
- return {
- type: actions.SHOW_CREATE_VAULT,
- }
-}
-
-function showRestoreVault () {
- return {
- type: actions.SHOW_RESTORE_VAULT,
- }
-}
-
-function forgotPassword () {
- return {
- type: actions.FORGOT_PASSWORD,
- }
-}
-
-function showInitializeMenu () {
- return {
- type: actions.SHOW_INIT_MENU,
- }
-}
-
-function showImportPage () {
- return {
- type: actions.SHOW_IMPORT_PAGE,
- }
-}
-
-function createNewVaultInProgress () {
- return {
- type: actions.CREATE_NEW_VAULT_IN_PROGRESS,
- }
-}
-
-function showNewVaultSeed (seed) {
- return {
- type: actions.SHOW_NEW_VAULT_SEED,
- value: seed,
- }
-}
-
-function backToUnlockView () {
- return {
- type: actions.BACK_TO_UNLOCK_VIEW,
- }
-}
-
-function showNewKeychain () {
- return {
- type: actions.SHOW_NEW_KEYCHAIN,
- }
-}
-
-//
-// unlock screen
-//
-
-function unlockInProgress () {
- return {
- type: actions.UNLOCK_IN_PROGRESS,
- }
-}
-
-function unlockFailed (message) {
- return {
- type: actions.UNLOCK_FAILED,
- value: message,
- }
-}
-
-function unlockMetamask (account) {
- return {
- type: actions.UNLOCK_METAMASK,
- value: account,
- }
-}
-
-function updateMetamaskState (newState) {
- return {
- type: actions.UPDATE_METAMASK_STATE,
- value: newState,
- }
-}
-
-function lockMetamask () {
- log.debug(`background.setLocked`)
- return callBackgroundThenUpdate(background.setLocked)
-}
-
-function setCurrentAccountTab (newTabName) {
- log.debug(`background.setCurrentAccountTab: ${newTabName}`)
- return callBackgroundThenUpdateNoSpinner(background.setCurrentAccountTab, newTabName)
-}
-
-function showAccountDetail (address) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.setSelectedAddress`)
- background.setSelectedAddress(address, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch({
- type: actions.SHOW_ACCOUNT_DETAIL,
- value: address,
- })
- })
- }
-}
-
-function backToAccountDetail (address) {
- return {
- type: actions.BACK_TO_ACCOUNT_DETAIL,
- value: address,
- }
-}
-
-function showAccountsPage () {
- return {
- type: actions.SHOW_ACCOUNTS_PAGE,
- }
-}
-
-function showConfTxPage (transForward = true) {
- return {
- type: actions.SHOW_CONF_TX_PAGE,
- transForward: transForward,
- }
-}
-
-function nextTx () {
- return {
- type: actions.NEXT_TX,
- }
-}
-
-function viewPendingTx (txId) {
- return {
- type: actions.VIEW_PENDING_TX,
- value: txId,
- }
-}
-
-function previousTx () {
- return {
- type: actions.PREVIOUS_TX,
- }
-}
-
-function showConfigPage (transitionForward = true) {
- return {
- type: actions.SHOW_CONFIG_PAGE,
- value: transitionForward,
- }
-}
-
-function showAddTokenPage (transitionForward = true) {
- return {
- type: actions.SHOW_ADD_TOKEN_PAGE,
- value: transitionForward,
- }
-}
-
-function addToken (address, symbol, decimals) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- background.addToken(address, symbol, decimals, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- setTimeout(() => {
- dispatch(actions.goHome())
- }, 250)
- })
- }
-}
-
-function goBackToInitView () {
- return {
- type: actions.BACK_TO_INIT_MENU,
- }
-}
-
-//
-// notice
-//
-
-function markNoticeRead (notice) {
- return (dispatch) => {
- dispatch(this.showLoadingIndication())
- log.debug(`background.markNoticeRead`)
- background.markNoticeRead(notice, (err, notice) => {
- dispatch(this.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err))
- }
- if (notice) {
- return dispatch(actions.showNotice(notice))
- } else {
- dispatch(this.clearNotices())
- return {
- type: actions.SHOW_ACCOUNTS_PAGE,
- }
- }
- })
- }
-}
-
-function showNotice (notice) {
- return {
- type: actions.SHOW_NOTICE,
- value: notice,
- }
-}
-
-function clearNotices () {
- return {
- type: actions.CLEAR_NOTICES,
- }
-}
-
-function markAccountsFound () {
- log.debug(`background.markAccountsFound`)
- return callBackgroundThenUpdate(background.markAccountsFound)
-}
-
-//
-// config
-//
-
-// default rpc target refers to localhost:8545 in this instance.
-function setDefaultRpcTarget (rpcList) {
- log.debug(`background.setDefaultRpcTarget`)
- return (dispatch) => {
- background.setDefaultRpc((err, result) => {
- if (err) {
- log.error(err)
- return dispatch(self.displayWarning('Had a problem changing networks.'))
- }
- })
- }
-}
-
-function setRpcTarget (newRpc) {
- log.debug(`background.setRpcTarget`)
- return (dispatch) => {
- background.setCustomRpc(newRpc, (err, result) => {
- if (err) {
- log.error(err)
- return dispatch(self.displayWarning('Had a problem changing networks!'))
- }
- })
- }
-}
-
-// Calls the addressBookController to add a new address.
-function addToAddressBook (recipient, nickname) {
- log.debug(`background.addToAddressBook`)
- return (dispatch) => {
- background.setAddressBook(recipient, nickname, (err, result) => {
- if (err) {
- log.error(err)
- return dispatch(self.displayWarning('Address book failed to update'))
- }
- })
- }
-}
-
-function setProviderType (type) {
- log.debug(`background.setProviderType`)
- background.setProviderType(type)
- return {
- type: actions.SET_PROVIDER_TYPE,
- value: type,
- }
-}
-
-function useEtherscanProvider () {
- log.debug(`background.useEtherscanProvider`)
- background.useEtherscanProvider()
- return {
- type: actions.USE_ETHERSCAN_PROVIDER,
- }
-}
-
-function showLoadingIndication (message) {
- return {
- type: actions.SHOW_LOADING,
- value: message,
- }
-}
-
-function hideLoadingIndication () {
- return {
- type: actions.HIDE_LOADING,
- }
-}
-
-function showSubLoadingIndication () {
- return {
- type: actions.SHOW_SUB_LOADING_INDICATION,
- }
-}
-
-function hideSubLoadingIndication () {
- return {
- type: actions.HIDE_SUB_LOADING_INDICATION,
- }
-}
-
-function displayWarning (text) {
- return {
- type: actions.DISPLAY_WARNING,
- value: text,
- }
-}
-
-function hideWarning () {
- return {
- type: actions.HIDE_WARNING,
- }
-}
-
-function requestExportAccount () {
- return {
- type: actions.REQUEST_ACCOUNT_EXPORT,
- }
-}
-
-function exportAccount (password, address) {
- var self = this
-
- return function (dispatch) {
- dispatch(self.showLoadingIndication())
-
- log.debug(`background.submitPassword`)
- background.submitPassword(password, function (err) {
- if (err) {
- log.error('Error in submiting password.')
- dispatch(self.hideLoadingIndication())
- return dispatch(self.displayWarning('Incorrect Password.'))
- }
- log.debug(`background.exportAccount`)
- background.exportAccount(address, function (err, result) {
- dispatch(self.hideLoadingIndication())
-
- if (err) {
- log.error(err)
- return dispatch(self.displayWarning('Had a problem exporting the account.'))
- }
-
- dispatch(self.showPrivateKey(result))
- })
- })
- }
-}
-
-function showPrivateKey (key) {
- return {
- type: actions.SHOW_PRIVATE_KEY,
- value: key,
- }
-}
-
-function saveAccountLabel (account, label) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- log.debug(`background.saveAccountLabel`)
- background.saveAccountLabel(account, label, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch({
- type: actions.SAVE_ACCOUNT_LABEL,
- value: { account, label },
- })
- })
- }
-}
-
-function showSendPage () {
- return {
- type: actions.SHOW_SEND_PAGE,
- }
-}
-
-function buyEth (opts) {
- return (dispatch) => {
- const url = getBuyEthUrl(opts)
- global.platform.openWindow({ url })
- dispatch({
- type: actions.BUY_ETH,
- })
- }
-}
-
-function buyEthView (address) {
- return {
- type: actions.BUY_ETH_VIEW,
- value: address,
- }
-}
-
-function coinBaseSubview () {
- return {
- type: actions.COINBASE_SUBVIEW,
- }
-}
-
-function pairUpdate (coin) {
- return (dispatch) => {
- dispatch(actions.showSubLoadingIndication())
- dispatch(actions.hideWarning())
- shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => {
- dispatch(actions.hideSubLoadingIndication())
- dispatch({
- type: actions.PAIR_UPDATE,
- value: {
- marketinfo: mktResponse,
- },
- })
- })
- }
-}
-
-function shapeShiftSubview (network) {
- var pair = 'btc_eth'
-
- return (dispatch) => {
- dispatch(actions.showSubLoadingIndication())
- shapeShiftRequest('marketinfo', {pair}, (mktResponse) => {
- shapeShiftRequest('getcoins', {}, (response) => {
- dispatch(actions.hideSubLoadingIndication())
- if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
- dispatch({
- type: actions.SHAPESHIFT_SUBVIEW,
- value: {
- marketinfo: mktResponse,
- coinOptions: response,
- },
- })
- })
- })
- }
-}
-
-function coinShiftRquest (data, marketData) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- shapeShiftRequest('shift', { method: 'POST', data}, (response) => {
- dispatch(actions.hideLoadingIndication())
- if (response.error) return dispatch(actions.displayWarning(response.error))
- var message = `
- Deposit your ${response.depositType} to the address bellow:`
- log.debug(`background.createShapeShiftTx`)
- background.createShapeShiftTx(response.deposit, response.depositType)
- dispatch(actions.showQrView(response.deposit, [message].concat(marketData)))
- })
- }
-}
-
-function showQrView (data, message) {
- return {
- type: actions.SHOW_QR_VIEW,
- value: {
- message: message,
- data: data,
- },
- }
-}
-function reshowQrCode (data, coin) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- shapeShiftRequest('marketinfo', {pair: `${coin.toLowerCase()}_eth`}, (mktResponse) => {
- if (mktResponse.error) return dispatch(actions.displayWarning(mktResponse.error))
-
- var message = [
- `Deposit your ${coin} to the address bellow:`,
- `Deposit Limit: ${mktResponse.limit}`,
- `Deposit Minimum:${mktResponse.minimum}`,
- ]
-
- dispatch(actions.hideLoadingIndication())
- return dispatch(actions.showQrView(data, message))
- })
- }
-}
-
-function shapeShiftRequest (query, options, cb) {
- var queryResponse, method
- !options ? options = {} : null
- options.method ? method = options.method : method = 'GET'
-
- var requestListner = function (request) {
- queryResponse = JSON.parse(this.responseText)
- cb ? cb(queryResponse) : null
- return queryResponse
- }
-
- var shapShiftReq = new XMLHttpRequest()
- shapShiftReq.addEventListener('load', requestListner)
- shapShiftReq.open(method, `https://shapeshift.io/${query}/${options.pair ? options.pair : ''}`, true)
-
- if (options.method === 'POST') {
- var jsonObj = JSON.stringify(options.data)
- shapShiftReq.setRequestHeader('Content-Type', 'application/json')
- return shapShiftReq.send(jsonObj)
- } else {
- return shapShiftReq.send()
- }
-}
-
-// Call Background Then Update
-//
-// A function generator for a common pattern wherein:
-// We show loading indication.
-// We call a background method.
-// We hide loading indication.
-// If it errored, we show a warning.
-// If it didn't, we update the state.
-function callBackgroundThenUpdateNoSpinner (method, ...args) {
- return (dispatch) => {
- method.call(background, ...args, (err) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- forceUpdateMetamaskState(dispatch)
- })
- }
-}
-
-function callBackgroundThenUpdate (method, ...args) {
- return (dispatch) => {
- dispatch(actions.showLoadingIndication())
- method.call(background, ...args, (err) => {
- dispatch(actions.hideLoadingIndication())
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- forceUpdateMetamaskState(dispatch)
- })
- }
-}
-
-function forceUpdateMetamaskState (dispatch) {
- log.debug(`background.getState`)
- background.getState((err, newState) => {
- if (err) {
- return dispatch(actions.displayWarning(err.message))
- }
- dispatch(actions.updateMetamaskState(newState))
- })
-}
diff --git a/responsive-ui/app/add-token.js b/responsive-ui/app/add-token.js
deleted file mode 100644
index b303b5c0d..000000000
--- a/responsive-ui/app/add-token.js
+++ /dev/null
@@ -1,219 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-
-const ethUtil = require('ethereumjs-util')
-const abi = require('human-standard-token-abi')
-const Eth = require('ethjs-query')
-const EthContract = require('ethjs-contract')
-
-const emptyAddr = '0x0000000000000000000000000000000000000000'
-
-module.exports = connect(mapStateToProps)(AddTokenScreen)
-
-function mapStateToProps (state) {
- return {
- }
-}
-
-inherits(AddTokenScreen, Component)
-function AddTokenScreen () {
- this.state = {
- warning: null,
- address: null,
- symbol: 'TOKEN',
- decimals: 18,
- }
- Component.call(this)
-}
-
-AddTokenScreen.prototype.render = function () {
- const state = this.state
- const props = this.props
- const { warning, symbol, decimals } = state
-
- return (
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- props.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Add Token'),
- ]),
-
- h('.error', {
- style: {
- display: warning ? 'block' : 'none',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, warning),
-
- // conf view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Address'),
- ]),
-
- h('section.flex-row.flex-center', [
- h('input#token-address', {
- name: 'address',
- placeholder: 'Token Address',
- onChange: this.tokenAddressDidChange.bind(this),
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- }),
- ]),
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Sybmol'),
- ]),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#token_symbol', {
- placeholder: `Like "ETH"`,
- value: symbol,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var symbol = element.value
- this.setState({ symbol })
- },
- }),
- ]),
-
- h('div', [
- h('span', {
- style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Decimals of Precision'),
- ]),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#token_decimals', {
- value: decimals,
- type: 'number',
- min: 0,
- max: 36,
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onChange: (event) => {
- var element = event.target
- var decimals = element.value.trim()
- this.setState({ decimals })
- },
- }),
- ]),
-
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick: (event) => {
- const valid = this.validateInputs()
- if (!valid) return
-
- const { address, symbol, decimals } = this.state
- this.props.dispatch(actions.addToken(address.trim(), symbol.trim(), decimals))
- },
- }, 'Add'),
- ]),
- ]),
- ])
- )
-}
-
-AddTokenScreen.prototype.componentWillMount = function () {
- if (typeof global.ethereumProvider === 'undefined') return
-
- this.eth = new Eth(global.ethereumProvider)
- this.contract = new EthContract(this.eth)
- this.TokenContract = this.contract(abi)
-}
-
-AddTokenScreen.prototype.tokenAddressDidChange = function (event) {
- const el = event.target
- const address = el.value.trim()
- if (ethUtil.isValidAddress(address) && address !== emptyAddr) {
- this.setState({ address })
- this.attemptToAutoFillTokenParams(address)
- }
-}
-
-AddTokenScreen.prototype.validateInputs = function () {
- let msg = ''
- const state = this.state
- const { address, symbol, decimals } = state
-
- const validAddress = ethUtil.isValidAddress(address)
- if (!validAddress) {
- msg += 'Address is invalid. '
- }
-
- const validDecimals = decimals >= 0 && decimals < 36
- if (!validDecimals) {
- msg += 'Decimals must be at least 0, and not over 36. '
- }
-
- const symbolLen = symbol.trim().length
- const validSymbol = symbolLen > 0 && symbolLen < 10
- if (!validSymbol) {
- msg += 'Symbol must be between 0 and 10 characters.'
- }
-
- const isValid = validAddress && validDecimals
-
- if (!isValid) {
- this.setState({
- warning: msg,
- })
- } else {
- this.setState({ warning: null })
- }
-
- return isValid
-}
-
-AddTokenScreen.prototype.attemptToAutoFillTokenParams = async function (address) {
- const contract = this.TokenContract.at(address)
-
- const results = await Promise.all([
- contract.symbol(),
- contract.decimals(),
- ])
-
- const [ symbol, decimals ] = results
- if (symbol && decimals) {
- console.log('SETTING SYMBOL AND DECIMALS', { symbol, decimals })
- this.setState({ symbol: symbol[0], decimals: decimals[0].toString() })
- }
-}
-
diff --git a/responsive-ui/app/app.js b/responsive-ui/app/app.js
deleted file mode 100644
index d1a20f079..000000000
--- a/responsive-ui/app/app.js
+++ /dev/null
@@ -1,591 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('./actions')
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
-// init
-const InitializeMenuScreen = require('./first-time/init-menu')
-const NewKeyChainScreen = require('./new-keychain')
-// unlock
-const UnlockScreen = require('./unlock')
-// accounts
-const AccountDetailScreen = require('./account-detail')
-const SendTransactionScreen = require('./send')
-const ConfirmTxScreen = require('./conf-tx')
-// notice
-const NoticeScreen = require('./components/notice')
-const generateLostAccountsNotice = require('../lib/lost-accounts-notice')
-// other views
-const ConfigScreen = require('./config')
-const AddTokenScreen = require('./add-token')
-const Import = require('./accounts/import')
-const InfoScreen = require('./info')
-const Loading = require('./components/loading')
-const SandwichExpando = require('sandwich-expando')
-const Dropdown = require('./components/dropdown').Dropdown
-const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
-const NetworkIndicator = require('./components/network')
-const BuyView = require('./components/buy-button-subview')
-const QrView = require('./components/qr-code')
-const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
-const HDRestoreVaultScreen = require('./keychains/hd/restore-vault')
-const RevealSeedConfirmation = require('./keychains/hd/recover-seed/confirmation')
-
-module.exports = connect(mapStateToProps)(App)
-
-inherits(App, Component)
-function App () { Component.call(this) }
-
-function mapStateToProps (state) {
- return {
- // state from plugin
- isLoading: state.appState.isLoading,
- loadingMessage: state.appState.loadingMessage,
- noActiveNotices: state.metamask.noActiveNotices,
- isInitialized: state.metamask.isInitialized,
- isUnlocked: state.metamask.isUnlocked,
- currentView: state.appState.currentView,
- activeAddress: state.appState.activeAddress,
- transForward: state.appState.transForward,
- seedWords: state.metamask.seedWords,
- unapprovedTxs: state.metamask.unapprovedTxs,
- unapprovedMsgs: state.metamask.unapprovedMsgs,
- menuOpen: state.appState.menuOpen,
- network: state.metamask.network,
- provider: state.metamask.provider,
- forgottenPassword: state.appState.forgottenPassword,
- lastUnreadNotice: state.metamask.lastUnreadNotice,
- lostAccounts: state.metamask.lostAccounts,
- frequentRpcList: state.metamask.frequentRpcList || [],
- }
-}
-
-App.prototype.render = function () {
- var props = this.props
- const { isLoading, loadingMessage, transForward, network } = props
- const isLoadingNetwork = network === 'loading' && props.currentView.name !== 'config'
- const loadMessage = loadingMessage || isLoadingNetwork ?
- `Connecting to ${this.getNetworkName()}` : null
-
- log.debug('Main ui render function')
-
- return (
-
- h('.flex-column.flex-grow.full-height', {
- style: {
- // Windows was showing a vertical scroll bar:
- overflow: 'hidden',
- position: 'relative',
- height: '100%',
- alignItems: 'center',
- },
- }, [
-
- // app bar
- this.renderAppBar(),
- this.renderNetworkDropdown(),
- this.renderDropdown(),
-
- h(Loading, {
- isLoading: isLoading || isLoadingNetwork,
- loadingMessage: loadMessage,
- }),
-
- // panel content
- h('.app-primary.flex-grow' + (transForward ? '.from-right' : '.from-left'), {
- style: {
- height: '100%',
- maxWidth: '850px',
- },
- }, [
- h(ReactCSSTransitionGroup, {
- className: 'css-transition-group',
- transitionName: 'main',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 300,
- }, [
- this.renderPrimary(),
- ]),
- ]),
- ])
- )
-}
-
-App.prototype.renderAppBar = function () {
- if (window.METAMASK_UI_TYPE === 'notification') {
- return null
- }
-
- const props = this.props
- const state = this.state || {}
- const isNetworkMenuOpen = state.isNetworkMenuOpen || false
-
- return (
-
- h('div', {
- style: {
- width: '100%'
- },
- }, [
-
- h('.app-header.flex-row.flex-space-between', {
- style: {
- alignItems: 'center',
- visibility: props.isUnlocked ? 'visible' : 'none',
- background: props.isUnlocked ? 'white' : 'none',
- height: '38px',
- position: 'relative',
- zIndex: 12,
- },
- }, [
-
- h('div.left-menu-section', {
- style: {
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- },
- }, [
-
- // mini logo
- h('img', {
- height: 24,
- width: 24,
- src: '/images/icon-128.png',
- }),
-
- h(NetworkIndicator, {
- network: this.props.network,
- provider: this.props.provider,
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- this.setState({ isNetworkMenuOpen: !isNetworkMenuOpen })
- },
- }),
- ]),
-
- // metamask name
- props.isUnlocked && h('h1', {
- style: {
- position: 'relative',
- left: '9px',
- },
- }, 'MetaMask'),
-
- props.isUnlocked && h('div', {
- style: {
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- },
- }, [
-
- // hamburger
- props.isUnlocked && h(SandwichExpando, {
- width: 16,
- barHeight: 2,
- padding: 0,
- isOpen: state.isMainMenuOpen,
- color: 'rgb(247,146,30)',
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- this.setState({ isMainMenuOpen: !state.isMainMenuOpen })
- },
- }),
- ]),
- ]),
- ])
- )
-}
-
-App.prototype.renderNetworkDropdown = function () {
- const props = this.props
- const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
- const rpcList = props.frequentRpcList
- const state = this.state || {}
- const isOpen = state.isNetworkMenuOpen
-
- return h(Dropdown, {
- isOpen,
- onClickOutside: (event) => {
- this.setState({ isNetworkMenuOpen: !isOpen })
- },
- zIndex: 11,
- style: {
- position: 'absolute',
- left: '2px',
- top: '36px',
- },
- innerStyle: {},
- }, [
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('mainnet')),
- },
- [
- h('.menu-icon.diamond'),
- 'Main Ethereum Network',
- providerType === 'mainnet' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('ropsten')),
- },
- [
- h('.menu-icon.red-dot'),
- 'Ropsten Test Network',
- providerType === 'ropsten' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('kovan')),
- },
- [
- h('.menu-icon.hollow-diamond'),
- 'Kovan Test Network',
- providerType === 'kovan' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setProviderType('rinkeby')),
- },
- [
- h('.menu-icon.golden-square'),
- 'Rinkeby Test Network',
- providerType === 'rinkeby' ? h('.check', '✓') : null,
- ]
- ),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => props.dispatch(actions.setDefaultRpcTarget(rpcList)),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- 'Localhost 8545',
- activeNetwork === 'http://localhost:8545' ? h('.check', '✓') : null,
- ]
- ),
-
- this.renderCustomOption(props.provider),
- this.renderCommonRpc(rpcList, props.provider),
-
- h(
- DropdownMenuItem,
- {
- closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
- onClick: () => this.props.dispatch(actions.showConfigPage()),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- 'Custom RPC',
- activeNetwork === 'custom' ? h('.check', '✓') : null,
- ]
- ),
-
- ])
-}
-
-App.prototype.renderDropdown = function () {
- const state = this.state || {}
- const isOpen = state.isMainMenuOpen
-
- return h(Dropdown, {
- isOpen: isOpen,
- zIndex: 11,
- onClickOutside: (event) => {
- this.setState({ isMainMenuOpen: !isOpen })
- },
- style: {
- position: 'absolute',
- right: '2px',
- top: '38px',
- },
- innerStyle: {},
- }, [
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.showConfigPage()) },
- }, 'Settings'),
-
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.showImportPage()) },
- }, 'Import Account'),
-
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.lockMetamask()) },
- }, 'Lock'),
-
- h(DropdownMenuItem, {
- closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- onClick: () => { this.props.dispatch(actions.showInfoPage()) },
- }, 'Info/Help'),
- ])
-}
-
-App.prototype.renderBackButton = function (style, justArrow = false) {
- var props = this.props
- return (
- h('.flex-row', {
- key: 'leftArrow',
- style: style,
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, [
- h('i.fa.fa-arrow-left.cursor-pointer'),
- justArrow ? null : h('div.cursor-pointer', {
- style: {
- marginLeft: '3px',
- },
- onClick: () => props.dispatch(actions.goBackToInitView()),
- }, 'BACK'),
- ])
- )
-}
-
-App.prototype.renderPrimary = function () {
- log.debug('rendering primary')
- var props = this.props
-
- // notices
- if (!props.noActiveNotices) {
- log.debug('rendering notice screen for unread notices.')
- return h(NoticeScreen, {
- notice: props.lastUnreadNotice,
- key: 'NoticeScreen',
- onConfirm: () => props.dispatch(actions.markNoticeRead(props.lastUnreadNotice)),
- })
- } else if (props.lostAccounts && props.lostAccounts.length > 0) {
- log.debug('rendering notice screen for lost accounts view.')
- return h(NoticeScreen, {
- notice: generateLostAccountsNotice(props.lostAccounts),
- key: 'LostAccountsNotice',
- onConfirm: () => props.dispatch(actions.markAccountsFound()),
- })
- }
-
- if (props.seedWords) {
- log.debug('rendering seed words')
- return h(HDCreateVaultComplete, {key: 'HDCreateVaultComplete'})
- }
-
- // show initialize screen
- if (!props.isInitialized || props.forgottenPassword) {
- // show current view
- log.debug('rendering an initialize screen')
- switch (props.currentView.name) {
-
- case 'restoreVault':
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
-
- default:
- log.debug('rendering menu screen')
- return h(InitializeMenuScreen, {key: 'menuScreenInit'})
- }
- }
-
- // show unlock screen
- if (!props.isUnlocked) {
- switch (props.currentView.name) {
-
- case 'restoreVault':
- log.debug('rendering restore vault screen')
- return h(HDRestoreVaultScreen, {key: 'HDRestoreVaultScreen'})
-
- case 'config':
- log.debug('rendering config screen from unlock screen.')
- return h(ConfigScreen, {key: 'config'})
-
- default:
- log.debug('rendering locked screen')
- return h(UnlockScreen, {key: 'locked'})
- }
- }
-
- // show current view
- switch (props.currentView.name) {
-
- case 'accountDetail':
- log.debug('rendering account detail screen')
- return h(AccountDetailScreen, {key: 'account-detail'})
-
- case 'sendTransaction':
- log.debug('rendering send tx screen')
- return h(SendTransactionScreen, {key: 'send-transaction'})
-
- case 'newKeychain':
- log.debug('rendering new keychain screen')
- return h(NewKeyChainScreen, {key: 'new-keychain'})
-
- case 'confTx':
- log.debug('rendering confirm tx screen')
- return h(ConfirmTxScreen, {key: 'confirm-tx'})
-
- case 'add-token':
- log.debug('rendering add-token screen from unlock screen.')
- return h(AddTokenScreen, {key: 'add-token'})
-
- case 'config':
- log.debug('rendering config screen')
- return h(ConfigScreen, {key: 'config'})
-
- case 'import-menu':
- log.debug('rendering import screen')
- return h(Import, {key: 'import-menu'})
-
- case 'reveal-seed-conf':
- log.debug('rendering reveal seed confirmation screen')
- return h(RevealSeedConfirmation, {key: 'reveal-seed-conf'})
-
- case 'info':
- log.debug('rendering info screen')
- return h(InfoScreen, {key: 'info'})
-
- case 'buyEth':
- log.debug('rendering buy ether screen')
- return h(BuyView, {key: 'buyEthView'})
-
- case 'qr':
- log.debug('rendering show qr screen')
- return h('div', {
- style: {
- position: 'absolute',
- height: '100%',
- top: '0px',
- left: '0px',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: () => props.dispatch(actions.backToAccountDetail(props.activeAddress)),
- style: {
- marginLeft: '10px',
- marginTop: '50px',
- },
- }),
- h('div', {
- style: {
- position: 'absolute',
- left: '44px',
- width: '285px',
- },
- }, [
- h(QrView, {key: 'qr'}),
- ]),
- ])
-
- default:
- log.debug('rendering default, account detail screen')
- return h(AccountDetailScreen, {key: 'account-detail'})
- }
-}
-
-App.prototype.toggleMetamaskActive = function () {
- if (!this.props.isUnlocked) {
- // currently inactive: redirect to password box
- var passwordBox = document.querySelector('input[type=password]')
- if (!passwordBox) return
- passwordBox.focus()
- } else {
- // currently active: deactivate
- this.props.dispatch(actions.lockMetamask(false))
- }
-}
-
-App.prototype.renderCustomOption = function (provider) {
- const { rpcTarget, type } = provider
- if (type !== 'rpc') return null
-
- // Concatenate long URLs
- let label = rpcTarget
- if (rpcTarget.length > 31) {
- label = label.substr(0, 34) + '...'
- }
-
- switch (rpcTarget) {
-
- case 'http://localhost:8545':
- return null
-
- default:
- return h(
- DropdownMenuItem,
- {
- key: rpcTarget,
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- label,
- h('.check', '✓'),
- ]
- )
- }
-}
-
-App.prototype.getNetworkName = function () {
- const { provider } = this.props
- const providerName = provider.type
-
- let name
-
- if (providerName === 'mainnet') {
- name = 'Main Ethereum Network'
- } else if (providerName === 'ropsten') {
- name = 'Ropsten Test Network'
- } else if (providerName === 'kovan') {
- name = 'Kovan Test Network'
- } else if (providerName === 'rinkeby') {
- name = 'Rinkeby Test Network'
- } else {
- name = 'Unknown Private Network'
- }
-
- return name
-}
-
-App.prototype.renderCommonRpc = function (rpcList, provider) {
- const { rpcTarget } = provider
- const props = this.props
-
- return rpcList.map((rpc) => {
- if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
- return null
- } else {
- return h(
- DropdownMenuItem,
- {
- key: rpc,
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setRpcTarget(rpc)),
- },
- [
- h('i.fa.fa-question-circle.fa-lg.menu-icon'),
- rpc,
- h('.check', '✓'),
- ]
- )
- }
- })
-}
diff --git a/responsive-ui/app/components/account-export.js b/responsive-ui/app/components/account-export.js
deleted file mode 100644
index 394d878f7..000000000
--- a/responsive-ui/app/components/account-export.js
+++ /dev/null
@@ -1,122 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const copyToClipboard = require('copy-to-clipboard')
-const actions = require('../actions')
-const ethUtil = require('ethereumjs-util')
-const connect = require('react-redux').connect
-
-module.exports = connect(mapStateToProps)(ExportAccountView)
-
-inherits(ExportAccountView, Component)
-function ExportAccountView () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-ExportAccountView.prototype.render = function () {
- var state = this.props
- var accountDetail = state.accountDetail
-
- if (!accountDetail) return h('div')
- var accountExport = accountDetail.accountExport
-
- var notExporting = accountExport === 'none'
- var exportRequested = accountExport === 'requested'
- var accountExported = accountExport === 'completed'
-
- if (notExporting) return h('div')
-
- if (exportRequested) {
- var warning = `Export private keys at your own risk.`
- return (
- h('div', {
- style: {
- display: 'inline-block',
- textAlign: 'center',
- },
- },
- [
- h('div', {
- key: 'exporting',
- style: {
- margin: '0 20px',
- },
- }, [
- h('p.error', warning),
- h('input#exportAccount.sizing-input', {
- type: 'password',
- placeholder: 'confirm password',
- onKeyPress: this.onExportKeyPress.bind(this),
- style: {
- position: 'relative',
- top: '1.5px',
- marginBottom: '7px',
- },
- }),
- ]),
- h('div', {
- key: 'buttons',
- style: {
- margin: '0 20px',
- },
- },
- [
- h('button', {
- onClick: () => this.onExportKeyPress({ key: 'Enter', preventDefault: () => {} }),
- style: {
- marginRight: '10px',
- },
- }, 'Submit'),
- h('button', {
- onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
- }, 'Cancel'),
- ]),
- (this.props.warning) && (
- h('span.error', {
- style: {
- margin: '20px',
- },
- }, this.props.warning.split('-'))
- ),
- ])
- )
- }
-
- if (accountExported) {
- return h('div.privateKey', {
- style: {
- margin: '0 20px',
- },
- }, [
- h('label', 'Your private key (click to copy):'),
- h('p.error.cursor-pointer', {
- style: {
- textOverflow: 'ellipsis',
- overflow: 'hidden',
- webkitUserSelect: 'text',
- width: '100%',
- },
- onClick: function (event) {
- copyToClipboard(ethUtil.stripHexPrefix(accountDetail.privateKey))
- },
- }, ethUtil.stripHexPrefix(accountDetail.privateKey)),
- h('button', {
- onClick: () => this.props.dispatch(actions.backToAccountDetail(this.props.address)),
- }, 'Done'),
- ])
- }
-}
-
-ExportAccountView.prototype.onExportKeyPress = function (event) {
- if (event.key !== 'Enter') return
- event.preventDefault()
-
- var input = document.getElementById('exportAccount').value
- this.props.dispatch(actions.exportAccount(input, this.props.address))
-}
diff --git a/responsive-ui/app/components/account-panel.js b/responsive-ui/app/components/account-panel.js
deleted file mode 100644
index abaaf8163..000000000
--- a/responsive-ui/app/components/account-panel.js
+++ /dev/null
@@ -1,86 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const Identicon = require('./identicon')
-const formatBalance = require('../util').formatBalance
-const addressSummary = require('../util').addressSummary
-
-module.exports = AccountPanel
-
-
-inherits(AccountPanel, Component)
-function AccountPanel () {
- Component.call(this)
-}
-
-AccountPanel.prototype.render = function () {
- var state = this.props
- var identity = state.identity || {}
- var account = state.account || {}
- var isFauceting = state.isFauceting
-
- var panelState = {
- key: `accountPanel${identity.address}`,
- identiconKey: identity.address,
- identiconLabel: identity.name || '',
- attributes: [
- {
- key: 'ADDRESS',
- value: addressSummary(identity.address),
- },
- balanceOrFaucetingIndication(account, isFauceting),
- ],
- }
-
- return (
-
- h('.identity-panel.flex-row.flex-space-between', {
- style: {
- flex: '1 0 auto',
- cursor: panelState.onClick ? 'pointer' : undefined,
- },
- onClick: panelState.onClick,
- }, [
-
- // account identicon
- h('.identicon-wrapper.flex-column.select-none', [
- h(Identicon, {
- address: panelState.identiconKey,
- imageify: state.imageifyIdenticons,
- }),
- h('span.font-small', panelState.identiconLabel.substring(0, 7) + '...'),
- ]),
-
- // account address, balance
- h('.identity-data.flex-column.flex-justify-center.flex-grow.select-none', [
-
- panelState.attributes.map((attr) => {
- return h('.flex-row.flex-space-between', {
- key: '' + Math.round(Math.random() * 1000000),
- }, [
- h('label.font-small.no-select', attr.key),
- h('span.font-small', attr.value),
- ])
- }),
- ]),
-
- ])
-
- )
-}
-
-function balanceOrFaucetingIndication (account, isFauceting) {
- // Temporarily deactivating isFauceting indication
- // because it shows fauceting for empty restored accounts.
- if (/* isFauceting*/ false) {
- return {
- key: 'Account is auto-funding.',
- value: 'Please wait.',
- }
- } else {
- return {
- key: 'BALANCE',
- value: formatBalance(account.balance),
- }
- }
-}
diff --git a/responsive-ui/app/components/balance.js b/responsive-ui/app/components/balance.js
deleted file mode 100644
index 57ca84564..000000000
--- a/responsive-ui/app/components/balance.js
+++ /dev/null
@@ -1,89 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const formatBalance = require('../util').formatBalance
-const generateBalanceObject = require('../util').generateBalanceObject
-const Tooltip = require('./tooltip.js')
-const FiatValue = require('./fiat-value.js')
-
-module.exports = EthBalanceComponent
-
-inherits(EthBalanceComponent, Component)
-function EthBalanceComponent () {
- Component.call(this)
-}
-
-EthBalanceComponent.prototype.render = function () {
- var props = this.props
- let { value } = props
- var style = props.style
- var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
- value = value ? formatBalance(value, 6, needsParse) : '...'
- var width = props.width
-
- return (
-
- h('.ether-balance.ether-balance-amount', {
- style: style,
- }, [
- h('div', {
- style: {
- display: 'inline',
- width: width,
- },
- }, this.renderBalance(value)),
- ])
-
- )
-}
-EthBalanceComponent.prototype.renderBalance = function (value) {
- var props = this.props
- if (value === 'None') return value
- if (value === '...') return value
- var balanceObj = generateBalanceObject(value, props.shorten ? 1 : 3)
- var balance
- var splitBalance = value.split(' ')
- var ethNumber = splitBalance[0]
- var ethSuffix = splitBalance[1]
- const showFiat = 'showFiat' in props ? props.showFiat : true
-
- if (props.shorten) {
- balance = balanceObj.shortBalance
- } else {
- balance = balanceObj.balance
- }
-
- var label = balanceObj.label
-
- return (
- h(Tooltip, {
- position: 'bottom',
- title: `${ethNumber} ${ethSuffix}`,
- }, h('div.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('div', {
- style: {
- width: '100%',
- textAlign: 'right',
- },
- }, this.props.incoming ? `+${balance}` : balance),
- h('div', {
- style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
- },
- }, label),
- ]),
-
- showFiat ? h(FiatValue, { value: props.value }) : null,
- ]))
- )
-}
diff --git a/responsive-ui/app/components/binary-renderer.js b/responsive-ui/app/components/binary-renderer.js
deleted file mode 100644
index 0b6a1f5c2..000000000
--- a/responsive-ui/app/components/binary-renderer.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ethUtil = require('ethereumjs-util')
-const extend = require('xtend')
-
-module.exports = BinaryRenderer
-
-inherits(BinaryRenderer, Component)
-function BinaryRenderer () {
- Component.call(this)
-}
-
-BinaryRenderer.prototype.render = function () {
- const props = this.props
- const { value, style } = props
- const text = this.hexToText(value)
-
- const defaultStyle = extend({
- width: '315px',
- maxHeight: '210px',
- resize: 'none',
- border: 'none',
- background: 'white',
- padding: '3px',
- }, style)
-
- return (
- h('textarea.font-small', {
- readOnly: true,
- style: defaultStyle,
- defaultValue: text,
- })
- )
-}
-
-BinaryRenderer.prototype.hexToText = function (hex) {
- try {
- const stripped = ethUtil.stripHexPrefix(hex)
- const buff = Buffer.from(stripped, 'hex')
- return buff.toString('utf8')
- } catch (e) {
- return hex
- }
-}
-
diff --git a/responsive-ui/app/components/bn-as-decimal-input.js b/responsive-ui/app/components/bn-as-decimal-input.js
deleted file mode 100644
index f3ace4720..000000000
--- a/responsive-ui/app/components/bn-as-decimal-input.js
+++ /dev/null
@@ -1,174 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
-const extend = require('xtend')
-
-module.exports = BnAsDecimalInput
-
-inherits(BnAsDecimalInput, Component)
-function BnAsDecimalInput () {
- this.state = { invalid: null }
- Component.call(this)
-}
-
-/* Bn as Decimal Input
- *
- * A component for allowing easy, decimal editing
- * of a passed in bn string value.
- *
- * On change, calls back its `onChange` function parameter
- * and passes it an updated bn string.
- */
-
-BnAsDecimalInput.prototype.render = function () {
- const props = this.props
- const state = this.state
-
- const { value, scale, precision, onChange, min, max } = props
-
- const suffix = props.suffix
- const style = props.style
- const valueString = value.toString(10)
- const newValue = this.downsize(valueString, scale, precision)
-
- return (
- h('.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('input.hex-input', {
- type: 'number',
- step: 'any',
- required: true,
- min,
- max,
- style: extend({
- display: 'block',
- textAlign: 'right',
- backgroundColor: 'transparent',
- border: '1px solid #bdbdbd',
-
- }, style),
- value: newValue,
- onBlur: (event) => {
- this.updateValidity(event)
- },
- onChange: (event) => {
- this.updateValidity(event)
- const value = (event.target.value === '') ? '' : event.target.value
-
-
- const scaledNumber = this.upsize(value, scale, precision)
- const precisionBN = new BN(scaledNumber, 10)
- onChange(precisionBN, event.target.checkValidity())
- },
- onInvalid: (event) => {
- const msg = this.constructWarning()
- if (msg === state.invalid) {
- return
- }
- this.setState({ invalid: msg })
- event.preventDefault()
- return false
- },
- }),
- h('div', {
- style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
- marginRight: '6px',
- width: '20px',
- },
- }, suffix),
- ]),
-
- state.invalid ? h('span.error', {
- style: {
- position: 'absolute',
- right: '0px',
- textAlign: 'right',
- transform: 'translateY(26px)',
- padding: '3px',
- background: 'rgba(255,255,255,0.85)',
- zIndex: '1',
- textTransform: 'capitalize',
- border: '2px solid #E20202',
- },
- }, state.invalid) : null,
- ])
- )
-}
-
-BnAsDecimalInput.prototype.setValid = function (message) {
- this.setState({ invalid: null })
-}
-
-BnAsDecimalInput.prototype.updateValidity = function (event) {
- const target = event.target
- const value = this.props.value
- const newValue = target.value
-
- if (value === newValue) {
- return
- }
-
- const valid = target.checkValidity()
-
- if (valid) {
- this.setState({ invalid: null })
- }
-}
-
-BnAsDecimalInput.prototype.constructWarning = function () {
- const { name, min, max } = this.props
- let message = name ? name + ' ' : ''
-
- if (min && max) {
- message += `must be greater than or equal to ${min} and less than or equal to ${max}.`
- } else if (min) {
- message += `must be greater than or equal to ${min}.`
- } else if (max) {
- message += `must be less than or equal to ${max}.`
- } else {
- message += 'Invalid input.'
- }
-
- return message
-}
-
-
-BnAsDecimalInput.prototype.downsize = function (number, scale, precision) {
- // if there is no scaling, simply return the number
- if (scale === 0) {
- return Number(number)
- } else {
- // if the scale is the same as the precision, account for this edge case.
- var decimals = (scale === precision) ? -1 : scale - precision
- return Number(number.slice(0, -scale) + '.' + number.slice(-scale, decimals))
- }
-}
-
-BnAsDecimalInput.prototype.upsize = function (number, scale, precision) {
- var stringArray = number.toString().split('.')
- var decimalLength = stringArray[1] ? stringArray[1].length : 0
- var newString = stringArray[0]
-
- // If there is scaling and decimal parts exist, integrate them in.
- if ((scale !== 0) && (decimalLength !== 0)) {
- newString += stringArray[1].slice(0, precision)
- }
-
- // Add 0s to account for the upscaling.
- for (var i = decimalLength; i < scale; i++) {
- newString += '0'
- }
- return newString
-}
diff --git a/responsive-ui/app/components/buy-button-subview.js b/responsive-ui/app/components/buy-button-subview.js
deleted file mode 100644
index 87084f92d..000000000
--- a/responsive-ui/app/components/buy-button-subview.js
+++ /dev/null
@@ -1,197 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../actions')
-const CoinbaseForm = require('./coinbase-form')
-const ShapeshiftForm = require('./shapeshift-form')
-const Loading = require('./loading')
-const AccountPanel = require('./account-panel')
-const RadioList = require('./custom-radio-list')
-
-module.exports = connect(mapStateToProps)(BuyButtonSubview)
-
-function mapStateToProps (state) {
- return {
- identity: state.appState.identity,
- account: state.metamask.accounts[state.appState.buyView.buyAddress],
- warning: state.appState.warning,
- buyView: state.appState.buyView,
- network: state.metamask.network,
- provider: state.metamask.provider,
- context: state.appState.currentView.context,
- isSubLoading: state.appState.isSubLoading,
- }
-}
-
-inherits(BuyButtonSubview, Component)
-function BuyButtonSubview () {
- Component.call(this)
-}
-
-BuyButtonSubview.prototype.render = function () {
- const props = this.props
- const isLoading = props.isSubLoading
-
- return (
- h('.buy-eth-section.flex-column', {
- style: {
- alignItems: 'center',
- },
- }, [
- // back button
- h('.flex-row', {
- style: {
- alignItems: 'center',
- justifyContent: 'center',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: this.backButtonContext.bind(this),
- style: {
- position: 'absolute',
- left: '10px',
- },
- }),
- h('h2.text-transform-uppercase.flex-center', {
- style: {
- width: '100vw',
- background: 'rgb(235, 235, 235)',
- color: 'rgb(174, 174, 174)',
- paddingTop: '4px',
- paddingBottom: '4px',
- },
- }, 'Buy Eth'),
- ]),
- h('div', {
- style: {
- position: 'absolute',
- top: '57vh',
- left: '49vw',
- },
- }, [
- h(Loading, {isLoading}),
- ]),
- h('div', {
- style: {
- width: '80%',
- },
- }, [
- h(AccountPanel, {
- showFullAddress: true,
- identity: props.identity,
- account: props.account,
- }),
- ]),
- h('h3.text-transform-uppercase', {
- style: {
- paddingLeft: '15px',
- fontFamily: 'Montserrat Light',
- width: '100vw',
- background: 'rgb(235, 235, 235)',
- color: 'rgb(174, 174, 174)',
- paddingTop: '4px',
- paddingBottom: '4px',
- },
- }, 'Select Service'),
- h('.flex-row.selected-exchange', {
- style: {
- position: 'relative',
- right: '35px',
- marginTop: '20px',
- marginBottom: '20px',
- },
- }, [
- h(RadioList, {
- defaultFocus: props.buyView.subview,
- labels: [
- 'Coinbase',
- 'ShapeShift',
- ],
- subtext: {
- 'Coinbase': 'Crypto/FIAT (USA only)',
- 'ShapeShift': 'Crypto',
- },
- onClick: this.radioHandler.bind(this),
- }),
- ]),
- h('h3.text-transform-uppercase', {
- style: {
- paddingLeft: '15px',
- fontFamily: 'Montserrat Light',
- width: '100vw',
- background: 'rgb(235, 235, 235)',
- color: 'rgb(174, 174, 174)',
- paddingTop: '4px',
- paddingBottom: '4px',
- },
- }, props.buyView.subview),
- this.formVersionSubview(),
- ])
- )
-}
-
-BuyButtonSubview.prototype.formVersionSubview = function () {
- const network = this.props.network
- if (network === '1') {
- if (this.props.buyView.formView.coinbase) {
- return h(CoinbaseForm, this.props)
- } else if (this.props.buyView.formView.shapeshift) {
- return h(ShapeshiftForm, this.props)
- }
- } else {
- return h('div.flex-column', {
- style: {
- alignItems: 'center',
- margin: '50px',
- },
- }, [
- h('h3.text-transform-uppercase', {
- style: {
- width: '225px',
- marginBottom: '15px',
- },
- }, 'In order to access this feature, please switch to the Main Network'),
- ((network === '3') || (network === '4') || (network === '42')) ? h('h3.text-transform-uppercase', 'or go to the') : null,
- (network === '3') ? h('button.text-transform-uppercase', {
- onClick: () => this.props.dispatch(actions.buyEth({ network })),
- style: {
- marginTop: '15px',
- },
- }, 'Ropsten Test Faucet') : null,
- (network === '4') ? h('button.text-transform-uppercase', {
- onClick: () => this.props.dispatch(actions.buyEth({ network })),
- style: {
- marginTop: '15px',
- },
- }, 'Rinkeby Test Faucet') : null,
- (network === '42') ? h('button.text-transform-uppercase', {
- onClick: () => this.props.dispatch(actions.buyEth({ network })),
- style: {
- marginTop: '15px',
- },
- }, 'Kovan Test Faucet') : null,
- ])
- }
-}
-
-BuyButtonSubview.prototype.navigateTo = function (url) {
- global.platform.openWindow({ url })
-}
-
-BuyButtonSubview.prototype.backButtonContext = function () {
- if (this.props.context === 'confTx') {
- this.props.dispatch(actions.showConfTxPage(false))
- } else {
- this.props.dispatch(actions.goHome())
- }
-}
-
-BuyButtonSubview.prototype.radioHandler = function (event) {
- switch (event.target.title) {
- case 'Coinbase':
- return this.props.dispatch(actions.coinBaseSubview())
- case 'ShapeShift':
- return this.props.dispatch(actions.shapeShiftSubview(this.props.provider.type))
- }
-}
diff --git a/responsive-ui/app/components/coinbase-form.js b/responsive-ui/app/components/coinbase-form.js
deleted file mode 100644
index f44d86045..000000000
--- a/responsive-ui/app/components/coinbase-form.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const actions = require('../actions')
-
-module.exports = connect(mapStateToProps)(CoinbaseForm)
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-inherits(CoinbaseForm, Component)
-
-function CoinbaseForm () {
- Component.call(this)
-}
-
-CoinbaseForm.prototype.render = function () {
- var props = this.props
-
- return h('.flex-column', {
- style: {
- marginTop: '35px',
- padding: '25px',
- width: '100%',
- },
- }, [
- h('.flex-row', {
- style: {
- justifyContent: 'space-around',
- margin: '33px',
- marginTop: '0px',
- },
- }, [
- h('button.btn-green', {
- onClick: this.toCoinbase.bind(this),
- }, 'Continue to Coinbase'),
-
- h('button.btn-red', {
- onClick: () => props.dispatch(actions.backTobuyView(props.accounts.address)),
- }, 'Cancel'),
- ]),
- ])
-}
-
-CoinbaseForm.prototype.toCoinbase = function () {
- const props = this.props
- const address = props.buyView.buyAddress
- props.dispatch(actions.buyEth({ network: '1', address, amount: 0 }))
-}
-
-CoinbaseForm.prototype.renderLoading = function () {
- return h('img', {
- style: {
- width: '27px',
- marginRight: '-27px',
- },
- src: 'images/loading.svg',
- })
-}
diff --git a/responsive-ui/app/components/copyButton.js b/responsive-ui/app/components/copyButton.js
deleted file mode 100644
index a25d0719c..000000000
--- a/responsive-ui/app/components/copyButton.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const copyToClipboard = require('copy-to-clipboard')
-
-const Tooltip = require('./tooltip')
-
-module.exports = CopyButton
-
-inherits(CopyButton, Component)
-function CopyButton () {
- Component.call(this)
-}
-
-// As parameters, accepts:
-// "value", which is the value to copy (mandatory)
-// "title", which is the text to show on hover (optional, defaults to 'Copy')
-CopyButton.prototype.render = function () {
- const props = this.props
- const state = this.state || {}
-
- const value = props.value
- const copied = state.copied
-
- const message = copied ? 'Copied' : props.title || ' Copy '
-
- return h('.copy-button', {
- style: {
- display: 'flex',
- alignItems: 'center',
- },
- }, [
-
- h(Tooltip, {
- title: message,
- }, [
- h('i.fa.fa-clipboard.cursor-pointer.color-orange', {
- style: {
- margin: '5px',
- },
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- copyToClipboard(value)
- this.debounceRestore()
- },
- }),
- ]),
-
- ])
-}
-
-CopyButton.prototype.debounceRestore = function () {
- this.setState({ copied: true })
- clearTimeout(this.timeout)
- this.timeout = setTimeout(() => {
- this.setState({ copied: false })
- }, 850)
-}
diff --git a/responsive-ui/app/components/copyable.js b/responsive-ui/app/components/copyable.js
deleted file mode 100644
index a4f6f4bc6..000000000
--- a/responsive-ui/app/components/copyable.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const Tooltip = require('./tooltip')
-const copyToClipboard = require('copy-to-clipboard')
-
-module.exports = Copyable
-
-inherits(Copyable, Component)
-function Copyable () {
- Component.call(this)
- this.state = {
- copied: false,
- }
-}
-
-Copyable.prototype.render = function () {
- const props = this.props
- const state = this.state
- const { value, children } = props
- const { copied } = state
-
- return h(Tooltip, {
- title: copied ? 'Copied!' : 'Copy',
- position: 'bottom',
- }, h('span', {
- style: {
- cursor: 'pointer',
- },
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- copyToClipboard(value)
- this.debounceRestore()
- },
- }, children))
-}
-
-Copyable.prototype.debounceRestore = function () {
- this.setState({ copied: true })
- clearTimeout(this.timeout)
- this.timeout = setTimeout(() => {
- this.setState({ copied: false })
- }, 850)
-}
diff --git a/responsive-ui/app/components/custom-radio-list.js b/responsive-ui/app/components/custom-radio-list.js
deleted file mode 100644
index a4c525396..000000000
--- a/responsive-ui/app/components/custom-radio-list.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = RadioList
-
-inherits(RadioList, Component)
-function RadioList () {
- Component.call(this)
-}
-
-RadioList.prototype.render = function () {
- const props = this.props
- const activeClass = '.custom-radio-selected'
- const inactiveClass = '.custom-radio-inactive'
- const {
- labels,
- defaultFocus,
- } = props
-
-
- return (
- h('.flex-row', {
- style: {
- fontSize: '12px',
- },
- }, [
- h('.flex-column.custom-radios', {
- style: {
- marginRight: '5px',
- },
- },
- labels.map((lable, i) => {
- let isSelcted = (this.state !== null)
- isSelcted = isSelcted ? (this.state.selected === lable) : (defaultFocus === lable)
- return h(isSelcted ? activeClass : inactiveClass, {
- title: lable,
- onClick: (event) => {
- this.setState({selected: event.target.title})
- props.onClick(event)
- },
- })
- })
- ),
- h('.text', {},
- labels.map((lable) => {
- if (props.subtext) {
- return h('.flex-row', {}, [
- h('.radio-titles', lable),
- h('.radio-titles-subtext', `- ${props.subtext[lable]}`),
- ])
- } else {
- return h('.radio-titles', lable)
- }
- })
- ),
- ])
- )
-}
-
diff --git a/responsive-ui/app/components/editable-label.js b/responsive-ui/app/components/editable-label.js
deleted file mode 100644
index 167be7eaf..000000000
--- a/responsive-ui/app/components/editable-label.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const findDOMNode = require('react-dom').findDOMNode
-
-module.exports = EditableLabel
-
-inherits(EditableLabel, Component)
-function EditableLabel () {
- Component.call(this)
-}
-
-EditableLabel.prototype.render = function () {
- const props = this.props
- const state = this.state
-
- if (state && state.isEditingLabel) {
- return h('div.editable-label', [
- h('input.sizing-input', {
- defaultValue: props.textValue,
- maxLength: '20',
- onKeyPress: (event) => {
- this.saveIfEnter(event)
- },
- }),
- h('button.editable-button', {
- onClick: () => this.saveText(),
- }, 'Save'),
- ])
- } else {
- return h('div.name-label', {
- onClick: (event) => {
- const nameAttribute = event.target.getAttribute('name')
- // checks for class to handle smaller CTA above the account name
- const classAttribute = event.target.getAttribute('class')
- if (nameAttribute === 'edit' || classAttribute === 'edit-text') {
- this.setState({ isEditingLabel: true })
- }
- },
- }, this.props.children)
- }
-}
-
-EditableLabel.prototype.saveIfEnter = function (event) {
- if (event.key === 'Enter') {
- this.saveText()
- }
-}
-
-EditableLabel.prototype.saveText = function () {
- var container = findDOMNode(this)
- var text = container.querySelector('.editable-label input').value
- var truncatedText = text.substring(0, 20)
- this.props.saveText(truncatedText)
- this.setState({ isEditingLabel: false, textLabel: truncatedText })
-}
diff --git a/responsive-ui/app/components/ens-input.js b/responsive-ui/app/components/ens-input.js
deleted file mode 100644
index 3a33ebf74..000000000
--- a/responsive-ui/app/components/ens-input.js
+++ /dev/null
@@ -1,170 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const extend = require('xtend')
-const debounce = require('debounce')
-const copyToClipboard = require('copy-to-clipboard')
-const ENS = require('ethjs-ens')
-const networkMap = require('ethjs-ens/lib/network-map.json')
-const ensRE = /.+\.eth$/
-const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
-
-
-module.exports = EnsInput
-
-inherits(EnsInput, Component)
-function EnsInput () {
- Component.call(this)
-}
-
-EnsInput.prototype.render = function () {
- const props = this.props
- const opts = extend(props, {
- list: 'addresses',
- onChange: () => {
- const network = this.props.network
- const networkHasEnsSupport = getNetworkEnsSupport(network)
- if (!networkHasEnsSupport) return
-
- const recipient = document.querySelector('input[name="address"]').value
- if (recipient.match(ensRE) === null) {
- return this.setState({
- loadingEns: false,
- ensResolution: null,
- ensFailure: null,
- })
- }
-
- this.setState({
- loadingEns: true,
- })
- this.checkName()
- },
- })
- return h('div', {
- style: { width: '100%' },
- }, [
- h('input.large-input', opts),
- // The address book functionality.
- h('datalist#addresses',
- [
- // Corresponds to the addresses owned.
- Object.keys(props.identities).map((key) => {
- const identity = props.identities[key]
- return h('option', {
- value: identity.address,
- label: identity.name,
- key: identity.address,
- })
- }),
- // Corresponds to previously sent-to addresses.
- props.addressBook.map((identity) => {
- return h('option', {
- value: identity.address,
- label: identity.name,
- key: identity.address,
- })
- }),
- ]),
- this.ensIcon(),
- ])
-}
-
-EnsInput.prototype.componentDidMount = function () {
- const network = this.props.network
- const networkHasEnsSupport = getNetworkEnsSupport(network)
- this.setState({ ensResolution: ZERO_ADDRESS })
-
- if (networkHasEnsSupport) {
- const provider = global.ethereumProvider
- this.ens = new ENS({ provider, network })
- this.checkName = debounce(this.lookupEnsName.bind(this), 200)
- }
-}
-
-EnsInput.prototype.lookupEnsName = function () {
- const recipient = document.querySelector('input[name="address"]').value
- const { ensResolution } = this.state
-
- log.info(`ENS attempting to resolve name: ${recipient}`)
- this.ens.lookup(recipient.trim())
- .then((address) => {
- if (address === ZERO_ADDRESS) throw new Error('No address has been set for this name.')
- if (address !== ensResolution) {
- this.setState({
- loadingEns: false,
- ensResolution: address,
- nickname: recipient.trim(),
- hoverText: address + '\nClick to Copy',
- ensFailure: false,
- })
- }
- })
- .catch((reason) => {
- log.error(reason)
- return this.setState({
- loadingEns: false,
- ensResolution: ZERO_ADDRESS,
- ensFailure: true,
- hoverText: reason.message,
- })
- })
-}
-
-EnsInput.prototype.componentDidUpdate = function (prevProps, prevState) {
- const state = this.state || {}
- const ensResolution = state.ensResolution
- // If an address is sent without a nickname, meaning not from ENS or from
- // the user's own accounts, a default of a one-space string is used.
- const nickname = state.nickname || ' '
- if (prevState && ensResolution && this.props.onChange &&
- ensResolution !== prevState.ensResolution) {
- this.props.onChange(ensResolution, nickname)
- }
-}
-
-EnsInput.prototype.ensIcon = function (recipient) {
- const { hoverText } = this.state || {}
- return h('span', {
- title: hoverText,
- style: {
- position: 'absolute',
- padding: '9px',
- transform: 'translatex(-40px)',
- },
- }, this.ensIconContents(recipient))
-}
-
-EnsInput.prototype.ensIconContents = function (recipient) {
- const { loadingEns, ensFailure, ensResolution } = this.state || { ensResolution: ZERO_ADDRESS}
-
- if (loadingEns) {
- return h('img', {
- src: 'images/loading.svg',
- style: {
- width: '30px',
- height: '30px',
- transform: 'translateY(-6px)',
- },
- })
- }
-
- if (ensFailure) {
- return h('i.fa.fa-warning.fa-lg.warning')
- }
-
- if (ensResolution && (ensResolution !== ZERO_ADDRESS)) {
- return h('i.fa.fa-check-circle.fa-lg.cursor-pointer', {
- style: { color: 'green' },
- onClick: (event) => {
- event.preventDefault()
- event.stopPropagation()
- copyToClipboard(ensResolution)
- },
- })
- }
-}
-
-function getNetworkEnsSupport (network) {
- return Boolean(networkMap[network])
-}
diff --git a/responsive-ui/app/components/eth-balance.js b/responsive-ui/app/components/eth-balance.js
deleted file mode 100644
index 4f538fd31..000000000
--- a/responsive-ui/app/components/eth-balance.js
+++ /dev/null
@@ -1,89 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const formatBalance = require('../util').formatBalance
-const generateBalanceObject = require('../util').generateBalanceObject
-const Tooltip = require('./tooltip.js')
-const FiatValue = require('./fiat-value.js')
-
-module.exports = EthBalanceComponent
-
-inherits(EthBalanceComponent, Component)
-function EthBalanceComponent () {
- Component.call(this)
-}
-
-EthBalanceComponent.prototype.render = function () {
- var props = this.props
- let { value } = props
- const { style, width } = props
- var needsParse = this.props.needsParse !== undefined ? this.props.needsParse : true
- value = value ? formatBalance(value, 6, needsParse) : '...'
-
- return (
-
- h('.ether-balance.ether-balance-amount', {
- style,
- }, [
- h('div', {
- style: {
- display: 'inline',
- width,
- },
- }, this.renderBalance(value)),
- ])
-
- )
-}
-EthBalanceComponent.prototype.renderBalance = function (value) {
- var props = this.props
- const { conversionRate, shorten, incoming, currentCurrency } = props
- if (value === 'None') return value
- if (value === '...') return value
- var balanceObj = generateBalanceObject(value, shorten ? 1 : 3)
- var balance
- var splitBalance = value.split(' ')
- var ethNumber = splitBalance[0]
- var ethSuffix = splitBalance[1]
- const showFiat = 'showFiat' in props ? props.showFiat : true
-
- if (shorten) {
- balance = balanceObj.shortBalance
- } else {
- balance = balanceObj.balance
- }
-
- var label = balanceObj.label
-
- return (
- h(Tooltip, {
- position: 'bottom',
- title: `${ethNumber} ${ethSuffix}`,
- }, h('div.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('div', {
- style: {
- width: '100%',
- textAlign: 'right',
- },
- }, incoming ? `+${balance}` : balance),
- h('div', {
- style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
- },
- }, label),
- ]),
-
- showFiat ? h(FiatValue, { value: props.value, conversionRate, currentCurrency }) : null,
- ]))
- )
-}
diff --git a/responsive-ui/app/components/fiat-value.js b/responsive-ui/app/components/fiat-value.js
deleted file mode 100644
index 8a64a1cfc..000000000
--- a/responsive-ui/app/components/fiat-value.js
+++ /dev/null
@@ -1,63 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const formatBalance = require('../util').formatBalance
-
-module.exports = FiatValue
-
-inherits(FiatValue, Component)
-function FiatValue () {
- Component.call(this)
-}
-
-FiatValue.prototype.render = function () {
- const props = this.props
- const { conversionRate, currentCurrency } = props
-
- const value = formatBalance(props.value, 6)
-
- if (value === 'None') return value
- var fiatDisplayNumber, fiatTooltipNumber
- var splitBalance = value.split(' ')
-
- if (conversionRate !== 0) {
- fiatTooltipNumber = Number(splitBalance[0]) * conversionRate
- fiatDisplayNumber = fiatTooltipNumber.toFixed(2)
- } else {
- fiatDisplayNumber = 'N/A'
- fiatTooltipNumber = 'Unknown'
- }
-
- return fiatDisplay(fiatDisplayNumber, currentCurrency)
-}
-
-function fiatDisplay (fiatDisplayNumber, fiatSuffix) {
- if (fiatDisplayNumber !== 'N/A') {
- return h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('div', {
- style: {
- width: '100%',
- textAlign: 'right',
- fontSize: '12px',
- color: '#333333',
- },
- }, fiatDisplayNumber),
- h('div', {
- style: {
- color: '#AEAEAE',
- marginLeft: '5px',
- fontSize: '12px',
- },
- }, fiatSuffix),
- ])
- } else {
- return h('div')
- }
-}
diff --git a/responsive-ui/app/components/hex-as-decimal-input.js b/responsive-ui/app/components/hex-as-decimal-input.js
deleted file mode 100644
index 4a71e9585..000000000
--- a/responsive-ui/app/components/hex-as-decimal-input.js
+++ /dev/null
@@ -1,154 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
-const extend = require('xtend')
-
-module.exports = HexAsDecimalInput
-
-inherits(HexAsDecimalInput, Component)
-function HexAsDecimalInput () {
- this.state = { invalid: null }
- Component.call(this)
-}
-
-/* Hex as Decimal Input
- *
- * A component for allowing easy, decimal editing
- * of a passed in hex string value.
- *
- * On change, calls back its `onChange` function parameter
- * and passes it an updated hex string.
- */
-
-HexAsDecimalInput.prototype.render = function () {
- const props = this.props
- const state = this.state
-
- const { value, onChange, min, max } = props
-
- const toEth = props.toEth
- const suffix = props.suffix
- const decimalValue = decimalize(value, toEth)
- const style = props.style
-
- return (
- h('.flex-column', [
- h('.flex-row', {
- style: {
- alignItems: 'flex-end',
- lineHeight: '13px',
- fontFamily: 'Montserrat Light',
- textRendering: 'geometricPrecision',
- },
- }, [
- h('input.hex-input', {
- type: 'number',
- required: true,
- min: min,
- max: max,
- style: extend({
- display: 'block',
- textAlign: 'right',
- backgroundColor: 'transparent',
- border: '1px solid #bdbdbd',
-
- }, style),
- value: parseInt(decimalValue),
- onBlur: (event) => {
- this.updateValidity(event)
- },
- onChange: (event) => {
- this.updateValidity(event)
- const hexString = (event.target.value === '') ? '' : hexify(event.target.value)
- onChange(hexString)
- },
- onInvalid: (event) => {
- const msg = this.constructWarning()
- if (msg === state.invalid) {
- return
- }
- this.setState({ invalid: msg })
- event.preventDefault()
- return false
- },
- }),
- h('div', {
- style: {
- color: ' #AEAEAE',
- fontSize: '12px',
- marginLeft: '5px',
- marginRight: '6px',
- width: '20px',
- },
- }, suffix),
- ]),
-
- state.invalid ? h('span.error', {
- style: {
- position: 'absolute',
- right: '0px',
- textAlign: 'right',
- transform: 'translateY(26px)',
- padding: '3px',
- background: 'rgba(255,255,255,0.85)',
- zIndex: '1',
- textTransform: 'capitalize',
- border: '2px solid #E20202',
- },
- }, state.invalid) : null,
- ])
- )
-}
-
-HexAsDecimalInput.prototype.setValid = function (message) {
- this.setState({ invalid: null })
-}
-
-HexAsDecimalInput.prototype.updateValidity = function (event) {
- const target = event.target
- const value = this.props.value
- const newValue = target.value
-
- if (value === newValue) {
- return
- }
-
- const valid = target.checkValidity()
- if (valid) {
- this.setState({ invalid: null })
- }
-}
-
-HexAsDecimalInput.prototype.constructWarning = function () {
- const { name, min, max } = this.props
- let message = name ? name + ' ' : ''
-
- if (min && max) {
- message += `must be greater than or equal to ${min} and less than or equal to ${max}.`
- } else if (min) {
- message += `must be greater than or equal to ${min}.`
- } else if (max) {
- message += `must be less than or equal to ${max}.`
- } else {
- message += 'Invalid input.'
- }
-
- return message
-}
-
-function hexify (decimalString) {
- const hexBN = new BN(parseInt(decimalString), 10)
- return '0x' + hexBN.toString('hex')
-}
-
-function decimalize (input, toEth) {
- if (input === '') {
- return ''
- } else {
- const strippedInput = ethUtil.stripHexPrefix(input)
- const inputBN = new BN(strippedInput, 'hex')
- return inputBN.toString(10)
- }
-}
diff --git a/responsive-ui/app/components/identicon.js b/responsive-ui/app/components/identicon.js
deleted file mode 100644
index c754bc6ba..000000000
--- a/responsive-ui/app/components/identicon.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const isNode = require('detect-node')
-const findDOMNode = require('react-dom').findDOMNode
-const jazzicon = require('jazzicon')
-const iconFactoryGen = require('../../lib/icon-factory')
-const iconFactory = iconFactoryGen(jazzicon)
-
-module.exports = IdenticonComponent
-
-inherits(IdenticonComponent, Component)
-function IdenticonComponent () {
- Component.call(this)
-
- this.defaultDiameter = 46
-}
-
-IdenticonComponent.prototype.render = function () {
- var props = this.props
- var diameter = props.diameter || this.defaultDiameter
- return (
- h('div', {
- key: 'identicon-' + this.props.address,
- style: {
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- height: diameter,
- width: diameter,
- borderRadius: diameter / 2,
- overflow: 'hidden',
- },
- })
- )
-}
-
-IdenticonComponent.prototype.componentDidMount = function () {
- var props = this.props
- const { address } = props
-
- if (!address) return
-
- var container = findDOMNode(this)
-
- var diameter = props.diameter || this.defaultDiameter
- if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter)
- container.appendChild(img)
- }
-}
-
-IdenticonComponent.prototype.componentDidUpdate = function () {
- var props = this.props
- const { address } = props
-
- if (!address) return
-
- var container = findDOMNode(this)
-
- var children = container.children
- for (var i = 0; i < children.length; i++) {
- container.removeChild(children[i])
- }
-
- var diameter = props.diameter || this.defaultDiameter
- if (!isNode) {
- var img = iconFactory.iconForAddress(address, diameter)
- container.appendChild(img)
- }
-}
-
diff --git a/responsive-ui/app/components/loading.js b/responsive-ui/app/components/loading.js
deleted file mode 100644
index 87d6f5d20..000000000
--- a/responsive-ui/app/components/loading.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
-
-
-inherits(LoadingIndicator, Component)
-module.exports = LoadingIndicator
-
-function LoadingIndicator () {
- Component.call(this)
-}
-
-LoadingIndicator.prototype.render = function () {
- const { isLoading, loadingMessage } = this.props
-
- return (
- h(ReactCSSTransitionGroup, {
- className: 'css-transition-group',
- transitionName: 'loader',
- transitionEnterTimeout: 150,
- transitionLeaveTimeout: 150,
- }, [
-
- isLoading ? h('div', {
- style: {
- zIndex: 10,
- position: 'absolute',
- flexDirection: 'column',
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- height: '100%',
- width: '100%',
- background: 'rgba(255, 255, 255, 0.8)',
- },
- }, [
- h('img', {
- src: 'images/loading.svg',
- }),
-
- h('br'),
-
- showMessageIfAny(loadingMessage),
- ]) : null,
- ])
- )
-}
-
-function showMessageIfAny (loadingMessage) {
- if (!loadingMessage) return null
- return h('span', loadingMessage)
-}
diff --git a/responsive-ui/app/components/mascot.js b/responsive-ui/app/components/mascot.js
deleted file mode 100644
index 973ec2cad..000000000
--- a/responsive-ui/app/components/mascot.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const metamaskLogo = require('metamask-logo')
-const debounce = require('debounce')
-
-module.exports = Mascot
-
-inherits(Mascot, Component)
-function Mascot () {
- Component.call(this)
- this.logo = metamaskLogo({
- followMouse: true,
- pxNotRatio: true,
- width: 200,
- height: 200,
- })
-
- this.refollowMouse = debounce(this.logo.setFollowMouse.bind(this.logo, true), 1000)
- this.unfollowMouse = this.logo.setFollowMouse.bind(this.logo, false)
-}
-
-Mascot.prototype.render = function () {
- // this is a bit hacky
- // the event emitter is on `this.props`
- // and we dont get that until render
- this.handleAnimationEvents()
-
- return h('#metamask-mascot-container', {
- style: { zIndex: 0 },
- })
-}
-
-Mascot.prototype.componentDidMount = function () {
- var targetDivId = 'metamask-mascot-container'
- var container = document.getElementById(targetDivId)
- container.appendChild(this.logo.container)
-}
-
-Mascot.prototype.componentWillUnmount = function () {
- this.animations = this.props.animationEventEmitter
- this.animations.removeAllListeners()
- this.logo.container.remove()
- this.logo.stopAnimation()
-}
-
-Mascot.prototype.handleAnimationEvents = function () {
- // only setup listeners once
- if (this.animations) return
- this.animations = this.props.animationEventEmitter
- this.animations.on('point', this.lookAt.bind(this))
- this.animations.on('setFollowMouse', this.logo.setFollowMouse.bind(this.logo))
-}
-
-Mascot.prototype.lookAt = function (target) {
- this.unfollowMouse()
- this.logo.lookAt(target)
- this.refollowMouse()
-}
diff --git a/responsive-ui/app/components/mini-account-panel.js b/responsive-ui/app/components/mini-account-panel.js
deleted file mode 100644
index c09cf5b7a..000000000
--- a/responsive-ui/app/components/mini-account-panel.js
+++ /dev/null
@@ -1,74 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const Identicon = require('./identicon')
-
-module.exports = AccountPanel
-
-
-inherits(AccountPanel, Component)
-function AccountPanel () {
- Component.call(this)
-}
-
-AccountPanel.prototype.render = function () {
- var props = this.props
- var picOrder = props.picOrder || 'left'
- const { imageSeed } = props
-
- return (
-
- h('.identity-panel.flex-row.flex-left', {
- style: {
- cursor: props.onClick ? 'pointer' : undefined,
- },
- onClick: props.onClick,
- }, [
-
- this.genIcon(imageSeed, picOrder),
-
- h('div.flex-column.flex-justify-center', {
- style: {
- lineHeight: '15px',
- order: 2,
- display: 'flex',
- alignItems: picOrder === 'left' ? 'flex-begin' : 'flex-end',
- },
- }, this.props.children),
- ])
- )
-}
-
-AccountPanel.prototype.genIcon = function (seed, picOrder) {
- const props = this.props
-
- // When there is no seed value, this is a contract creation.
- // We then show the contract icon.
- if (!seed) {
- return h('.identicon-wrapper.flex-column.select-none', {
- style: {
- order: picOrder === 'left' ? 1 : 3,
- },
- }, [
- h('i.fa.fa-file-text-o.fa-lg', {
- style: {
- fontSize: '42px',
- transform: 'translate(0px, -16px)',
- },
- }),
- ])
- }
-
- // If there was a seed, we return an identicon for that address.
- return h('.identicon-wrapper.flex-column.select-none', {
- style: {
- order: picOrder === 'left' ? 1 : 3,
- },
- }, [
- h(Identicon, {
- address: seed,
- imageify: props.imageifyIdenticons,
- }),
- ])
-}
-
diff --git a/responsive-ui/app/components/network.js b/responsive-ui/app/components/network.js
deleted file mode 100644
index 698a0bbb9..000000000
--- a/responsive-ui/app/components/network.js
+++ /dev/null
@@ -1,124 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = Network
-
-inherits(Network, Component)
-
-function Network () {
- Component.call(this)
-}
-
-Network.prototype.render = function () {
- const props = this.props
- const networkNumber = props.network
- let providerName
- try {
- providerName = props.provider.type
- } catch (e) {
- providerName = null
- }
- let iconName, hoverText
-
- if (networkNumber === 'loading') {
- return h('span', {
- style: {
- display: 'flex',
- alignItems: 'center',
- flexDirection: 'row',
- },
- onClick: (event) => this.props.onClick(event),
- }, [
- h('img', {
- title: 'Attempting to connect to blockchain.',
- style: {
- width: '27px',
- },
- src: 'images/loading.svg',
- }),
- h('i.fa.fa-sort-desc'),
- ])
- } else if (providerName === 'mainnet') {
- hoverText = 'Main Ethereum Network'
- iconName = 'ethereum-network'
- } else if (providerName === 'ropsten') {
- hoverText = 'Ropsten Test Network'
- iconName = 'ropsten-test-network'
- } else if (parseInt(networkNumber) === 3) {
- hoverText = 'Ropsten Test Network'
- iconName = 'ropsten-test-network'
- } else if (providerName === 'kovan') {
- hoverText = 'Kovan Test Network'
- iconName = 'kovan-test-network'
- } else if (providerName === 'rinkeby') {
- hoverText = 'Rinkeby Test Network'
- iconName = 'rinkeby-test-network'
- } else {
- hoverText = 'Unknown Private Network'
- iconName = 'unknown-private-network'
- }
-
- return (
- h('#network_component.pointer', {
- title: hoverText,
- onClick: (event) => this.props.onClick(event),
- }, [
- (function () {
- switch (iconName) {
- case 'ethereum-network':
- return h('.network-indicator', [
- h('.menu-icon.diamond'),
- h('.network-name', {
- style: {
- color: '#039396',
- }},
- 'Ethereum Main Net'),
- ])
- case 'ropsten-test-network':
- return h('.network-indicator', [
- h('.menu-icon.red-dot'),
- h('.network-name', {
- style: {
- color: '#ff6666',
- }},
- 'Ropsten Test Net'),
- ])
- case 'kovan-test-network':
- return h('.network-indicator', [
- h('.menu-icon.hollow-diamond'),
- h('.network-name', {
- style: {
- color: '#690496',
- }},
- 'Kovan Test Net'),
- ])
- case 'rinkeby-test-network':
- return h('.network-indicator', [
- h('.menu-icon.golden-square'),
- h('.network-name', {
- style: {
- color: '#e7a218',
- }},
- 'Rinkeby Test Net'),
- ])
- default:
- return h('.network-indicator', [
- h('i.fa.fa-question-circle.fa-lg', {
- style: {
- margin: '10px',
- color: 'rgb(125, 128, 130)',
- },
- }),
-
- h('.network-name', {
- style: {
- color: '#AEAEAE',
- }},
- 'Private Network'),
- ])
- }
- })(),
- ])
- )
-}
diff --git a/responsive-ui/app/components/notice.js b/responsive-ui/app/components/notice.js
deleted file mode 100644
index d9f0067cd..000000000
--- a/responsive-ui/app/components/notice.js
+++ /dev/null
@@ -1,126 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const ReactMarkdown = require('react-markdown')
-const linker = require('extension-link-enabler')
-const findDOMNode = require('react-dom').findDOMNode
-
-module.exports = Notice
-
-inherits(Notice, Component)
-function Notice () {
- Component.call(this)
-}
-
-Notice.prototype.render = function () {
- const { notice, onConfirm } = this.props
- const { title, date, body } = notice
- const state = this.state || { disclaimerDisabled: true }
- const disabled = state.disclaimerDisabled
-
- return (
- h('.flex-column.flex-center.flex-grow', [
- h('h3.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- title,
- ]),
-
- h('h5.flex-center.text-transform-uppercase.terms-header', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- textAlign: 'center',
- padding: 6,
- },
- }, [
- date,
- ]),
-
- h('style', `
-
- .markdown {
- overflow-x: hidden;
- }
-
- .markdown h1, .markdown h2, .markdown h3 {
- margin: 10px 0;
- font-weight: bold;
- }
-
- .markdown strong {
- font-weight: bold;
- }
- .markdown em {
- font-style: italic;
- }
-
- .markdown p {
- margin: 10px 0;
- }
-
- .markdown a {
- color: #df6b0e;
- }
-
- `),
-
- h('div.markdown', {
- onScroll: (e) => {
- var object = e.currentTarget
- if (object.offsetHeight + object.scrollTop + 100 >= object.scrollHeight) {
- this.setState({disclaimerDisabled: false})
- }
- },
- style: {
- background: 'rgb(235, 235, 235)',
- height: '310px',
- padding: '6px',
- width: '90%',
- overflowY: 'scroll',
- scroll: 'auto',
- },
- }, [
- h(ReactMarkdown, {
- className: 'notice-box',
- source: body,
- skipHtml: true,
- }),
- ]),
-
- h('button', {
- disabled,
- onClick: () => {
- this.setState({disclaimerDisabled: true})
- onConfirm()
- },
- style: {
- marginTop: '18px',
- },
- }, 'Accept'),
- ])
- )
-}
-
-Notice.prototype.componentDidMount = function () {
- var node = findDOMNode(this)
- linker.setupListener(node)
- if (document.getElementsByClassName('notice-box')[0].clientHeight < 310) {
- this.setState({disclaimerDisabled: false})
- }
-}
-
-Notice.prototype.componentWillUnmount = function () {
- var node = findDOMNode(this)
- linker.teardownListener(node)
-}
diff --git a/responsive-ui/app/components/pending-msg-details.js b/responsive-ui/app/components/pending-msg-details.js
deleted file mode 100644
index 16308d121..000000000
--- a/responsive-ui/app/components/pending-msg-details.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const AccountPanel = require('./account-panel')
-
-module.exports = PendingMsgDetails
-
-inherits(PendingMsgDetails, Component)
-function PendingMsgDetails () {
- Component.call(this)
-}
-
-PendingMsgDetails.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAddress
- var identity = state.identities[address] || { address: address }
- var account = state.accounts[address] || { address: address }
-
- return (
- h('div', {
- key: msgData.id,
- style: {
- margin: '10px 20px',
- },
- }, [
-
- // account that will sign
- h(AccountPanel, {
- showFullAddress: true,
- identity: identity,
- account: account,
- imageifyIdenticons: state.imageifyIdenticons,
- }),
-
- // message data
- h('.tx-data.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-row.flex-space-between', [
- h('label.font-small', 'MESSAGE'),
- h('span.font-small', msgParams.data),
- ]),
- ]),
-
- ])
- )
-}
-
diff --git a/responsive-ui/app/components/pending-msg.js b/responsive-ui/app/components/pending-msg.js
deleted file mode 100644
index b2cac164a..000000000
--- a/responsive-ui/app/components/pending-msg.js
+++ /dev/null
@@ -1,56 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const PendingTxDetails = require('./pending-msg-details')
-
-module.exports = PendingMsg
-
-inherits(PendingMsg, Component)
-function PendingMsg () {
- Component.call(this)
-}
-
-PendingMsg.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- return (
-
- h('div', {
- key: msgData.id,
- }, [
-
- // header
- h('h3', {
- style: {
- fontWeight: 'bold',
- textAlign: 'center',
- },
- }, 'Sign Message'),
-
- h('.error', {
- style: {
- margin: '10px',
- },
- }, `Signing this message can have
- dangerous side effects. Only sign messages from
- sites you fully trust with your entire account.
- This will be fixed in a future version.`),
-
- // message details
- h(PendingTxDetails, state),
-
- // sign + cancel
- h('.flex-row.flex-space-around', [
- h('button', {
- onClick: state.cancelMessage,
- }, 'Cancel'),
- h('button', {
- onClick: state.signMessage,
- }, 'Sign'),
- ]),
- ])
-
- )
-}
-
diff --git a/responsive-ui/app/components/pending-personal-msg-details.js b/responsive-ui/app/components/pending-personal-msg-details.js
deleted file mode 100644
index 1050513f2..000000000
--- a/responsive-ui/app/components/pending-personal-msg-details.js
+++ /dev/null
@@ -1,60 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const AccountPanel = require('./account-panel')
-const BinaryRenderer = require('./binary-renderer')
-
-module.exports = PendingMsgDetails
-
-inherits(PendingMsgDetails, Component)
-function PendingMsgDetails () {
- Component.call(this)
-}
-
-PendingMsgDetails.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- var msgParams = msgData.msgParams || {}
- var address = msgParams.from || state.selectedAddress
- var identity = state.identities[address] || { address: address }
- var account = state.accounts[address] || { address: address }
-
- var { data } = msgParams
-
- return (
- h('div', {
- key: msgData.id,
- style: {
- margin: '10px 20px',
- },
- }, [
-
- // account that will sign
- h(AccountPanel, {
- showFullAddress: true,
- identity: identity,
- account: account,
- imageifyIdenticons: state.imageifyIdenticons,
- }),
-
- // message data
- h('div', {
- style: {
- height: '260px',
- },
- }, [
- h('label.font-small', { style: { display: 'block' } }, 'MESSAGE'),
- h(BinaryRenderer, {
- value: data,
- style: {
- height: '215px',
- },
- }),
- ]),
-
- ])
- )
-}
-
diff --git a/responsive-ui/app/components/pending-personal-msg.js b/responsive-ui/app/components/pending-personal-msg.js
deleted file mode 100644
index 4542adb28..000000000
--- a/responsive-ui/app/components/pending-personal-msg.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const PendingTxDetails = require('./pending-personal-msg-details')
-
-module.exports = PendingMsg
-
-inherits(PendingMsg, Component)
-function PendingMsg () {
- Component.call(this)
-}
-
-PendingMsg.prototype.render = function () {
- var state = this.props
- var msgData = state.txData
-
- return (
-
- h('div', {
- key: msgData.id,
- }, [
-
- // header
- h('h3', {
- style: {
- fontWeight: 'bold',
- textAlign: 'center',
- },
- }, 'Sign Message'),
-
- // message details
- h(PendingTxDetails, state),
-
- // sign + cancel
- h('.flex-row.flex-space-around', [
- h('button', {
- onClick: state.cancelPersonalMessage,
- }, 'Cancel'),
- h('button', {
- onClick: state.signPersonalMessage,
- }, 'Sign'),
- ]),
- ])
-
- )
-}
-
diff --git a/responsive-ui/app/components/pending-tx.js b/responsive-ui/app/components/pending-tx.js
deleted file mode 100644
index d7d602f31..000000000
--- a/responsive-ui/app/components/pending-tx.js
+++ /dev/null
@@ -1,480 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const actions = require('../actions')
-const clone = require('clone')
-
-const ethUtil = require('ethereumjs-util')
-const BN = ethUtil.BN
-const hexToBn = require('../../../app/scripts/lib/hex-to-bn')
-const util = require('../util')
-const MiniAccountPanel = require('./mini-account-panel')
-const Copyable = require('./copyable')
-const EthBalance = require('./eth-balance')
-const addressSummary = util.addressSummary
-const nameForAddress = require('../../lib/contract-namer')
-const BNInput = require('./bn-as-decimal-input')
-
-const MIN_GAS_PRICE_GWEI_BN = new BN(2)
-const GWEI_FACTOR = new BN(1e9)
-const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR)
-const MIN_GAS_LIMIT_BN = new BN(21000)
-
-module.exports = PendingTx
-inherits(PendingTx, Component)
-function PendingTx () {
- Component.call(this)
- this.state = {
- valid: true,
- txData: null,
- submitting: false,
- }
-}
-
-PendingTx.prototype.render = function () {
- const props = this.props
- const { currentCurrency, blockGasLimit } = props
-
- const conversionRate = props.conversionRate
- const txMeta = this.gatherTxMeta()
- const txParams = txMeta.txParams || {}
-
- // Account Details
- const address = txParams.from || props.selectedAddress
- const identity = props.identities[address] || { address: address }
- const account = props.accounts[address]
- const balance = account ? account.balance : '0x0'
-
- // recipient check
- const isValidAddress = !txParams.to || util.isValidAddress(txParams.to)
-
- // Gas
- const gas = txParams.gas
- const gasBn = hexToBn(gas)
- const gasLimit = new BN(parseInt(blockGasLimit))
- const safeGasLimit = this.bnMultiplyByFraction(gasLimit, 19, 20).toString(10)
-
- // Gas Price
- const gasPrice = txParams.gasPrice || MIN_GAS_PRICE_BN.toString(16)
- const gasPriceBn = hexToBn(gasPrice)
-
- const txFeeBn = gasBn.mul(gasPriceBn)
- const valueBn = hexToBn(txParams.value)
- const maxCost = txFeeBn.add(valueBn)
-
- const dataLength = txParams.data ? (txParams.data.length - 2) / 2 : 0
-
- const balanceBn = hexToBn(balance)
- const insufficientBalance = balanceBn.lt(maxCost)
-
- this.inputs = []
-
- return (
-
- h('div', {
- key: txMeta.id,
- }, [
-
- h('form#pending-tx-form', {
- onSubmit: this.onSubmit.bind(this),
-
- }, [
-
- // tx info
- h('div', [
-
- h('.flex-row.flex-center', {
- style: {
- maxWidth: '100%',
- },
- }, [
-
- h(MiniAccountPanel, {
- imageSeed: address,
- picOrder: 'right',
- }, [
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Bold, Montserrat, sans-serif',
- },
- }, identity.name),
-
- h(Copyable, {
- value: ethUtil.toChecksumAddress(address),
- }, [
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Light, Montserrat, sans-serif',
- },
- }, addressSummary(address, 6, 4, false)),
- ]),
-
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Light, Montserrat, sans-serif',
- },
- }, [
- h(EthBalance, {
- value: balance,
- conversionRate,
- currentCurrency,
- inline: true,
- labelColor: '#F7861C',
- }),
- ]),
- ]),
-
- forwardCarrat(),
-
- this.miniAccountPanelForRecipient(),
- ]),
-
- h('style', `
- .table-box {
- margin: 7px 0px 0px 0px;
- width: 100%;
- }
- .table-box .row {
- margin: 0px;
- background: rgb(236,236,236);
- display: flex;
- justify-content: space-between;
- font-family: Montserrat Light, sans-serif;
- font-size: 13px;
- padding: 5px 25px;
- }
- .table-box .row .value {
- font-family: Montserrat Regular;
- }
- `),
-
- h('.table-box', [
-
- // Ether Value
- // Currently not customizable, but easily modified
- // in the way that gas and gasLimit currently are.
- h('.row', [
- h('.cell.label', 'Amount'),
- h(EthBalance, { value: txParams.value, currentCurrency, conversionRate }),
- ]),
-
- // Gas Limit (customizable)
- h('.cell.row', [
- h('.cell.label', 'Gas Limit'),
- h('.cell.value', {
- }, [
- h(BNInput, {
- name: 'Gas Limit',
- value: gasBn,
- precision: 0,
- scale: 0,
- // The hard lower limit for gas.
- min: MIN_GAS_LIMIT_BN.toString(10),
- max: safeGasLimit,
- suffix: 'UNITS',
- style: {
- position: 'relative',
- top: '5px',
- },
- onChange: this.gasLimitChanged.bind(this),
-
- ref: (hexInput) => { this.inputs.push(hexInput) },
- }),
- ]),
- ]),
-
- // Gas Price (customizable)
- h('.cell.row', [
- h('.cell.label', 'Gas Price'),
- h('.cell.value', {
- }, [
- h(BNInput, {
- name: 'Gas Price',
- value: gasPriceBn,
- precision: 9,
- scale: 9,
- suffix: 'GWEI',
- min: MIN_GAS_PRICE_GWEI_BN.toString(10),
- style: {
- position: 'relative',
- top: '5px',
- },
- onChange: this.gasPriceChanged.bind(this),
- ref: (hexInput) => { this.inputs.push(hexInput) },
- }),
- ]),
- ]),
-
- // Max Transaction Fee (calculated)
- h('.cell.row', [
- h('.cell.label', 'Max Transaction Fee'),
- h(EthBalance, { value: txFeeBn.toString(16), currentCurrency, conversionRate }),
- ]),
-
- h('.cell.row', {
- style: {
- fontFamily: 'Montserrat Regular',
- background: 'white',
- padding: '10px 25px',
- },
- }, [
- h('.cell.label', 'Max Total'),
- h('.cell.value', {
- style: {
- display: 'flex',
- alignItems: 'center',
- },
- }, [
- h(EthBalance, {
- value: maxCost.toString(16),
- currentCurrency,
- conversionRate,
- inline: true,
- labelColor: 'black',
- fontSize: '16px',
- }),
- ]),
- ]),
-
- // Data size row:
- h('.cell.row', {
- style: {
- background: '#f7f7f7',
- paddingBottom: '0px',
- },
- }, [
- h('.cell.label'),
- h('.cell.value', {
- style: {
- fontFamily: 'Montserrat Light',
- fontSize: '11px',
- },
- }, `Data included: ${dataLength} bytes`),
- ]),
- ]), // End of Table
-
- ]),
-
- h('style', `
- .conf-buttons button {
- margin-left: 10px;
- text-transform: uppercase;
- }
- `),
-
- txMeta.simulationFails ?
- h('.error', {
- style: {
- marginLeft: 50,
- fontSize: '0.9em',
- },
- }, 'Transaction Error. Exception thrown in contract code.')
- : null,
-
- !isValidAddress ?
- h('.error', {
- style: {
- marginLeft: 50,
- fontSize: '0.9em',
- },
- }, 'Recipient address is invalid. Sending this transaction will result in a loss of ETH.')
- : null,
-
- insufficientBalance ?
- h('span.error', {
- style: {
- marginLeft: 50,
- fontSize: '0.9em',
- },
- }, 'Insufficient balance for transaction')
- : null,
-
- // send + cancel
- h('.flex-row.flex-space-around.conf-buttons', {
- style: {
- display: 'flex',
- justifyContent: 'flex-end',
- margin: '14px 25px',
- },
- }, [
-
-
- insufficientBalance ?
- h('button.btn-green', {
- onClick: props.buyEth,
- }, 'Buy Ether')
- : null,
-
- h('button', {
- onClick: (event) => {
- this.resetGasFields()
- event.preventDefault()
- },
- }, 'Reset'),
-
- // Accept Button
- h('input.confirm.btn-green', {
- type: 'submit',
- value: 'SUBMIT',
- style: { marginLeft: '10px' },
- disabled: insufficientBalance || !this.state.valid || !isValidAddress || this.state.submitting,
- }),
-
- h('button.cancel.btn-red', {
- onClick: props.cancelTransaction,
- }, 'Reject'),
- ]),
- ]),
- ])
- )
-}
-
-PendingTx.prototype.miniAccountPanelForRecipient = function () {
- const props = this.props
- const txData = props.txData
- const txParams = txData.txParams || {}
- const isContractDeploy = !('to' in txParams)
-
- // If it's not a contract deploy, send to the account
- if (!isContractDeploy) {
- return h(MiniAccountPanel, {
- imageSeed: txParams.to,
- picOrder: 'left',
- }, [
-
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Bold, Montserrat, sans-serif',
- },
- }, nameForAddress(txParams.to, props.identities)),
-
- h(Copyable, {
- value: ethUtil.toChecksumAddress(txParams.to),
- }, [
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Light, Montserrat, sans-serif',
- },
- }, addressSummary(txParams.to, 6, 4, false)),
- ]),
-
- ])
- } else {
- return h(MiniAccountPanel, {
- picOrder: 'left',
- }, [
-
- h('span.font-small', {
- style: {
- fontFamily: 'Montserrat Bold, Montserrat, sans-serif',
- },
- }, 'New Contract'),
-
- ])
- }
-}
-
-PendingTx.prototype.gasPriceChanged = function (newBN, valid) {
- log.info(`Gas price changed to: ${newBN.toString(10)}`)
- const txMeta = this.gatherTxMeta()
- txMeta.txParams.gasPrice = '0x' + newBN.toString('hex')
- this.setState({
- txData: clone(txMeta),
- valid,
- })
-}
-
-PendingTx.prototype.gasLimitChanged = function (newBN, valid) {
- log.info(`Gas limit changed to ${newBN.toString(10)}`)
- const txMeta = this.gatherTxMeta()
- txMeta.txParams.gas = '0x' + newBN.toString('hex')
- this.setState({
- txData: clone(txMeta),
- valid,
- })
-}
-
-PendingTx.prototype.resetGasFields = function () {
- log.debug(`pending-tx resetGasFields`)
-
- this.inputs.forEach((hexInput) => {
- if (hexInput) {
- hexInput.setValid()
- }
- })
-
- this.setState({
- txData: null,
- valid: true,
- })
-}
-
-PendingTx.prototype.onSubmit = function (event) {
- event.preventDefault()
- const txMeta = this.gatherTxMeta()
- const valid = this.checkValidity()
- this.setState({ valid, submitting: true })
- if (valid && this.verifyGasParams()) {
- this.props.sendTransaction(txMeta, event)
- } else {
- this.props.dispatch(actions.displayWarning('Invalid Gas Parameters'))
- this.setState({ submitting: false })
- }
-}
-
-PendingTx.prototype.checkValidity = function () {
- const form = this.getFormEl()
- const valid = form.checkValidity()
- return valid
-}
-
-PendingTx.prototype.getFormEl = function () {
- const form = document.querySelector('form#pending-tx-form')
- // Stub out form for unit tests:
- if (!form) {
- return { checkValidity () { return true } }
- }
- return form
-}
-
-// After a customizable state value has been updated,
-PendingTx.prototype.gatherTxMeta = function () {
- log.debug(`pending-tx gatherTxMeta`)
- const props = this.props
- const state = this.state
- const txData = clone(state.txData) || clone(props.txData)
-
- log.debug(`UI has defaulted to tx meta ${JSON.stringify(txData)}`)
- return txData
-}
-
-PendingTx.prototype.verifyGasParams = function () {
- // We call this in case the gas has not been modified at all
- if (!this.state) { return true }
- return (
- this._notZeroOrEmptyString(this.state.gas) &&
- this._notZeroOrEmptyString(this.state.gasPrice)
- )
-}
-
-PendingTx.prototype._notZeroOrEmptyString = function (obj) {
- return obj !== '' && obj !== '0x0'
-}
-
-PendingTx.prototype.bnMultiplyByFraction = function (targetBN, numerator, denominator) {
- const numBN = new BN(numerator)
- const denomBN = new BN(denominator)
- return targetBN.mul(numBN).div(denomBN)
-}
-
-function forwardCarrat () {
- return (
- h('img', {
- src: 'images/forward-carrat.svg',
- style: {
- padding: '5px 6px 0px 10px',
- height: '37px',
- },
- })
- )
-}
diff --git a/responsive-ui/app/components/qr-code.js b/responsive-ui/app/components/qr-code.js
deleted file mode 100644
index 06b9aed9b..000000000
--- a/responsive-ui/app/components/qr-code.js
+++ /dev/null
@@ -1,79 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const qrCode = require('qrcode-npm').qrcode
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const isHexPrefixed = require('ethereumjs-util').isHexPrefixed
-const CopyButton = require('./copyButton')
-
-module.exports = connect(mapStateToProps)(QrCodeView)
-
-function mapStateToProps (state) {
- return {
- Qr: state.appState.Qr,
- buyView: state.appState.buyView,
- warning: state.appState.warning,
- }
-}
-
-inherits(QrCodeView, Component)
-
-function QrCodeView () {
- Component.call(this)
-}
-
-QrCodeView.prototype.render = function () {
- const props = this.props
- const Qr = props.Qr
- const address = `${isHexPrefixed(Qr.data) ? 'ethereum:' : ''}${Qr.data}`
- const qrImage = qrCode(4, 'M')
- qrImage.addData(address)
- qrImage.make()
- return h('.main-container.flex-column', {
- key: 'qr',
- style: {
- justifyContent: 'center',
- paddingBottom: '45px',
- paddingLeft: '45px',
- paddingRight: '45px',
- alignItems: 'center',
- },
- }, [
- Array.isArray(Qr.message) ? h('.message-container', this.renderMultiMessage()) : h('.qr-header', Qr.message),
-
- this.props.warning ? this.props.warning && h('span.error.flex-center', {
- style: {
- textAlign: 'center',
- width: '229px',
- height: '82px',
- },
- },
- this.props.warning) : null,
-
- h('#qr-container.flex-column', {
- style: {
- marginTop: '25px',
- marginBottom: '15px',
- },
- dangerouslySetInnerHTML: {
- __html: qrImage.createTableTag(4),
- },
- }),
- h('.flex-row', [
- h('h3.ellip-address', {
- style: {
- width: '247px',
- },
- }, Qr.data),
- h(CopyButton, {
- value: Qr.data,
- }),
- ]),
- ])
-}
-
-QrCodeView.prototype.renderMultiMessage = function () {
- var Qr = this.props.Qr
- var multiMessage = Qr.message.map((message) => h('.qr-message', message))
- return multiMessage
-}
diff --git a/responsive-ui/app/components/range-slider.js b/responsive-ui/app/components/range-slider.js
deleted file mode 100644
index 823f5eb01..000000000
--- a/responsive-ui/app/components/range-slider.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = RangeSlider
-
-inherits(RangeSlider, Component)
-function RangeSlider () {
- Component.call(this)
-}
-
-RangeSlider.prototype.render = function () {
- const state = this.state || {}
- const props = this.props
- const onInput = props.onInput || function () {}
- const name = props.name
- const {
- min = 0,
- max = 100,
- increment = 1,
- defaultValue = 50,
- mirrorInput = false,
- } = this.props.options
- const {container, input, range} = props.style
-
- return (
- h('.flex-row', {
- style: container,
- }, [
- h('input', {
- type: 'range',
- name: name,
- min: min,
- max: max,
- step: increment,
- style: range,
- value: state.value || defaultValue,
- onChange: mirrorInput ? this.mirrorInputs.bind(this, event) : onInput,
- }),
-
- // Mirrored input for range
- mirrorInput ? h('input.large-input', {
- type: 'number',
- name: `${name}Mirror`,
- min: min,
- max: max,
- value: state.value || defaultValue,
- step: increment,
- style: input,
- onChange: this.mirrorInputs.bind(this, event),
- }) : null,
- ])
- )
-}
-
-RangeSlider.prototype.mirrorInputs = function (event) {
- this.setState({value: event.target.value})
-}
diff --git a/responsive-ui/app/components/shapeshift-form.js b/responsive-ui/app/components/shapeshift-form.js
deleted file mode 100644
index e0a720426..000000000
--- a/responsive-ui/app/components/shapeshift-form.js
+++ /dev/null
@@ -1,306 +0,0 @@
-const PersistentForm = require('../../lib/persistent-form')
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const connect = require('react-redux').connect
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
-const actions = require('../actions')
-const Qr = require('./qr-code')
-const isValidAddress = require('../util').isValidAddress
-module.exports = connect(mapStateToProps)(ShapeshiftForm)
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- isSubLoading: state.appState.isSubLoading,
- qrRequested: state.appState.qrRequested,
- }
-}
-
-inherits(ShapeshiftForm, PersistentForm)
-
-function ShapeshiftForm () {
- PersistentForm.call(this)
- this.persistentFormParentId = 'shapeshift-buy-form'
-}
-
-ShapeshiftForm.prototype.render = function () {
- return h(ReactCSSTransitionGroup, {
- className: 'css-transition-group',
- transitionName: 'main',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 300,
- }, [
- this.props.qrRequested ? h(Qr, {key: 'qr'}) : this.renderMain(),
- ])
-}
-
-ShapeshiftForm.prototype.renderMain = function () {
- const marketinfo = this.props.buyView.formView.marketinfo
- const coinOptions = this.props.buyView.formView.coinOptions
- var coin = marketinfo.pair.split('_')[0].toUpperCase()
-
- return h('.flex-column', {
- style: {
- // marginTop: '10px',
- padding: '25px',
- paddingTop: '5px',
- width: '100%',
- minHeight: '215px',
- alignItems: 'center',
- overflowY: 'auto',
- },
- }, [
- h('.flex-row', {
- style: {
- justifyContent: 'center',
- alignItems: 'baseline',
- height: '42px',
- },
- }, [
- h('img', {
- src: coinOptions[coin].image,
- width: '25px',
- height: '25px',
- style: {
- marginRight: '5px',
- },
- }),
-
- h('.input-container', [
- h('input#fromCoin.buy-inputs.ex-coins', {
- type: 'text',
- list: 'coinList',
- autoFocus: true,
- dataset: {
- persistentFormId: 'input-coin',
- },
- style: {
- boxSizing: 'border-box',
- },
- onChange: this.handleLiveInput.bind(this),
- defaultValue: 'BTC',
- }),
-
- this.renderCoinList(),
-
- h('i.fa.fa-pencil-square-o.edit-text', {
- style: {
- fontSize: '12px',
- color: '#F7861C',
- position: 'relative',
- bottom: '48px',
- left: '106px',
- },
- }),
- ]),
-
- h('.icon-control', [
- h('i.fa.fa-refresh.fa-4.orange', {
- style: {
- bottom: '5px',
- left: '5px',
- color: '#F7861C',
- },
- onClick: this.updateCoin.bind(this),
- }),
- h('i.fa.fa-chevron-right.fa-4.orange', {
- style: {
- position: 'relative',
- bottom: '26px',
- left: '10px',
- color: '#F7861C',
- },
- onClick: this.updateCoin.bind(this),
- }),
- ]),
-
- h('#toCoin.ex-coins', marketinfo.pair.split('_')[1].toUpperCase()),
-
- h('img', {
- src: coinOptions[marketinfo.pair.split('_')[1].toUpperCase()].image,
- width: '25px',
- height: '25px',
- style: {
- marginLeft: '5px',
- },
- }),
- ]),
- h('.flex-column', {
- style: {
- alignItems: 'flex-start',
- },
- }, [
- this.props.warning ? this.props.warning && h('span.error.flex-center', {
- style: {
- textAlign: 'center',
- width: '229px',
- height: '82px',
- },
- },
- this.props.warning) : this.renderInfo(),
- ]),
-
- h(this.activeToggle('.input-container'), {
- style: {
- padding: '10px',
- paddingTop: '0px',
- width: '100%',
- },
- }, [
-
- h('div', `${coin} Address:`),
-
- h('input#fromCoinAddress.buy-inputs', {
- type: 'text',
- placeholder: `Your ${coin} Refund Address`,
- dataset: {
- persistentFormId: 'refund-address',
- },
- style: {
- boxSizing: 'border-box',
- width: '227px',
- height: '30px',
- padding: ' 5px ',
- },
- }),
-
- h('i.fa.fa-pencil-square-o.edit-text', {
- style: {
- fontSize: '12px',
- color: '#F7861C',
- position: 'relative',
- bottom: '10px',
- right: '11px',
- },
- }),
- h('.flex-row', {
- style: {
- justifyContent: 'flex-end',
- },
- }, [
- h('button', {
- onClick: this.shift.bind(this),
- style: {
- marginTop: '10px',
- position: 'relative',
- bottom: '40px',
- },
- },
- 'Submit'),
- ]),
- ]),
- ])
-}
-
-ShapeshiftForm.prototype.shift = function () {
- var props = this.props
- var withdrawal = this.props.buyView.buyAddress
- var returnAddress = document.getElementById('fromCoinAddress').value
- var pair = this.props.buyView.formView.marketinfo.pair
- var data = {
- 'withdrawal': withdrawal,
- 'pair': pair,
- 'returnAddress': returnAddress,
- // Public api key
- 'apiKey': '803d1f5df2ed1b1476e4b9e6bcd089e34d8874595dda6a23b67d93c56ea9cc2445e98a6748b219b2b6ad654d9f075f1f1db139abfa93158c04e825db122c14b6',
- }
- var message = [
- `Deposit Limit: ${props.buyView.formView.marketinfo.limit}`,
- `Deposit Minimum:${props.buyView.formView.marketinfo.minimum}`,
- ]
- if (isValidAddress(withdrawal)) {
- this.props.dispatch(actions.coinShiftRquest(data, message))
- }
-}
-
-ShapeshiftForm.prototype.renderCoinList = function () {
- var list = Object.keys(this.props.buyView.formView.coinOptions).map((item) => {
- return h('option', {
- value: item,
- }, item)
- })
-
- return h('datalist#coinList', {
- onClick: (event) => {
- event.preventDefault()
- },
- }, list)
-}
-
-ShapeshiftForm.prototype.updateCoin = function (event) {
- event.preventDefault()
- const props = this.props
- var coinOptions = this.props.buyView.formView.coinOptions
- var coin = document.getElementById('fromCoin').value
-
- if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
- var message = 'Not a valid coin'
- return props.dispatch(actions.displayWarning(message))
- } else {
- return props.dispatch(actions.pairUpdate(coin))
- }
-}
-
-ShapeshiftForm.prototype.handleLiveInput = function () {
- const props = this.props
- var coinOptions = this.props.buyView.formView.coinOptions
- var coin = document.getElementById('fromCoin').value
-
- if (!coinOptions[coin.toUpperCase()] || coin.toUpperCase() === 'ETH') {
- return null
- } else {
- return props.dispatch(actions.pairUpdate(coin))
- }
-}
-
-ShapeshiftForm.prototype.renderInfo = function () {
- const marketinfo = this.props.buyView.formView.marketinfo
- const coinOptions = this.props.buyView.formView.coinOptions
- var coin = marketinfo.pair.split('_')[0].toUpperCase()
-
- return h('span', {
- style: {
- },
- }, [
- h('h3.flex-row.text-transform-uppercase', {
- style: {
- color: '#868686',
- paddingTop: '4px',
- justifyContent: 'space-around',
- textAlign: 'center',
- fontSize: '17px',
- },
- }, `Market Info for ${marketinfo.pair.replace('_', ' to ').toUpperCase()}:`),
- h('.marketinfo', ['Status : ', `${coinOptions[coin].status}`]),
- h('.marketinfo', ['Exchange Rate: ', `${marketinfo.rate}`]),
- h('.marketinfo', ['Limit: ', `${marketinfo.limit}`]),
- h('.marketinfo', ['Minimum : ', `${marketinfo.minimum}`]),
- ])
-}
-
-ShapeshiftForm.prototype.activeToggle = function (elementType) {
- if (!this.props.buyView.formView.response || this.props.warning) return elementType
- return `${elementType}.inactive`
-}
-
-ShapeshiftForm.prototype.renderLoading = function () {
- return h('span', {
- style: {
- position: 'absolute',
- left: '70px',
- bottom: '194px',
- background: 'transparent',
- width: '229px',
- height: '82px',
- display: 'flex',
- justifyContent: 'center',
- },
- }, [
- h('img', {
- style: {
- width: '60px',
- },
- src: 'images/loading.svg',
- }),
- ])
-}
diff --git a/responsive-ui/app/components/shift-list-item.js b/responsive-ui/app/components/shift-list-item.js
deleted file mode 100644
index 32bfbeda4..000000000
--- a/responsive-ui/app/components/shift-list-item.js
+++ /dev/null
@@ -1,204 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const vreme = new (require('vreme'))
-const explorerLink = require('../../lib/explorer-link')
-const actions = require('../actions')
-const addressSummary = require('../util').addressSummary
-
-const CopyButton = require('./copyButton')
-const EthBalance = require('./eth-balance')
-const Tooltip = require('./tooltip')
-
-
-module.exports = connect(mapStateToProps)(ShiftListItem)
-
-function mapStateToProps (state) {
- return {
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- }
-}
-
-inherits(ShiftListItem, Component)
-
-function ShiftListItem () {
- Component.call(this)
-}
-
-ShiftListItem.prototype.render = function () {
- return (
- h('.transaction-list-item.flex-row', {
- style: {
- paddingTop: '20px',
- paddingBottom: '20px',
- justifyContent: 'space-around',
- alignItems: 'center',
- },
- }, [
- h('div', {
- style: {
- width: '0px',
- position: 'relative',
- bottom: '19px',
- },
- }, [
- h('img', {
- src: 'https://info.shapeshift.io/sites/default/files/logo.png',
- style: {
- height: '35px',
- width: '132px',
- position: 'absolute',
- clip: 'rect(0px,23px,34px,0px)',
- },
- }),
- ]),
-
- this.renderInfo(),
- this.renderUtilComponents(),
- ])
- )
-}
-
-function formatDate (date) {
- return vreme.format(new Date(date), 'March 16 2014 14:30')
-}
-
-ShiftListItem.prototype.renderUtilComponents = function () {
- var props = this.props
- const { conversionRate, currentCurrency } = props
-
- switch (props.response.status) {
- case 'no_deposits':
- return h('.flex-row', [
- h(CopyButton, {
- value: this.props.depositAddress,
- }),
- h(Tooltip, {
- title: 'QR Code',
- }, [
- h('i.fa.fa-qrcode.pointer.pop-hover', {
- onClick: () => props.dispatch(actions.reshowQrCode(props.depositAddress, props.depositType)),
- style: {
- margin: '5px',
- marginLeft: '23px',
- marginRight: '12px',
- fontSize: '20px',
- color: '#F7861C',
- },
- }),
- ]),
- ])
- case 'received':
- return h('.flex-row')
-
- case 'complete':
- return h('.flex-row', [
- h(CopyButton, {
- value: this.props.response.transaction,
- }),
- h(EthBalance, {
- value: `${props.response.outgoingCoin}`,
- conversionRate,
- currentCurrency,
- width: '55px',
- shorten: true,
- needsParse: false,
- incoming: true,
- style: {
- fontSize: '15px',
- color: '#01888C',
- },
- }),
- ])
-
- case 'failed':
- return ''
- default:
- return ''
- }
-}
-
-ShiftListItem.prototype.renderInfo = function () {
- var props = this.props
- switch (props.response.status) {
- case 'no_deposits':
- return h('.flex-column', {
- style: {
- width: '200px',
- overflow: 'hidden',
- },
- }, [
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, `${props.depositType} to ETH via ShapeShift`),
- h('div', 'No deposits received'),
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, formatDate(props.time)),
- ])
- case 'received':
- return h('.flex-column', {
- style: {
- width: '200px',
- overflow: 'hidden',
- },
- }, [
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, `${props.depositType} to ETH via ShapeShift`),
- h('div', 'Conversion in progress'),
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, formatDate(props.time)),
- ])
- case 'complete':
- var url = explorerLink(props.response.transaction, parseInt('1'))
-
- return h('.flex-column.pointer', {
- style: {
- width: '200px',
- overflow: 'hidden',
- },
- onClick: () => global.platform.openWindow({ url }),
- }, [
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, 'From ShapeShift'),
- h('div', formatDate(props.time)),
- h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- width: '100%',
- },
- }, addressSummary(props.response.transaction)),
- ])
-
- case 'failed':
- return h('span.error', '(Failed)')
- default:
- return ''
- }
-}
diff --git a/responsive-ui/app/components/tab-bar.js b/responsive-ui/app/components/tab-bar.js
deleted file mode 100644
index 6295e7dd9..000000000
--- a/responsive-ui/app/components/tab-bar.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = TabBar
-
-inherits(TabBar, Component)
-function TabBar () {
- Component.call(this)
-}
-
-TabBar.prototype.render = function () {
- const props = this.props
- const state = this.state || {}
- const { tabs = [], defaultTab, tabSelected } = props
- const { subview = defaultTab } = state
-
- return (
- h('.flex-row.space-around.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- paddingTop: '4px',
- },
- }, tabs.map((tab) => {
- const { key, content } = tab
- return h(subview === key ? '.activeForm' : '.inactiveForm.pointer', {
- onClick: () => {
- this.setState({ subview: key })
- tabSelected(key)
- },
- }, content)
- }))
- )
-}
-
diff --git a/responsive-ui/app/components/template.js b/responsive-ui/app/components/template.js
deleted file mode 100644
index b6ed8eaa0..000000000
--- a/responsive-ui/app/components/template.js
+++ /dev/null
@@ -1,18 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = NewComponent
-
-inherits(NewComponent, Component)
-function NewComponent () {
- Component.call(this)
-}
-
-NewComponent.prototype.render = function () {
- const props = this.props
-
- return (
- h('span', props.message)
- )
-}
diff --git a/responsive-ui/app/components/token-cell.js b/responsive-ui/app/components/token-cell.js
deleted file mode 100644
index 19d7139bb..000000000
--- a/responsive-ui/app/components/token-cell.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const Identicon = require('./identicon')
-const prefixForNetwork = require('../../lib/etherscan-prefix-for-network')
-
-module.exports = TokenCell
-
-inherits(TokenCell, Component)
-function TokenCell () {
- Component.call(this)
-}
-
-TokenCell.prototype.render = function () {
- const props = this.props
- const { address, symbol, string, network, userAddress } = props
-
- return (
- h('li.token-cell', {
- style: { cursor: network === '1' ? 'pointer' : 'default' },
- onClick: this.view.bind(this, address, userAddress, network),
- }, [
-
- h(Identicon, {
- diameter: 50,
- address,
- network,
- }),
-
- h('h3', `${string || 0} ${symbol}`),
-
- h('span', { style: { flex: '1 0 auto' } }),
-
- /*
- h('button', {
- onClick: this.send.bind(this, address),
- }, 'SEND'),
- */
-
- ])
- )
-}
-
-TokenCell.prototype.send = function (address, event) {
- event.preventDefault()
- event.stopPropagation()
- const url = tokenFactoryFor(address)
- if (url) {
- navigateTo(url)
- }
-}
-
-TokenCell.prototype.view = function (address, userAddress, network, event) {
- const url = etherscanLinkFor(address, userAddress, network)
- if (url) {
- navigateTo(url)
- }
-}
-
-function navigateTo (url) {
- global.platform.openWindow({ url })
-}
-
-function etherscanLinkFor (tokenAddress, address, network) {
- const prefix = prefixForNetwork(network)
- return `https://${prefix}etherscan.io/token/${tokenAddress}?a=${address}`
-}
-
-function tokenFactoryFor (tokenAddress) {
- return `https://tokenfactory.surge.sh/#/token/${tokenAddress}`
-}
-
diff --git a/responsive-ui/app/components/token-list.js b/responsive-ui/app/components/token-list.js
deleted file mode 100644
index 20cfa897e..000000000
--- a/responsive-ui/app/components/token-list.js
+++ /dev/null
@@ -1,192 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const TokenTracker = require('eth-token-tracker')
-const TokenCell = require('./token-cell.js')
-const normalizeAddress = require('eth-sig-util').normalize
-
-const defaultTokens = []
-const contracts = require('eth-contract-metadata')
-for (const address in contracts) {
- const contract = contracts[address]
- if (contract.erc20) {
- contract.address = address
- defaultTokens.push(contract)
- }
-}
-
-module.exports = TokenList
-
-inherits(TokenList, Component)
-function TokenList () {
- this.state = {
- tokens: [],
- isLoading: true,
- network: null,
- }
- Component.call(this)
-}
-
-TokenList.prototype.render = function () {
- const state = this.state
- const { tokens, isLoading, error } = state
- const { userAddress, network } = this.props
-
- if (isLoading) {
- return this.message('Loading')
- }
-
- if (error) {
- log.error(error)
- return this.message('There was a problem loading your token balances.')
- }
-
- const tokenViews = tokens.map((tokenData) => {
- tokenData.network = network
- tokenData.userAddress = userAddress
- return h(TokenCell, tokenData)
- })
-
- return h('div', [
- h('ol', {
- style: {
- height: '260px',
- overflowY: 'auto',
- display: 'flex',
- flexDirection: 'column',
- },
- }, [
- h('style', `
-
- li.token-cell {
- display: flex;
- flex-direction: row;
- align-items: center;
- padding: 10px;
- }
-
- li.token-cell > h3 {
- margin-left: 12px;
- }
-
- li.token-cell:hover {
- background: white;
- cursor: pointer;
- }
-
- `),
- ...tokenViews,
- tokenViews.length ? null : this.message('No Tokens Found.'),
- ]),
- this.addTokenButtonElement(),
- ])
-}
-
-TokenList.prototype.addTokenButtonElement = function () {
- return h('div', [
- h('div.footer.hover-white.pointer', {
- key: 'reveal-account-bar',
- onClick: () => {
- this.props.addToken()
- },
- style: {
- display: 'flex',
- height: '40px',
- padding: '10px',
- justifyContent: 'center',
- alignItems: 'center',
- },
- }, [
- h('i.fa.fa-plus.fa-lg'),
- ]),
- ])
-}
-
-TokenList.prototype.message = function (body) {
- return h('div', {
- style: {
- display: 'flex',
- height: '250px',
- alignItems: 'center',
- justifyContent: 'center',
- padding: '30px',
- },
- }, body)
-}
-
-TokenList.prototype.componentDidMount = function () {
- this.createFreshTokenTracker()
-}
-
-TokenList.prototype.createFreshTokenTracker = function () {
- if (this.tracker) {
- // Clean up old trackers when refreshing:
- this.tracker.stop()
- this.tracker.removeListener('update', this.balanceUpdater)
- this.tracker.removeListener('error', this.showError)
- }
-
- if (!global.ethereumProvider) return
- const { userAddress } = this.props
- this.tracker = new TokenTracker({
- userAddress,
- provider: global.ethereumProvider,
- tokens: uniqueMergeTokens(defaultTokens, this.props.tokens),
- pollingInterval: 8000,
- })
-
-
- // Set up listener instances for cleaning up
- this.balanceUpdater = this.updateBalances.bind(this)
- this.showError = (error) => {
- this.setState({ error, isLoading: false })
- }
- this.tracker.on('update', this.balanceUpdater)
- this.tracker.on('error', this.showError)
-
- this.tracker.updateBalances()
- .then(() => {
- this.updateBalances(this.tracker.serialize())
- })
- .catch((reason) => {
- log.error(`Problem updating balances`, reason)
- this.setState({ isLoading: false })
- })
-}
-
-TokenList.prototype.componentWillUpdate = function (nextProps) {
- if (nextProps.network === 'loading') return
- const oldNet = this.props.network
- const newNet = nextProps.network
-
- if (oldNet && newNet && newNet !== oldNet) {
- this.setState({ isLoading: true })
- this.createFreshTokenTracker()
- }
-}
-
-TokenList.prototype.updateBalances = function (tokens) {
- const heldTokens = tokens.filter(token => {
- return token.balance !== '0' && token.string !== '0.000'
- })
- this.setState({ tokens: heldTokens, isLoading: false })
-}
-
-TokenList.prototype.componentWillUnmount = function () {
- if (!this.tracker) return
- this.tracker.stop()
-}
-
-function uniqueMergeTokens (tokensA, tokensB) {
- const uniqueAddresses = []
- const result = []
- tokensA.concat(tokensB).forEach((token) => {
- const normal = normalizeAddress(token.address)
- if (!uniqueAddresses.includes(normal)) {
- uniqueAddresses.push(normal)
- result.push(token)
- }
- })
- return result
-}
-
diff --git a/responsive-ui/app/components/tooltip.js b/responsive-ui/app/components/tooltip.js
deleted file mode 100644
index edbc074bb..000000000
--- a/responsive-ui/app/components/tooltip.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ReactTooltip = require('react-tooltip-component')
-
-module.exports = Tooltip
-
-inherits(Tooltip, Component)
-function Tooltip () {
- Component.call(this)
-}
-
-Tooltip.prototype.render = function () {
- const props = this.props
- const { position, title, children } = props
-
- return h(ReactTooltip, {
- position: position || 'left',
- title,
- fixed: false,
- }, children)
-}
diff --git a/responsive-ui/app/components/transaction-list-item-icon.js b/responsive-ui/app/components/transaction-list-item-icon.js
deleted file mode 100644
index 431054340..000000000
--- a/responsive-ui/app/components/transaction-list-item-icon.js
+++ /dev/null
@@ -1,68 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const Tooltip = require('./tooltip')
-
-const Identicon = require('./identicon')
-
-module.exports = TransactionIcon
-
-inherits(TransactionIcon, Component)
-function TransactionIcon () {
- Component.call(this)
-}
-
-TransactionIcon.prototype.render = function () {
- const { transaction, txParams, isMsg } = this.props
- switch (transaction.status) {
- case 'unapproved':
- return h(!isMsg ? '.unapproved-tx-icon' : 'i.fa.fa-certificate.fa-lg')
-
- case 'rejected':
- return h('i.fa.fa-exclamation-triangle.fa-lg.warning', {
- style: {
- width: '24px',
- },
- })
-
- case 'failed':
- return h('i.fa.fa-exclamation-triangle.fa-lg.error', {
- style: {
- width: '24px',
- },
- })
-
- case 'submitted':
- return h(Tooltip, {
- title: 'Pending',
- position: 'bottom',
- }, [
- h('i.fa.fa-ellipsis-h', {
- style: {
- fontSize: '27px',
- },
- }),
- ])
- }
-
- if (isMsg) {
- return h('i.fa.fa-certificate.fa-lg', {
- style: {
- width: '24px',
- },
- })
- }
-
- if (txParams.to) {
- return h(Identicon, {
- diameter: 24,
- address: txParams.to || transaction.hash,
- })
- } else {
- return h('i.fa.fa-file-text-o.fa-lg', {
- style: {
- width: '24px',
- },
- })
- }
-}
diff --git a/responsive-ui/app/components/transaction-list-item.js b/responsive-ui/app/components/transaction-list-item.js
deleted file mode 100644
index dbda66a31..000000000
--- a/responsive-ui/app/components/transaction-list-item.js
+++ /dev/null
@@ -1,165 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const EthBalance = require('./eth-balance')
-const addressSummary = require('../util').addressSummary
-const explorerLink = require('../../lib/explorer-link')
-const CopyButton = require('./copyButton')
-const vreme = new (require('vreme'))
-const Tooltip = require('./tooltip')
-const numberToBN = require('number-to-bn')
-
-const TransactionIcon = require('./transaction-list-item-icon')
-const ShiftListItem = require('./shift-list-item')
-module.exports = TransactionListItem
-
-inherits(TransactionListItem, Component)
-function TransactionListItem () {
- Component.call(this)
-}
-
-TransactionListItem.prototype.render = function () {
- const { transaction, network, conversionRate, currentCurrency } = this.props
- if (transaction.key === 'shapeshift') {
- if (network === '1') return h(ShiftListItem, transaction)
- }
- var date = formatDate(transaction.time)
-
- let isLinkable = false
- const numericNet = parseInt(network)
- isLinkable = numericNet === 1 || numericNet === 3 || numericNet === 4 || numericNet === 42
-
- var isMsg = ('msgParams' in transaction)
- var isTx = ('txParams' in transaction)
- var isPending = transaction.status === 'unapproved'
- let txParams
- if (isTx) {
- txParams = transaction.txParams
- } else if (isMsg) {
- txParams = transaction.msgParams
- }
-
- const nonce = txParams.nonce ? numberToBN(txParams.nonce).toString(10) : ''
-
- const isClickable = ('hash' in transaction && isLinkable) || isPending
- return (
- h(`.transaction-list-item.flex-row.flex-space-between${isClickable ? '.pointer' : ''}`, {
- onClick: (event) => {
- if (isPending) {
- this.props.showTx(transaction.id)
- }
- event.stopPropagation()
- if (!transaction.hash || !isLinkable) return
- var url = explorerLink(transaction.hash, parseInt(network))
- global.platform.openWindow({ url })
- },
- style: {
- padding: '20px 0',
- },
- }, [
-
- h('.identicon-wrapper.flex-column.flex-center.select-none', [
- h('.pop-hover', {
- onClick: (event) => {
- event.stopPropagation()
- if (!isTx || isPending) return
- var url = `https://metamask.github.io/eth-tx-viz/?tx=${transaction.hash}`
- global.platform.openWindow({ url })
- },
- }, [
- h(TransactionIcon, { txParams, transaction, isTx, isMsg }),
- ]),
- ]),
-
- h(Tooltip, {
- title: 'Transaction Number',
- position: 'bottom',
- }, [
- h('span', {
- style: {
- display: 'flex',
- cursor: 'normal',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center',
- padding: '10px',
- },
- }, nonce),
- ]),
-
- h('.flex-column', {style: {width: '200px', overflow: 'hidden'}}, [
- domainField(txParams),
- h('div', date),
- recipientField(txParams, transaction, isTx, isMsg),
- ]),
-
- // Places a copy button if tx is successful, else places a placeholder empty div.
- transaction.hash ? h(CopyButton, { value: transaction.hash }) : h('div', {style: { display: 'flex', alignItems: 'center', width: '26px' }}),
-
- isTx ? h(EthBalance, {
- value: txParams.value,
- conversionRate,
- currentCurrency,
- width: '55px',
- shorten: true,
- showFiat: false,
- style: {fontSize: '15px'},
- }) : h('.flex-column'),
- ])
- )
-}
-
-function domainField (txParams) {
- return h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- width: '100%',
- },
- }, [
- txParams.origin,
- ])
-}
-
-function recipientField (txParams, transaction, isTx, isMsg) {
- let message
-
- if (isMsg) {
- message = 'Signature Requested'
- } else if (txParams.to) {
- message = addressSummary(txParams.to)
- } else {
- message = 'Contract Published'
- }
-
- return h('div', {
- style: {
- fontSize: 'x-small',
- color: '#ABA9AA',
- },
- }, [
- message,
- failIfFailed(transaction),
- ])
-}
-
-function formatDate (date) {
- return vreme.format(new Date(date), 'March 16 2014 14:30')
-}
-
-function failIfFailed (transaction) {
- if (transaction.status === 'rejected') {
- return h('span.error', ' (Rejected)')
- }
- if (transaction.err) {
- return h(Tooltip, {
- title: transaction.err.message,
- position: 'bottom',
- }, [
- h('span.error', ' (Failed)'),
- ])
- }
-}
diff --git a/responsive-ui/app/components/transaction-list.js b/responsive-ui/app/components/transaction-list.js
deleted file mode 100644
index ae6aaec8c..000000000
--- a/responsive-ui/app/components/transaction-list.js
+++ /dev/null
@@ -1,83 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-const TransactionListItem = require('./transaction-list-item')
-
-module.exports = TransactionList
-
-
-inherits(TransactionList, Component)
-function TransactionList () {
- Component.call(this)
-}
-
-TransactionList.prototype.render = function () {
- const { transactions, network, unapprovedMsgs, conversionRate } = this.props
-
- var shapeShiftTxList
- if (network === '1') {
- shapeShiftTxList = this.props.shapeShiftTxList
- }
- const txsToRender = !shapeShiftTxList ? transactions.concat(unapprovedMsgs) : transactions.concat(unapprovedMsgs, shapeShiftTxList)
- .sort((a, b) => b.time - a.time)
-
- return (
-
- h('section.transaction-list', {
- style: {
- height: '100%',
- },
- }, [
-
- h('style', `
- .transaction-list .transaction-list-item:not(:last-of-type) {
- border-bottom: 1px solid #D4D4D4;
- }
- .transaction-list .transaction-list-item .ether-balance-label {
- display: block !important;
- font-size: small;
- }
- `),
-
- h('.tx-list', {
- style: {
- overflowY: 'auto',
- height: '100%',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, [
-
- txsToRender.length
- ? txsToRender.map((transaction, i) => {
- let key
- switch (transaction.key) {
- case 'shapeshift':
- const { depositAddress, time } = transaction
- key = `shift-tx-${depositAddress}-${time}-${i}`
- break
- default:
- key = `tx-${transaction.id}-${i}`
- }
- return h(TransactionListItem, {
- transaction, i, network, key,
- conversionRate,
- showTx: (txId) => {
- this.props.viewPendingTx(txId)
- },
- })
- })
- : h('.flex-center', {
- style: {
- flexDirection: 'column',
- height: '100%',
- },
- }, [
- 'No transaction history.',
- ]),
- ]),
- ])
- )
-}
-
diff --git a/responsive-ui/app/conf-tx.js b/responsive-ui/app/conf-tx.js
deleted file mode 100644
index 747d3ce2b..000000000
--- a/responsive-ui/app/conf-tx.js
+++ /dev/null
@@ -1,213 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-const NetworkIndicator = require('./components/network')
-const txHelper = require('../lib/tx-helper')
-const isPopupOrNotification = require('../../app/scripts/lib/is-popup-or-notification')
-
-const PendingTx = require('./components/pending-tx')
-const PendingMsg = require('./components/pending-msg')
-const PendingPersonalMsg = require('./components/pending-personal-msg')
-const Loading = require('./components/loading')
-
-module.exports = connect(mapStateToProps)(ConfirmTxScreen)
-
-function mapStateToProps (state) {
- return {
- identities: state.metamask.identities,
- accounts: state.metamask.accounts,
- selectedAddress: state.metamask.selectedAddress,
- unapprovedTxs: state.metamask.unapprovedTxs,
- unapprovedMsgs: state.metamask.unapprovedMsgs,
- unapprovedPersonalMsgs: state.metamask.unapprovedPersonalMsgs,
- index: state.appState.currentView.context,
- warning: state.appState.warning,
- network: state.metamask.network,
- provider: state.metamask.provider,
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- blockGasLimit: state.metamask.currentBlockGasLimit,
- }
-}
-
-inherits(ConfirmTxScreen, Component)
-function ConfirmTxScreen () {
- Component.call(this)
-}
-
-ConfirmTxScreen.prototype.render = function () {
- const props = this.props
- const { network, provider, unapprovedTxs, currentCurrency,
- unapprovedMsgs, unapprovedPersonalMsgs, conversionRate, blockGasLimit } = props
-
- var unconfTxList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
-
- var txData = unconfTxList[props.index] || {}
- var txParams = txData.params || {}
- var isNotification = isPopupOrNotification() === 'notification'
-
-
- log.info(`rendering a combined ${unconfTxList.length} unconf msg & txs`)
- if (unconfTxList.length === 0) return h(Loading, { isLoading: true })
-
- return (
-
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- !isNotification ? h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: this.goHome.bind(this),
- }) : null,
- h('h2.page-subtitle', 'Confirm Transaction'),
- isNotification ? h(NetworkIndicator, {
- network: network,
- provider: provider,
- }) : null,
- ]),
-
- h('h3', {
- style: {
- alignSelf: 'center',
- display: unconfTxList.length > 1 ? 'block' : 'none',
- },
- }, [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- style: {
- display: props.index === 0 ? 'none' : 'inline-block',
- },
- onClick: () => props.dispatch(actions.previousTx()),
- }),
- ` ${props.index + 1} of ${unconfTxList.length} `,
- h('i.fa.fa-arrow-right.fa-lg.cursor-pointer', {
- style: {
- display: props.index + 1 === unconfTxList.length ? 'none' : 'inline-block',
- },
- onClick: () => props.dispatch(actions.nextTx()),
- }),
- ]),
-
- warningIfExists(props.warning),
-
- h(ReactCSSTransitionGroup, {
- className: 'css-transition-group',
- transitionName: 'main',
- transitionEnterTimeout: 300,
- transitionLeaveTimeout: 300,
- }, [
-
- currentTxView({
- // Properties
- txData: txData,
- key: txData.id,
- selectedAddress: props.selectedAddress,
- accounts: props.accounts,
- identities: props.identities,
- conversionRate,
- currentCurrency,
- blockGasLimit,
- // Actions
- buyEth: this.buyEth.bind(this, txParams.from || props.selectedAddress),
- sendTransaction: this.sendTransaction.bind(this),
- cancelTransaction: this.cancelTransaction.bind(this, txData),
- signMessage: this.signMessage.bind(this, txData),
- signPersonalMessage: this.signPersonalMessage.bind(this, txData),
- cancelMessage: this.cancelMessage.bind(this, txData),
- cancelPersonalMessage: this.cancelPersonalMessage.bind(this, txData),
- }),
-
- ]),
- ])
- )
-}
-
-function currentTxView (opts) {
- log.info('rendering current tx view')
- const { txData } = opts
- const { txParams, msgParams, type } = txData
-
- if (txParams) {
- log.debug('txParams detected, rendering pending tx')
- return h(PendingTx, opts)
- } else if (msgParams) {
- log.debug('msgParams detected, rendering pending msg')
-
- if (type === 'eth_sign') {
- log.debug('rendering eth_sign message')
- return h(PendingMsg, opts)
- } else if (type === 'personal_sign') {
- log.debug('rendering personal_sign message')
- return h(PendingPersonalMsg, opts)
- }
- }
-}
-
-ConfirmTxScreen.prototype.buyEth = function (address, event) {
- event.preventDefault()
- this.props.dispatch(actions.buyEthView(address))
-}
-
-ConfirmTxScreen.prototype.sendTransaction = function (txData, event) {
- this.stopPropagation(event)
- this.props.dispatch(actions.updateAndApproveTx(txData))
-}
-
-ConfirmTxScreen.prototype.cancelTransaction = function (txData, event) {
- this.stopPropagation(event)
- event.preventDefault()
- this.props.dispatch(actions.cancelTx(txData))
-}
-
-ConfirmTxScreen.prototype.signMessage = function (msgData, event) {
- log.info('conf-tx.js: signing message')
- var params = msgData.msgParams
- params.metamaskId = msgData.id
- this.stopPropagation(event)
- this.props.dispatch(actions.signMsg(params))
-}
-
-ConfirmTxScreen.prototype.stopPropagation = function (event) {
- if (event.stopPropagation) {
- event.stopPropagation()
- }
-}
-
-ConfirmTxScreen.prototype.signPersonalMessage = function (msgData, event) {
- log.info('conf-tx.js: signing personal message')
- var params = msgData.msgParams
- params.metamaskId = msgData.id
- this.stopPropagation(event)
- this.props.dispatch(actions.signPersonalMsg(params))
-}
-
-ConfirmTxScreen.prototype.cancelMessage = function (msgData, event) {
- log.info('canceling message')
- this.stopPropagation(event)
- this.props.dispatch(actions.cancelMsg(msgData))
-}
-
-ConfirmTxScreen.prototype.cancelPersonalMessage = function (msgData, event) {
- log.info('canceling personal message')
- this.stopPropagation(event)
- this.props.dispatch(actions.cancelPersonalMsg(msgData))
-}
-
-ConfirmTxScreen.prototype.goHome = function (event) {
- this.stopPropagation(event)
- this.props.dispatch(actions.goHome())
-}
-
-function warningIfExists (warning) {
- if (warning &&
- // Do not display user rejections on this screen:
- warning.indexOf('User denied transaction signature') === -1) {
- return h('.error', {
- style: {
- margin: 'auto',
- },
- }, warning)
- }
-}
diff --git a/responsive-ui/app/config.js b/responsive-ui/app/config.js
deleted file mode 100644
index 62785c49b..000000000
--- a/responsive-ui/app/config.js
+++ /dev/null
@@ -1,211 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-const currencies = require('./conversion.json').rows
-const validUrl = require('valid-url')
-const copyToClipboard = require('copy-to-clipboard')
-
-module.exports = connect(mapStateToProps)(ConfigScreen)
-
-function mapStateToProps (state) {
- return {
- metamask: state.metamask,
- warning: state.appState.warning,
- }
-}
-
-inherits(ConfigScreen, Component)
-function ConfigScreen () {
- Component.call(this)
-}
-
-ConfigScreen.prototype.render = function () {
- var state = this.props
- var metamaskState = state.metamask
- var warning = state.warning
-
- return (
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- state.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Settings'),
- ]),
-
- h('.error', {
- style: {
- display: warning ? 'block' : 'none',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, warning),
-
- // conf view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
-
- currentProviderDisplay(metamaskState),
-
- h('div', { style: {display: 'flex'} }, [
- h('input#new_rpc', {
- placeholder: 'New RPC URL',
- style: {
- width: 'inherit',
- flex: '1 0 auto',
- height: '30px',
- margin: '8px',
- },
- onKeyPress (event) {
- if (event.key === 'Enter') {
- var element = event.target
- var newRpc = element.value
- rpcValidation(newRpc, state)
- }
- },
- }),
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick (event) {
- event.preventDefault()
- var element = document.querySelector('input#new_rpc')
- var newRpc = element.value
- rpcValidation(newRpc, state)
- },
- }, 'Save'),
- ]),
-
- h('hr.horizontal-line'),
-
- currentConversionInformation(metamaskState, state),
-
- h('hr.horizontal-line'),
-
- h('div', {
- style: {
- marginTop: '20px',
- },
- }, [
- h('p', {
- style: {
- fontFamily: 'Montserrat Light',
- fontSize: '13px',
- },
- }, `State logs contain your public account addresses and sent transactions.`),
- h('br'),
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick (event) {
- copyToClipboard(window.logState())
- },
- }, 'Copy State Logs'),
- ]),
-
- h('hr.horizontal-line'),
-
- h('div', {
- style: {
- marginTop: '20px',
- },
- }, [
- h('button', {
- style: {
- alignSelf: 'center',
- },
- onClick (event) {
- event.preventDefault()
- state.dispatch(actions.revealSeedConfirmation())
- },
- }, 'Reveal Seed Words'),
- ]),
-
- ]),
- ]),
- ])
- )
-}
-
-function rpcValidation (newRpc, state) {
- if (validUrl.isWebUri(newRpc)) {
- state.dispatch(actions.setRpcTarget(newRpc))
- } else {
- var appendedRpc = `http://${newRpc}`
- if (validUrl.isWebUri(appendedRpc)) {
- state.dispatch(actions.displayWarning('URIs require the appropriate HTTP/HTTPS prefix.'))
- } else {
- state.dispatch(actions.displayWarning('Invalid RPC URI'))
- }
- }
-}
-
-function currentConversionInformation (metamaskState, state) {
- var currentCurrency = metamaskState.currentCurrency
- var conversionDate = metamaskState.conversionDate
- return h('div', [
- h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, 'Current Conversion'),
- h('span', {style: { fontWeight: 'bold', paddingRight: '10px', fontSize: '13px'}}, `Updated ${Date(conversionDate)}`),
- h('select#currentCurrency', {
- onChange (event) {
- event.preventDefault()
- var element = document.getElementById('currentCurrency')
- var newCurrency = element.value
- state.dispatch(actions.setCurrentCurrency(newCurrency))
- },
- defaultValue: currentCurrency,
- }, currencies.map((currency) => {
- return h('option', {key: currency.code, value: currency.code}, `${currency.code} - ${currency.name}`)
- })
- ),
- ])
-}
-
-function currentProviderDisplay (metamaskState) {
- var provider = metamaskState.provider
- var title, value
-
- switch (provider.type) {
-
- case 'mainnet':
- title = 'Current Network'
- value = 'Main Ethereum Network'
- break
-
- case 'ropsten':
- title = 'Current Network'
- value = 'Ropsten Test Network'
- break
-
- case 'kovan':
- title = 'Current Network'
- value = 'Kovan Test Network'
- break
-
- case 'rinkeby':
- title = 'Current Network'
- value = 'Rinkeby Test Network'
- break
-
- default:
- title = 'Current RPC'
- value = metamaskState.provider.rpcTarget
- }
-
- return h('div', [
- h('span', {style: { fontWeight: 'bold', paddingRight: '10px'}}, title),
- h('span', value),
- ])
-}
diff --git a/responsive-ui/app/conversion.json b/responsive-ui/app/conversion.json
deleted file mode 100644
index 155ffc4fc..000000000
--- a/responsive-ui/app/conversion.json
+++ /dev/null
@@ -1,207 +0,0 @@
-{
- "rows": [
- {
- "code": "REP",
- "name": "Augur",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "BCN",
- "name": "Bytecoin",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "BTC",
- "name": "Bitcoin",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "BTS",
- "name": "BitShares",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "BLK",
- "name": "Blackcoin",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "GBP",
- "name": "British Pound Sterling",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "CAD",
- "name": "Canadian Dollar",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "CNY",
- "name": "Chinese Yuan",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "DSH",
- "name": "Dashcoin",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "DOGE",
- "name": "Dogecoin",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "ETC",
- "name": "Ethereum Classic",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "EUR",
- "name": "Euro",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "GNO",
- "name": "GNO",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "GNT",
- "name": "GNT",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "JPY",
- "name": "Japanese Yen",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "LTC",
- "name": "Litecoin",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "MAID",
- "name": "MaidSafeCoin",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "XEM",
- "name": "NEM",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "XLM",
- "name": "Stellar",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "XMR",
- "name": "Monero",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "XRP",
- "name": "Ripple",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "RUR",
- "name": "Ruble",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "STEEM",
- "name": "Steem",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "STRAT",
- "name": "STRAT",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "UAH",
- "name": "Ukrainian Hryvnia",
- "statuses": [
- "secondary"
- ]
- },
- {
- "code": "USD",
- "name": "US Dollar",
- "statuses": [
- "primary",
- "secondary"
- ]
- },
- {
- "code": "WAVES",
- "name": "WAVES",
- "statuses": [
- "primary"
- ]
- },
- {
- "code": "ZEC",
- "name": "Zcash",
- "statuses": [
- "primary"
- ]
- }
- ]
-}
diff --git a/responsive-ui/app/css/debug.css b/responsive-ui/app/css/debug.css
deleted file mode 100644
index 3e125bcd4..000000000
--- a/responsive-ui/app/css/debug.css
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-debug / dev
-*/
-
-#app-content {
- border: 2px solid green;
-}
-
-#design-container {
- position: absolute;
- left: 360px;
- top: -42px;
- width: calc(100vw - 360px);
- height: 100vh;
- overflow: scroll;
-}
-
-#design-container img {
- width: 2000px;
- margin-right: 600px;
-} \ No newline at end of file
diff --git a/responsive-ui/app/css/fonts.css b/responsive-ui/app/css/fonts.css
deleted file mode 100644
index 3b9f581b9..000000000
--- a/responsive-ui/app/css/fonts.css
+++ /dev/null
@@ -1,36 +0,0 @@
-@import url(https://fonts.googleapis.com/css?family=Roboto:300,500);
-@import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css);
-
-@font-face {
- font-family: 'Montserrat Regular';
- src: url('/fonts/Montserrat/Montserrat-Regular.woff') format('woff');
- src: url('/fonts/Montserrat/Montserrat-Regular.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
- font-size: 'small';
-
-}
-
-@font-face {
- font-family: 'Montserrat Bold';
- src: url('/fonts/Montserrat/Montserrat-Bold.woff') format('woff');
- src: url('/fonts/Montserrat/Montserrat-Bold.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'Montserrat Light';
- src: url('/fonts/Montserrat/Montserrat-Light.woff') format('woff');
- src: url('/fonts/Montserrat/Montserrat-Light.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-
-@font-face {
- font-family: 'Montserrat UltraLight';
- src: url('/fonts/Montserrat/Montserrat-UltraLight.woff') format('woff');
- src: url('/fonts/Montserrat/Montserrat-UltraLight.ttf') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
diff --git a/responsive-ui/app/css/index.css b/responsive-ui/app/css/index.css
deleted file mode 100644
index 2ae92bbd6..000000000
--- a/responsive-ui/app/css/index.css
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
-faint orange (textfield shades) #FAF6F0
-light orange (button shades): #F5C26D
-dark orange (text): #F5A623
-borders/font/any gray: #4A4A4A
-*/
-
-/*
-application specific styles
-*/
-
-* {
- box-sizing: border-box;
-}
-
-html, body {
- font-family: 'Montserrat Regular', Arial;
- color: #4D4D4D;
- font-weight: 300;
- line-height: 1.4em;
- background: #F7F7F7;
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
-}
-
-.css-transition-group {
- flex: 1;
- height: 100%;
-}
-
-input:focus, textarea:focus {
- outline: none;
-}
-
-#app-content {
- overflow-x: hidden;
- min-width: 357px;
- height: 100%;
-}
-
-button, input[type="submit"] {
- font-family: 'Montserrat Bold';
- outline: none;
- cursor: pointer;
- padding: 8px 12px;
- border: none;
- color: white;
- transform-origin: center center;
- transition: transform 50ms ease-in;
- /* default orange */
- background: rgba(247, 134, 28, 1);
- box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36);
-}
-
-.btn-green, input[type="submit"].btn-green {
- background: rgba(106, 195, 96, 1);
- box-shadow: 0px 3px 6px rgba(106, 195, 96, 0.36);
-}
-
-.btn-red {
- background: rgba(254, 35, 17, 1);
- box-shadow: 0px 3px 6px rgba(254, 35, 17, 0.36);
-}
-
-button[disabled], input[type="submit"][disabled] {
- cursor: not-allowed;
- background: rgba(197, 197, 197, 1);
- box-shadow: 0px 3px 6px rgba(197, 197, 197, 0.36);
-}
-
-button.spaced {
- margin: 2px;
-}
-
-button:not([disabled]):hover, input[type="submit"]:not([disabled]):hover {
- transform: scale(1.1);
-}
-button:not([disabled]):active, input[type="submit"]:not([disabled]):active {
- transform: scale(0.95);
-}
-
-a {
- text-decoration: none;
- color: inherit;
-}
-
-a:hover{
- color: #df6b0e;
-}
-
-/*
-app
-*/
-
-.active {
- color: #909090;
-}
-
-button.primary {
- padding: 8px 12px;
- background: #F7861C;
- box-shadow: 0px 3px 6px rgba(247, 134, 28, 0.36);
- color: white;
- font-size: 1.1em;
- font-family: 'Montserrat Regular';
- text-transform: uppercase;
-}
-
-button.btn-thin {
- border: 1px solid;
- border-color: #4D4D4D;
- color: #4D4D4D;
- background: rgb(255, 174, 41);
- border-radius: 4px;
- min-width: 200px;
- margin: 12px 0;
- padding: 6px;
- font-size: 13px;
-}
-
-.app-header {
- padding: 6px 8px;
-}
-
-.app-header h1 {
- font-family: 'Montserrat Regular';
- text-transform: uppercase;
- color: #AEAEAE;
-}
-
-h2.page-subtitle {
- font-family: 'Montserrat Regular';
- text-transform: uppercase;
- color: #AEAEAE;
- font-size: 1em;
- margin: 12px;
-}
-
-.app-primary {
-
-}
-
-.app-footer {
- padding-bottom: 10px;
- align-items: center;
-}
-
-.identicon {
- height: 46px;
- width: 46px;
- background-size: cover;
- border-radius: 100%;
- border: 3px solid gray;
-}
-
-textarea.twelve-word-phrase {
- padding: 12px;
- width: 300px;
- height: 140px;
- font-size: 16px;
- background: white;
- resize: none;
-}
-
-.network-indicator {
- display: flex;
- align-items: center;
- font-size: 0.6em;
-
-}
-
-.network-name {
- width: 5.2em;
- line-height: 9px;
- text-rendering: geometricPrecision;
-}
-
-.check {
- margin-left: 7px;
- color: #F7861C;
- flex: 1 0 auto;
- display: flex;
- justify-content: flex-end;
-}
-/*
-app sections
-*/
-
-/* initialize */
-
-.initialize-screen hr {
- width: 60px;
- margin: 12px;
- border-color: #F7861C;
- border-style: solid;
-}
-
-.initialize-screen label {
- margin-top: 20px;
-}
-
-.initialize-screen button.create-vault {
- margin-top: 40px;
-}
-
-.initialize-screen .warning {
- font-size: 14px;
- margin: 0 16px;
-}
-
-/* unlock */
-.error {
- color: #E20202;
-}
-
-.warning {
- color: #FFAE00;
-}
-
-.lock {
- width: 50px;
- height: 50px;
-}
-
-.lock.locked {
- transform: scale(1.5);
- opacity: 0.0;
- transition: opacity 400ms ease-in, transform 400ms ease-in;
-}
-.lock.unlocked {
- transform: scale(1);
- opacity: 1;
- transition: opacity 500ms ease-out, transform 500ms ease-out, background 200ms ease-in;
-}
-
-.lock.locked .lock-top {
- transform: scaleX(1) translateX(0);
- transition: transform 250ms ease-in;
-}
-.lock.unlocked .lock-top {
- transform: scaleX(-1) translateX(-12px);
- transition: transform 250ms ease-in;
-}
-.lock.unlocked:hover {
- border-radius: 4px;
- background: #e5e5e5;
- border: 1px solid #b1b1b1;
-}
-.lock.unlocked:active {
- background: #c3c3c3;
-}
-
-.section-title .fa-arrow-left {
- margin: -2px 8px 0px -8px;
-}
-
-.unlock-screen #metamask-mascot-container {
- margin-top: 24px;
-}
-
-.unlock-screen h1 {
- margin-top: -28px;
- margin-bottom: 42px;
-}
-
-.unlock-screen input[type=password] {
- width: 260px;
- /*height: 36px;
- margin-bottom: 24px;
- padding: 8px;*/
-}
-
-.sizing-input{
- font-size: 14px;
- height: 30px;
- padding-left: 5px;
-}
-.editable-label{
- display: flex;
-}
-/* Webkit */
-.unlock-screen input::-webkit-input-placeholder {
- text-align: center;
- font-size: 1.2em;
-}
-/* Firefox 18- */
-.unlock-screen input:-moz-placeholder {
- text-align: center;
- font-size: 1.2em;
-}
-/* Firefox 19+ */
-.unlock-screen input::-moz-placeholder {
- text-align: center;
- font-size: 1.2em;
-}
-/* IE */
-.unlock-screen input:-ms-input-placeholder {
- text-align: center;
- font-size: 1.2em;
-}
-
-input.large-input, textarea.large-input {
- /*margin-bottom: 24px;*/
- padding: 8px;
-}
-
-input.large-input {
- height: 36px;
-}
-
-.letter-spacey {
- letter-spacing: 0.1em;
-}
-
-
-
-/* accounts */
-
-.accounts-section {
- margin: 0 0px;
-}
-
-.accounts-section .horizontal-line {
- margin: 0px 18px;
-}
-
-.accounts-list-option {
- height: 120px;
-}
-
-.accounts-list-option .identicon-wrapper {
- width: 100px;
-}
-
-.unconftx-link {
- margin-top: 24px;
- cursor: pointer;
-}
-
-.unconftx-link .fa-arrow-right {
- margin: 0px -8px 0px 8px;
-}
-
-/* identity panel */
-
-.identity-panel {
- font-weight: 500;
-}
-
-.identity-panel .identicon-wrapper {
- margin: 4px;
- margin-top: 8px;
- display: flex;
- align-items: center;
-}
-
-.identity-panel .identicon-wrapper span {
- margin: 0 auto;
-}
-
-.identity-panel .identity-data {
- margin: 8px 8px 8px 18px;
-}
-
-.identity-panel i {
- margin-top: 32px;
- margin-right: 6px;
- color: #B9B9B9;
-}
-
-.identity-panel .arrow-right {
- padding-left: 18px;
- width: 42px;
- min-width: 18px;
- height: 100%;
-}
-
-.identity-copy.flex-column {
- flex: 0.25 0 auto;
- justify-content: center;
-}
-
-/* accounts screen */
-
-.identity-section {
-
-}
-
-.identity-section .identity-panel {
- background: #E9E9E9;
- border-bottom: 1px solid #B1B1B1;
- cursor: pointer;
-}
-
-.identity-section .identity-panel.selected {
- background: white;
- color: #F3C83E;
-}
-
-.identity-section .identity-panel.selected .identicon {
- border-color: orange;
-}
-
-.identity-section .accounts-list-option:hover,
-.identity-section .accounts-list-option.selected {
- background:white;
-}
-
-/* account detail screen */
-
-.account-detail-section {
- display: flex;
- flex-wrap: wrap;
-}
-.name-label{
-
-}
-
-.unapproved-tx-icon {
- height: 16px;
- width: 16px;
- background: rgb(47, 174, 244);
- border-color: #AEAEAE;
- border-radius: 13px;
-}
-
-.edit-text {
- height: 100%;
- visibility: hidden;
-}
-.editing-label {
- display: flex;
- justify-content: flex-start;
- margin-left: 50px;
- margin-bottom: 2px;
- font-size: 11px;
- text-rendering: geometricPrecision;
- color: #F7861C;
-}
-.name-label:hover .edit-text {
- visibility: visible;
-}
-/* tx confirm */
-
-.unconftx-section input[type=password] {
- height: 22px;
- padding: 2px;
- margin: 12px;
- margin-bottom: 24px;
- border-radius: 4px;
- border: 2px solid #F3C83E;
- background: #FAF6F0;
-}
-
-/* Send Screen */
-
-.send-screen {
-
-}
-
-.send-screen section {
- margin: 8px 16px;
-}
-
-.send-screen input {
- width: 100%;
- font-size: 12px;
-}
-
-/* Ether Balance Widget */
-
-.ether-balance-amount {
- color: #F7861C;
-}
-
-.ether-balance-label {
- color: #ABA9AA;
-}
-
-/* Info screen */
-.info-gray{
- font-family: 'Montserrat Regular';
- text-transform: uppercase;
- color: #AEAEAE;
-}
-
-.icon-size{
- width: 20px;
-}
-
-.info{
- font-family: 'Montserrat Regular', Arial;
- padding-bottom: 10px;
- display: inline-block;
- padding-left: 5px;
-}
-
-/* buy eth warning screen */
-.custom-radios {
- justify-content: space-around;
- align-items: center;
-}
-
-
-.custom-radio-selected {
- width: 17px;
- height: 17px;
- border: solid;
- border-style: double;
- border-radius: 15px;
- border-width: 5px;
- background: rgba(247, 134, 28, 1);
- border-color: #F7F7F7;
-}
-
-.custom-radio-inactive {
- width: 14px;
- height: 14px;
- border: solid;
- border-width: 1px;
- border-radius: 24px;
- border-color: #AEAEAE;
-}
-
-.radio-titles {
- color: rgba(247, 134, 28, 1);
-}
-
-.radio-titles-subtext {
-
-}
-
-.selected-exchange {
-
-}
-
-.buy-radio {
-
-}
-
-.eth-warning{
- transition: opacity 400ms ease-in, transform 400ms ease-in;
-}
-
-.buy-subview{
- transition: opacity 400ms ease-in, transform 400ms ease-in;
-}
-
-.input-container:hover .edit-text{
- visibility: visible;
-}
-
-.buy-inputs{
- font-family: 'Montserrat Light';
- font-size: 13px;
- height: 20px;
- background: transparent;
- box-sizing: border-box;
- border: solid;
- border-color: transparent;
- border-width: 0.5px;
- border-radius: 2px;
-
-}
-.input-container:hover .buy-inputs{
- box-sizing: inherit;
- border: solid;
- border-color: #F7861C;
- border-width: 0.5px;
- border-radius: 2px;
-}
-
-.buy-inputs:focus{
- border: solid;
- border-color: #F7861C;
- border-width: 0.5px;
- border-radius: 2px;
-}
-
-.activeForm {
- background: #F7F7F7;
- border: none;
- border-radius: 8px 8px 0px 0px;
- width: 50%;
- text-align: center;
- padding-bottom: 4px;
-
-}
-
-.inactiveForm {
- border: none;
- border-radius: 8px 8px 0px 0px;
- width: 50%;
- text-align: center;
- padding-bottom: 4px;
-}
-
-.ex-coins {
- font-family: 'Montserrat Regular';
- text-transform: uppercase;
- text-align: center;
- font-size: 33px;
- width: 118px;
- height: 42px;
- padding: 1px;
- color: #4D4D4D;
-}
-
-.marketinfo{
- font-family: 'Montserrat light';
- color: #AEAEAE;
- font-size: 15px;
- line-height: 17px;
-}
-
-#fromCoin::-webkit-calendar-picker-indicator {
- display: none;
-}
-
-#coinList {
- width: 400px;
- height: 500px;
- overflow: scroll;
-}
-
-.icon-control .fa-refresh{
- visibility: hidden;
-}
-
-.icon-control:hover .fa-refresh{
- visibility: visible;
-}
-
-.icon-control:hover .fa-chevron-right{
- visibility: hidden;
-}
-
-.inactive {
- color: #AEAEAE;
-}
-
-.inactive button{
- background: #AEAEAE;
- color: white;
-}
-
-.ellip-address {
- overflow: hidden;
- text-overflow: ellipsis;
- width: 5em;
- font-size: 14px;
- font-family: "Montserrat Light";
- margin-left: 5px;
-}
-
-.qr-header {
- font-size: 25px;
- margin-top: 40px;
-}
-
-.qr-message {
- font-size: 12px;
- color: #F7861C;
-}
-
-div.message-container > div:first-child {
- margin-top: 18px;
- font-size: 15px;
- color: #4D4D4D;
-}
-
-.pop-hover:hover {
- transform: scale(1.1);
-}
diff --git a/responsive-ui/app/css/lib.css b/responsive-ui/app/css/lib.css
deleted file mode 100644
index b0ca958a2..000000000
--- a/responsive-ui/app/css/lib.css
+++ /dev/null
@@ -1,272 +0,0 @@
-/* color */
-
-.color-orange {
- color: #F7861C;
-}
-
-.color-forest {
- color: #0A5448;
-}
-
-/* lib */
-
-.full-width {
- width: 100%;
-}
-
-.full-height {
- height: 100%;
-}
-
-.flex-column {
- display: flex;
- flex-direction: column;
-}
-
-.space-between {
- justify-content: space-between;
-}
-
-.space-around {
- justify-content: space-around;
-}
-
-.flex-column-bottom {
- display: flex;
- flex-direction: column-reverse;
-}
-
-.flex-row {
- display: flex;
- flex-direction: row;
-}
-
-.flex-space-between {
- justify-content: space-between;
-}
-
-.flex-space-around {
- justify-content: space-around;
-}
-
-.flex-right {
- display: flex;
- flex-direction: row;
- justify-content: flex-end;
-}
-
-.flex-left {
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
-}
-
-.flex-fixed {
- flex: none;
-}
-
-.flex-basis-auto {
- flex-basis: auto;
-}
-
-.flex-grow {
- flex: 1 1 auto;
-}
-
-.flex-wrap {
- flex-wrap: wrap;
-}
-
-.flex-center {
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.flex-justify-center {
- justify-content: center;
-}
-
-.flex-align-center {
- align-items: center;
-}
-
-.flex-self-end {
- align-self: flex-end;
-}
-
-.flex-self-stretch {
- align-self: stretch;
-}
-
-.flex-vertical {
- flex-direction: column;
-}
-
-.z-bump {
- z-index: 1;
-}
-
-.select-none {
- cursor: inherit;
- -moz-user-select: none;
- -webkit-user-select: none;
- -ms-user-select: none;
- user-select: none;
-}
-
-.pointer {
- cursor: pointer;
-}
-.cursor-pointer {
- cursor: pointer;
- transform-origin: center center;
- transition: transform 50ms ease-in-out;
-}
-.cursor-pointer:hover {
- transform: scale(1.1);
-}
-.cursor-pointer:active {
- transform: scale(0.95);
-}
-
-.cursor-disabled {
- cursor: not-allowed;
-}
-
-.margin-bottom-sml {
- margin-bottom: 20px;
-}
-
-.margin-bottom-med {
- margin-bottom: 40px;
-}
-
-.margin-right-left {
- margin: 0 20px;
-}
-
-.bold {
- font-weight: bold;
-}
-
-.text-transform-uppercase {
- text-transform: uppercase;
-}
-
-.font-small {
- font-size: 12px;
-}
-
-.font-medium {
- font-size: 1.2em;
-}
-
-hr.horizontal-line {
- display: block;
- height: 1px;
- border: 0;
- border-top: 1px solid #ccc;
- margin: 1em 0;
- padding: 0;
-}
-
-.hover-white:hover {
- background: white;
-}
-
-.red-dot {
- background: #E91550;
- color: white;
- border-radius: 10px;
-}
-
-.diamond {
- transform: rotate(45deg);
- background: #038789;
-}
-
-.hollow-diamond {
- transform: rotate(45deg);
- border: 3px solid #690496;
-}
-
-.golden-square {
- background: #EBB33F;
-}
-
-.pending-dot {
- background: red;
- left: 14px;
- top: 14px;
- color: white;
- border-radius: 10px;
- height: 20px;
- min-width: 20px;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 4px;
- z-index: 1;
-}
-
-.keyring-label {
- z-index: 1;
- font-size: 11px;
- background: rgba(255,0,0,0.8);
- bottom: -47px;
- color: white;
- border-radius: 10px;
- height: 20px;
- min-width: 20px;
- position: relative;
- display: flex;
- align-items: center;
- justify-content: center;
- padding: 4px;
-}
-
-.ether-balance {
- display: flex;
- align-items: center;
-}
-
-.tabSection {
- min-width: 350px;
-}
-
-.menu-icon {
- display: inline-block;
- height: 9px;
- min-width: 9px;
- margin: 13px;
-}
-.ether-icon {
- background: rgb(0, 163, 68);
- border-radius: 20px;
-}
-.testnet-icon {
- background: #2465E1;
-}
-
-.drop-menu-item {
- display: flex;
- align-items: center;
-}
-
-.invisible {
- visibility: hidden;
-}
-
-.one-line-concat {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-.critical-error {
- text-align: center;
- margin-top: 20px;
- color: red;
-}
diff --git a/responsive-ui/app/css/reset.css b/responsive-ui/app/css/reset.css
deleted file mode 100644
index 9ce89e8bc..000000000
--- a/responsive-ui/app/css/reset.css
+++ /dev/null
@@ -1,48 +0,0 @@
-/* http://meyerweb.com/eric/tools/css/reset/
- v2.0 | 20110126
- License: none (public domain)
-*/
-
-html, body, div, span, applet, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-a, abbr, acronym, address, big, cite, code,
-del, dfn, em, img, ins, kbd, q, s, samp,
-small, strike, strong, sub, sup, tt, var,
-b, u, i, center,
-dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, embed,
-figure, figcaption, footer, header, hgroup,
-menu, nav, output, ruby, section, summary,
-time, mark, audio, video {
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-/* HTML5 display-role reset for older browsers */
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-body {
- line-height: 1;
-}
-ol, ul {
- list-style: none;
-}
-blockquote, q {
- quotes: none;
-}
-blockquote:before, blockquote:after,
-q:before, q:after {
- content: '';
- content: none;
-}
-table {
- border-collapse: collapse;
- border-spacing: 0;
-} \ No newline at end of file
diff --git a/responsive-ui/app/css/transitions.css b/responsive-ui/app/css/transitions.css
deleted file mode 100644
index 393a944f9..000000000
--- a/responsive-ui/app/css/transitions.css
+++ /dev/null
@@ -1,42 +0,0 @@
-/* universal */
-.app-primary .main-enter {
- position: absolute;
- width: 100%;
-}
-
-/* center position */
-.app-primary.from-right .main-enter-active,
-.app-primary.from-left .main-enter-active {
- overflow-x: hidden;
- transform: translateX(0px);
- transition: transform 300ms ease-in;
-}
-
-/* exited positions */
-.app-primary.from-left .main-leave-active {
- transform: translateX(360px);
- transition: transform 300ms ease-in;
-}
-.app-primary.from-right .main-leave-active {
- transform: translateX(-360px);
- transition: transform 300ms ease-in;
-}
-
-/* loader transitions */
-.loader-enter, .loader-leave-active {
- opacity: 0.0;
- transition: opacity 150 ease-in;
-}
-.loader-enter-active, .loader-leave {
- opacity: 1.0;
- transition: opacity 150 ease-in;
-}
-
-/* entering positions */
-.app-primary.from-right .main-enter:not(.main-enter-active) {
- transform: translateX(360px);
-}
-.app-primary.from-left .main-enter:not(.main-enter-active) {
- transform: translateX(-360px);
-}
-
diff --git a/responsive-ui/app/first-time/init-menu.js b/responsive-ui/app/first-time/init-menu.js
deleted file mode 100644
index cc7c51bd3..000000000
--- a/responsive-ui/app/first-time/init-menu.js
+++ /dev/null
@@ -1,179 +0,0 @@
-const inherits = require('util').inherits
-const EventEmitter = require('events').EventEmitter
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const Mascot = require('../components/mascot')
-const actions = require('../actions')
-const Tooltip = require('../components/tooltip')
-const getCaretCoordinates = require('textarea-caret')
-
-module.exports = connect(mapStateToProps)(InitializeMenuScreen)
-
-inherits(InitializeMenuScreen, Component)
-function InitializeMenuScreen () {
- Component.call(this)
- this.animationEventEmitter = new EventEmitter()
-}
-
-function mapStateToProps (state) {
- return {
- // state from plugin
- currentView: state.appState.currentView,
- warning: state.appState.warning,
- }
-}
-
-InitializeMenuScreen.prototype.render = function () {
- var state = this.props
-
- switch (state.currentView.name) {
-
- default:
- return this.renderMenu(state)
-
- }
-}
-
-// InitializeMenuScreen.prototype.componentDidMount = function(){
-// document.getElementById('password-box').focus()
-// }
-
-InitializeMenuScreen.prototype.renderMenu = function (state) {
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- h(Mascot, {
- animationEventEmitter: this.animationEventEmitter,
- }),
-
- h('h1', {
- style: {
- fontSize: '1.3em',
- textTransform: 'uppercase',
- color: '#7F8082',
- marginBottom: 10,
- },
- }, 'MetaMask'),
-
-
- h('div', [
- h('h3', {
- style: {
- fontSize: '0.8em',
- color: '#7F8082',
- display: 'inline',
- },
- }, 'Encrypt your new DEN'),
-
- h(Tooltip, {
- title: 'Your DEN is your password-encrypted storage within MetaMask.',
- }, [
- h('i.fa.fa-question-circle.pointer', {
- style: {
- fontSize: '18px',
- position: 'relative',
- color: 'rgb(247, 134, 28)',
- top: '2px',
- marginLeft: '4px',
- },
- }),
- ]),
- ]),
-
- h('span.in-progress-notification', state.warning),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'New Password (min 8 chars)',
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: 'Confirm Password',
- onKeyPress: this.createVaultOnEnter.bind(this),
- onInput: this.inputChanged.bind(this),
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
-
- h('button.primary', {
- onClick: this.createNewVaultAndKeychain.bind(this),
- style: {
- margin: 12,
- },
- }, 'Create'),
-
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: this.showRestoreVault.bind(this),
- style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
- },
- }, 'Import Existing DEN'),
- ]),
-
- ])
- )
-}
-
-InitializeMenuScreen.prototype.createVaultOnEnter = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.createNewVaultAndKeychain()
- }
-}
-
-InitializeMenuScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-InitializeMenuScreen.prototype.showRestoreVault = function () {
- this.props.dispatch(actions.showRestoreVault())
-}
-
-InitializeMenuScreen.prototype.createNewVaultAndKeychain = function () {
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
-
- if (password.length < 8) {
- this.warning = 'password not long enough'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- if (password !== passwordConfirm) {
- this.warning = 'passwords don\'t match'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
-
- this.props.dispatch(actions.createNewVaultAndKeychain(password))
-}
-
-InitializeMenuScreen.prototype.inputChanged = function (event) {
- // tell mascot to look at page action
- var element = event.target
- var boundingRect = element.getBoundingClientRect()
- var coordinates = getCaretCoordinates(element, element.selectionEnd)
- this.animationEventEmitter.emit('point', {
- x: boundingRect.left + coordinates.left - element.scrollLeft,
- y: boundingRect.top + coordinates.top - element.scrollTop,
- })
-}
diff --git a/responsive-ui/app/img/identicon-tardigrade.png b/responsive-ui/app/img/identicon-tardigrade.png
deleted file mode 100644
index 1742a32b8..000000000
--- a/responsive-ui/app/img/identicon-tardigrade.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/app/img/identicon-walrus.png b/responsive-ui/app/img/identicon-walrus.png
deleted file mode 100644
index d58fae912..000000000
--- a/responsive-ui/app/img/identicon-walrus.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/app/info.js b/responsive-ui/app/info.js
deleted file mode 100644
index e8470de97..000000000
--- a/responsive-ui/app/info.js
+++ /dev/null
@@ -1,154 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-
-module.exports = connect(mapStateToProps)(InfoScreen)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(InfoScreen, Component)
-function InfoScreen () {
- Component.call(this)
-}
-
-InfoScreen.prototype.render = function () {
- const state = this.props
- const version = global.platform.getVersion()
-
- return (
- h('.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: (event) => {
- state.dispatch(actions.goHome())
- },
- }),
- h('h2.page-subtitle', 'Info'),
- ]),
-
- // main view
- h('.flex-column.flex-justify-center.flex-grow.select-none', [
- h('.flex-space-around', {
- style: {
- padding: '20px',
- },
- }, [
- // current version number
-
- h('.info.info-gray', [
- h('div', 'Metamask'),
- h('div', {
- style: {
- marginBottom: '10px',
- },
- }, `Version: ${version}`),
- ]),
-
- h('div', {
- style: {
- marginBottom: '5px',
- }},
- [
- h('div', [
- h('a', {
- href: 'https://metamask.io/privacy.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Privacy Policy'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/terms.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Terms of Use'),
- ]),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/attributions.html',
- target: '_blank',
- onClick (event) { this.navigateTo(event.target.href) },
- }, [
- h('div.info', 'Attributions'),
- ]),
- ]),
- ]
- ),
-
- h('hr', {
- style: {
- margin: '10px 0 ',
- width: '7em',
- },
- }),
-
- h('div', {
- style: {
- paddingLeft: '30px',
- }},
- [
- h('div.fa.fa-github', [
- h('a.info', {
- href: 'https://github.com/MetaMask/faq',
- target: '_blank',
- }, 'Need Help? Read our FAQ!'),
- ]),
- h('div', [
- h('a', {
- href: 'https://metamask.io/',
- target: '_blank',
- }, [
- h('img.icon-size', {
- src: 'images/icon-128.png',
- style: {
- // IE6-9
- filter: 'grayscale(100%)',
- // Microsoft Edge and Firefox 35+
- WebkitFilter: 'grayscale(100%)',
- },
- }),
- h('div.info', 'Visit our web site'),
- ]),
- ]),
- h('div.fa.fa-slack', [
- h('a.info', {
- href: 'http://slack.metamask.io',
- target: '_blank',
- }, 'Join the conversation on Slack'),
- ]),
-
- h('div.fa.fa-twitter', [
- h('a.info', {
- href: 'https://twitter.com/metamask_io',
- target: '_blank',
- }, 'Follow us on Twitter'),
- ]),
-
- h('div.fa.fa-envelope', [
- h('a.info', {
- target: '_blank',
- style: { width: '85vw' },
- href: 'mailto:help@metamask.io?subject=Feedback',
- }, 'Email us!'),
- ]),
- ]),
- ]),
- ]),
- ])
- )
-}
-
-InfoScreen.prototype.navigateTo = function (url) {
- global.platform.openWindow({ url })
-}
-
diff --git a/responsive-ui/app/keychains/hd/create-vault-complete.js b/responsive-ui/app/keychains/hd/create-vault-complete.js
deleted file mode 100644
index c32751fff..000000000
--- a/responsive-ui/app/keychains/hd/create-vault-complete.js
+++ /dev/null
@@ -1,76 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../actions')
-
-module.exports = connect(mapStateToProps)(CreateVaultCompleteScreen)
-
-inherits(CreateVaultCompleteScreen, Component)
-function CreateVaultCompleteScreen () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- seed: state.appState.currentView.seedWords,
- cachedSeed: state.metamask.seedWords,
- }
-}
-
-CreateVaultCompleteScreen.prototype.render = function () {
- var state = this.props
- var seed = state.seed || state.cachedSeed || ''
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- // // subtitle and nav
- // h('.section-title.flex-row.flex-center', [
- // h('h2.page-subtitle', 'Vault Created'),
- // ]),
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: 36,
- marginBottom: 8,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Vault Created',
- ]),
-
- h('div', {
- style: {
- fontSize: '1em',
- marginTop: '10px',
- textAlign: 'center',
- },
- }, [
- h('span.error', 'These 12 words are the only way to restore your MetaMask accounts.\nSave them somewhere safe and secret.'),
- ]),
-
- h('textarea.twelve-word-phrase', {
- readOnly: true,
- value: seed,
- }),
-
- h('button.primary', {
- onClick: () => this.confirmSeedWords(),
- style: {
- margin: '24px',
- fontSize: '0.9em',
- },
- }, 'I\'ve copied it somewhere safe'),
- ])
- )
-}
-
-CreateVaultCompleteScreen.prototype.confirmSeedWords = function () {
- this.props.dispatch(actions.confirmSeedWords())
-}
diff --git a/responsive-ui/app/keychains/hd/recover-seed/confirmation.js b/responsive-ui/app/keychains/hd/recover-seed/confirmation.js
deleted file mode 100644
index 4ccbec9fc..000000000
--- a/responsive-ui/app/keychains/hd/recover-seed/confirmation.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const inherits = require('util').inherits
-
-const Component = require('react').Component
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../../actions')
-
-module.exports = connect(mapStateToProps)(RevealSeedConfirmation)
-
-inherits(RevealSeedConfirmation, Component)
-function RevealSeedConfirmation () {
- Component.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-RevealSeedConfirmation.prototype.render = function () {
- const props = this.props
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Reveal Seed Words',
- ]),
-
- h('.div', {
- style: {
- display: 'flex',
- flexDirection: 'column',
- padding: '20px',
- justifyContent: 'center',
- },
- }, [
-
- h('h4', 'Do not recover your seed words in a public place! These words can be used to steal all your accounts.'),
-
- // confirmation
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'Enter your password to confirm',
- onKeyPress: this.checkConfirmation.bind(this),
- style: {
- width: 260,
- marginTop: '12px',
- },
- }),
-
- h('.flex-row.flex-space-between', {
- style: {
- marginTop: 30,
- width: '50%',
- },
- }, [
- // cancel
- h('button.primary', {
- onClick: this.goHome.bind(this),
- }, 'CANCEL'),
-
- // submit
- h('button.primary', {
- onClick: this.revealSeedWords.bind(this),
- }, 'OK'),
-
- ]),
-
- (props.warning) && (
- h('span.error', {
- style: {
- margin: '20px',
- },
- }, props.warning.split('-'))
- ),
-
- props.inProgress && (
- h('span.in-progress-notification', 'Generating Seed...')
- ),
- ]),
- ])
- )
-}
-
-RevealSeedConfirmation.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-RevealSeedConfirmation.prototype.goHome = function () {
- this.props.dispatch(actions.showConfigPage(false))
-}
-
-// create vault
-
-RevealSeedConfirmation.prototype.checkConfirmation = function (event) {
- if (event.key === 'Enter') {
- event.preventDefault()
- this.revealSeedWords()
- }
-}
-
-RevealSeedConfirmation.prototype.revealSeedWords = function () {
- var password = document.getElementById('password-box').value
- this.props.dispatch(actions.requestRevealSeed(password))
-}
diff --git a/responsive-ui/app/keychains/hd/restore-vault.js b/responsive-ui/app/keychains/hd/restore-vault.js
deleted file mode 100644
index 06e51d9b3..000000000
--- a/responsive-ui/app/keychains/hd/restore-vault.js
+++ /dev/null
@@ -1,152 +0,0 @@
-const inherits = require('util').inherits
-const PersistentForm = require('../../../lib/persistent-form')
-const connect = require('react-redux').connect
-const h = require('react-hyperscript')
-const actions = require('../../actions')
-
-module.exports = connect(mapStateToProps)(RestoreVaultScreen)
-
-inherits(RestoreVaultScreen, PersistentForm)
-function RestoreVaultScreen () {
- PersistentForm.call(this)
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- forgottenPassword: state.appState.forgottenPassword,
- }
-}
-
-RestoreVaultScreen.prototype.render = function () {
- var state = this.props
- this.persistentFormParentId = 'restore-vault-form'
-
- return (
-
- h('.initialize-screen.flex-column.flex-center.flex-grow', [
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginBottom: 24,
- width: '100%',
- fontSize: '20px',
- padding: 6,
- },
- }, [
- 'Restore Vault',
- ]),
-
- // wallet seed entry
- h('h3', 'Wallet Seed'),
- h('textarea.twelve-word-phrase.letter-spacey', {
- dataset: {
- persistentFormId: 'wallet-seed',
- },
- placeholder: 'Enter your secret twelve word phrase here to restore your vault.',
- }),
-
- // password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box',
- placeholder: 'New Password (min 8 chars)',
- dataset: {
- persistentFormId: 'password',
- },
- style: {
- width: 260,
- marginTop: 12,
- },
- }),
-
- // confirm password
- h('input.large-input.letter-spacey', {
- type: 'password',
- id: 'password-box-confirm',
- placeholder: 'Confirm Password',
- onKeyPress: this.createOnEnter.bind(this),
- dataset: {
- persistentFormId: 'password-confirmation',
- },
- style: {
- width: 260,
- marginTop: 16,
- },
- }),
-
- (state.warning) && (
- h('span.error.in-progress-notification', state.warning)
- ),
-
- // submit
-
- h('.flex-row.flex-space-between', {
- style: {
- marginTop: 30,
- width: '50%',
- },
- }, [
-
- // cancel
- h('button.primary', {
- onClick: this.showInitializeMenu.bind(this),
- }, 'CANCEL'),
-
- // submit
- h('button.primary', {
- onClick: this.createNewVaultAndRestore.bind(this),
- }, 'OK'),
-
- ]),
- ])
-
- )
-}
-
-RestoreVaultScreen.prototype.showInitializeMenu = function () {
- if (this.props.forgottenPassword) {
- this.props.dispatch(actions.backToUnlockView())
- } else {
- this.props.dispatch(actions.showInitializeMenu())
- }
-}
-
-RestoreVaultScreen.prototype.createOnEnter = function (event) {
- if (event.key === 'Enter') {
- this.createNewVaultAndRestore()
- }
-}
-
-RestoreVaultScreen.prototype.createNewVaultAndRestore = function () {
- // check password
- var passwordBox = document.getElementById('password-box')
- var password = passwordBox.value
- var passwordConfirmBox = document.getElementById('password-box-confirm')
- var passwordConfirm = passwordConfirmBox.value
- if (password.length < 8) {
- this.warning = 'Password not long enough'
-
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- if (password !== passwordConfirm) {
- this.warning = 'Passwords don\'t match'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- // check seed
- var seedBox = document.querySelector('textarea.twelve-word-phrase')
- var seed = seedBox.value.trim()
- if (seed.split(' ').length !== 12) {
- this.warning = 'seed phrases are 12 words long'
- this.props.dispatch(actions.displayWarning(this.warning))
- return
- }
- // submit
- this.warning = null
- this.props.dispatch(actions.displayWarning(this.warning))
- this.props.dispatch(actions.createNewVaultAndRestore(password, seed))
-}
diff --git a/responsive-ui/app/new-keychain.js b/responsive-ui/app/new-keychain.js
deleted file mode 100644
index cc9633166..000000000
--- a/responsive-ui/app/new-keychain.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-
-module.exports = connect(mapStateToProps)(NewKeychain)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(NewKeychain, Component)
-function NewKeychain () {
- Component.call(this)
-}
-
-NewKeychain.prototype.render = function () {
- // const props = this.props
-
- return (
- h('div', {
- style: {
- background: 'blue',
- },
- }, [
- h('h1', `Here's a list!!!!`),
- ])
- )
-}
diff --git a/responsive-ui/app/reducers.js b/responsive-ui/app/reducers.js
deleted file mode 100644
index 11efca529..000000000
--- a/responsive-ui/app/reducers.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const extend = require('xtend')
-
-//
-// Sub-Reducers take in the complete state and return their sub-state
-//
-const reduceIdentities = require('./reducers/identities')
-const reduceMetamask = require('./reducers/metamask')
-const reduceApp = require('./reducers/app')
-
-window.METAMASK_CACHED_LOG_STATE = null
-
-module.exports = rootReducer
-
-function rootReducer (state, action) {
- // clone
- state = extend(state)
-
- if (action.type === 'GLOBAL_FORCE_UPDATE') {
- return action.value
- }
-
- //
- // Identities
- //
-
- state.identities = reduceIdentities(state, action)
-
- //
- // MetaMask
- //
-
- state.metamask = reduceMetamask(state, action)
-
- //
- // AppState
- //
-
- state.appState = reduceApp(state, action)
-
- window.METAMASK_CACHED_LOG_STATE = state
- return state
-}
-
-window.logState = function () {
- var stateString = JSON.stringify(window.METAMASK_CACHED_LOG_STATE, removeSeedWords, 2)
- console.log(stateString)
- return stateString
-}
-
-function removeSeedWords (key, value) {
- return key === 'seedWords' ? undefined : value
-}
diff --git a/responsive-ui/app/reducers/app.js b/responsive-ui/app/reducers/app.js
deleted file mode 100644
index 2fcc9bfe0..000000000
--- a/responsive-ui/app/reducers/app.js
+++ /dev/null
@@ -1,585 +0,0 @@
-const extend = require('xtend')
-const actions = require('../actions')
-const txHelper = require('../../lib/tx-helper')
-
-module.exports = reduceApp
-
-
-function reduceApp (state, action) {
- log.debug('App Reducer got ' + action.type)
- // clone and defaults
- const selectedAddress = state.metamask.selectedAddress
- const hasUnconfActions = checkUnconfActions(state)
- let name = 'accounts'
- if (selectedAddress) {
- name = 'accountDetail'
- }
- if (hasUnconfActions) {
- log.debug('pending txs detected, defaulting to conf-tx view.')
- name = 'confTx'
- }
-
- var defaultView = {
- name,
- detailView: null,
- context: selectedAddress,
- }
-
- // confirm seed words
- var seedWords = state.metamask.seedWords
- var seedConfView = {
- name: 'createVaultComplete',
- seedWords,
- }
-
- // default state
- var appState = extend({
- shouldClose: false,
- menuOpen: false,
- currentView: seedWords ? seedConfView : defaultView,
- accountDetail: {
- subview: 'transactions',
- },
- transForward: true, // Used to render transition direction
- isLoading: false, // Used to display loading indicator
- warning: null, // Used to display error text
- }, state.appState)
-
- switch (action.type) {
-
- // transition methods
-
- case actions.TRANSITION_FORWARD:
- return extend(appState, {
- transForward: true,
- })
-
- case actions.TRANSITION_BACKWARD:
- return extend(appState, {
- transForward: false,
- })
-
- // intialize
-
- case actions.SHOW_CREATE_VAULT:
- return extend(appState, {
- currentView: {
- name: 'createVault',
- },
- transForward: true,
- warning: null,
- })
-
- case actions.SHOW_RESTORE_VAULT:
- return extend(appState, {
- currentView: {
- name: 'restoreVault',
- },
- transForward: true,
- forgottenPassword: true,
- })
-
- case actions.FORGOT_PASSWORD:
- return extend(appState, {
- currentView: {
- name: 'restoreVault',
- },
- transForward: false,
- forgottenPassword: true,
- })
-
- case actions.SHOW_INIT_MENU:
- return extend(appState, {
- currentView: defaultView,
- transForward: false,
- })
-
- case actions.SHOW_CONFIG_PAGE:
- return extend(appState, {
- currentView: {
- name: 'config',
- context: appState.currentView.context,
- },
- transForward: action.value,
- })
-
- case actions.SHOW_ADD_TOKEN_PAGE:
- return extend(appState, {
- currentView: {
- name: 'add-token',
- context: appState.currentView.context,
- },
- transForward: action.value,
- })
-
- case actions.SHOW_IMPORT_PAGE:
-
- return extend(appState, {
- currentView: {
- name: 'import-menu',
- },
- transForward: true,
- })
-
- case actions.SHOW_INFO_PAGE:
- return extend(appState, {
- currentView: {
- name: 'info',
- context: appState.currentView.context,
- },
- transForward: true,
- })
-
- case actions.CREATE_NEW_VAULT_IN_PROGRESS:
- return extend(appState, {
- currentView: {
- name: 'createVault',
- inProgress: true,
- },
- transForward: true,
- isLoading: true,
- })
-
- case actions.SHOW_NEW_VAULT_SEED:
- return extend(appState, {
- currentView: {
- name: 'createVaultComplete',
- seedWords: action.value,
- },
- transForward: true,
- isLoading: false,
- })
-
- case actions.NEW_ACCOUNT_SCREEN:
- return extend(appState, {
- currentView: {
- name: 'new-account',
- context: appState.currentView.context,
- },
- transForward: true,
- })
-
- case actions.SHOW_SEND_PAGE:
- return extend(appState, {
- currentView: {
- name: 'sendTransaction',
- context: appState.currentView.context,
- },
- transForward: true,
- warning: null,
- })
-
- case actions.SHOW_NEW_KEYCHAIN:
- return extend(appState, {
- currentView: {
- name: 'newKeychain',
- context: appState.currentView.context,
- },
- transForward: true,
- })
-
- // unlock
-
- case actions.UNLOCK_METAMASK:
- return extend(appState, {
- forgottenPassword: appState.forgottenPassword ? !appState.forgottenPassword : null,
- detailView: {},
- transForward: true,
- isLoading: false,
- warning: null,
- })
-
- case actions.LOCK_METAMASK:
- return extend(appState, {
- currentView: defaultView,
- transForward: false,
- warning: null,
- })
-
- case actions.BACK_TO_INIT_MENU:
- return extend(appState, {
- warning: null,
- transForward: false,
- forgottenPassword: true,
- currentView: {
- name: 'InitMenu',
- },
- })
-
- case actions.BACK_TO_UNLOCK_VIEW:
- return extend(appState, {
- warning: null,
- transForward: true,
- forgottenPassword: false,
- currentView: {
- name: 'UnlockScreen',
- },
- })
- // reveal seed words
-
- case actions.REVEAL_SEED_CONFIRMATION:
- return extend(appState, {
- currentView: {
- name: 'reveal-seed-conf',
- },
- transForward: true,
- warning: null,
- })
-
- // accounts
-
- case actions.SET_SELECTED_ACCOUNT:
- return extend(appState, {
- activeAddress: action.value,
- })
-
- case actions.GO_HOME:
- return extend(appState, {
- currentView: extend(appState.currentView, {
- name: 'accountDetail',
- }),
- accountDetail: {
- subview: 'transactions',
- accountExport: 'none',
- privateKey: '',
- },
- transForward: false,
- warning: null,
- })
-
- case actions.SHOW_ACCOUNT_DETAIL:
- return extend(appState, {
- forgottenPassword: appState.forgottenPassword ? !appState.forgottenPassword : null,
- currentView: {
- name: 'accountDetail',
- context: action.value,
- },
- accountDetail: {
- subview: 'transactions',
- accountExport: 'none',
- privateKey: '',
- },
- transForward: false,
- })
-
- case actions.BACK_TO_ACCOUNT_DETAIL:
- return extend(appState, {
- currentView: {
- name: 'accountDetail',
- context: action.value,
- },
- accountDetail: {
- subview: 'transactions',
- accountExport: 'none',
- privateKey: '',
- },
- transForward: false,
- })
-
- case actions.SHOW_ACCOUNTS_PAGE:
- return extend(appState, {
- currentView: {
- name: seedWords ? 'createVaultComplete' : 'accounts',
- seedWords,
- },
- transForward: true,
- isLoading: false,
- warning: null,
- scrollToBottom: false,
- forgottenPassword: false,
- })
-
- case actions.SHOW_NOTICE:
- return extend(appState, {
- transForward: true,
- isLoading: false,
- })
-
- case actions.REVEAL_ACCOUNT:
- return extend(appState, {
- scrollToBottom: true,
- })
-
- case actions.SHOW_CONF_TX_PAGE:
- return extend(appState, {
- currentView: {
- name: 'confTx',
- context: 0,
- },
- transForward: action.transForward,
- warning: null,
- isLoading: false,
- })
-
- case actions.SHOW_CONF_MSG_PAGE:
- return extend(appState, {
- currentView: {
- name: hasUnconfActions ? 'confTx' : 'account-detail',
- context: 0,
- },
- transForward: true,
- warning: null,
- isLoading: false,
- })
-
- case actions.COMPLETED_TX:
- log.debug('reducing COMPLETED_TX for tx ' + action.value)
- const otherUnconfActions = getUnconfActionList(state)
- .filter(tx => tx.id !== action.value)
- const hasOtherUnconfActions = otherUnconfActions.length > 0
-
- if (hasOtherUnconfActions) {
- log.debug('reducer detected txs - rendering confTx view')
- return extend(appState, {
- transForward: false,
- currentView: {
- name: 'confTx',
- context: 0,
- },
- warning: null,
- })
- } else {
- log.debug('attempting to close popup')
- return extend(appState, {
- // indicate notification should close
- shouldClose: true,
- transForward: false,
- warning: null,
- currentView: {
- name: 'accountDetail',
- context: state.metamask.selectedAddress,
- },
- accountDetail: {
- subview: 'transactions',
- },
- })
- }
-
- case actions.NEXT_TX:
- return extend(appState, {
- transForward: true,
- currentView: {
- name: 'confTx',
- context: ++appState.currentView.context,
- warning: null,
- },
- })
-
- case actions.VIEW_PENDING_TX:
- const context = indexForPending(state, action.value)
- return extend(appState, {
- transForward: true,
- currentView: {
- name: 'confTx',
- context,
- warning: null,
- },
- })
-
- case actions.PREVIOUS_TX:
- return extend(appState, {
- transForward: false,
- currentView: {
- name: 'confTx',
- context: --appState.currentView.context,
- warning: null,
- },
- })
-
- case actions.TRANSACTION_ERROR:
- return extend(appState, {
- currentView: {
- name: 'confTx',
- errorMessage: 'There was a problem submitting this transaction.',
- },
- })
-
- case actions.UNLOCK_FAILED:
- return extend(appState, {
- warning: action.value || 'Incorrect password. Try again.',
- })
-
- case actions.SHOW_LOADING:
- return extend(appState, {
- isLoading: true,
- loadingMessage: action.value,
- })
-
- case actions.HIDE_LOADING:
- return extend(appState, {
- isLoading: false,
- })
-
- case actions.SHOW_SUB_LOADING_INDICATION:
- return extend(appState, {
- isSubLoading: true,
- })
-
- case actions.HIDE_SUB_LOADING_INDICATION:
- return extend(appState, {
- isSubLoading: false,
- })
- case actions.CLEAR_SEED_WORD_CACHE:
- return extend(appState, {
- transForward: true,
- currentView: {},
- isLoading: false,
- accountDetail: {
- subview: 'transactions',
- accountExport: 'none',
- privateKey: '',
- },
- })
-
- case actions.DISPLAY_WARNING:
- return extend(appState, {
- warning: action.value,
- isLoading: false,
- })
-
- case actions.HIDE_WARNING:
- return extend(appState, {
- warning: undefined,
- })
-
- case actions.REQUEST_ACCOUNT_EXPORT:
- return extend(appState, {
- transForward: true,
- currentView: {
- name: 'accountDetail',
- context: appState.currentView.context,
- },
- accountDetail: {
- subview: 'export',
- accountExport: 'requested',
- },
- })
-
- case actions.EXPORT_ACCOUNT:
- return extend(appState, {
- accountDetail: {
- subview: 'export',
- accountExport: 'completed',
- },
- })
-
- case actions.SHOW_PRIVATE_KEY:
- return extend(appState, {
- accountDetail: {
- subview: 'export',
- accountExport: 'completed',
- privateKey: action.value,
- },
- })
-
- case actions.BUY_ETH_VIEW:
- return extend(appState, {
- transForward: true,
- currentView: {
- name: 'buyEth',
- context: appState.currentView.name,
- },
- identity: state.metamask.identities[action.value],
- buyView: {
- subview: 'Coinbase',
- amount: '15.00',
- buyAddress: action.value,
- formView: {
- coinbase: true,
- shapeshift: false,
- },
- },
- })
-
- case actions.COINBASE_SUBVIEW:
- return extend(appState, {
- buyView: {
- subview: 'Coinbase',
- formView: {
- coinbase: true,
- shapeshift: false,
- },
- buyAddress: appState.buyView.buyAddress,
- amount: appState.buyView.amount,
- },
- })
-
- case actions.SHAPESHIFT_SUBVIEW:
- return extend(appState, {
- buyView: {
- subview: 'ShapeShift',
- formView: {
- coinbase: false,
- shapeshift: true,
- marketinfo: action.value.marketinfo,
- coinOptions: action.value.coinOptions,
- },
- buyAddress: appState.buyView.buyAddress,
- amount: appState.buyView.amount,
- },
- })
-
- case actions.PAIR_UPDATE:
- return extend(appState, {
- buyView: {
- subview: 'ShapeShift',
- formView: {
- coinbase: false,
- shapeshift: true,
- marketinfo: action.value.marketinfo,
- coinOptions: appState.buyView.formView.coinOptions,
- },
- buyAddress: appState.buyView.buyAddress,
- amount: appState.buyView.amount,
- warning: null,
- },
- })
-
- case actions.SHOW_QR:
- return extend(appState, {
- qrRequested: true,
- transForward: true,
-
- Qr: {
- message: action.value.message,
- data: action.value.data,
- },
- })
-
- case actions.SHOW_QR_VIEW:
- return extend(appState, {
- currentView: {
- name: 'qr',
- context: appState.currentView.context,
- },
- transForward: true,
- Qr: {
- message: action.value.message,
- data: action.value.data,
- },
- })
- default:
- return appState
- }
-}
-
-function checkUnconfActions (state) {
- const unconfActionList = getUnconfActionList(state)
- const hasUnconfActions = unconfActionList.length > 0
- return hasUnconfActions
-}
-
-function getUnconfActionList (state) {
- const { unapprovedTxs, unapprovedMsgs,
- unapprovedPersonalMsgs, network } = state.metamask
-
- const unconfActionList = txHelper(unapprovedTxs, unapprovedMsgs, unapprovedPersonalMsgs, network)
- return unconfActionList
-}
-
-function indexForPending (state, txId) {
- const unconfTxList = getUnconfActionList(state)
- const match = unconfTxList.find((tx) => tx.id === txId)
- const index = unconfTxList.indexOf(match)
- return index
-}
diff --git a/responsive-ui/app/reducers/identities.js b/responsive-ui/app/reducers/identities.js
deleted file mode 100644
index 341a404e7..000000000
--- a/responsive-ui/app/reducers/identities.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const extend = require('xtend')
-
-module.exports = reduceIdentities
-
-function reduceIdentities (state, action) {
- // clone + defaults
- var idState = extend({
-
- }, state.identities)
-
- switch (action.type) {
- default:
- return idState
- }
-}
diff --git a/responsive-ui/app/reducers/metamask.js b/responsive-ui/app/reducers/metamask.js
deleted file mode 100644
index e0c416c2d..000000000
--- a/responsive-ui/app/reducers/metamask.js
+++ /dev/null
@@ -1,137 +0,0 @@
-const extend = require('xtend')
-const actions = require('../actions')
-
-module.exports = reduceMetamask
-
-function reduceMetamask (state, action) {
- let newState
-
- // clone + defaults
- var metamaskState = extend({
- isInitialized: false,
- isUnlocked: false,
- rpcTarget: 'https://rawtestrpc.metamask.io/',
- identities: {},
- unapprovedTxs: {},
- noActiveNotices: true,
- lastUnreadNotice: undefined,
- frequentRpcList: [],
- addressBook: [],
- }, state.metamask)
-
- switch (action.type) {
-
- case actions.SHOW_ACCOUNTS_PAGE:
- newState = extend(metamaskState)
- delete newState.seedWords
- return newState
-
- case actions.SHOW_NOTICE:
- return extend(metamaskState, {
- noActiveNotices: false,
- lastUnreadNotice: action.value,
- })
-
- case actions.CLEAR_NOTICES:
- return extend(metamaskState, {
- noActiveNotices: true,
- })
-
- case actions.UPDATE_METAMASK_STATE:
- return extend(metamaskState, action.value)
-
- case actions.UNLOCK_METAMASK:
- return extend(metamaskState, {
- isUnlocked: true,
- isInitialized: true,
- selectedAddress: action.value,
- })
-
- case actions.LOCK_METAMASK:
- return extend(metamaskState, {
- isUnlocked: false,
- })
-
- case actions.SET_RPC_LIST:
- return extend(metamaskState, {
- frequentRpcList: action.value,
- })
-
- case actions.SET_RPC_TARGET:
- return extend(metamaskState, {
- provider: {
- type: 'rpc',
- rpcTarget: action.value,
- },
- })
-
- case actions.SET_PROVIDER_TYPE:
- return extend(metamaskState, {
- provider: {
- type: action.value,
- },
- })
-
- case actions.COMPLETED_TX:
- var stringId = String(action.id)
- newState = extend(metamaskState, {
- unapprovedTxs: {},
- unapprovedMsgs: {},
- })
- for (const id in metamaskState.unapprovedTxs) {
- if (id !== stringId) {
- newState.unapprovedTxs[id] = metamaskState.unapprovedTxs[id]
- }
- }
- for (const id in metamaskState.unapprovedMsgs) {
- if (id !== stringId) {
- newState.unapprovedMsgs[id] = metamaskState.unapprovedMsgs[id]
- }
- }
- return newState
-
- case actions.SHOW_NEW_VAULT_SEED:
- return extend(metamaskState, {
- isUnlocked: true,
- isInitialized: false,
- seedWords: action.value,
- })
-
- case actions.CLEAR_SEED_WORD_CACHE:
- newState = extend(metamaskState, {
- isUnlocked: true,
- isInitialized: true,
- selectedAddress: action.value,
- })
- delete newState.seedWords
- return newState
-
- case actions.SHOW_ACCOUNT_DETAIL:
- newState = extend(metamaskState, {
- isUnlocked: true,
- isInitialized: true,
- selectedAddress: action.value,
- })
- delete newState.seedWords
- return newState
-
- case actions.SAVE_ACCOUNT_LABEL:
- const account = action.value.account
- const name = action.value.label
- var id = {}
- id[account] = extend(metamaskState.identities[account], { name })
- var identities = extend(metamaskState.identities, id)
- return extend(metamaskState, { identities })
-
- case actions.SET_CURRENT_FIAT:
- return extend(metamaskState, {
- currentCurrency: action.value.currentCurrency,
- conversionRate: action.value.conversionRate,
- conversionDate: action.value.conversionDate,
- })
-
- default:
- return metamaskState
-
- }
-}
diff --git a/responsive-ui/app/root.js b/responsive-ui/app/root.js
deleted file mode 100644
index 9e7314b20..000000000
--- a/responsive-ui/app/root.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const Provider = require('react-redux').Provider
-const h = require('react-hyperscript')
-const App = require('./app')
-
-module.exports = Root
-
-inherits(Root, Component)
-function Root () { Component.call(this) }
-
-Root.prototype.render = function () {
- return (
-
- h(Provider, {
- store: this.props.store,
- }, [
- h(App),
- ])
-
- )
-}
diff --git a/responsive-ui/app/send.js b/responsive-ui/app/send.js
deleted file mode 100644
index a21a219eb..000000000
--- a/responsive-ui/app/send.js
+++ /dev/null
@@ -1,288 +0,0 @@
-const inherits = require('util').inherits
-const PersistentForm = require('../lib/persistent-form')
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const Identicon = require('./components/identicon')
-const actions = require('./actions')
-const util = require('./util')
-const numericBalance = require('./util').numericBalance
-const addressSummary = require('./util').addressSummary
-const isHex = require('./util').isHex
-const EthBalance = require('./components/eth-balance')
-const EnsInput = require('./components/ens-input')
-const ethUtil = require('ethereumjs-util')
-module.exports = connect(mapStateToProps)(SendTransactionScreen)
-
-function mapStateToProps (state) {
- var result = {
- address: state.metamask.selectedAddress,
- accounts: state.metamask.accounts,
- identities: state.metamask.identities,
- warning: state.appState.warning,
- network: state.metamask.network,
- addressBook: state.metamask.addressBook,
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- }
-
- result.error = result.warning && result.warning.split('.')[0]
-
- result.account = result.accounts[result.address]
- result.identity = result.identities[result.address]
- result.balance = result.account ? numericBalance(result.account.balance) : null
-
- return result
-}
-
-inherits(SendTransactionScreen, PersistentForm)
-function SendTransactionScreen () {
- PersistentForm.call(this)
-}
-
-SendTransactionScreen.prototype.render = function () {
- this.persistentFormParentId = 'send-tx-form'
-
- const props = this.props
- const {
- address,
- account,
- identity,
- network,
- identities,
- addressBook,
- conversionRate,
- currentCurrency,
- } = props
-
- return (
-
- h('.send-screen.flex-column.flex-grow', [
-
- //
- // Sender Profile
- //
-
- h('.account-data-subsection.flex-row.flex-grow', {
- style: {
- margin: '0 20px',
- },
- }, [
-
- // header - identicon + nav
- h('.flex-row.flex-space-between', {
- style: {
- marginTop: '15px',
- },
- }, [
- // back button
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer.color-orange', {
- onClick: this.back.bind(this),
- }),
-
- // large identicon
- h('.identicon-wrapper.flex-column.flex-center.select-none', [
- h(Identicon, {
- diameter: 62,
- address: address,
- }),
- ]),
-
- // invisible place holder
- h('i.fa.fa-users.fa-lg.invisible', {
- style: {
- marginTop: '28px',
- },
- }),
-
- ]),
-
- // account label
-
- h('.flex-column', {
- style: {
- marginTop: '10px',
- alignItems: 'flex-start',
- },
- }, [
- h('h2.font-medium.color-forest.flex-center', {
- style: {
- paddingTop: '8px',
- marginBottom: '8px',
- },
- }, identity && identity.name),
-
- // address and getter actions
- h('.flex-row.flex-center', {
- style: {
- marginBottom: '8px',
- },
- }, [
-
- h('div', {
- style: {
- lineHeight: '16px',
- },
- }, addressSummary(address)),
-
- ]),
-
- // balance
- h('.flex-row.flex-center', [
-
- h(EthBalance, {
- value: account && account.balance,
- conversionRate,
- currentCurrency,
- }),
-
- ]),
- ]),
- ]),
-
- //
- // Required Fields
- //
-
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: '15px',
- marginBottom: '16px',
- },
- }, [
- 'Send Transaction',
- ]),
-
- // error message
- props.error && h('span.error.flex-center', props.error),
-
- // 'to' field
- h('section.flex-row.flex-center', [
- h(EnsInput, {
- name: 'address',
- placeholder: 'Recipient Address',
- onChange: this.recipientDidChange.bind(this),
- network,
- identities,
- addressBook,
- }),
- ]),
-
- // 'amount' and send button
- h('section.flex-row.flex-center', [
-
- h('input.large-input', {
- name: 'amount',
- placeholder: 'Amount',
- type: 'number',
- style: {
- marginRight: '6px',
- },
- dataset: {
- persistentFormId: 'tx-amount',
- },
- }),
-
- h('button.primary', {
- onClick: this.onSubmit.bind(this),
- style: {
- textTransform: 'uppercase',
- },
- }, 'Next'),
-
- ]),
-
- //
- // Optional Fields
- //
- h('h3.flex-center.text-transform-uppercase', {
- style: {
- background: '#EBEBEB',
- color: '#AEAEAE',
- marginTop: '16px',
- marginBottom: '16px',
- },
- }, [
- 'Transaction Data (optional)',
- ]),
-
- // 'data' field
- h('section.flex-column.flex-center', [
- h('input.large-input', {
- name: 'txData',
- placeholder: '0x01234',
- style: {
- width: '100%',
- resize: 'none',
- },
- dataset: {
- persistentFormId: 'tx-data',
- },
- }),
- ]),
- ])
- )
-}
-
-SendTransactionScreen.prototype.navigateToAccounts = function (event) {
- event.stopPropagation()
- this.props.dispatch(actions.showAccountsPage())
-}
-
-SendTransactionScreen.prototype.back = function () {
- var address = this.props.address
- this.props.dispatch(actions.backToAccountDetail(address))
-}
-
-SendTransactionScreen.prototype.recipientDidChange = function (recipient, nickname) {
- this.setState({
- recipient: recipient,
- nickname: nickname,
- })
-}
-
-SendTransactionScreen.prototype.onSubmit = function () {
- const state = this.state || {}
- const recipient = state.recipient || document.querySelector('input[name="address"]').value.replace(/^[.\s]+|[.\s]+$/g, '')
- const nickname = state.nickname || ' '
- const input = document.querySelector('input[name="amount"]').value
- const value = util.normalizeEthStringToWei(input)
- const txData = document.querySelector('input[name="txData"]').value
- const balance = this.props.balance
- let message
-
- if (value.gt(balance)) {
- message = 'Insufficient funds.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if (input < 0) {
- message = 'Can not send negative amounts of ETH.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if ((!util.isValidAddress(recipient) && !txData) || (!recipient && !txData)) {
- message = 'Recipient address is invalid.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- if (!isHex(ethUtil.stripHexPrefix(txData)) && txData) {
- message = 'Transaction data must be hex string.'
- return this.props.dispatch(actions.displayWarning(message))
- }
-
- this.props.dispatch(actions.hideWarning())
-
- this.props.dispatch(actions.addToAddressBook(recipient, nickname))
-
- var txParams = {
- from: this.props.address,
- value: '0x' + value.toString(16),
- }
-
- if (recipient) txParams.to = ethUtil.addHexPrefix(recipient)
- if (txData) txParams.data = txData
-
- this.props.dispatch(actions.signTx(txParams))
-}
diff --git a/responsive-ui/app/settings.js b/responsive-ui/app/settings.js
deleted file mode 100644
index 454cc95e0..000000000
--- a/responsive-ui/app/settings.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-
-module.exports = connect(mapStateToProps)(AppSettingsPage)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(AppSettingsPage, Component)
-function AppSettingsPage () {
- Component.call(this)
-}
-
-AppSettingsPage.prototype.render = function () {
- return (
-
- h('.account-detail-section.flex-column.flex-grow', [
-
- // subtitle and nav
- h('.flex-row.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: this.navigateToAccounts.bind(this),
- }),
- h('h2.page-subtitle', 'Settings'),
- ]),
-
- h('label', {
- htmlFor: 'settings-rpc-endpoint',
- }, 'RPC Endpoint:'),
- h('input', {
- type: 'url',
- id: 'settings-rpc-endpoint',
- onKeyPress: this.onKeyPress.bind(this),
- }),
-
- ])
-
- )
-}
-
-AppSettingsPage.prototype.componentDidMount = function () {
- document.querySelector('input').focus()
-}
-
-AppSettingsPage.prototype.onKeyPress = function (event) {
- // get submit event
- if (event.key === 'Enter') {
- // this.submitPassword(event)
- }
-}
-
-AppSettingsPage.prototype.navigateToAccounts = function (event) {
- event.stopPropagation()
- this.props.dispatch(actions.showAccountsPage())
-}
diff --git a/responsive-ui/app/store.js b/responsive-ui/app/store.js
deleted file mode 100644
index ba9e58b49..000000000
--- a/responsive-ui/app/store.js
+++ /dev/null
@@ -1,21 +0,0 @@
-const createStore = require('redux').createStore
-const applyMiddleware = require('redux').applyMiddleware
-const thunkMiddleware = require('redux-thunk')
-const rootReducer = require('./reducers')
-const createLogger = require('redux-logger')
-
-global.METAMASK_DEBUG = 'GULP_METAMASK_DEBUG'
-
-module.exports = configureStore
-
-const loggerMiddleware = createLogger({
- predicate: () => global.METAMASK_DEBUG,
-})
-
-const middlewares = [thunkMiddleware, loggerMiddleware]
-
-const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore)
-
-function configureStore (initialState) {
- return createStoreWithMiddleware(rootReducer, initialState)
-}
diff --git a/responsive-ui/app/template.js b/responsive-ui/app/template.js
deleted file mode 100644
index d15b30fd2..000000000
--- a/responsive-ui/app/template.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-
-module.exports = connect(mapStateToProps)(COMPONENTNAME)
-
-function mapStateToProps (state) {
- return {}
-}
-
-inherits(COMPONENTNAME, Component)
-function COMPONENTNAME () {
- Component.call(this)
-}
-
-COMPONENTNAME.prototype.render = function () {
- const props = this.props
-
- return (
- h('div', {
- style: {
- background: 'blue',
- },
- }, [
- `Hello, ${props.sender}`,
- ])
- )
-}
-
diff --git a/responsive-ui/app/unlock.js b/responsive-ui/app/unlock.js
deleted file mode 100644
index 1aee3c5d0..000000000
--- a/responsive-ui/app/unlock.js
+++ /dev/null
@@ -1,118 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('./actions')
-const getCaretCoordinates = require('textarea-caret')
-const EventEmitter = require('events').EventEmitter
-
-const Mascot = require('./components/mascot')
-
-module.exports = connect(mapStateToProps)(UnlockScreen)
-
-inherits(UnlockScreen, Component)
-function UnlockScreen () {
- Component.call(this)
- this.animationEventEmitter = new EventEmitter()
-}
-
-function mapStateToProps (state) {
- return {
- warning: state.appState.warning,
- }
-}
-
-UnlockScreen.prototype.render = function () {
- const state = this.props
- const warning = state.warning
- return (
- h('.flex-column', [
- h('.unlock-screen.flex-column.flex-center.flex-grow', [
-
- h(Mascot, {
- animationEventEmitter: this.animationEventEmitter,
- }),
-
- h('h1', {
- style: {
- fontSize: '1.4em',
- textTransform: 'uppercase',
- color: '#7F8082',
- },
- }, 'MetaMask'),
-
- h('input.large-input', {
- type: 'password',
- id: 'password-box',
- placeholder: 'enter password',
- style: {
-
- },
- onKeyPress: this.onKeyPress.bind(this),
- onInput: this.inputChanged.bind(this),
- }),
-
- h('.error', {
- style: {
- display: warning ? 'block' : 'none',
- padding: '0 20px',
- textAlign: 'center',
- },
- }, warning),
-
- h('button.primary.cursor-pointer', {
- onClick: this.onSubmit.bind(this),
- style: {
- margin: 10,
- },
- }, 'Unlock'),
- ]),
-
- h('.flex-row.flex-center.flex-grow', [
- h('p.pointer', {
- onClick: () => this.props.dispatch(actions.forgotPassword()),
- style: {
- fontSize: '0.8em',
- color: 'rgb(247, 134, 28)',
- textDecoration: 'underline',
- },
- }, 'I forgot my password.'),
- ]),
- ])
- )
-}
-
-UnlockScreen.prototype.componentDidMount = function () {
- document.getElementById('password-box').focus()
-}
-
-UnlockScreen.prototype.onSubmit = function (event) {
- const input = document.getElementById('password-box')
- const password = input.value
- this.props.dispatch(actions.tryUnlockMetamask(password))
-}
-
-UnlockScreen.prototype.onKeyPress = function (event) {
- if (event.key === 'Enter') {
- this.submitPassword(event)
- }
-}
-
-UnlockScreen.prototype.submitPassword = function (event) {
- var element = event.target
- var password = element.value
- // reset input
- element.value = ''
- this.props.dispatch(actions.tryUnlockMetamask(password))
-}
-
-UnlockScreen.prototype.inputChanged = function (event) {
- // tell mascot to look at page action
- var element = event.target
- var boundingRect = element.getBoundingClientRect()
- var coordinates = getCaretCoordinates(element, element.selectionEnd)
- this.animationEventEmitter.emit('point', {
- x: boundingRect.left + coordinates.left - element.scrollLeft,
- y: boundingRect.top + coordinates.top - element.scrollTop,
- })
-}
diff --git a/responsive-ui/app/util.js b/responsive-ui/app/util.js
deleted file mode 100644
index ac3f42c6b..000000000
--- a/responsive-ui/app/util.js
+++ /dev/null
@@ -1,217 +0,0 @@
-const ethUtil = require('ethereumjs-util')
-
-var valueTable = {
- wei: '1000000000000000000',
- kwei: '1000000000000000',
- mwei: '1000000000000',
- gwei: '1000000000',
- szabo: '1000000',
- finney: '1000',
- ether: '1',
- kether: '0.001',
- mether: '0.000001',
- gether: '0.000000001',
- tether: '0.000000000001',
-}
-var bnTable = {}
-for (var currency in valueTable) {
- bnTable[currency] = new ethUtil.BN(valueTable[currency], 10)
-}
-
-module.exports = {
- valuesFor: valuesFor,
- addressSummary: addressSummary,
- miniAddressSummary: miniAddressSummary,
- isAllOneCase: isAllOneCase,
- isValidAddress: isValidAddress,
- numericBalance: numericBalance,
- parseBalance: parseBalance,
- formatBalance: formatBalance,
- generateBalanceObject: generateBalanceObject,
- dataSize: dataSize,
- readableDate: readableDate,
- normalizeToWei: normalizeToWei,
- normalizeEthStringToWei: normalizeEthStringToWei,
- normalizeNumberToWei: normalizeNumberToWei,
- valueTable: valueTable,
- bnTable: bnTable,
- isHex: isHex,
-}
-
-function valuesFor (obj) {
- if (!obj) return []
- return Object.keys(obj)
- .map(function (key) { return obj[key] })
-}
-
-function addressSummary (address, firstSegLength = 10, lastSegLength = 4, includeHex = true) {
- if (!address) return ''
- let checked = ethUtil.toChecksumAddress(address)
- if (!includeHex) {
- checked = ethUtil.stripHexPrefix(checked)
- }
- return checked ? checked.slice(0, firstSegLength) + '...' + checked.slice(checked.length - lastSegLength) : '...'
-}
-
-function miniAddressSummary (address) {
- if (!address) return ''
- var checked = ethUtil.toChecksumAddress(address)
- return checked ? checked.slice(0, 4) + '...' + checked.slice(-4) : '...'
-}
-
-function isValidAddress (address) {
- var prefixed = ethUtil.addHexPrefix(address)
- if (address === '0x0000000000000000000000000000000000000000') return false
- return (isAllOneCase(prefixed) && ethUtil.isValidAddress(prefixed)) || ethUtil.isValidChecksumAddress(prefixed)
-}
-
-function isAllOneCase (address) {
- if (!address) return true
- var lower = address.toLowerCase()
- var upper = address.toUpperCase()
- return address === lower || address === upper
-}
-
-// Takes wei Hex, returns wei BN, even if input is null
-function numericBalance (balance) {
- if (!balance) return new ethUtil.BN(0, 16)
- var stripped = ethUtil.stripHexPrefix(balance)
- return new ethUtil.BN(stripped, 16)
-}
-
-// Takes hex, returns [beforeDecimal, afterDecimal]
-function parseBalance (balance) {
- var beforeDecimal, afterDecimal
- const wei = numericBalance(balance)
- var weiString = wei.toString()
- const trailingZeros = /0+$/
-
- beforeDecimal = weiString.length > 18 ? weiString.slice(0, weiString.length - 18) : '0'
- afterDecimal = ('000000000000000000' + wei).slice(-18).replace(trailingZeros, '')
- if (afterDecimal === '') { afterDecimal = '0' }
- return [beforeDecimal, afterDecimal]
-}
-
-// Takes wei hex, returns an object with three properties.
-// Its "formatted" property is what we generally use to render values.
-function formatBalance (balance, decimalsToKeep, needsParse = true) {
- var parsed = needsParse ? parseBalance(balance) : balance.split('.')
- var beforeDecimal = parsed[0]
- var afterDecimal = parsed[1]
- var formatted = 'None'
- if (decimalsToKeep === undefined) {
- if (beforeDecimal === '0') {
- if (afterDecimal !== '0') {
- var sigFigs = afterDecimal.match(/^0*(.{2})/) // default: grabs 2 most significant digits
- if (sigFigs) { afterDecimal = sigFigs[0] }
- formatted = '0.' + afterDecimal + ' ETH'
- }
- } else {
- formatted = beforeDecimal + '.' + afterDecimal.slice(0, 3) + ' ETH'
- }
- } else {
- afterDecimal += Array(decimalsToKeep).join('0')
- formatted = beforeDecimal + '.' + afterDecimal.slice(0, decimalsToKeep) + ' ETH'
- }
- return formatted
-}
-
-
-function generateBalanceObject (formattedBalance, decimalsToKeep = 1) {
- var balance = formattedBalance.split(' ')[0]
- var label = formattedBalance.split(' ')[1]
- var beforeDecimal = balance.split('.')[0]
- var afterDecimal = balance.split('.')[1]
- var shortBalance = shortenBalance(balance, decimalsToKeep)
-
- if (beforeDecimal === '0' && afterDecimal.substr(0, 5) === '00000') {
- // eslint-disable-next-line eqeqeq
- if (afterDecimal == 0) {
- balance = '0'
- } else {
- balance = '<1.0e-5'
- }
- } else if (beforeDecimal !== '0') {
- balance = `${beforeDecimal}.${afterDecimal.slice(0, decimalsToKeep)}`
- }
-
- return { balance, label, shortBalance }
-}
-
-function shortenBalance (balance, decimalsToKeep = 1) {
- var truncatedValue
- var convertedBalance = parseFloat(balance)
- if (convertedBalance > 1000000) {
- truncatedValue = (balance / 1000000).toFixed(decimalsToKeep)
- return `${truncatedValue}m`
- } else if (convertedBalance > 1000) {
- truncatedValue = (balance / 1000).toFixed(decimalsToKeep)
- return `${truncatedValue}k`
- } else if (convertedBalance === 0) {
- return '0'
- } else if (convertedBalance < 0.001) {
- return '<0.001'
- } else if (convertedBalance < 1) {
- var stringBalance = convertedBalance.toString()
- if (stringBalance.split('.')[1].length > 3) {
- return convertedBalance.toFixed(3)
- } else {
- return stringBalance
- }
- } else {
- return convertedBalance.toFixed(decimalsToKeep)
- }
-}
-
-function dataSize (data) {
- var size = data ? ethUtil.stripHexPrefix(data).length : 0
- return size + ' bytes'
-}
-
-// Takes a BN and an ethereum currency name,
-// returns a BN in wei
-function normalizeToWei (amount, currency) {
- try {
- return amount.mul(bnTable.wei).div(bnTable[currency])
- } catch (e) {}
- return amount
-}
-
-function normalizeEthStringToWei (str) {
- const parts = str.split('.')
- let eth = new ethUtil.BN(parts[0], 10).mul(bnTable.wei)
- if (parts[1]) {
- var decimal = parts[1]
- while (decimal.length < 18) {
- decimal += '0'
- }
- const decimalBN = new ethUtil.BN(decimal, 10)
- eth = eth.add(decimalBN)
- }
- return eth
-}
-
-var multiple = new ethUtil.BN('10000', 10)
-function normalizeNumberToWei (n, currency) {
- var enlarged = n * 10000
- var amount = new ethUtil.BN(String(enlarged), 10)
- return normalizeToWei(amount, currency).div(multiple)
-}
-
-function readableDate (ms) {
- var date = new Date(ms)
- var month = date.getMonth()
- var day = date.getDate()
- var year = date.getFullYear()
- var hours = date.getHours()
- var minutes = '0' + date.getMinutes()
- var seconds = '0' + date.getSeconds()
-
- var dateStr = `${month}/${day}/${year}`
- var time = `${hours}:${minutes.substr(-2)}:${seconds.substr(-2)}`
- return `${dateStr} ${time}`
-}
-
-function isHex (str) {
- return Boolean(str.match(/^(0x)?[0-9a-fA-F]+$/))
-}
diff --git a/responsive-ui/css.js b/responsive-ui/css.js
deleted file mode 100644
index 043363cd7..000000000
--- a/responsive-ui/css.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-
-module.exports = bundleCss
-
-var cssFiles = {
- 'fonts.css': fs.readFileSync(path.join(__dirname, '/app/css/fonts.css'), 'utf8'),
- 'reset.css': fs.readFileSync(path.join(__dirname, '/app/css/reset.css'), 'utf8'),
- 'lib.css': fs.readFileSync(path.join(__dirname, '/app/css/lib.css'), 'utf8'),
- 'index.css': fs.readFileSync(path.join(__dirname, '/app/css/index.css'), 'utf8'),
- 'transitions.css': fs.readFileSync(path.join(__dirname, '/app/css/transitions.css'), 'utf8'),
- 'react-tooltip-component.css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-tooltip-component', 'dist', 'react-tooltip-component.css'), 'utf8'),
- 'react-css': fs.readFileSync(path.join(__dirname, '..', 'node_modules', 'react-select', 'dist', 'react-select.css'), 'utf8'),
-}
-
-function bundleCss () {
- var cssBundle = Object.keys(cssFiles).reduce(function (bundle, fileName) {
- var fileContent = cssFiles[fileName]
- var output = String()
-
- output += '/*========== ' + fileName + ' ==========*/\n\n'
- output += fileContent
- output += '\n\n'
-
- return bundle + output
- }, String())
-
- return cssBundle
-}
diff --git a/responsive-ui/design/00-metamask-SignIn.jpg b/responsive-ui/design/00-metamask-SignIn.jpg
deleted file mode 100644
index 2becdb032..000000000
--- a/responsive-ui/design/00-metamask-SignIn.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/01-metamask-SelectAcc.jpg b/responsive-ui/design/01-metamask-SelectAcc.jpg
deleted file mode 100644
index 239091a98..000000000
--- a/responsive-ui/design/01-metamask-SelectAcc.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/02-metamask-AccDetails.jpg b/responsive-ui/design/02-metamask-AccDetails.jpg
deleted file mode 100644
index d7d408ffc..000000000
--- a/responsive-ui/design/02-metamask-AccDetails.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/02a-metamask-AccDetails-OverToken.jpg b/responsive-ui/design/02a-metamask-AccDetails-OverToken.jpg
deleted file mode 100644
index f26ff31e8..000000000
--- a/responsive-ui/design/02a-metamask-AccDetails-OverToken.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/02a-metamask-AccDetails-OverTransaction.jpg b/responsive-ui/design/02a-metamask-AccDetails-OverTransaction.jpg
deleted file mode 100644
index 8a06be6b9..000000000
--- a/responsive-ui/design/02a-metamask-AccDetails-OverTransaction.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/02a-metamask-AccDetails.jpg b/responsive-ui/design/02a-metamask-AccDetails.jpg
deleted file mode 100644
index c37e0f539..000000000
--- a/responsive-ui/design/02a-metamask-AccDetails.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/02b-metamask-AccDetails-Send.jpg b/responsive-ui/design/02b-metamask-AccDetails-Send.jpg
deleted file mode 100644
index 10f2d27fd..000000000
--- a/responsive-ui/design/02b-metamask-AccDetails-Send.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/03-metamask-Qr.jpg b/responsive-ui/design/03-metamask-Qr.jpg
deleted file mode 100644
index 9c09de42f..000000000
--- a/responsive-ui/design/03-metamask-Qr.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/05-metamask-Menu.jpg b/responsive-ui/design/05-metamask-Menu.jpg
deleted file mode 100644
index 0a43d7b2a..000000000
--- a/responsive-ui/design/05-metamask-Menu.jpg
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/final_screen_dao_accounts.png b/responsive-ui/design/chromeStorePics/final_screen_dao_accounts.png
deleted file mode 100644
index 805cc96b6..000000000
--- a/responsive-ui/design/chromeStorePics/final_screen_dao_accounts.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/final_screen_dao_locked.png b/responsive-ui/design/chromeStorePics/final_screen_dao_locked.png
deleted file mode 100644
index 9d9e33930..000000000
--- a/responsive-ui/design/chromeStorePics/final_screen_dao_locked.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/final_screen_dao_notification.png b/responsive-ui/design/chromeStorePics/final_screen_dao_notification.png
deleted file mode 100644
index d56a5ce62..000000000
--- a/responsive-ui/design/chromeStorePics/final_screen_dao_notification.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/final_screen_wei_account.png b/responsive-ui/design/chromeStorePics/final_screen_wei_account.png
deleted file mode 100644
index d503ff301..000000000
--- a/responsive-ui/design/chromeStorePics/final_screen_wei_account.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/final_screen_wei_notification.png b/responsive-ui/design/chromeStorePics/final_screen_wei_notification.png
deleted file mode 100644
index 3560c51ff..000000000
--- a/responsive-ui/design/chromeStorePics/final_screen_wei_notification.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/icon-128.png b/responsive-ui/design/chromeStorePics/icon-128.png
deleted file mode 100644
index ae687147d..000000000
--- a/responsive-ui/design/chromeStorePics/icon-128.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/icon-64.png b/responsive-ui/design/chromeStorePics/icon-64.png
deleted file mode 100644
index 7062cf4f1..000000000
--- a/responsive-ui/design/chromeStorePics/icon-64.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/metamask_icon.ai b/responsive-ui/design/chromeStorePics/metamask_icon.ai
deleted file mode 100644
index 27400c5a4..000000000
--- a/responsive-ui/design/chromeStorePics/metamask_icon.ai
+++ /dev/null
@@ -1,2383 +0,0 @@
-%PDF-1.5 %
-1 0 obj <</Metadata 2 0 R/OCProperties<</D<</ON[5 0 R]/Order 6 0 R/RBGroups[]>>/OCGs[5 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <</Length 47428/Subtype/XML/Type/Metadata>>stream
-<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
-<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Adobe XMP Core 5.6-c111 79.158366, 2015/09/25-01:12:00 ">
- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
- <rdf:Description rdf:about=""
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:xmp="http://ns.adobe.com/xap/1.0/"
- xmlns:xmpGImg="http://ns.adobe.com/xap/1.0/g/img/"
- xmlns:xmpMM="http://ns.adobe.com/xap/1.0/mm/"
- xmlns:stRef="http://ns.adobe.com/xap/1.0/sType/ResourceRef#"
- xmlns:stEvt="http://ns.adobe.com/xap/1.0/sType/ResourceEvent#"
- xmlns:illustrator="http://ns.adobe.com/illustrator/1.0/"
- xmlns:xmpTPg="http://ns.adobe.com/xap/1.0/t/pg/"
- xmlns:stDim="http://ns.adobe.com/xap/1.0/sType/Dimensions#"
- xmlns:xmpG="http://ns.adobe.com/xap/1.0/g/"
- xmlns:pdf="http://ns.adobe.com/pdf/1.3/">
- <dc:format>application/pdf</dc:format>
- <dc:title>
- <rdf:Alt>
- <rdf:li xml:lang="x-default">metamask_icon</rdf:li>
- </rdf:Alt>
- </dc:title>
- <xmp:CreatorTool>Adobe Illustrator CC 2015 (Macintosh)</xmp:CreatorTool>
- <xmp:CreateDate>2016-06-15T14:23:12-04:00</xmp:CreateDate>
- <xmp:ModifyDate>2016-06-15T14:23:12-04:00</xmp:ModifyDate>
- <xmp:MetadataDate>2016-06-15T14:23:12-04:00</xmp:MetadataDate>
- <xmp:Thumbnails>
- <rdf:Alt>
- <rdf:li rdf:parseType="Resource">
- <xmpGImg:width>240</xmpGImg:width>
- <xmpGImg:height>256</xmpGImg:height>
- <xmpGImg:format>JPEG</xmpGImg:format>
- <xmpGImg:image>/9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA&#xA;AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK&#xA;DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f&#xA;Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAADwAwER&#xA;AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA&#xA;AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB&#xA;UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE&#xA;1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ&#xA;qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy&#xA;obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp&#xA;0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo&#xA;+DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7&#xA;FXnP5r/mvB5Tg/RmnAT6/cJyUMKx28bVAkf+ZjT4U+k7UDYuo1HBsObl6bTce5+l5X+Wf5t6jonm&#xA;KZtfu5rzTNVcG+lkZpHilACLOAamgUBWC/sgUrxAzEwakxl6uRczUaYSj6eYfS9vcQXEEdxA6ywT&#xA;KskUimqsjCqsCOoIObUG3UkUvxQ7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXY&#xA;q7FXYq7FXYq7FXln5rfnHb+X1l0bQnWfXCCs0+zR2tfEGoaTwXoO/hmJqNTw7Dm5mm0plvL6fvfO&#xA;U889xPJcXEjTTzM0ksshLO7saszMdySTUk5qybdsBSzAl7R+Rv5ni0dPKutTqto5ppNw/KqyOwH1&#xA;c0BHFuVVJpTpvUUz9Jnr0n4Ov1mnv1D4ve82LrHYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq&#xA;7FUn1Pzl5W0yF5r3VLeNI9no4kYfNU5N+GY89XijsZC/mfkHIhpMstxE18h8ynCmqg7iorQ7HMhx&#xA;3Yq7FXYq7FXYq7FXjf5v/nG2nPL5e8tXAN9Ro9Rv039A7D04WBp6nUM1Ph7fFXjg6nU16Y83P0ul&#xA;v1S5PAWZmYsxJYmpJ3JJzWu0axV2KuxV9Ifkr+Zq67py6FrF1y121+G3eUjlcwKtQeRPxyIAeXci&#xA;jbnkc2mlz8Qo83U6vT8J4h9L1PMxwnYq7FXYq7FXYq7FXYq7FXYq7FXYqlN95s8t2I/0jUYQQaFE&#xA;b1HHzWPk34Zi5Nbhh9Uh9/3OVi0Waf0xP3fex7UfzX0WEOtjBNdSCoR2AjjPgak8/wDhcwcvbWIf&#xA;SDL7B+v7HOxdi5T9REftP6vtYre/mf5ouD+5eK0UdoowxPzMnqfhmsydsZpcqj7h+u3aY+x8Eedy&#xA;95/VTFdc803n1dptVv5powSVjeRmqx7IhNMxPEy5jRJPx2cwY8WEWAB8N0l8gRXnm/z/AKXazpXT&#xA;7WX65NCo5II4PjHqVrXk3FDX+btXNtodLETDqddqiYH7H1LnQPOuxV2KuxV2KuZlVSzEBQKknYAD&#xA;FXhX5t/nOsyzaB5XuCEDBbzVoXZSSrA8Ld0I2qKM/foNt81+o1X8Mfm7LTaT+KXyeI5r3YuxV2Ku&#xA;xV2KqtpdXNpdQ3VrI0NzA6yQyoaMroaqwPiCMINboIsUX1j+XH5g6f5w0WOcNHDq0I439irbqwoD&#xA;IiklvTaux7dK1GbnBmEx5ukz4DjPky3Lmh2KuxV2KuxV2KuxVKb/AM2eW7CoudQhDA0KI3qMD7rH&#xA;yYZjZdbhh9Uh9/3OVi0Waf0xP3fex6//ADY0OHktnbzXTKaKxpFGw8QTyb/hcwMnbWIfSDL7B+Pg&#xA;5+PsXKa4iI/afx8WO3/5ra9OJEtYIbVG2RqNJIo/1iQv/C5gZe2sp+kCP2n8fBz8XYuIVxEy+wfj&#xA;4sVvdY1a+FLy8muFBLBZJGZQT4KTQZrMmfJP6pE/F2ePBjh9MQPghMqbXYqler+YLPTgUJ9W57Qq&#xA;en+se2X4dPKfuaMueMPewW+vrm9uGnuH5Ox2G/FR/KoPQZtYQERQdZOZkbL3L/nG7y8Y7PVPMEqj&#xA;lOy2VqxBDBEpJKQSPsszINu6nNpoYbGTqdfPcRe1ZnuvdirsVdirsVeF/n1+Y96l1N5O04+lCERt&#xA;Vn35uXAkWBfBOJVmI+1XjsAeWv1ec3wD4uy0eAVxn4PEM17sXYq7FXYq7FXYq7FU18seZNU8uaxD&#xA;qumymOeKqsBQh0YUZCGDDceI2O+ESlH6TRYmEZbSFh7bbfmL5mubeO4iv6xSqHQ+lD0YV/kzVy7U&#xA;1MTRl9kf1Owj2XpiLEftP61T/Hvmv/lt/wCSUP8AzRkf5W1P877I/qZfyTp/5v2n9bv8e+a/+W3/&#xA;AJJQ/wDNGP8AK2p/nfZH9S/yTp/5v2n9bv8AHvmv/lt/5JQ/80Y/ytqf532R/Uv8k6f+b9p/W7/H&#xA;vmv/AJbf+SUP/NGP8ran+d9kf1L/ACTp/wCb9p/W7/Hvmv8A5bf+SUP/ADRj/K2p/nfZH9S/yTp/&#xA;5v2n9bHtW1/WtUeuoXTz8eiGioCNtkUKv4ZDNqsmX6zbdh0uPF9ApL8ob3Yq7FXYq7FWO695pW0d&#xA;rWyo9wtRJKd1Q+A8WH3ZmYNLxby5OJn1PDtHmw6SR5JGkclnclmY9STuTmzArZ1xN7uhhlmmSGJS&#xA;8sjBI0HUsxoAPpwhiS+zvLGhxaF5e0/SIiGFlAkTOoIDuB8b0JNOb1bN5jhwxAdBknxSJ70zybB2&#xA;KuxV2KpX5o12HQfL2oaxNxK2UDyKjHiHkpSOOu9ObkL9OQyT4Yks8cOKQHe+Nr6+u7+8mvLyVp7q&#xA;4cyTTOaszNuSc0ZJJsu/AAFBRwJdirsVdirsVdirsVdirKvI2tmC6OmzN+5uDWEmlFkp03/mp9/z&#xA;zX67BY4hzDm6PNR4T1Z5mpdo7FXYq7FXYqg7laSn33y2PJgVLJIdirsVWu6IjO7BUUEsxNAAOpJO&#xA;IFqTTD9c81yT1gsGaKIH4px8LtT+Xuo/HNlg0gG8ubrs2qJ2ixzM1w3Yqzz8k/L66z5/s2kAMGmK&#xA;2oSAkgkwkCKlO4ldDTwBzJ0sOKfucbVz4YHz2fU+bd0rsVdirsVdirxT/nIzzWi2ll5ZtZ1Mkj/W&#xA;dRjQnkqoB6KPTajli9D/ACqcwNbk2EQ7DQ49zIvB81zs3Yq7FXYq7FXYq7FXYq7FW0d0dXRirqQV&#xA;YGhBG4IIxItQXp3ljWjqunc5Cv1qI8J1Xb/Van+UPxrmh1WDw5bcnc6fNxx35pvmO5DsVdirsVQ1&#xA;2v2W+gnJwYlD5YxdiqheXttZwGe4cRxjap6k+AHc5KEDI0GM5iIssE1fzBeakeB/dWw6Qqevux7n&#xA;Nth08Ye91eXPKfuSzL2h2KuxV9If84/eVk03ys+tyEm51lqhSKcIYHdEArv8Zq3uKZtdHjqN97qN&#xA;bkuVdz1PMtw3Yq7FXYqp3V1b2ltNdXMgit4EaWaVjRVRByZifAAYCaSBez418169Nr/mPUdYl5Vv&#xA;Z2kjVyCyRVpEhIp9iMKv0Zo8k+KRLv8AHDhiB3JVkGbsVdirsVdirsVdirsVdirsVTPy7q50vU45&#xA;2J9B/guFHdD36H7J3/DKNTh8SFdejdgy8Er6PUYpY5okljblHIoZGHQqwqDmhIINF3QNiwuwJdir&#xA;sVUrlaxH23yUeaCg8tYJfq2t2Wmx/vW5TleUcC/abtv/ACj3OXYsEp8uTVlzRhz5sD1DULm+uGnu&#xA;GLE/ZX9lR/KozbY8YgKDqsmQyNlDZNg7FXYqiNN0+51HUbXT7UBrm8mjggUmgLysEWp7bnDEWaRK&#xA;VCy+0tM0+307TbXT7YEW9nDHbwgmp4RKEWp+QzfRFCnnpSs2UThQ7FXYq7FXmX59ebIdL8ovpEMw&#xA;Goauyx+mrFXW2U8pH2/Zbj6dD15HwOYmryVGupczR4uKd9A+ac1Tt3Yq7FXYq7FXYq7FXYq7FXYq&#xA;7FXYqzXyJrSem2lztRgS9sSQAQT8SD3ruPpzV6/Bvxj4ux0Wb+EsxzWuwdirsVadeSlfEEYhDE9b&#xA;8zwWLNb24E10pKuK/AhHjTqa9s2ODSme52Dh5tSI7DcsJmmlmkaWVy8jmrOxqTm0AAFB1hJJsrMK&#xA;HYq7FXYq9S/5x+8qvqXmp9bkIFtoq1CEV5zTo6IBXb4RVq9jTMzR47lfc4WtyVHh730jm0dS7FXY&#xA;q7FXYq+X/wA+dQmuvzGu4JPsWMFvBF/qtGJ/+JTHNTq5Xk9zudHGsY83nmYrlOxV2KuxV2KuxV2K&#xA;uxV2KuxV2KtqrMwVQSxNABuSTirN/Lfl9LBVurhQ1626g7iMeA/yvE/R89VqdRx7D6XZ6fT8O55s&#xA;tUggEdDuM1zmt4pdirsVYZ5s8s+pLJfWS0lNXmhH7fcsv+V4jv8APrs9JqaHDJ1+p01+qLDM2brn&#xA;Yq7FXYq7FX0n/wA48to48kyR2cwfUPrLyanEdmjZvhiA2rwMaAj35ZtdHXBtzdRrr49+XR6hmW4b&#xA;sVdirsVdir5I/Ne/+vfmJrs1QeFx6G3/AC7osP8AzLzTag3Mu800axhieUN7sVdirsVdirsVdirs&#xA;VdirsVdirMPLHl8wAXt4hE5/uYmFCg/mI8f1ZrdVqL9MeTsdNgr1HmyXMJzEXatWOndf1ZVMbswr&#xA;ZFLsVdiqGu13VvoOTgWJYV5o8vFS9/aL8O7XEQ7eLj28c2ml1H8MnXanT/xBi+Z7guxV2KuxVP8A&#xA;yLf+abLzPZP5ZDyarI4SO3XdZVO7JKKgenQVYkjiPiqKVFuKUhIcPNqzRiYni5PsKIymJDKFWXiP&#xA;UCElQ1N6EgEivtm7dCuxV2KuxV4P+Zn5i/m7o189tNbRaNYszi2urVBOsqEkD/SJAw5bV2VG8QNs&#xA;12fNlie4Oy0+DFId5eL3FxPczyXFxI01xMzSTSuSzu7GrMzHckk1JzBJt2AFLMCXYq7FXYq7FXYq&#xA;7FXYq7FXYqyvyv5fZWF9ex0IobaNvv5kfq/2s1+q1H8Mfi5+mwfxS+DKswHOdiqrbuVkA7Nsf4ZG&#xA;Q2SEZlTN2KuxVTnTlEfbcfRhid0FBZcwYd5k8uNAz3tkg+rdZYl6oe7KKfZ/V8umy02pv0y5uu1G&#xA;nr1R5MbzNcN2KuxVnH5Z/mdP5MuXjayhudPu5Fa9cJS6CAEUjkqoIFa8W2/1ak5kYM/B02cbUafx&#xA;Ou76X8s+ZdL8x6RDqumGU2s32TLG8R5DZl+IUbi1VJQlajrm1hMSFh1GTGYGimmTYOxV2KqN9HZS&#xA;Wk0d8sT2boVuEnCmIodiHDfDT54DVbpF3s+b/wAyfI/kCy9fU/LvmWzJZix0f1BOQSWJWF4OZXsq&#xA;q6/N81efFAbxkPc7bBmmdpRPveZZiOY7FXYq7FXYq7FXYq7FXYqybyz5cMhjv7xaRD4oYSPteDN/&#xA;k+Hj8uuDqdTXpi5um09+osvzXOwdirsVdiqYIwZA3iMoIZt4pdirsVS9l4sV8DTLg1tEAih6YVYT&#xA;5k8vGzY3dsC1qxJdf99knpt+z4ZtNNqOLY83W6jT8O45JBmW4jsVZP8Alp5c07zH5z0/SNQd1tZz&#xA;I7rH1f0o2l4V/ZDcNzl2CAlMAtOomYQJD65gggt4I7e3jWGCFRHFFGAqIiiiqqjYADYAZugKdGTa&#xA;/FDsVdirHfNvkDyv5rjUava87iNGSC7iYxzRhvBhs1DuA4I9sqyYYz5tuLNKHJ4v5q/5x58xWBlu&#xA;NAuE1S1G6270iuQCTtv+7fitN+QJ7LmDk0Uh9O7sMeuifq2eUzQzQTPDMjRTRMUkjcFWVlNCrA7g&#xA;g5hkU5oNrMCXYq7FXYq7FXYq7FWR+XfLJuAl5eDjBUGKEjdx4nwX9fy64Wo1NemPNzNPpr9UuTMs&#xA;1rsXYq7FXYq7FUVavVSh6jcfLK5hkFfIMnYq7FUHdLSWviK/wyyHJgVLJoWuiOjI4DIwKsp3BB2I&#xA;OINKRbB/MPl19Pb6xb1ezY713MZPY+3gfo+e10+o49j9Tq9Rp+DcckkzKcZmP5P3EsH5k6G8cTTM&#xA;ZZIyqgkhZIXRm27IrFj7DL9Mf3gcfVC8ZfWWbl0jsVdirsVdirwr87POX5jaTqj6dFIdP0O4VTaX&#xA;dorK8o6lXuDusgZTVUI+HrUHfX6rLOJrkHZaTFjkL5l4jmvdi7FXYq7FXYq7FXYqn/lzy6t8purr&#xA;kLZTREG3Mg77/wAvbbMTU6jg2HNy9Pp+Lc8maqqooVQFVRRVGwAHYZqyXZAN4q7FXYq7FXYqvhfj&#xA;Ip7dD9ORkNkhHZUzdirsVULpKoG/l/jkoFiULlrF2KrJYYpozHKiyRt9pGAIP0HCCQbCCAdiwTzD&#xA;obabcB4qm0lJ9M7nif5Sf1ZttPn4xvzdXqMPAduT6E/Jz8tofLejx6pqMStrt+iyNzSj20bLtCOY&#xA;DK9G/edN/h7VO+02DhFnmXn9Vn4zQ+kPSMynEdirsVdirsVS7zBoGl6/pM+l6nCJrScUI6MrD7Lo&#xA;ezKehyM4CQos4TMTYfKfn3yJq3lDWHs7pWkspCTYX1KJMgp4Vo61oy9vlQ5p82EwNF3WHMMgsMYq&#xA;MpbnVGKuxVvFXYqnnlvQDfSfWbhSLRDsP9+MOw9h3zF1Oo4BQ5uVp8HEbPJm6IiIqIoVFACqBQAD&#xA;YADNUTbswKXYq7FXYq7FXYq7FXYqjoX5xg9+h+eUyFFmF+BLsVWyLyRl8RtiChAZewdirsVTjyfZ&#xA;JeeZ9NidOarOkpUio/dH1Afo45mdnx4s8R5/du4faE+HBI+X37Pds7N4t2KuxV2KuxV2KuxV5Z+Y&#xA;esC91gWcZBhsKpUb1kahf7qcfozke2dTx5eEcoff1/U9b2PpuDFxHnP7un62K5p3buxV2KuxV1Bi&#xA;qFukowcdDsfnlkCxKhk2LsVdirsVdirsVdirsVRFo/xFfHcZCYZBE5WydirsVQEq8ZGHv+vLgdmB&#xA;W4UOxVmH5WQCTzOzn/dFvI4+kqn/ABvm27GiDm90T+h1PbUiMI85D9L17OpeVdirsVdirsVdiqG1&#xA;K/i0+wuL2X7ECFyK0qR0Ue7HbKs+UY4GZ6Btw4jkmIjqXh000k0zzSsWkkYu7HqWY1Jzz+UjIknm&#xA;XvYxEQAOQWYGTsVdirsVdiq2ROaFfHp88INIKAIIJB6jrlrB2FXYq7FXYq7FXYq7FV0bcXDeBwEJ&#xA;CPylm7FXYqhbtTyDdiKfTlkCxKhk2LsVZ7+UduW1S+uO0cCx/TI4P/MvN32HC5yl3Cvn/Y6PtydQ&#xA;jHvN/L+16jnSPNuxV2KuxV2KuxVhP5l60IrOPSY6+rccZZj29NSeI+l1r9GaHtzUgQGMc5bn3f2/&#xA;c73sTTEzOQ8o7D3/ANn3vOM5d6d2KuxV2KuxV2KuxVCXiFT6iqWB+1Sn8csgejEhBfW4/Bvw/rlv&#xA;Chr64n8px4Va+uD+T8ceBWvrv+R+P9mHgVv67/kfj/ZjwK19cP8AL+OPArX1yT+UY8KtfXJfBfx/&#xA;rjwhU2s5Ge3Ut9rv/DMeYosgr5FLsVUL3l9WZlFWX4hX26/hkoc0FKDdSnwHyGZPCGKhZ6oLy3We&#xA;CTlGxIBoBupKnt4jLMuA45cMhu1Yc0ckeKPJ6F+UmpSxapdQMapPGrGvjG1BT/kYc2vYs6nKPeL+&#xA;X9rqO3IeiMu418/7HsA3GdE807FXYq7FXYq7FXi/mfVP0nrl1dA1i5cIaGo9NPhUj/Wpy+nOF7Qz&#xA;+LmlLpyHuH4t7jQYPCwxj15n3n8UlWYbmOxV2KuxV2KuxV2KuIB2PTFUDdWaV5caqe/cZbCbAhAy&#xA;WjCpQ8h4d8tElUCCDQ9ckrWKpZrHmHTtKUeuxeY9II6F6eJBIoMztJoMmf6dh3nk4Os7Rxaceo2e&#xA;4c2Far5x1a+5JE31W3bb04z8RHu/X7qZ0ul7IxYtz6pef6v7XltX2zmy7A8EfL9f9id+R9d9WP8A&#xA;Rc5q8YLW7kjdR1Tfeo6j2+WaztrRcJ8WPI8/1/jr73adh6/iHgy5jl7u78dPcy5RyYL4mmc+9GnN&#xA;o1HK9iP1ZjzCQisrZOxVp1DoynowIPyOIKscl/dc+ewSvL2p1zNiL5NZNCy888na79QvDa3DgWlw&#xA;d2Y0CPTZvDfofo8M67tfQ+LDiiPXH7Q8b2Nr/CnwSPol9h7/ANb2PytcvZ6rYSqwX96odu3FzRq/&#xA;Qc5fRZTDPEjvr57PT6/GJ4ZA91/J79A3KJT7Z2bxS/FXYq7FXYqk/m7VRpug3UyvwnkX0oN6Hm+1&#xA;V91FWzC7Rz+FhkevIe8/i3N7PweLmiOnM/D8U8azhnt3Yq7FXYq7FXYq7FXYq7FXEAih6Yqg54Ch&#xA;5L9j9WWRlbAhQeNHFGFcmChJ9b0DXL6ALpN8lt2kVwysfcSLyI+hfpzP0WqwY5XliZfju/b8HB12&#xA;DPkjWKQj+O/9nxYTe/l55tilc+gt11Zpo5VPInc7OUcn6M6XD23pSBvw+RH6rDzGXsXUgnbi8wf1&#xA;0Uiu9K1SzAa7s5rdTsGljZAfkWAzZYtTjyfTKMvcQ67Jp8kPqiY+8KNrczWtxHcQNwliYMje4yeX&#xA;HGcTGXIscWWWOQlHmHrei39tqUMVzAQyMKuvdGAqVb3GcDqsEsMjGX9vm+g6bUxzQE4/2eSco3Fw&#xA;3gcwyHITAEEAjodxlLJ2KXYqx/X7J5UubeJgj3MThHaoVWcFakgHau+Z2kyiMoyPKJH2OPqMZnjl&#xA;EcyCEB5f/LjSLBEm1AC+ux1Dbwqd+iftf7KvyGZ2t7dy5DUPRH7fn+p1ej7DxYxc/XL7Pl+tkDoI&#xA;3KqAoX7IGwA7UzUg3u7iq2fQWlzGfTbadl4mWJHK+HJQaZ30JcUQe8PAzjwyI7iiskxdirsVdirz&#xA;L8y9S9fV4rFSeFmnxj/iySjH/heOcp25n4sogP4R9p/ZT1PYmDhxmZ/iP2D9tsPzSO7dirsVdirs&#xA;VdirsVdirsVdiriARQ9MVQc8BT4hun6ssjK2BDdq1JCP5h+IxmNkhF5WydiqAu9A0O8Ltc2FvLJJ&#xA;9uQxrzP+zpy/HMnHrc0KEZyAHnt8nGyaPDO+KEST5b/NRsPLOlaYH/R0RgEn205u6kjvRy1D8snn&#xA;12TNXiG68h+hjp9Hjw2MYoHzP6VVlZTRhQ5SC5CJt5l4hCaEdK98hKKQVfIMnYqo3dstxEV2DjdG&#xA;8DkoSooKhp8jrW2mqJE3UH+XJZB1ChddLSWviMYcmJfQsESwwRxL9mNQo+QFM9BAfPyV+FDsVdiq&#xA;jeXdvZ2st1cOEhhUs7HwGQyZIwiZS2AZ48cpyEY7kvD7+7kvL2e7kFHuJGkYDoORrQfLOAzZDOZk&#xA;ept73FjEICI6ClDK2x2KuxV2KuxV2KuxV2KuxV2KuxVxAIoeh64qhZIjE4dd0B+7LAbY1SKBBAI6&#xA;HplbJ2KuxV2KrJI1kWh69jhBpBCElhaM77jscsErYkK8NwGor/a7HxyEopBV8iydiqhcW5kKyRkL&#xA;Mn2GPT3ByUZVz5IbVDcyQLTizuI2U9mYgZZijcuEdWGSXDEnufQeegPn7sVdirsVYb+ZmqGDS4dP&#xA;Q/Fdvyk6f3cRBp47tT7s0fbmfhxiA/iP2D9tO67EwcWQzP8ACPtP7LeaZyr1TsVdirsVdirsVdir&#xA;sVdirsVdirsVWvJGgq7BR2qaYgEoQc2qW4BVVMn4A/x/DLRiKLVIbscAGQjbpWtPbtgMFtEJIj/Z&#xA;NfbvlZFJtdil2KuxVogEUIqMUIWa3K1ZN18O4yyMkEKkFxyoj9ex8cEoqCr5Bk7FUTpEdv8Apmxe&#xA;YqkQuYWmZjReIcVJJ2+z3zI0kgMsCeXEPvcfVRJxSA58J+57pnfPBuxV2KuxV5B531M3/mK4INYr&#xA;b/R46eEZPL/hy2cV2rn8TOe6O3y/bb2fZeHw8A75b/P9lJDmudi7FXYq7FXYq7FXYq7FXYqoSXtq&#xA;nWQE+A3/AFZIQJRaEk1c7iOP5Fj/AAH9csGHvRaFkv7t+shA8F2/VvlgxgLagSSanqckhVtY+UnI&#xA;9F3+nBIqjcrQ7FVRZ5V/aqPA75ExCbVUuwdnFPcZEwTauro32SDkCEt4pdiqhNbhqsmzeHY5KMmJ&#xA;DoJzXhJs3YnDKPUKCr5Bk7FWd+RvOPp+npOoyfu9ltJ2/Z7CNj4fy+HTpnQ9k9pVWKZ/qn9H6vk8&#xA;92r2dd5YD3j9P6/m9CzpXnHYq7FXhnnLS30vzHeW4BWF3M1vQED05PiAX2U1X6M4vX4PDzSHTmPj&#xA;+Ke00GfxMMT15H4fi0l5N4nMOnMdybxONK7kfHFXVPjirVT44q6p8cVdU+OKuqcKrZEEiFT9B8Di&#xA;DSoB0ZGKt1GWgpW4q7FWwCTQdT0xVHxR+mgXv1Jysm0L8CuxV2KuxV2KqiXEq96jwORMQm1dbpD9&#xA;oFfxGQMCm1VWVhVSD8sjSVssSyDfY9jhBpSFkbsh4S9f2W7HCRfJVbIpdir0fyR5zW4WPStRci5A&#xA;421wxr6ngjH+bw8fn16jsvtTjrHk+roe/wAvf9/v58x2n2Zw3kx/T1Hd5+77vdym2b50TsVef/m1&#xA;pJktbTVY1FYCYJyAa8X3Qk+CtUf7LNH21guImOmx/H45u97Ez1IwPXcfj8cnmOc49G7FXYq7FXYq&#xA;7FXYq7FXYqpTw+otR9odMINKgiCDQ9csS1iqItI6vzPRenzyMiqLyCHYq7FXYq7FXYq7FXYq4Eg1&#xA;HXFVVLmRdj8Q9+uRMQm1UXETijinz3GR4SE2vRgopXkg6N1p88iUoTWNf0bRoBNqd3Hao1eAc1Zq&#xA;UrxQVZqV3oMtw6fJlNQFtWbUQxC5mmMXn5w+TbYqYJbi8J7wRFeP/I4xfhmwx9i6g86j7z+q3Ayd&#xA;sYByuXuH66ehfl//AM5Q+UtVuk0rzAH0mT4Y7XUp6GGToo9dgW9JjWpY/B1qV79Tp4zEAJkGQeX1&#xA;BgZkwFRe3wzRTRJNC6yRSANHIhDKyncEEbEHL2hC6xpcGq6ZcafOSIp1oWHUEEMp+hgDlWfCMkDA&#xA;8i24MxxTExzDwG5t5ra5ltpl4zQO0ci9aMh4kfeM4ecDEkHmHuYTEoiQ5FTyLJ2KuxV2KuxV2Kux&#xA;V2KuxVDXMNayL/shkolKGAJIA6nYZNUwRAihR2yolC7FXYq7FXYq7FW1VmPFQWJ6AbnEC+Skgc0V&#xA;DpGpzbpbPTxYcR/w1MyIaTLLlEuPPV4o85BEDy3rJNDBT3Lp/A5aOzs3837Q1HtHD/O+wq48pamR&#xA;UvCPYs38Fy4dk5e+P4+DSe1sXdL7P1q8Xk+cj97cqp/yVLfrK5ZHsiXWX4+xql2vHpH8farR+Tog&#xA;f3l0zDwVAv6y2Wx7IHWX2Ncu1z0j9quvlLTlIPqzVH+Uv/NOWfyTi75fZ+pq/lbL3R+39b5x/OyS&#xA;VfzBvrLmWt7JII7ZDT4VeFJW6UrV5Cc2uk00MUKiHV6rUTyyuRYJmS4zsVfU/wDziJp/mFdA1bUJ&#xA;72QaC8/oWOnHiUNwqq00+68h8JRBxeh+LkKgHCgvoLFDx/8AM3SBZeYfrMakQ36erWlF9RfhkA8e&#xA;zH55yna+Dgy8Q5S+/r+v4vV9kZ+PFwnnHb4dP1fBiOat2rsVdirsVdirsVdirsVdiqvaWF9euUtL&#xA;eW4cdViRnI+fEHJ48Up/SCfcwyZYw+oge9PY/wArfMqQrdskahhX0ORaVK+KqD+GbQdkZjGzQdbL&#xA;tnCDQstDybIrFJboJKv2k4EkfOrKckOxz1l9jWe2B0j9v7FaLyfbj++uHf8A1AF/XyyyPZEesj+P&#xA;m1y7Xl0iPv8A1Ky+U9MBqXlYeBZf4KMsHZWLvl+Pg1HtXKekfx8VceW9G/5Z6+/N/wDmrLv5Ow/z&#xA;ftP62r+Uc3877B+pXTSNLQUFrER/lKGP3tXLY6TEP4R8mqWryn+I/NWis7SI1igjjPiqgfqGWRww&#xA;jyAHwapZpy5kn4q2WNbsVdirsVdirsVdir5U/O7/AMmdrP8A0bf9QsWZEOTRPmwbJMU28p+XL3zL&#xA;5l03QbIH6xqNwkAcKX9NWPxysq78Y0q7ewOKv0B8teXNJ8t6FZ6HpEPoafYpwgjJLHclmZierMzF&#xA;ifE4WKZYqxn8wtFj1Hy7PMIw11YqZoHrSiggyj6UB28QM13amAZMJPWO/wCv7HY9l6g48wH8Mtv1&#xA;fa8XzkXr3Yq7FXYq7FXYqmOm+Xdc1Ir9SspZkbYS8eMe3/FjUT8cvxaXLk+mJP3fNx82qxY/qkB9&#xA;/wAubK9I/KjUpZEfVJ0t4OrRRHnL8q04D51ObTB2LMm8hoeXP9X3usz9tQArGLPny/X9zL9N/L3y&#xA;tYgH6r9akH+7Lk+pX5rtH/wubTF2Zgh0s+e/7PsdVm7Tzz60PLb9v2sghhhhiWKFFjiQUSNAFUD2&#xA;A2zPjEAUOTgSkSbPNfhQo3NnaXScLmFJV3oHANK+HhjSQUovPKNhIpNo720gHwgMXSvuG5fgcrOM&#xA;MxkKQ3fl7zBa1IjW6Qb8o9zT/V+E/cMgcZbBkCXNdCNzHNG8Ug2ZWFCCPHvkKZ2vW4gbo4+nb9eB&#xA;VTFLsUOxV2KuxV2KuxVpnVBViAPE4q8U89flBq3mfzvf6yt/b2un3Xo8Kh3mAjhSNqpRF6pt8eWx&#xA;nQa5Qsr7b/nH3yssai51C+llH2mjaKNT/sTHIR/wWPiFfDD178qfyf8AKnli6/Ttrp3p35jMVrcT&#xA;SPI4jcDm4ViVUsNgwANKjocnC+rXOuj1DJsHYq0yqylWAZWFGU7gg9sVeBa/pbaXrN3YN0gkIQ+K&#xA;H4kP0qQc4fVYfDySj3H+x7nS5vExxl3j+1L8ob21VmYKoJYmgA3JOICkp5p3kjzRfjlFYPHHt8c9&#xA;IhuKggPQn6Bmbi7OzT5Rr37OFl7RwQ5yv3bsp0z8o3qj6nfLQN8cNupNV9pG40/4DNli7E6zl8B+&#xA;v9jrM3bnSEfif1ftZlp3lLy5p9Da2EQdSGWRx6jgjuGfkR9GbbFosOP6Yj7/AL3U5dbmyfVI/d9y&#xA;bZlOK7FXYq7FXYq7FXYq7FVKe1tbheM8KSgdA6huvz+WNKCkWoeSdNnFbVjav4CrqfoJr+OQOMNg&#xA;yFILvylrlpVolE6AVLQtv16cTRvuyswLYMgSx5b23k9OZWRx1SRSp/GhyBDMFUXUF/aQj5Gv9MaV&#xA;VW7ganxUJ7EYFVVZWFVII8RviriQBUmgHUnFUNNfINo/iPiemGlQTu7mrmpxVrFWReVfLr3cyXt0&#xA;g+poaorb+ow26fyg9a/LxyyEba5zrZneXNDsVdirsVYV538iXeuajBe2Uscb8PSnEpIFFJKsOIap&#xA;3pmo7Q7OlmmJRIG1G3cdndpRwwMZAnexShp35S6ZEQ1/eS3J2PCICJfcGvMn6KZDF2JAfVIy+xnl&#xA;7bmfpiI/b+plmk+X9H0lWXT7VYOf22BLMfYsxZqfTmzwabHi+gU6vPqcmX6zaYZe0OxV2KuxV2Ku&#xA;xV2KuxV2KuxV2KuxV2KuxVRu7K1vITDcxiSM9j/AjcYCLSDSQ3vkbTpSWtZHtif2f7xfuJDf8NkD&#xA;jDMZCkV55O1m3HJEW4UVJMR3FP8AJbifurkDAsxkCXjRtX/5Yrjb/ip/6YOEsuIK40PX5lANpKQO&#xA;nIcev+tTHgK8YVB5S8wEf7y/8lI/+asPAUcYVU8ma4w3RE9mcfwrj4ZR4gRlr5EvfXT61NGIK/vP&#xA;TLF6eAqoGSGNByBmccaRRrHGOKIAqqOwAoBlrSuxV2Kv/9k=</xmpGImg:image>
- </rdf:li>
- </rdf:Alt>
- </xmp:Thumbnails>
- <xmpMM:RenditionClass>proof:pdf</xmpMM:RenditionClass>
- <xmpMM:OriginalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</xmpMM:OriginalDocumentID>
- <xmpMM:DocumentID>xmp.did:d4d07395-aa96-47c2-a9e5-d0351947bb0c</xmpMM:DocumentID>
- <xmpMM:InstanceID>uuid:c63c1031-e157-9748-9c58-86481308e954</xmpMM:InstanceID>
- <xmpMM:DerivedFrom rdf:parseType="Resource">
- <stRef:instanceID>uuid:1abccb90-0c26-4942-b156-fd2eb962e3e1</stRef:instanceID>
- <stRef:documentID>xmp.did:58fdc1b8-1448-3a44-9e20-282d8ec1cf95</stRef:documentID>
- <stRef:originalDocumentID>uuid:65E6390686CF11DBA6E2D887CEACB407</stRef:originalDocumentID>
- <stRef:renditionClass>proof:pdf</stRef:renditionClass>
- </xmpMM:DerivedFrom>
- <xmpMM:History>
- <rdf:Seq>
- <rdf:li rdf:parseType="Resource">
- <stEvt:action>saved</stEvt:action>
- <stEvt:instanceID>xmp.iid:d4d07395-aa96-47c2-a9e5-d0351947bb0c</stEvt:instanceID>
- <stEvt:when>2016-06-15T14:23:10-04:00</stEvt:when>
- <stEvt:softwareAgent>Adobe Illustrator CC 2015 (Macintosh)</stEvt:softwareAgent>
- <stEvt:changed>/</stEvt:changed>
- </rdf:li>
- </rdf:Seq>
- </xmpMM:History>
- <illustrator:StartupProfile>Web</illustrator:StartupProfile>
- <illustrator:Type>Document</illustrator:Type>
- <xmpTPg:NPages>1</xmpTPg:NPages>
- <xmpTPg:HasVisibleTransparency>True</xmpTPg:HasVisibleTransparency>
- <xmpTPg:HasVisibleOverprint>False</xmpTPg:HasVisibleOverprint>
- <xmpTPg:MaxPageSize rdf:parseType="Resource">
- <stDim:w>128.000000</stDim:w>
- <stDim:h>128.000000</stDim:h>
- <stDim:unit>Pixels</stDim:unit>
- </xmpTPg:MaxPageSize>
- <xmpTPg:PlateNames>
- <rdf:Seq>
- <rdf:li>Cyan</rdf:li>
- <rdf:li>Magenta</rdf:li>
- <rdf:li>Yellow</rdf:li>
- <rdf:li>Black</rdf:li>
- </rdf:Seq>
- </xmpTPg:PlateNames>
- <xmpTPg:SwatchGroups>
- <rdf:Seq>
- <rdf:li rdf:parseType="Resource">
- <xmpG:groupName>Default Swatch Group</xmpG:groupName>
- <xmpG:groupType>0</xmpG:groupType>
- <xmpG:Colorants>
- <rdf:Seq>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>White</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>255</xmpG:green>
- <xmpG:blue>255</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>Black</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>0</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Red</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>0</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Yellow</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>255</xmpG:green>
- <xmpG:blue>0</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Green</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>255</xmpG:green>
- <xmpG:blue>0</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Cyan</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>255</xmpG:green>
- <xmpG:blue>255</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Blue</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>255</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>RGB Magenta</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>255</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=193 G=39 B=45</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>193</xmpG:red>
- <xmpG:green>39</xmpG:green>
- <xmpG:blue>45</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=237 G=28 B=36</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>237</xmpG:red>
- <xmpG:green>28</xmpG:green>
- <xmpG:blue>36</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=241 G=90 B=36</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>241</xmpG:red>
- <xmpG:green>90</xmpG:green>
- <xmpG:blue>36</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=247 G=147 B=30</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>247</xmpG:red>
- <xmpG:green>147</xmpG:green>
- <xmpG:blue>30</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=251 G=176 B=59</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>251</xmpG:red>
- <xmpG:green>176</xmpG:green>
- <xmpG:blue>59</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=252 G=238 B=33</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>252</xmpG:red>
- <xmpG:green>238</xmpG:green>
- <xmpG:blue>33</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=217 G=224 B=33</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>217</xmpG:red>
- <xmpG:green>224</xmpG:green>
- <xmpG:blue>33</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=140 G=198 B=63</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>140</xmpG:red>
- <xmpG:green>198</xmpG:green>
- <xmpG:blue>63</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=57 G=181 B=74</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>57</xmpG:red>
- <xmpG:green>181</xmpG:green>
- <xmpG:blue>74</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=0 G=146 B=69</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>146</xmpG:green>
- <xmpG:blue>69</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=0 G=104 B=55</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>104</xmpG:green>
- <xmpG:blue>55</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=34 G=181 B=115</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>34</xmpG:red>
- <xmpG:green>181</xmpG:green>
- <xmpG:blue>115</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=0 G=169 B=157</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>169</xmpG:green>
- <xmpG:blue>157</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=41 G=171 B=226</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>41</xmpG:red>
- <xmpG:green>171</xmpG:green>
- <xmpG:blue>226</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=0 G=113 B=188</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>113</xmpG:green>
- <xmpG:blue>188</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=46 G=49 B=146</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>46</xmpG:red>
- <xmpG:green>49</xmpG:green>
- <xmpG:blue>146</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=27 G=20 B=100</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>27</xmpG:red>
- <xmpG:green>20</xmpG:green>
- <xmpG:blue>100</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=102 G=45 B=145</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>102</xmpG:red>
- <xmpG:green>45</xmpG:green>
- <xmpG:blue>145</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=147 G=39 B=143</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>147</xmpG:red>
- <xmpG:green>39</xmpG:green>
- <xmpG:blue>143</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=158 G=0 B=93</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>158</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>93</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=212 G=20 B=90</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>212</xmpG:red>
- <xmpG:green>20</xmpG:green>
- <xmpG:blue>90</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=237 G=30 B=121</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>237</xmpG:red>
- <xmpG:green>30</xmpG:green>
- <xmpG:blue>121</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=199 G=178 B=153</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>199</xmpG:red>
- <xmpG:green>178</xmpG:green>
- <xmpG:blue>153</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=153 G=134 B=117</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>153</xmpG:red>
- <xmpG:green>134</xmpG:green>
- <xmpG:blue>117</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=115 G=99 B=87</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>115</xmpG:red>
- <xmpG:green>99</xmpG:green>
- <xmpG:blue>87</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=83 G=71 B=65</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>83</xmpG:red>
- <xmpG:green>71</xmpG:green>
- <xmpG:blue>65</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=198 G=156 B=109</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>198</xmpG:red>
- <xmpG:green>156</xmpG:green>
- <xmpG:blue>109</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=166 G=124 B=82</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>166</xmpG:red>
- <xmpG:green>124</xmpG:green>
- <xmpG:blue>82</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=140 G=98 B=57</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>140</xmpG:red>
- <xmpG:green>98</xmpG:green>
- <xmpG:blue>57</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=117 G=76 B=36</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>117</xmpG:red>
- <xmpG:green>76</xmpG:green>
- <xmpG:blue>36</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=96 G=56 B=19</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>96</xmpG:red>
- <xmpG:green>56</xmpG:green>
- <xmpG:blue>19</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=66 G=33 B=11</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>66</xmpG:red>
- <xmpG:green>33</xmpG:green>
- <xmpG:blue>11</xmpG:blue>
- </rdf:li>
- </rdf:Seq>
- </xmpG:Colorants>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:groupName>Grays</xmpG:groupName>
- <xmpG:groupType>1</xmpG:groupType>
- <xmpG:Colorants>
- <rdf:Seq>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=0 G=0 B=0</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>0</xmpG:red>
- <xmpG:green>0</xmpG:green>
- <xmpG:blue>0</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=26 G=26 B=26</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>26</xmpG:red>
- <xmpG:green>26</xmpG:green>
- <xmpG:blue>26</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=51 G=51 B=51</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>51</xmpG:red>
- <xmpG:green>51</xmpG:green>
- <xmpG:blue>51</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=77 G=77 B=77</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>77</xmpG:red>
- <xmpG:green>77</xmpG:green>
- <xmpG:blue>77</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=102 G=102 B=102</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>102</xmpG:red>
- <xmpG:green>102</xmpG:green>
- <xmpG:blue>102</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=128 G=128 B=128</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>128</xmpG:red>
- <xmpG:green>128</xmpG:green>
- <xmpG:blue>128</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=153 G=153 B=153</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>153</xmpG:red>
- <xmpG:green>153</xmpG:green>
- <xmpG:blue>153</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=179 G=179 B=179</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>179</xmpG:red>
- <xmpG:green>179</xmpG:green>
- <xmpG:blue>179</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=204 G=204 B=204</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>204</xmpG:red>
- <xmpG:green>204</xmpG:green>
- <xmpG:blue>204</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=230 G=230 B=230</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>230</xmpG:red>
- <xmpG:green>230</xmpG:green>
- <xmpG:blue>230</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=242 G=242 B=242</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>242</xmpG:red>
- <xmpG:green>242</xmpG:green>
- <xmpG:blue>242</xmpG:blue>
- </rdf:li>
- </rdf:Seq>
- </xmpG:Colorants>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:groupName>Web Color Group</xmpG:groupName>
- <xmpG:groupType>1</xmpG:groupType>
- <xmpG:Colorants>
- <rdf:Seq>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=63 G=169 B=245</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>63</xmpG:red>
- <xmpG:green>169</xmpG:green>
- <xmpG:blue>245</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=122 G=201 B=67</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>122</xmpG:red>
- <xmpG:green>201</xmpG:green>
- <xmpG:blue>67</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=255 G=147 B=30</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>147</xmpG:green>
- <xmpG:blue>30</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=255 G=29 B=37</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>29</xmpG:green>
- <xmpG:blue>37</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=255 G=123 B=172</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>255</xmpG:red>
- <xmpG:green>123</xmpG:green>
- <xmpG:blue>172</xmpG:blue>
- </rdf:li>
- <rdf:li rdf:parseType="Resource">
- <xmpG:swatchName>R=189 G=204 B=212</xmpG:swatchName>
- <xmpG:mode>RGB</xmpG:mode>
- <xmpG:type>PROCESS</xmpG:type>
- <xmpG:red>189</xmpG:red>
- <xmpG:green>204</xmpG:green>
- <xmpG:blue>212</xmpG:blue>
- </rdf:li>
- </rdf:Seq>
- </xmpG:Colorants>
- </rdf:li>
- </rdf:Seq>
- </xmpTPg:SwatchGroups>
- <pdf:Producer>Adobe PDF library 15.00</pdf:Producer>
- </rdf:Description>
- </rdf:RDF>
-</x:xmpmeta>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-<?xpacket end="w"?> endstream endobj 3 0 obj <</Count 1/Kids[7 0 R]/Type/Pages>> endobj 7 0 obj <</ArtBox[19.792 16.0 109.0 112.0]/BleedBox[0.0 0.0 128.0 128.0]/Contents 8 0 R/Group 9 0 R/LastModified(D:20160615142312-04'00')/MediaBox[0.0 0.0 128.0 128.0]/Parent 3 0 R/PieceInfo<</Illustrator 10 0 R>>/Resources<</ColorSpace<</CS0 11 0 R>>/ExtGState<</GS0 12 0 R>>/ProcSet[/PDF/ImageC]/Properties<</MC0 5 0 R>>/XObject<</Im0 13 0 R>>>>/Thumb 14 0 R/TrimBox[0.0 0.0 128.0 128.0]/Type/Page>> endobj 8 0 obj <</Filter/FlateDecode/Length 106>>stream
-HwVu6PprqV*234R04S32P4ճT(J
-W*w6PH/H+
-8;W:dYmnJk$j=`^PKX*GV"-/6MPPhMW4o*<SJ[.r.2B:%l2U+:>jFegTA5n:ROqi.
-8M?-(/t#IN>re.=TbIMqYWQK1D%b&pOLGa]H?hKs'8Gqa4A/k;[i&\e-=4:h!/H6BW;~> endstream endobj 16 0 obj [/Indexed/DeviceRGB 255 17 0 R] endobj 17 0 obj <</Filter[/ASCII85Decode/FlateDecode]/Length 428>>stream
-8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0
-b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup`
-E1r!/,*0[*9.aFIR2&b-C#s<Xl5FH@[<=!#6V)uDBXnIr.F>oRZ7Dl%MLY\.?d>Mn
-6%Q2oYfNRF$$+ON<+]RUJmC0I<jlL.oXisZ;SYU[/7#<&37rclQKqeJe#,UF7Rgb1
-VNWFKf>nDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j<etJICj7e7nPMb=O6S7UOH<
-PO7r\I.Hu&e0d&E<.')fERr/l+*W,)q^D*ai5<uuLX.7g/>$XKrcYp0n+Xl_nU*O(
-l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 13 0 obj <</BitsPerComponent 8/ColorSpace 11 0 R/DecodeParms<</BitsPerComponent 4/Colors 3/Columns 880>>/Filter/FlateDecode/Height 947/Intent/RelativeColorimetric/Length 90241/Name/X/SMask 18 0 R/Subtype/Image/Type/XObject/Width 880>>stream
-Hoi@Hy&8_nyA'?
-I
-
-W<* '%Y%Vmao!ǩkv>w u{=Q<\ȃ*fƸmqY%ŏRp
-
-iHF'>hd,I#_ыTj~Q5cR`n:s e8 P
-WWzٶ:lgl7ɃHiJ&/ Ӻg.}C'dD|V֪'9TL*4I]6
->#gV-?}= TjOK<>Nh auOBnY#qkB)fiQ@ 
-
-ztut&ksg1twuO/J>_9Ezb(Jr2h+ɓ)⇻A!_:۪.%ٱ4E3w~ sOq9F$~E<GJ?
-7"P 16?w'PƔP m?U AJOC/%-n :d}_HR0Iyc5SjV} nǡ!1I,C8LaP)GcA 1 (E4F|Q#0#0PW{ V<^FLz@%k0u'I1q<$p5SyV(%AǓ8MYĶQEY'd72k/Q޼;L&^1* ev<7V2Sy+G F"wA
-P&rA\9gJC
-c1BuUU!hB
-m?IXqBf=O-uS]*pb Lp
-+Qf1XGbu.AL}{;j:1XM;`m)ݒr2??b<g2|NDq)}s*[SwLGER>ӥ^"T.4{7V:7cO n]&IIʴ׭]׳L&ټ~e?618qW 6$уS-J+j &HR#Y(u3C"vaVO qˤg/{Nd* w4~8`ਡODT
-( ƃ(rVu6z0F|iU6_Up_ |7//y e26kaE9JTh<'| e\xy(7QQ1Z)7#5eoӈ0g+ۨwCxc XSg")-nkEJN[* FAKLLR7R.LBME#@*
-~U݊tEEVOt7U콊ؾxԜ'isjf=O[ZO ((A>&]r"т|f0`A|0/2}+58{:!ELTǝuB1HzGQ0g[|Q_[VSor^Gy?lD$g=?ȩՕLN9
-K*RYģpu0%K'*- lpD <P#YG}Ũ4Iϸ.V;IQ&+=u PaqUS_q(R o*B&Bc@-٫m 大+R/rlpך`m{ͯ-VrteO&^LOF"e59h9Ą˵Jhoq{50ށ:58Ƀ*ôx'/>ID2MnݾbL)OYׯR3OF"R j"iO8%{Pqs ?Hee}-XJNm\-H/}G<b"µŭ|xy}}YM>ϩZ&L/u>7&I wQ) /+P.bP"$N55B]={2`[Hnk?-s\粓y*dqP9I,1k[`^A/n3ՕcVna-_s%YSM{b FǠoZnkE%yt$mAs%Ev]JW^xA Xk0v_KӉ i$Fߪ/u( jLIO%k/S<zYWnZ <Qb誒&[qDz1'MwcU0s)/PzRmu/X?OydR<ɇ0m'hˤS!m(/6oGF"HCs cf䐧YBhߔsyڡy߿n,@21crXS>r7B>Y,770ݙs)]ubQ9OΈL12$jn*2*쾊O&iV"sr+ 2LjȞCxҜJ 9:Jʌ H(hxA&xk i&Iu$6ԕj:.E Q\-^*%V@V;RM]dLW<}*w&Kߊ{-7@-&;.
-C66 @9TBUfI[#v1r`,f/5n TLֹޤosIwT&\ߍ#UBXJ&uo6TE-EHLu[FUf
-x謖Xz{FEr6qiVd>սl
-\Uv^dKCR&p6kڄo@)ɛzxZZfBv5nFC `r{Lŷy7g2H&;x@kASYQC,29Wp
-c!{)r*Rj!&#8ˁScM}Zi*H&Mf$\P
-Ŵ\Id eDҐIЍF1|CeH ldԬ6i.2K8t׎&t(Q+ZfB*R&~?g4|W~ !$1[NIkqS(T['iͧ4*m~@?>KT)ΕJ3t
-dEÀ."!|g_F>";,o)%OQ~Z2FB
-3%f_,%.u;}oZ_`>19)ۂ֙Ĥ b- 2z[&;BEz1i6Cӯ!G9htj9'I#8ˁB!=*t-T:zTG\2z;F3}ZgLhHӍָ!fiVL:,N0EwHVsR I !-U֐L1#4zvB`V|u 4i$\"&^Xjbޟ mR q6H JER/-N&w',͌ƹӿ8!fI|1TBS?D%}35fW̊CȊ\!/5n:VC1@#&R&2rÚ!"H <O"$;,ƔG)! Piq6k^6垾nmGţt,Q\W
-Ho[]H&lB<iΌ')Lt`=CB >OS&c1[pUyuN'v9
-L凍\L2铥Akqq$CkDyQcOzq*8
-U_D"QAPA@Iw涱DZIPPiG~;9]6ovp3U$lJ'o0 bRvLž~cIFeA[QIPY1o7xGvΛji$-I g2lc.Ť=I !;e0'ZJZwzT6b3; )g  SVG1, xt $(!b1Ѯ-~$"3V[fK@MR+3ϟePIa~Fp2 ÞqZJZ
-0 '0$:HJ\ ;``pPL=NM.H1Eb~ԓvsK`TO=hwѓ
-m crE?m}F!e_JRPF
-7b1T}<x4zV,&읲yeTJ=q#cz>)Rv:5[QГO"5o) c^mXyTعT=%o-oK2U~c͠B>(h1*h|:
-ؐ<pD ŤG|i-jzREQˠ'
-c'z>wTҺ辣QEx=D19-d!}?d!}3Z#)nmDzly_|1^Nd`Q0l9'0Nn<X
-(iC4P+ $
-cT6^b-4je˷O|zS~?_qCjRr̖E˓>jEk.C-n#E<IO{vE5ӄ&EN& ݆
-w&B gw)#„S]\QVQ>$I_jJX,\^YSd|'zD%{o1!䅇qx';qڈ><a X// :z556hz^`tNʦ]arDhKUvXegf¤~ubU4u+&gb85I nݣTc%NN~(dX'Bh%=fj-NK2z]W"Ly't l^fZ&a,- EKv|deKhߙDs8^{2yc"~tto`Vxhv۠dN`}ʼnChVrfg֭iљO т|,I@3&7r~x]5K~ <'ɸNjG==`jߖ}ƋWǭnZ\Lҳo`M2 iCɍ|a'BN$ɸN~(<'x[)!tDJ`ɨuO&7R,R6=<{.q;!t&O6vse8-@ʨmk$bfa%܌*
-sMzC*d\'\z1zADd&<u;e] x^,Yo`ΓZA>
-9$Y"?LtzK_14*Y|!ԯ)7$U
-L&\Pby?ޓur!m FZKGbrΓͲc)eE+WqytT?w ]]}["֫<O?ZI(BڸR9S!&[J9,^ٟ,9&GU
-=
-
-7]=!I
-AQש'=FE4b2&al6>
-hB");Is*QY9c"1鲒z2klvy0 7>
-d֕MW.oBgDtʿv(uX4Kp}Gߓ-8,]o^ѓ[J^c(NY]$eo h9[ƣ:1vt᥌e| q'Kp4 b
-4 4@ߩ߿NN d ;tSl}OJ*IprG l?
-ע('㵢đgi
-&!&;=@OK1Ŏ=5:2J.778&$k4RJGL*sͽ֨+IN,Iij&}`K闍sEvDRϿd}OIb_93Da`(r\|@O@Moߎ$gi)R~cb]_+$H!n~F]1GL*vZFi
- &NA@Ot\ᏻNoV0
-'?Ztw
-٫
-
-w~Lwɰd_X2oĂϼ0aL&5QPRK00*?%
-GC;0SO!䒢(m @bc_v(JkE@mK8h/M Hhb IYeIQ}v޸r7byH~Լ0qi_VS!=#_mLĤgiҰ= X.o7=<ZdR'4!sdqak5kMMJ(PtKx#I
-d!թXKtkcZ*yͅ (  w¯<\*Db,$=OVp'1K.:|/lӥ+<LZdg4b5H<R+188{ x#2sI
-|?$d}Q3׶]Aʰ''[0'&lR3 =brNG]>i&o练Ɏ[UlL=t _wHY{D'C%A)Cyt)8tDzPˠ|!B!DDEg ̓~WF/Vs'A\U/!
-.a{0Ç
-.ĕ#_uMLzb)ZOVfc+UA)"
-4D')58=26L">^&Ư~nc#{Uҭ' T Z; $U:ri
-_͒K 쳷x#LJ4K\4^mΔX][XVBf@)5:'7}OV2L=Piϲgc0Yh-8iҧVk6\o'Nq|$T($)y6Aߓg O"Hb1flsarEtku*F?L$ |)> R ѸoB(L7H>IwUhc}[3;/)go2qCJ= RHOY$BkѧJ6)b Fl{h-8թrbVyZgcF;HҢt@ʰߓŤA#v齌3BILODxRzI;e5 Rkw'w9OD
-yš|%0KeX\vIِ)H{fZ;qRC{ /Dny]&OkꉥUS=l'凯Gw%)H3ct:BxO 3$0.e#PɶO
-|XZE_\(ZODh<R^ihIy)҈;
-rk'eG!% :W!G{DNhJ\9\wACl
-wϱR>"j'3J)_PKwG&) wZtݠVwgc)ßHaO&nr#<r:%Bh;]d"+VKicZ_ o=)C6Ki&RLYe`
-UB.t/MO0tx!Dn}~yLҿV]=2f^CQ_uyp%(I͹䈬!I-yBs95kIAQnԩ{Sѯp篧Gm2=d7R&Ӻ4M 54<P'|->;=NGc2ncRt`AJxw&ӷ4p#BΣ)Óe6y0)%L^_׫rhe{-G^O9&%4j2Q/
-LAHiL"CɇvMå)30PfۿՂXa0)QqVgsIV^UB~l׋ Gސp3 L4RI9&M?V !$)n+Ye6\V0YO'j Sm,u^)dw>R CҠ/eO 5`2 j'#=%JXHPe9zTw?pf}iTnQntwR)OX"pO%tT&Ϗ]3)$7ePf[pr޸||l5pndғ+ĽH9zK6]mŤ zͿ
-'}nMty!׸/0y([v7t%OZ`bsI=P'L'ol3{%RJ }&|DQ5M,$)KBcuq\B銞SV'Ofw57'H#RΘs9'R/)Ȗ1BrTk,pY
-}+;B(Ř ɯGE'ts+ mF\wO;KlTȒ_SOcf@=-M//:GnW?qPgE9o
-W!DdUb;<޵s[#Vۦ-Q|_緍Thwr+PKR*B@E` kR.Itiai^ArȥkP_ڃbDJl2ˣfgIrlX?gw>X<}"W
-*e Oh)5ЋPŅ]lxh7&\B{ԭxhvRzE,Y0C>yF UJA)_~D<KTn33[jǻ_\'?^BkB<~Uc>7DAA$;)Q&%AGt)K^y4ν* o{MO8pr\r@x"B<Xt)Pǎ)Q'eR>qبrۑ]JƾИk7lJ){'@o<qN4M[-Fl"NA2y:q!߸fl W2Z;fj#SWfd2SׄiՓΜ)~.yV hG<y3ߎ|RCϣw÷Ҭ.}'!3ՑLLri66v6y
-0A%Aj-\v('9{-ҥ6x{"Zw(%̝ٟ(j915Ʈ#M&*=6ʹX%
-&(%}-( $7&#Md1:Uˑ 4_}͸S d2Y+8 k7.٩OKSn˧zZ.A<dPH {P&Wra3/B]
-E<X[ .[(g5\ dK<lfxR3JybebU hbP͍F'*%2):ȗ.yjH)sFȤ3AQ<21iQR0"|*$lf_JP&QZKav-/~^3P) $HPHL&R~hb*$<=g}s|R8$Pʪ.7TJٗFa#}diعgCr6C2yRhBnҁctБ/]2\ۑRH)+6rB& &|IJVQj9C 29ereR-Gw)̣Ҟ&MszbjR@6<I0 )a8rn1kt?P&c
-d4<@{d΍b}rJ4E7l;|@*w&$!ϧUke2t-:]
-,!߼l]}
-Og6*beC
-$_X;T1HI>~@C"a(R
-tRuf:NReؚ3CQJXkl cfS,hICc=u0_Wfk>knL1ז^O> ~Q'tz`'#W xV
-t`O=?7F{Nvfowvv*QJ*0
-D?ޙa B J_$<z;i{wF#e={\&C[r!7&'kn¼~Ѻ{]2 @ *n{Q^Qw+eǔwT>~',U)+DBGbe!z/E"-|tʌWXbvF<6NHP&?pdrA[_Wm_
-5?&PF1J'3p|R]]9M]9LL2 Q
-LrHP<ɤv4ΒV^ZYv?`vFRB(M( 
-H4JoէX)Ϣ G)<Ʈ@C*p&̟\q7H&5UQ^Z^u-R)E7?A|^u60H%LϐORКr{$$A@$n|^v$zn₰WSo_Z[sSrdRޛ>||R
-%
-X3J*%0|,ϙ"g,39!+\JdR"NtgQ^ҊRlr?R)i'a,P * Jycq?DVI1? IM<(.-i[-gb\~{ ֟!ɥOZ:,Ø9{ٵJ:36pVݕII- o޾Ѳcݷ85kk,K(;9g' 8r[a/#<4+,
-:VInI(o d^r@ԛ/{w?p_&4(eDRcёD>]+Xkdqj22y{6pdRw
-VNͪ^32 X)mP ?sbֺVf{D0/#o`7ΒVm_Z_~ BpSETTzaLtZv2Z)8Jq%S&I?IHd:A7.ɲG=Pkɳ)?(_;YDlgO_!;FJ**e' )2H& zӏz,T=Y]=+eQ/0g"cb|蛲IkF $!YrڪKK4.»5Jj;>i:':nA){;,nXepx}P<4MXyd@
-ƏA)(#nao$<2cIGG&/Zw$Q ھފ}!iD_~ϾzdÈ40
-$lWS/`_wt7U6?J)p0g%z*u#"#eDy ڔן8ȈggnW4c[4R~zŰ:,,G L}ʳAHLBoHxVۗ~,9ʛ;`:A)10C|E"<g !$,)_E,%L>Edxvۭ
-tbX:OZ` RFyxQh$TIcz78'a0y&'2Yd̟L/b]U/`_w[Q|$w
-H\A=xraOjVDEI`NI&Ό8隧ϗ7E69t}y^&+tz“/޽%vp\ԧ">AnB.WC(yS&rt+YHJ W"U|C~KJǬwRŔ!3c[1 FdI2qǐxCo)Bi)LN0&%6$5KL#xG;n䟴T%m8<9%S4o6 I@Kq=ow;Gnۊhх|!`Jd}<v,Yl6I<i]`4M(,^H:;`%5bdɑ| 4L^r1鞽^U6\g* rCa%BB]` IroI~V!I\>&ozIki[іp뺤u13O*QL#dI'LH;, o+R1 ;ϝ DDX| R&K!R]?y;i'|WKCr0X,>{;P7`Hdt~ìsVBF *`V7'98QN;
-\CD}#IgJE>Bm'Rӆ"ixؐcχn' =B3]LItf-"`*E'GI)\R&'vؒNK)¤V3,L*> E}o||
-Dң[+lvu,ޒfZ˭+G_2T$fvS3DJUzDJF+7$; S2[+K}t]aBz1e m л~> R"eΙFc!έ|F W"%FI O)KHrڰ8:3Rƿ$ %R$Z㼩{W"=q t)pmyۊd@}zY:3JJ[F,qB&$Haos\7h=$%L&8ͤj߹4n1ȡ3)틤 %
-n^_G,hZm|R0e"<9XiI$O.<z>>j<3!R i^L LrД/15D6ĖmEl6uA]W6<=H"Hk!<?zo+I4mչt)vu/ת@1v,u13C43շ^!<XAR %
-H0i9 003Lz6<9 2orPLhĆ"098Hh;IL6VtД05.3תR#RFp6/
-Q$EmHfDSɼ߽4Z
-&H㑒#RʆBl, m+
-L`ڪlѠ6~TK''W"y0i%#
-D'a?t1<|)zXZgz9x;$"%v)i)юec^$RӔ/7hJd]kUҳg}qOb&3IYJD~Fە30k1.zmE[_=.FZA
-V$*#%RJsci$—0R.dL@&@@R+Q,8+δqh_=DXq(%8wr⧟L ڼj,zIQ6ǃj\kNA[fk$^rθ%rď?;s
-2 h"V <44^WGúZU6v=JIF.
-ẅ́c=M~_ghf]Sɷϩ`6SVOVd-6秋1}ᓈ/U# ??I}G> ;9G'#~,CڹI9=3 z+{ak?qz8gd%$
-g8& Dỷ^/Z,iUJ
-$
-<
-J)H ®A]T*Cp&NlLnfUYT*V%6a50C00D?Փ+os9ؿAtjJ|LGq'l/-~zG7 0OhAW\m5-2V*Z<!Q=dF-V"`R!ZZͿ |;?E*80K2HGܲ,K
-w0 Wքa+[<.劣SUZyId h"fm!aSs,Z:ŏ>ĵ.d쑭J (h5iI5˾:b-#0o#%E?+IFxl'Qw`4smH*3Ͽ9b#|9.Ī:Id .2}'lY; {o
-{0y=k=+78\ɲE*'k_k>1+m;QO
-=Sb#VS2H'?]/},6P.
-w0iO6si"=[Դ-=ұ7'#_Gp[rHsē%^ lJR
-$EFj-3>YM#D?Vx<P |9w (
-C#-%4 l0VE>љxH$D#=>D += $AYH\4:襑SO|#܊⟞={G.\?}|ٿS+Kڸ'Kz%QOC)JJ6sµ,LT&)Ъ?n8dU%璤䓉D[EJb_y
-s}tHO
-8TSsm֕$+F".P(.
-Źڬ6:TQߵO"4TJ͕Wr'x(9$ IO= XN=?
-+38B0 gS[=%;ˋ/qUb'D}$C*,
-@S8e1[ gY4UrgI(9+ʝ'%ItuKkK8Ӥ<h'ÎHJL %'3]j QcD$~H؝ ;A㩕bA U"})i`.|'V(*>DtT0|vƐ8{bRI6eGX(Z9-A:E1/'|Ŵɲnw4e驒/tDyC=nzu ^<CO / QL#8K&<'A˰ßɋ$;)rOt:D姻e3}lߛDObh{@Rbxi"/žI)(*~]xAp=q S͸CfT>|{1~05$Ia6e?*/W5;glkJ<zs{]3ankGO[a ddx|*JSHSo֭
-w jKЮM|<
- JZ$O|v؟ _
-P 3>o tC, U͂d7; V %gI${r5Tpi`ԓNߛDObZjwW,[\{S󥐏D|~H՗(/)K$ 0"'
-sS0Hb<)V:o(Ic\&zb2|1$m$;āko`\}|0O%_߁RȧEr |'Puqn9dԜ;x@߇uZH?Jm K]T{I.;aCk(9
-ji4.;Nꌒi2:dm\xLd>v`n+̿>.ҟTQy$K!߼>^U+qGp)gQ9ݔw6'
--vY`+Iѩ"[pi4agi.uR1N<N#ԧ:Aa 0<IbA#ԝ=O&F&u˝m.;?z= p0ӗƚ|KK0HUf'xOuJ슝 31h ;c"\#<^Aٺ;``
-ƾ`bh[4AixCx!)ICK7ۋTeRֽJUM{fmM'DiEecs飫+>gHvPJQImHoT'iWB?ZF|2.u/S(rc*'}J
-^s=hg6t7;=X~|r>vfT"xL_?;Hɂ6eEk nU[_NdQaUJZkшvw1qR
-5mYlQlDne6$@ڡO?wd[:(
-VkkWX 2.$<<HJf'oD\mX"Vs@62CR?L<M'd^s0VVt+z&9&C+%ԤWdo*x'y' nI\\{-*%q'i*C5r$EfR,L[SHiXqEmGb"푯# W0hm߳Y B~RڦdR8K,uN{_dHANmr(ѩhP5J7dޞIEVn >y =VCyY_)*=)$OwJRozj?D?@h|8և77_!xK}rBv6!f'up-0mA J~̀|%G||RWqTmήtkC%n'OJɕXB"ÉMRd|Or i/@#5<֊@/wy |rayxU6E)|/Od^msN̸RvIٙ^pN}I-נ nvTSST>rOZq ,|2J}WB)mVJ`ٞ)ia K c=>r 6qvHBgzf;&
-dKz9A|X|/㬶<X"M:ze&~:o|
-.KwfZ
-B/Gne^;͓SufuG%A}C<*xKVߜ('5froo? b,*^uZ vš\>k'_27ɼ<ņ$xt{]Y)V“>ʜ D 8Ҏ<'gy'G&zʃp}0c7ӳDo]BGr "$\x7533>
-olMze[nw hyɞI>j[IJ)J"`>enX
-EZU%RܨCRe]`&Q0,Oo2L~r ?L8v<zҍwCr 9{7'<$H}ҭG]NÌ}m~r2K
-WW%60q9~ Fp9Y~Ci@2:UւO*+'^aqpEz;)*l}rI6vOƇepD}2Jޭn(6l*w64wrRYZa:?+Vt&uu3=/;KKĠ.`"ҁhڋтLlHh;8l#~+D{I?8Q+Mէ|RcZ
->VS>'"+=r!cTVPv D)/n_)
-Yʙ
-VrB+><}
-,gGCO֗$Ħ223؍{UQ0!"z^"eT*'TмM9%Tkժ $e:;__r'8j)Iԫ.]k#8O
-ϓpC`:Tjϓu4-ZCIOKÅV7~fyuJoyR]eJsDx2O-vGض^DDY? pUΞ*b6IYq oe Ӳ|x9 7}tp΅ƻDJҴ%-4BDe<7JZsOټጭҵ8q $DAiB<8DϜ9lJ.fO'A<Onum'hDwr]zy_DD).gFJ*xN2ABO9%^Ϸd'VVbg.v6qҁDJxt'jn~|YB9d /]D
-foq] <)[ ]iyHncd~ vQWi˓(g~C<w&TB6B3N|F[K^ԉ"%&k.@O̜2S+X.hŇ.iDd{T!鶈wZpIn?Y=r < OjjmCFDz=n(1E9H)jMD )CN3S´lv<^
-@;eNkMQ\,Bn/nѵr$yKԊ_{Xzdރ><TT^ӜJGi!KSNΘ'U5-1ĥF@x2^vgx:Fx(ye)
-UR$A!7sT6lws,7fnzR˾cgǥ3z:j) T<HϓPKaS> A1d]-k|p"hQ6ɣTaQYVeUjNo2&I <]HIx2dZ$"]E9H fN-OişbJ|NW~1ӷbS.J_rBP.D
-cA
- 4"E(@cC㝣2H!:ovj'+j' *'nb`rZb$"24RrqpUwL%@`_FJYAZG̺>- Iy *Waq;zGh9 @^ ;[qPAC`5OjZU6EU3]i&</i$Psra5Play2wrB/~z8
-Jm.Zs/Sg~}gw C]piaeZK|uvpj'љضs޽OSEZk'UV' xr=
-qLʖOz$"Jv(CH<x~<Ճs*!I'4BN|MEEaLE4TMCߘVtJ20Ij w?y<ȴ=1I Hmc v JKrW I`\BV[h?L4EکI6m[\ F\H=<R{lrH<cX=iA>IW
-PJPpL>L:_HIWi͊
-5U
-{2-nt IHR2{r,҉B܀1`u s% L^IJwM./?O¦x6yp8"SgQw%aTB6P!J.ԘsFb<w9٦ddJ-7e7I݃$$9 I*1&
-I;џOЧVkT̬+ rwKX4OSnNFRg?{7GE "{j󇇷]x"?sQ3n:JԐ ܥ+5Vyē)Bg4mHB™TiU+p*'5y{*QV-=AJG5gCkqKyZ>J'\ :b҅E&VR]z94x I(3 <)1 <j]V^{-MB$$q\j PC07-em ɟ./- O=zݦ6 ZP<G`u{LoIhp,5hM7!6fD@P`sNJas( 3Fʔd ˈ'7+}mHB !%$BΫ;E4CVt*6<`؉;@-,?ͫ ڿüEe6f^"NR =^;89iy\;wbWjO`3sۙ+䑇;+oQ'U:0R2[[M<mB;%Hݳ lߑ* 5m܉FFm[5KmIǺ&w҅HtOIAlf3/wS<؋g;P z?^Rrߣzu]񨋂c6jMO3?Oj˵HZcO2͂'sOY_UF$!TI RR &aJ ЯU75y'L}Y}zHTRN{~%oӋBQ(7BŕJ̭)IQxXgWK4R|)Ժ-< Od'Sv1C-IS#!لKRF`+=ތ2U q
-4OҋcHJ{2cr2l'5)Ry<8ϡ"dAqx-,On!LPP` ɦTO\RFr!~
-YO!EJh_?X|}$I^u RaQ3nUܶ,xRӁ'^O<jb u
-$ IhRk FHڰ $eA7j*ؕyǪ& @5:&Rci<fW ]wMgOA?Etly]?&#%i0t#ix{ךsE 73ΑvSFVqyzCf~5d.nC=+FBB"$I)T9qS*XB`#_ɪ-/
-9"ɵHɿ*T#6mvv' xypJ5 sXhyҊ&]kK2e&cu]$_\aB`ull%lh(6a3B3 <ɽy'Y1.~[yO8!BJN-Ԩ--R>kڸ9G(j2fV-9iL7j. ޓو[[E '-D ePv|&oo8>3}=y/<2!/#ړgme_
-./g MA~5xR/Ynne@=c$5!“?iHfUφ8Ucl3]\<TfVj%K*oـ['G^
-B~ri~?5c2 $HCDaAř$""WW$uwjfvvڭڣfv-P rprk췻!NBw߫OP <}- O[|'O#e#g`RJ13C_^SlFI?}I8nf`N$|@ e,ydMUn$9K1|N=@~{ 太7$ŻI_2FB"l3~n@♨z2|Rا:Dx|r])O03[<+$xa0.uN3zގZk`QS}m>@,5:,kQ0P~"@#!񰊿 ^)\3g%݋N0O|?Z}1I
-DPÁ2$BGFťs>7gO` 伍r_`bc RJX䨙m^ CWۘZ=u[͂\ mRJݦֶ̗́{CG>0P KqQ>UD .ҐstӢSV6 &a!0ZtЄ~wQ>$bUI`5`SJ`qmN(`فX{VF)y}U|RWT"< b?<ɾRꑙ-O,_2"ƼZYk>sa8 o
-r+9g[9mj6FO&@FZ{->9_b uR
-'TYXSpmx5t1۪Od%N?`jb9nyƎDwOe$o>9lBރT1S G%įNL&6'$;ۘXMY L+`" |2;[2}r 3ye -/1 1JY+v"X꫟vC0d-1K$0(\.Uiiڗt ĒeBߎ(i&©Y) UjL6E+Ep%L \!@}co1q쳢VLѥϸy-e>La 9;\  :fYJYC=i[IqK=&\CkZn%a|Ju>~W-m(SJTӼ غdÄDl.탄<' ί".2rA Quj2&jBWb̌}2d.p! vGZb0#~6z`^[<3-;iP0Gne䝒_D*(ֻ)2Rh-܆Of ۳ådWዄ7<r7x9KrPTY'~a\ުPY\zllfLt'v"<<L얚 v@"Wʑ
-7uU٨9V/}yr 5HՄ.;>:Rn|BrKbƊ%3˔[_Dr*#B}ĩR_!/
-]bfi"p~}SL<'(%Dp)"<aec2S`0[FJ9c%wB-^r˥VY;nMZL\:\{ZwLII=-3-D7kr!nBKC@^8 }I
-|;d!I쓻b0[K家т>Uʑjۀ͚Khw+VN-=ƨ_SgM 23Le0/!׽ѫx$#}k.b+9@BRJ.O-cv{e ߛI3㓐-—>UJ`J
-Z\z服`/~κMTQ)=p HoJ b!Orw?tTŇC"b3L-E!r[FCWI_g4d`}]yyjII
-tC9O皇WI=f~"Xu>:63;;n3>Њ<"*%,Z-.;гv`Vrʈ__:\?HO9S[sKf^p)UDxɡ
-ꑙ&5Ԩ]U.D*K&NWl3|M7呜OTTO-Fx?֢hG bm f;M)a%5̮$y-5{.@&A)W8üܝj=P+?vu܉pHʷ)Sdœ t ԿE{RV \ܧw(xXEX5 ~OBHO鑚/دۧ;Й1sZiW*AY+,i)jʃ"
-<
-veGT
-^txZ`vIr@ 1P^A]t3snZ9zO*O>q*eɍOB,0LfZmq'SVuǖ֡&Rj= =aٳәqG}'O>w`&mI6d`nāRid!`KaS^x{x/c瀵_]=ٲŨpqÙ_pN:XG`z·uIwEr?0OadmjV2D
-s_Iǘ'JO⾑[q#%O#V\/HRDa)dfhjoeN[CBy9zRM)`w>/ %I LwzÖ ⪟<d|EvPBKr׵Y}SزHyLQy$N'UR. qQ3'!a)#(KmXX?%ӡ#xZ66¦̓5#: +|I }r9 ^B^*Ua{.:ȿ{WW\__SEǫ6aׅ'3v}` t4'%\<cē*<:Rf_\.DO) n)i`t\t$KfK
-Gse_5N[l*Qdw홸H'5`3R}*Ӷ'l/{<Y]]eS0̓xB`0<I 7Ӵov'+”gɋ.+$ye| QGm .1"5"%KJrY#MmR'e*&xv,׻ f#@ Y>9p_x;ieeHuJni]tEJ Яxő&4'E {BvhZWyڌWM.ozil2rw#> ;YpQuϪ+>&ܿۗM[1gt,1湐Tjג"ela`F-xJI$-d2'1OuHd(0LNeEnrow"jS<$e:K ? (1hNpxI2i)̥]oU+Mdoa 񻸄16>)a?R%]E8)€TI=XVd) %EJVXp
-)AdH LXZwyøEKЛL'jjE/ &)6*sę|,$CJ`v1Rk݄'%$zRK='1L2)+wO"JSVs$'IO҆I65Gd 2cnx'udV/8<4_ &5RZCDOrJ8kcY)tFlEA hT9mr^9MO6MM{O
-'?K6H2$li0gmN:Bk"%&
-X8rKfãÒ2-wsh9Ȓ U<YS(}`0KvH YP|GqLM&IX7 o$eaYH׭]Zk'diRwUO'uZx}c0=fVĂ7̃IrPZ)#EQI& x2!;we6O&Y}[A1vk|Ay d[ ᕘ"C%HLTR]dHi~)gܖF8WHj/r1ϰ3w9gC>6!KR<<^B>aBIk  >Ʀ%W*aKkջ)h7'k'G x>2Â{f*v
-oH\6_?৖
-AEdR
--QO^g*J= \gyhT
-ոͩ.;'sRrO^)s2t"CwUuŲ^cN譛g^
-%RqY(%m~ apink_)%II_)9N2?'Kl[* |2%i/ytTw)
-Ly
-K@) IcUR#O|\);i(d= pm\ ?5Sy[
-۩D֢vV)rmjhg%dKJ *ھ{
-% opV 􁧔RnǙ3T6(ja?!%QO\m
-X\H)iN/wp'*>'0+O6d݂5sP
-
-(RIQ!y|r3II~3Odo
-Z֛
-lÆHFO=Ac7RNk%
-g/o:l! Wv) R&/Š<d ux}UE9D aJgnh?t,h2$?*
-hT`HN90/,9cka َqvЅEqH#uۀ,X;: R>R嬢p?|,c ד02󖢨T ?/: IF{rgkazX,E^-)Ja"ŜHF}):^W{)zZ\i|wmL
-ifɍIp q!,iT*X6},I[G"c59G6@BOvV E#)qeȿb;$[<?L*,]8s;}PYL--RV_QTw@JVλ bYL,y_/u{
-U-!*a^xIcne&7'y~ XrDXF%ME}FZ2}Z)9!Rei4QADʇ8k飕P
-vːdl{g`ed{{/pK;W+X$@4*.?_tjD)Lx9!ol S5(FZB.bΰqʍ #!)׍'% {QY W |#?YO}EtSg'MқeSRȦH
-.mkiw|XZ՘L*{(`|R-]}bJFVHy1e;RR4S hy,q`;8CF"#{ :xsr%(,#" Ci4-kuV 󅤋f}9,F%uEĠD
-p~gK仳ls3cGׂ+ݞ כ)X,`YZtd<΋!PRD>/p'g"]8WvJ:HJ;5)z֧b3C"Ͽb[S
-ӭ?2g+XiT\$$lR_0(LʠRu_Nt)Hȓw8Qw0uL ӾEu=x43ȋ8Dq #
-JEFYxGðZڼp6//g}C՘(Y0vf8'ILp<B*ZQYK×{A "HILeOw8?^:'Ӿ|EuPG;'Iq;6'QdvTɝ9~dmֿ,,&.I#:YvRRiJQ@1)1ɹYIJ GQ}SC6`ȋ8//
- ՘ X>egQQLeNVH Po$dzHa#f<IQ}22wFE)$3:ʍ!1ccKI&ʖAy'q^} |Nj+뾜^Y3gO4NuJDQTOz;Gz _*^X`{sd אTYvXj5%@`9,;[2Ce|;o]L)o709_VM 3{Vjѐrrc%FvL7vh UvX.ʒ%Z]m~wYg2IK5HDJo<\gQ(J{>#YdEB- ߛCC*ƈi/ ,S;3KuiQFqo(u/ '%h԰՗ۛ()F+eȿb;3 9tl`ܚo*KERXv~KR
-F|Oo6riwȐhsv{ɓN-߳e9,1 Kp5$Lh@֤l ?ehZ)_$񗃺Z'ъ3T`0醴*,<q a`e?R[桵)߮뱿g_vv;W_ׯtG˿ÀGB߃ 5S,n,1rY=7)RXT㲑қݞun %=S2&| %RݚO.?]HZ^(W t8c_\u]|ď|t׷0lhXna23D'u٪a,#U*irmR4ݒ-xOR#}g<?|t>޿6툢,1rj]dQnpW?R g=r`0E$+HĞ0og NߵACFؙc}4sȏ;{l[D]
-7DH;~аLf
-Sf 6D~^#eA
-}!ORԤ{6XrK H~P.A^
-㨨%Dx`U@4nrEʙrh
-sr KU+m)7{biƬw"X,wrI 3 ak')jB= D;`)T (?et@T +Hhe/ 斗5~,(YΡoOrkW8:<}g7GQ_ކuC4,AtI0RH)úlgŅ\DWXAIIQL%A8>2IXbe
-<&)j#H9`za>(jrٰ,*QjL6t4.~XDʷYѓf(*RJ6
-xoMɤT!կ ? K3( /1t9=2arU6,a8kX6:;8bH)o#e7Ii
-W#R\_>_? "t94_s]0R4R"BnqD%H=NJ%;dʩ|@yUМGr~#R23D_G\*ᠨD9"j 3i>ib8 qRͲ&kaҡ8m3ug=r`vu&r_}X<o8 pΠHY [-SE][5
-Rv! 6&uW,3t9Fw*ʃ{ٰu
-s.}93e(;=aÇ.4s@_5 ``V
-Y\e0I:T'%ybH͌HٽTۄ<BHD{(jJTPR2ϓ†eF7TKp8I9?ɌO3LL9Г9zi#8οvwIxΜːV6j+5UWizjWEj6UwەY !!`\CUO"c}Z. !m`n1$ߙ, ig`~W3g,j.,Xh#&HE׽^,eD8٤>fugy5sR宺_y(iMF2lnL^UKa+;*[.2cڙ%j>TyYI SKcJg)exJ_7HJ +sZG~58cL2a~ɁeRZXa PҖՄ _"!1aRDgT.c 5!`f#Mt'$>0r`9-E* 9 M;6НH')ZL
-MȺ6v1zDR>Փ.1|(aKvX.(Xfj"C>1L@d"'Fփ(W+
-J|=jR ? ~cU>H[09Dڄ°fX·82ӫ蒋1vJw[I{-NKnp6D`6KNsKv9g{,Ťu
-N8W5@/32WP-;E/jRF- ,RFŃ/Zmҙ _lox `cGvȹ!#M4.cg)p31R'c&SA_ Z>&)Oü<<^HJǓ/3+a^<
-Mn-MHx .b[k`&]Oz5^B뿓1̳<H!{;ҾRTP
-^jRV͉ao6pj#MNb(ޟ ,sT;T\K=('HJ!!8JngDoi rǘ_u* > r;U:;Pg^\Kô'V>ܨ~{{-Lu0lm JDr!pOw
-{DJУj1
- 娟C_+gO'Z%;0$l
-΅s#%a-ƲJdeJY>UJYIɁIiVaӽK 0;oU0m)Uc6
-D|SPS"2]%OKz۔&%\wG&a3-e+ɠοI!{B_}V'$4TKdzaHงI9^[bD5S ðXyT&e6r`b63` +qX
-*F0`9ÁJrqI 
-`鰼!o@U-@ʁLFV{[De%:BgO<><9P>=a
-+ԗ֒oxػ*b R*ŰJ
-bFoUpvhRJ_ß<ǕmNyjȸ+M5*+rgC<
-+e]iEOyXfA0Ko0,}jݳnҐ2 9ُ ace(Սbt#h)EZ|tQ-_zh|w۰zsrIjZ|]GcW(;Gq(>f13ƄdΓpa5IJ$*/ &ia'mI aXGK1h^b,]~ּYx8(6T.f\ m:X-=FPbZ4>ѓI({ndaبIb0$- Ű za 4ԍNc̈ۦS˗Kõ? }ЮsQ14z4]rO%pZ ĸlPbИ)7'$Vkf=94tb=x-/#n ȟ#YaNMJ4n#݊q\Kj 7C{9'n6\:Kwe'cυu1&)#z=i/ZN)t?|0 Linw )Z^u 8`ؔ*FG8 ( ]ֈqu%ڌgi Zx1\jxC{|7IDb^ϹC#JI J|蘄FA\/%L`cRIEZ8P>;Ma.;nI g"&1,mb:4:.11hLF(9juW. Zط*pd};]9_t|\<\:`9]&a46q=ԞV{ɡ":HJ Ib0\&p.e} ıs H4R74mk_׹|_|9w~\Y.Уբlp$iFaS\%2mg;wתk8wkQ
->
-8)W`㥨b@#QC&ƴi1b7:l\T|W)y#|峿^k.Vu8(4Gnã\D4hh{U4ъ#Q4'ILF= H+ ם@QRqlgV!?^.DGyBfy"U4Jq&rpwCk{K^㟦>!q8ч-nwkQ?ߑFF򤮘LKI<$,/rV|Ơ(j86gA'!ٮ0W% ܞhKŕxr|f\AO*s]o
-#*T4{U1^\F@Ejݨ?xU<6|Ѩ'gЏ8+=JulY+IP]* Y4Ba]l FbُC U/}G9RK}Yې1btrЈ9]MPDT1Ӫ>rziE-@Rt:%ȐS}l2GňhdЍU=ǔe[B,t5{uo}w.J=WŁ&a DbD+@c܍oIb'YI
-Orx_GȓR, %.4>"Jc,mZ
-Ew~=|ts||f|~7>򵞖ګˢ[lFF0Уq0w87OjEL <^*)a2FuⰊ_ua(Ƹ3-* r1?%b7Lb2&;ʑ \Prտ~Xk)/z0$ Fc!DD^6w9t$(RyRK`I6Or}"OR+T`E`zЪ@X\7XG##uEqf(%o O$|Q1^KsFi[끐Wցح~xA4)"O03Ƀ<X<^8,>bU=R86gy>Lj 暧_؅dRܘnۀhteOn}sOY[_{uI)
-^iFrLj.ub0
-2FC1=tGHȓ'SSg 33GL0>v9RZ)9H̳̚zhPhԔXS[`/gSk4N:S1T,uTKݗEOD̍{~0!vƚgE'!3 3|3 }R|?]S…f@>)2HBn.Y%"V"yЍX.}3\%\5T#x+{ B:p0%n8=XO@ąHh^ȓXbR}qxVaS-9VDZgä:.U tAt1b7#aܤݬ+tP{r.5{u -eRG'ychcg\R8E%C'- +&Lr{1Sb$E8oS\>N)BBU~PJ4h[WuhҤp~iRPB;qqbqǹlv9>vHy$& <G_t|=ڭfOֆ-TK2$qIr`tKṇYڜ8tu/N={G.VG{> y?z~>me)+qe~j$RZFJѤSkL=x@)v*bhbbLCI@W+6"~رN6;\
-\8ꁋ3!OSk?'険Q
- D!H _E*߮h$l4.4/Y*ɥpEKXQX%QLȎ'/~7"m(.
-V
-^~q|zh=ԊtT|bzR'7RJk}>z&[`߾]ѽZ9aExS*)&|/?SQi]=µI45 O$E@cfg`{G=7fJf.VFai%@B͔O(1f]7NŮňnİ5=0)}OJl3 MIaf+1){rf{y nV B1/<Xġ>ױ㿛=ٿP1X"G#]B} 1<VLdP\YM VM̓k)hߪ6ʓa#pn2L
-oiГL&chbP\bf»ӈ?b|eoϴTDZFaP0h'ꑹ$Iؓ)bİM_s۶mRxR"0 Up0PYՉ&C© R~wh\JJfa&YV,ͣ14%'ErX9qx[英 {glHu:{64|mN>*F>hhYa*JIكIvGRiaC(7oieR=~̭F32icInTIFYӉڭTGvĎvkцweÑΏC&aN;
-=j&Zy 7*ѓ.Vޣf3.W$dɏR~,׈"*&=?BD?o gދtԅ]gB?σ YE[ҟdJK hD7bJjF2L.)~bL6e=pl Ё'C{򓥚T&Yn(Z65?Mz.~wΞ=1:=BsK Ђ!(.\Tbf(F ,zR$ I)ѓh'1\$yzTݎ'j_"j"pt! ~;U(qb2@/Qh%Q=TIYI=3F"a>`$Rf*ɛU[F;sf]z봽n*x[c=d8}؀0'=]Qa:S'
-!%Ub#$FOI P0E)yٚ0O
-wՀǕ/}e_t8C7#F Vj휜@O$`$ݪ6ГEC^ݩ5-Src<yUx0iw]b!PpF]O ðǓzF[P oYI8^f4I$R%C^h2Lh\i#sr2kaG"dFoy5e_v|59[aē{KَIIjI_$fz%zÔΔnbYe!JH(I6e&3~j]`.w4썃ơΦ.뤻,i7l~.\{0OZmAL-Rf2),L"tD(EҒL5R$-w-[`$~ڜ<dolrQmvkkj2lJo4g a;5xT~>RZ7dSI4`x]}Hi#oV)#1II1^mXX[vRF>C8vXp3AmeO;j vx%0l}Oj
-uI >hߪ6'1%rbQuwkV("͑Lpɦ 09nt:),G:ݶqɾ+^;RCðuٺQ~~<p$[z)=v1lbgXe⾮7^4qr.Uai5c0cq+`
-uڂ=-nqpeOl{Laغ$+(&<)cNa'p5Hfp)A"[2bdcTj+ K̋VX/ߦ3oʼnؾβP4
-]`/ݺnnSѴvlTUhNN]׮hR-ߝWB MjqL~{ιc&&yս'`=1JL
-J‡r0~~*r:!8MݒBIT*|RIT},oa
-ec1a{m"nA#YSݿPM#M|,\x@^[‹9@'V)%@9&cݒBP>IZ|_ 1j[H!F^P6.u֬lRKֵ>12m{Ntuϱ%qr#ݝ=T'%X-Ap|{>"nyIꪢP(IQ&u:K`5ׄy)goX#!, n4O3FJaF؀1*|L`lq7v !GolN/[Xƈ[v#c}-)
-eYJ'P2)v~MMsc5 s
-%쓂Ї5c*%R FF3I"LjC悈@2%%zZS-Y$+㕜az[Eǔ6v'"ީ-CBY{J'5*P2IYϚ[jRw7.
-_33̭f"&l_H&MwBhJo{^+HOPؕ>N\Q薶cu}? PP6'Eut Q*UBYP("lă|R1n41')wobC*
-)8[\ب+&|l  M!hO'qK]jH*P(I:g:FFTj~mpHR%z掯}h/̚쓒;du|R;kgz+eikwL,p/s d2pcn6klx=J-Lcc3MP@t2$yR({d=!5*B^UUQYRR1mٽ~G^<{̟|mgY,^AffQ5*yS(_FEtn%(&
- r ADPoK8 I(φRedЭ̤yR
-(:F4BU] ƀF* ޯ?xgק;p}
-8ǃ@B=d9a®36&w֬>Iٸd5Ks̭fuMm!X4>!pprl"&C6l|!:>?[tKNuOT6:랈x
-R-iKl΃aX"A]+Mx5 "!Hwxg"❌/U)QԪs޸pż=:nIPo<~٧~C?=qD[>Im( b!S[ω
-$$.VH+jsݴ$!^ ,4cO$>Ӻ)Hۍ$mzb+ϙuv$c;Gq{k_w9{*ֹsm6.e۲F6{1N&CxLjƬ1R+Dp GD _fS0%A,O ᓐɎ';N8ucǎ=zȑc>j~ ׿~zgu/5HHbih
-,d"0 0&y9`-Ǽ!ˆ&Rp{GYNԯ3|䓟z)|{?zo]u:Oކ.!샓q1-Fuo|:q>ol3t 7\Ds$%+]UX%*̾zs'8NFWR=np\ZJ
-PsmA?!3Ҙ~3C!۵$$ŸG'vr{_k (%& {v9 H0r?aL1ƬQ"65OmE8!En?0H&wK赑Fw?{FP?G"'3thq4RH@%< %mZp<aUPQVַ}1'fsLq\Qq0sܻ 44R\ر4Yu8d쳩Р\aFwSl*]#$ggq4< ?7
-uwcݽ\wқxZ|J^:/A0I8
-#a`)9b& ޡ˩6\E^.9"CI, b}1Nˑxpͱ<Z7xdabp[fJx+U6?*'ۑk$#H0XO01|&<3un97<0.gu- Ruܒ85
-[n4&it,Ay>TI[iwQ^?6@W[ɤ"U8_jhCoE$.ؓ=ǾʇAͦBŨWBaRPՉzxp>Z<Ơ"ki2YKQ"|Jٶ|9\2|Uτ›Wᒱ<2i߹`oh>FR=Qīy9 YW
-pp*`z<&9Lj-}d
-P-1/r!Zo|t1!Ēhr,gut2Z:ޭNד? Վ򠯲NAfV
-ф1Ecx+pkwtݥi$Uo>Xe[h<B
-M Zx2%d?3<]vK r>ak3Xrf%êG?$%r!!/J VEN\6c+PQHչ?H^@-yL%`2/i "ZDWJfS\r 96ܑ3Í`!0(qت2nRCRc%?ﻥnʹfضT^g3i~#l"RJnS'Tpa$ ,cۈb.WuxRi5!~5/M-
-(,⠨8 dk{Wp^Uk}eiH6H,G:g"Ckg[9n9<\Ӆ^B,M$$Y}Э&l'DmP-XgR6ǰǪ0IC#_k?rvw؋;ZGmFRs1USG]XΦP1.gu%JCsh!
-s' w a/f8
-?|"tABeQF#m<hDٴMm,ʆ<0KkKxKJͲ)׭\cYK&
-kmW_waIBacU#lAh(*Z!ۇ>4^D8oMӋ 8A #1 ab/3.,rj}>Q6Y6qx fgan`˽2%w`лc}q<#I[[HښTqhN%y-'(v s0)EXVP<o9H"3`.'yoS)-lkT5+QL;(޸OڲFX6j&Xk,k`K IX3Q'd,_H M:ܽ=y|M÷'˪hH
-"Щ$KyǒP=ԖeSլ{j{R2L|}qRO~V
-XF6UMNJ$Iӭ-‹Yθo=^?=$^z›OnHAO',yr{Ԑw#2lE3R2dw'YC6JcL VNLD[ޠbQI.kL c$IqSn0B_ѓKK(Ey@vsLxf$uH/k)zw|
-/`n3vYZTu+jgwya6WSbF fHJ
-S%̻Յd͊3*eϖeSclj'-U]VcEscqpZx<<%]9y1CM'$ez0OOmmà?L#cwπ*!Z2.*aUұFVf,y W\nVbcin{Eظ+[PW;%{ʥ*2tM491bB$v Ꭾ+5d!"0EXh(kfCrZD8#K`F&t%6E}6d:R2;UƴR}[U닳em'/{)+SI6aWgIhR fqy7'-]_$;aݴ ;
-H1WI+=7 +"dGoO8($y4`0c?Y^&jdђFgeT6jV܅e2l Nfbk ɭ`P%kg]>/qWIضh<e/=^o8j:Onۇ>6) t MRR^'#$u``>lGpf1)h2 |r3*2#C([N^-`˽-p@9b$L)KZ^BsWz着ՔؕS EXM <{𭳷xc0 +0"ꌭSIںsgtЊ Ll,5liA$oZ&<ZIYxIV@tI=A||"8򝺥T !#1D
-&\eb׀&`ͿX_Ƙo#b\CގJN'T 8Rҹjq0RnE\.$۳ZV.x%גߠ+ڶ젫To.[~Tg I+|kKpBL^(wѮ:A%TϏ{zM.L´Ur4d f`B)1pH 0e [0͵B*^DWfkIzt&]od^ʬQoL0YA h
-X%_z7HJC }H{_|raf8! f0#~-5ogj˰2X9˹R6*%%d+z>ԼTtR Q53 9ҜAL[J_wݧr UvUUv鯺g$O;`0gv.,=Z Zv`Y2t$"–p&[DWf ϟR
-.-mSc9sNRD nx[<@Fx^@=֒.k0RN'7?%nҋhzG0 fC)mpH6euA'-LZ>R0[H9ğ-$7z*vlsW1[(Z wZPa/y@OGoH8#OʷF#
-n<b l;茷Yϧ(ɫ0y rELGMkoh{Rmy:`dCH%'֌ #1 ;ag eU2QeBf:&fsS09/
-&]A;v7\y+3DL‚\0DLW=80R<ާ`$ር©?+s5)2`7g+Æn~XQo<1Vo[*̎-;o&FnO~M¤Z`NW+6uN(lǴ
-L꼷HXR|2L|m> \r^¾SxdVZh^ _}H<)*$89C?## 'gwϛx.d$\/⇔۲k$$
-#mq<  p`-$[7vL0`07XgAga U'HQA*JGG$RǼo@tǁ>y%F?$
-rޝ;He{쳷쫑;2pb$EQu)mX %YKEC4?|\9bx.& j-`pnC&ӗS~>K%U|n
-!Ü.Vimt«~P"Sg]C(]*yg?
-EQEQuFL
-H pT/!&_aBA+ʄbJZDhjhb"SlSF[qvBP
-P)-7Bd I&;=&_{{|!;Lsw9W=!ግPڇ#=^v^fV$Ax 6G<=\ k˰n
-]J{X/-0GOKK;ֺW̷Baפ =R2X
- 0M5bcдp;NY#pMg|ӌ4W4,v_}&:2Z=lX͚j0T<6g2n}Md~’=}.5+۳)H8tYyhJ-k~'3~,Ϩ&XƂd Xnp.ù຤FіP>7`&&X护M5*~Z${S:ƎVBLJ`Y+TH$\gR|%1닶43hXz4J w @(_R `_ g,]ƜrlY.8.lg;jȾX8w޸`oO:ݔpZDE-#*5D^A;LI56(VX 2"sAVãTl1qVx`L2% 4MTદpuwVUn2"`Cpٯ+ sAGETdTQXRP#m5)hՖg}Ԉ $!)f,Q*>ZEB ַG0ujEq@{usIg0ufs_7ZY<kK1{&F[gVG:e7 ΍˷T [531ɊDÖDy3w+q!JA(ov
-si-q8Z,lQ7Oi FYk}8b'<n8YR88k}oiL#ky3=L,݆4.(tn67Ux^_U5w-62}[7ܵl"-]óo6Ufs煝0/>_z_W9.Or?KSy/?X?'[Ư
-q'+l魌~_$ۘ\zFܠ=F_.LkQG+Y I1ӠMå;o]syk.Z5׽FĖ .?Ǐ}Q$^k0p2E~L4Z ^b7k'7-Xx]#]Z\)߽+k"IJj~ނU7:>"p3{+P֬&Y}4cI,ҝ~eݣV_y{&!DqK;]F>pqO׳UQ+fRn r[mEeZv7a񺷛p^k͖wpR{YP^:y-[W!=AvZk^w7nquEٍ+y*+E/lͼn=XN|qڏۏ}kO*lXZu^{Nj7hk k!9n>JTO2A: 8A ߆xm8 Wgqys޾;[Y5kmx] ~G7K~ t"\ZjU\^<K;;!niVuC0sTYPW*n;2ovޯBlB:?LגkUTY(|W~j__w+_ ]FRZkAɈ>y[sΜ ~lm}r~̜~=oT*ZKc2 J
-에T{aku)\`f+Qg>q,^yײjv}5}_CC9?׍5py¸<{{n9ZFp699%D@7˚qDuX7MA
-0PGDrz-oD]][,Sghۃ,o)ZOXSK[j_Md,o) =doٽ]w:I߭V
-0D3ܩIF) rv7u2Vysr5NZ_kWG,7.W1n*I'cT/#^ "DA7Yy#H^GN(JPysRn@ͽZWm$Bd8bnPy!X,o*%`b ͵vaDm9*k`U74\U䷌*G`R 7{~oỲIFAJYAj'c*ay#Pvs$^e#'$;#%#7Btu /]PY(n6 }j2%5JoN3o*(SQZ@{`%(n~̼*8_$75vQ89m}3
-Nyʼ0 Nz$ 7k'{7uv!D P´vYsv.Jy3wh9#</X卐%:鍐m%>5P%(-+y#d^oɡ7B"Cd\¼2k'qIYiT!J}q#d!7'a/:$nVަ4A7'FٯX2>c:$Ok
-a "TZKX3@-DL~sCBؚJRa#jdSaSB=Pj~>?7}uݼH:ӕ8Ps%!kQ}լ'0@5s7y1zޚ: ym184hR3 ̷݃]0@5O u |d TsZB tS%dN=ycՌyh :z˨oy:I9jJ
- <Sx!q
-ष=lC*'-g^IP`4ŽRߊ  M; O8C<o D~3=zd= =uRup6p9DgV_@g*epZ$FQ󛸿Aj1ѥ$DZa4}_@gKRt#7Hlm%%
-pNUo1cpMCp?!;24 J9o[o 8)ur> 8ЩʏG7$8\)An^F<jO|2}"+tqlgG[&.ߺ-c2Ӹ8hcOP"ËA' rg!-uFzԨ/NR1x=,xs7PC~E[I7Pq~Oɇ-ej8>=3u|lRbz=,p%s[ p}h{3t~7P$翛h{Ki1rM,oMbqEkoM/
-#S-3cyw;߁\FoP/][o-?$
-5|k҆@1J NPlgƶfҟMTo8NV>P'z  y(ɘos|l]k^.dRgs
-L"57B,泪q9tիK
-0N-8$_])yts\YOlӉX4bBoޅ tPp ˛…\sZ#N˚5[6iHom^=vh\gSr#7Г\`|tPߗQ߄VMc=-4$aykh؟uP څu4%ݔ|`Yͷě=J=>KzwR1j5L҄<Yno8Ol7B_: ono'Ǜ墚o kޛKN`fz|%3zh;hK.4$cb.m@o.Do+) NTo\:ޛGwrR\- WSj!?ӛz78{qlpw0ǯkTL*1ӛΥK[x~Ω Z{#h|wU+gR uoEb}7YLm Vog
->~[V\rg ;pmU
-tR͡Ƴjlor7|HR̦z 7#ۍ@1J"9!wc,w{{j6PjޛGkNcQ[SԪloOu'70jb.7}{s~L4
-2/jyi$!C|.M{{ , }{si 7-"zt+XC|>mo.5:h.E<ձ7օj!'3x9܃ Grxu8{r}Ft#7G닩t<u!%ߑi,eAT.¥=_
-X2q etӴ"ݓ
-H9{I5+H7*Po|s -=z +N욾!yۙ7G~2o(1Ņ-ۅ U]Ϸ_t
-qOƲJ~/(ȾUzC~R_9<Pvۧ[,Dy}vjz,]z_cNM*@o*sԄ%3v%WU-V>PvNɿXXμBkG ׬r
-My9
-䝛W
-꿖9-gPAwo7Tg["W*k3r-
-ˇ6ͩߟB=$1(#ѴnҜtO*i=.71o'upL{y4]'|βhzĞG .Y=:$&KaLn٭0YpL9 pB,+kUpW](y"D?-qet@x<({aހt^erӳn2zށ{+[3А
-(x@-Sz506{xgF?PP9"Q].Lpe۵g
-ƣ .3ug[,< ӧ -V08]55刭4O镅Hj+ h x],ݥg0OXl\6 ˔AzK& Ɉ8(lf\"s8(Ƭs3 .3p@c^w? Pp|.<M8|DE88+'\"'=>}`E24tۧn{M9}dB}|?
-PxqK~ h.][ '_Z` 8n$2yzZ`\u\$О
-#Q˙AC?3
-"{QiL- s@7V&7;WǞq̓;Np@wgܚkM'.1孢k\\$=KlT\"6qP uFWc}KnL{
-$AQ#+X
->x4 "2h;NA*
-% a)Pa HA) ;gY{w?;ݻ;{o4Hz%"ADo)E$8P"HH $9Lo8T98I"/!S9R{K[# #xVVX)Aȏ| NUl@p Po&vPfKo|& ]`M~.48q
-8'%& {PnE$"4)m778&Lwnoepxo%?L,pn\㨷1Ln+5qtA7X]6%xPrɋ `(9gwre';ZvQ.Yt^T$ m7
-O!_k#5ݯ4cH $JIz j{.i
-LoW_0H>4`z8YtЪ2:ʑn/qHw7&yU]T]5)ly=5HN\o'`9rsGn&=/l+洄nYMjJc!YC{쒀,J(`b__4߀vMdd`U,{7aZ~ҏ1r~En$7Ħ7ʯ<൦!x\oou~lQTlaboқ|La(L(pݳ2EFӑ-z]\ш`b;$B^4yV}["l{ e+Oã1 *-{#$@@Szj.l 6a䬮TΔa}ܫ)rQ i"eͿ?Ckĭ4z\*ʡۻgo`pSEo>gz>iJbӄzJ|
-sN/ߗs) K.|"T= Kz3H=7t}wjjC,"[_)ZzD%E_/bL!8Ӂ)R&x-wޏ/0rރn ʜT$2fRUWY.{j
-Gmd aҲrJVʂ>l̘ n/Jj{Sư5B҇d[$g$;|gp\-AW-<>nT="8 ydt|C}aLÀkA܄3Q1.r?)xұ[V
-h3 d t"=T͖ '[wFeK!) R6V
-49{Yx} -m?zΛPQ;Fvw(97uUK6S7M^uJ.*cGׄ .$SF\ˌ_k<l.=u u^Qp`N-R- °SY9r -&aJ`U5{mxZgF: |qk
-=gG(%z+
-%QSE@EXݒ?lVC]A Eإ
-*hE`/ymiiݖ7ܙs?sWO.X}[2t6BmE`6NBnn l@) '?X>Y e ^#S?YB\ܑnƒskl_m^FPB-/+?faP!E2 .dup}R-Ԩg
- Y1T.k'Ql o܅φoKll}aW%rɳ&$Rxؾb11ԁ'lO\)d9ҭ)>Mp]7Z‚G':u΀(q)
-u$dlM
-'wk S-| O;y]
-1ԍ]7T5ھGOݸ$kTF`OV|PčM]tMcY }v,n \fcj{.)ٚUŠrLV$B@u*B7F6y2|rr;+\[ιrptrCx!r](P
-g=c(1 fB8P
-G]d i9++m'A<jn79TM0LٙfS;qP2 j@2OيP'8}cPQ猪sQborI`
-2bd3o$yUݸ뜺UMAW3]sWL#:$`d3`RJ>UdQn3%ilrO8Ӫo+9ETOiSWhrFdw3:{ϣlW .6lY{ex!8t_xW>mΈȀ5{J=WFsLhPv$}_RMפ}
-˴{Bzr5x.UI&${C[#Eqx(կa9EP\%wEOwS8q'^ӘD٢#AJSTY+v0ZGM0٪]lQm>Pvy$+^D & H}Bp8o/wo$_u.7Zհ 7D-z VwԼuYa0N@Ye囍 'cmt-ƗYkC#01*SuS,٩p܅[C_qbhjF Y.&L0W7O.(Uf?UʍlE0%ݹ@"qy*`@vyIy%Yqp
-~&enc*wnjIcw5kΗ@,'k;}Y.Z.\\)+;=V~M+\`I)^*-O0 ! AB\u߃7%˵ .}w[<Ċsdr#Go?"Z-6K1
-$d/:0\}]7>
-vTUC:ˉA€e>Ś<Ovx_'M8jdc3tS˷}Å17{ĨAL--3"\& AڒC(D9=ڭz&b] 0
-HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽
- 
-V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'K
-x-
-ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9
-N')].uJr
- wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4
-n3ܣkGݯz=[==<=G</z^^j^ ޡZQB0FX'+t<u-{__ߘ-G,}/Hh 8mW2p[AiAN#8$X?AKHI{!7<qWy(!46-aaaW @@`lYĎH,$((Yh7ъb<b*b<~L&Y&9%uMssNpJP%MI JlN<DHJIڐtCj'KwKgC%Nd |ꙪO=%mLuvx:HoL!ȨC&13#s$/Y=OsbsrnsO1v=ˏϟ\h٢#¼oZ<]TUt}`IÒsKV-Y,+>TB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O
-zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km
-%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 17.0 %%AI8_CreatorVersion: 19.2.1 %%For: (Zachary Mitton) () %%Title: (metamask_icon) %%CreationDate: 6/15/16 2:23 PM %%Canvassize: 16383 %%BoundingBox: 98 -140 188 -44 %%HiResBoundingBox: 98.7919746568114 -140 188 -44 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 13.0 %AI12_BuildNumber: 147 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Registration]) %AI3_Cropmarks: 79 -156 207 -28 %AI3_TemplateBox: 180.5 -120.5 180.5 -120.5 %AI3_TileBox: -163 -488 449 304 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI17_Begin_Content_if_version_gt:17 1 %AI9_OpenToView: -39.6666666666679 23.666666666667 3 1419 866 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_Alternate_Content %AI9_OpenToView: -39.6666666666679 23.666666666667 3 1419 866 18 0 0 -5 38 0 0 0 1 1 0 1 1 0 1 %AI17_End_Versioned_Content %AI5_OpenViewLayers: 7 %%PageOrigin:-220 -420 %AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 24 0 obj <</Length 22700>>stream
-%%BoundingBox: 98 -140 188 -44 %%HiResBoundingBox: 98.7919746568114 -140 188 -44 %AI7_Thumbnail: 120 128 8 %%BeginData: 22554 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD24FFA776FD75FFA04A4AA1FD73FFA04A754A75A8FD71FF7C4475 %4A6F4A6FA8FD6FFFA04A754B754B754A75FD6EFF764A6F4A754A6F4A754A %76FD6CFF764A754B754A754B754A754AA1FD69FFA8754A6F4A754A6F4A75 %4A6F4A6F4AA1FD44FFA7C9A075A8FD1EFFA8754A754B754B754B754B754B %754B754ACAFD3FFFCFC9C299C1997476FD1EFFA76F4A754A6F4A754A6F4A %754A6F4A754A4B4AFD3BFFA7C99FC198BB98C198754AA8FD1DFFA8754A75 %4A754B754A754B754A754B754A754B6F76FD37FFC9C99FC198C199C199C1 %99754A75FD1DFFA74B4A754A6F4A754A6F4A754A6F4A754A6F4A754A4A76 %FD31FFA8C9A0C1999998C1999F99C199C1746F4A4A76FD1CFFA1754A754B %754B754B754B754B754B754B754B754B754B6F7CFD2CFFCAC9C89FC198C1 %99C199C199C199C1C1C175754B754ACAFD1BFF7D4A4A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A6FA8FD27FFCAC9A1C2989998C199C199 %C199C199C199C199C16E4B4A754A75A8FD1AFF7C6F4A754B754A754B754A %754B754A754B754A754B754A754B754A75FD24FFC9C99FC199C199C199C1 %99C199C199C199C199C1C1994A754B754A6F76FD1AFF764A4A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A76A8FD1DFFA7C9A0C1 %99BB989998C1999F99C1999F99C1999F99C199C199994A4B4A754A6F4AA8 %FD19FF756F4B754B754B754B754B754B754B754B754B754B754B754B754B %754B754A76FD1AFFCAC299C198C199C199C199C199C199C199C199C199C1 %99C199C199994B754B754B754A7CFD19FF764A4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A99FD04C199C1C1C199C1 %C1C199C1C1C199C1C1C199C1C1C199C198C199C199C199C199C199C199C1 %99C199C199C199C199C199754A754A6F4A754A4A7DFD18FF7C6E4B754A75 %4B754A754B754A754B754A754B754A754B754A754B754A754B754A754BFD %05C1BBC1C1C1BBC1C1C1BBC1C1C1BBC1C1C1BBC1C1C199C199C199C199C1 %99C199C199C199C199C199C199C199C199754B754A754B754A754BFD19FF %754A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A4B74C199C199C199C199C199C199C199C199C199C199C199C199 %9F99C1999F99C1999F99C1999F99C1999F99C1999F99C1994B4A754A6F4A %754A6F4A76FD18FFA14A754B754B754B754B754B754B754B754B754B754B %754B754B754B754B754B754B754B7599C2FD16C199C199C199C199C199C1 %99C199C199C199C199C199C175754B754B754B754B754B75A1FD18FF4A4B %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1 %99C199C199C199C199C199C199C199C199C199C16E4B4A6F4A754A6F4A75 %4A6F4AFD18FFA16F4B754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B75FD16C199C199C199C199C199C199 %C199C199C199C1999F6F754A754B754A754B754A754A7CFD18FF764A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A9999C199C199C199C199C199C199C199C199C199C199C199 %9F99C1999F99C1999F99C1999F99C199994A6F4A6F4A754A6F4A754A6F4A %4A7DFD17FFCA4A754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B7575FD17C199C199C199C199C199C1 %99C199C1C1994B754B754B754B754B754B754B754BFD18FF764A4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A4B74C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1 %99C199C199C199C199C199C199754A6F4A754A6F4A754A6F4A754A6F4A7C %FD18FF754B754A754B754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B7599FD13C1BBC199C199C199C199C1 %99C199C199754A754B754A754B754A754B754A754B75A8FD17FFA04A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A7599C199C199C199C199C199C199C199C199C199 %C199C1999F99C1999F99C199C174754A6F4A754A6F4A754A6F4A754A6F4A %6F75FD18FF4A754B754B754B754B754B754B754B754B754B754B754B754B %754B754B754B754B754B754B754B754B754B754A9FFD14C199C199C199C1 %99C199C175754B754B754B754B754B754B754B754B754AA7FD17FF7D4A4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A4B4AC1C1C199C1BBC199C1BBC199C1BBC199 %C1BBC199C199C199C199C199C16F4B4A754A6F4A754A6F4A754A6F4A754A %6F4A75A8FD17FF764A754A754B754A754B754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B7575FD13C199C1 %99C199C1BBC16F754B754A754B754A754B754A754B754A754B6F75FD17FF %A84A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A4B74C199C199C199C199C199 %C199C199C199C199C199C199C199994A4B4A754A6F4A754A6F4A754A6F4A %754A6F4A754AA1FD17FF76754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %9FFD11C199C199C199994B754B754B754B754B754B754B754B754B754B75 %4B75A8FD16FFA86F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A99C1C1 %99C1BBC199C1BBC199C1BBC199C1BBC199C199994A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A6F4A6F75FD17FFA74A754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A754B754A754B754A754B754A %754B754A754B754AFD13C199754B754A754B754A754B754A754B754A754B %754A754B754ACAFD16FFCA4A6F4A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A4B4AC1BBC199C199C199C199C199C199C199C1996F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A75FD17FF7D6F4B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B7599FD10C19F4A754B754B754B754B754B %754B754B754B754B754B754B6F7CFD17FF764A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %4A6F4A754A6F4A754A7599C1BBC199C1BBC199C1BBC199C1BBC199C1C199 %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754AA8FD17FF75754A %754B754A754B754A754B754A754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A7599C199FD12C1994A754B75 %4A754B754A754B754A754B754A754B754A75FD17FFA8754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A7599C1999999C199C199C199C199C199C199 %C199C199C199994A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A7CFD %17FF75754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754B754B7599C199C199FD13C1 %99994B754B754B754B754B754B754B754B754B754B754A7CFD15FFA8754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A7599C199C199C199C1BBC199C1BB %C199C1BBC199C1BBC199C199C199994A6F4A754A6F4A754A6F4A754A6F4A %754A6F4A754A76A8FD13FFA84A754B754A754B754A754B754A754B754A75 %4B754A754B754A754B754A754B754A754B754A754B754A754B754A754B75 %99C199C199C199C199FD0FC1BBC199C199994B754A754B754A754B754A75 %4B754A754B754A754AFD14FFA14A4A754A6F4A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A75 %75C199C1999F99C199C199C199C199C199C199C199C199C199C199C199C1 %99754A6F4A754A6F4A754A6F4A754A6F4A754A4B4AA8FD14FF7C4A754B75 %4B754B754B754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B7599C199C199C199C199C199FD11C199C199C1 %C1754A754B754B754B754B754B754B754B7576FD12FFA8A151754A6F4A75 %4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A4B74C199C199C199C199C199C199C1BBC199C1 %BBC199C1BBC199C1BBC199C199C199C199754A754A6F4A754A6F4A754A6F %4A754A757DFD11FFA14A4A4A754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A754B754A754B754A754B754A7575C199 %C199C199C199C199C199C1BBFD0FC199C199C199C199754A754B754A754B %754A754B754A754A4A75CFFD10FFA8754A4A754A6F4A754A6F4A754A6F4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %4B6EC1999F99C1999F99C1999F99C199C199C199C199C199C199C199C199 %C199C199C1999F99C199754A754A6F4A754A6F4A754A6F4A754A4A4ACAFD %11FFA8754A754B754B754B754B754B754B754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B7575C199C199C199C199C199C199C1 %99C199FD11C199C199C199C199754B754B754B754B754B754B754B754ACA %FD13FFA87C4A4B4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A756EC199C199C199C199C199C199C199 %C199C199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C199754A %6F4A754A6F4A754A6F4A754AA7FD17FF75754A754B754A754B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B756FC199C199C1 %99C199C199C199C199C199C199FD11C199C199C199C199C199754B754A75 %4B754A754B754A76FD13FFA8CA7DA176754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A4B6EC199C1999F99 %C1999F99C1999F99C1999F99C199C199C199C199C199C199C199C199C199 %9F99C1999F99C199C198754A6F4A754A6F4A754A4B4AFD12FFA87C4A4A4A %754B754B754B754B754B754B754B754B754B754B754B754B754B754B754B %754B754B754B7575C199C199C199C199C199C199C199C199C199C199FD11 %C199C199C199C199C199C199754B754B754B754B754A75FD14FFA8754A4A %754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A4B4A9F99C199C199C199C199C199C199C199C199C199C199C199 %C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C199C1994B4A754A %6F4A754A6F4AFD16FFA8A14B754B754A754B754A754B754A754B754A754B %754A754B754A754B754A754B754A7575C199C199C199C199C199C199C199 %C199C199C199C199C199FD11C199C199C199C199C199C199754A754B754A %754B6FA7FD18FF516F4A6F4A754A6F4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A4B4AC1999F99C1999F99C1999F99C1999F99C1999F99 %C1999F99C199C199C199C199C199C199C199C199C1999F99C1999F99C199 %9F99C1754B4A754A6F4A6F4AA8FD17FFA1754B754B754B754B754B754B75 %4B754B754B754B754B754B754B754B754B754BC1C1C199C199C199C199C1 %99C199C199C199C199C199C199C199FD11C199C199C199C199C199C199C1 %75754B754B754AA7FD15FFA8A14B4A4A754A6F4A754A6F4A754A6F4A754A %6F4A754A6F4A754A6F4A754A6F4A756E9999C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C1BBC199C1BBC199C1BBC199C199 %C199C199C199C199C199C199C174754A6F4AA1FD17FF4B6F4B754A754B75 %4A754B754A754B754A754B754A754B754A754B754A754B754AC1C1C199C1 %99C199C199C199C199C199C199C199C199C199C199C199FD11C199C199C1 %99C199C199C199C199C175754A76FD18FFCA4B4B4A6F4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A6F4A6F4A9999C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C199C199C199C199C199C1 %99C199C199C1999F99C1999F99C1999F99C199C16E4BA8FD1AFF756F4B75 %4B754B754B754B754B754B754B754B754B754B754B754B756F9F99C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199FD0FC1 %99C199C199C199C199C199C199C199C1A1FD1CFF4B4B4A754A6F4A754A6F %4A754A6F4A754A6F4A754A6F4A754A4B4A9F99C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C1BBC199C1BBC1 %99C1BBC199C199C199C199C199C199C199C199C198CAFD1CFFCF4A754A75 %4B754A754B754A754B754A754B754A754B754A754B9999C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199FD0FC199C1 %99C199C199C199C199C199C199C1CAFD1DFFA84A6F4A754A6F4A754A6F4A %754A754A754A754A754A6F4A99999F99C1999F99C1999F99C1999F99C199 %9F99C1999F99C1999F99C1999F99C1999F99C199C199C199C199C199C199 %C199C199C1999F99C1999F99C1999F99C199FD1FFFC299C1C1C19FFD0FC1 %99C1C1C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199FD11C199C199C199C199C199C199C199C2FD1EFFCABBC1 %99C1C1C199C1C1C199C1C1C199C1C1C199C1C1C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1BBC199C1BBC199C1BBC199C199C199C199C199C199C199C1A0FD1EFF %FD18C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199FD0FC199C199C199C199C199C199C198C9FD1DFF %C9C199C199C199C199C199C199C199C199C199C199C199C199C199C1999F %99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1 %999F99C199C199C199C199C199C199C199C199C1999F99C1999F99C19999 %A1FD1DFFC9BBFD19C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199FD0FC199C199C199C199C199C199C198 %C9FD1DFFC1C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C199C1 %99C199BBA7FD1CFFC9FD1BC199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199FD0FC199C199C199C199C1 %99C199CFFD1CFFC298C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C1999F99C1999F99C1999F99C1999F99C1999F99C1999F %99C1999F99C1999F99C1999F99C199C199C199C199C199C199C1999F99C1 %999F99C1999F98C1A8FD1CFFFD1EC199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199FD0FC199C199C199C199 %C199C199FD1CFFC9C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C199C199C199C199C199C199C199C199C199C199C199 %C199C1999999C1999999C1999999C1BBC199C1BBC199C1BBC199C1999999 %C19999989999999899A8FD1BFFC2FD1EC1BBC199C199C199C199C199C199 %C1999999C1999999C1999999C199BB99C1999999C1999999FD0DC1999999 %C1999999C1999998C9FD1AFFC998C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199999899999998999999989999 %99989999999899999998BB999998999999989999C199C199C199C199C199 %C199C199C199999899279998999999A0FD1AFFC2FD23C199C199C199C199 %C199C199C199C199C199C199C1999F515299C199C199C199C199FD0DC199 %9999C1992E4BC199C199C2A8FD18FFCAC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C19999989999 %99989999999899999998C175510528057598999999989999C199C1BBC199 %C1BBC199C1BBC199C19999989927286FBB99C198C9FD18FFC9BBFD25C199 %C199C199C1999999C1999999C1BB994B2E0628272E279999C1999999C199 %FD0DC1BBC199BB992E282E99C199C1A0FD18FF9FC199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C1999F99 %C1999998999999989999BB98752706052827280528279998FD0499C199C1 %99C199C199C199C199C199C1989998990528054B98C198A0A9FD16FFCAFD %29C199C199C199C199C1999F7552282E272E272E272E272875C199C199C1 %99FD0FC199C1752E062E51C1BBC199FD17FFC998C1BBC199C1BBC199C1BB %C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C199C199C199C199992706052805280528272805280528989999C199C199 %C199C1BBC199C1BBC199C1BBC199999951057699C199C1999FA8FD16FFFD %2AC199C199C199C199C199A07576272E2728052E2728272E277599C199C1 %99C199FD0DC199C1759FFD04C199C199CAFD15FFA7C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C1999F99C199C1BBC1C1C1999F7575272827280528057598C1 %999F99C199C199C199C199C199C199C199C198BBC1C199C1999F98BBA7FD %15FFC2FD2EC199C199C199FD0BC17576512E27C19FC199C199FD0FC199FD %05C199C199CFFD14FFCA98C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1999F99C1 %999F99C1BBC199C1BBC199FD05C1999F99C199C199C199C199C1BBC199C1 %BBC199C1BBC1999999C199C1BBC198C1CAFD14FFC2FD31C199C199FD11C1 %99C199C199C199FD0DC199C199FD05C199FD14FFA8C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C1999F99C199C199C199C199C199C199C199C199C1 %99C199C1999F99C199C199C199C199C199C199C199C1999999C199C199C1 %CAFD13FFCFFD32C199C199FD15C199C199C199FD0FC1BBC1C1C199FD14FF %A0C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1 %BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C199C199C1BBC199C1BBC199C1 %BBC199C1999999C199C1CAFD13FFC1BBFD33C199C199FD15C199C199C199 %FD0DC199C1C1C1C2FD13FFC998C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1999F99C199C199C199C199C199C199C199C198C2FD13FFFD52C199C1 %99FD0DC199C1A1FD12FFA7C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1 %BBC199C1BBC199C199C199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC1 %99C199C199C199C199C1BBC199C1BBC199C1BBC198C9FD12FFC2BBFD35C1 %99C199C199C199FD17C199C199FD0DC1C9FD12FF99C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199999899999998C1999999C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %98C2FD11FFC9FD31C199C199BB99C199BB99C199C199C199C199FD15C199 %C199FD0BC1BAC9FD10FFC2BBC199C1BBC199C1BBC199C1BBC199C1BBC199 %C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C1BBC199C199C1FD0499 %98999999989999C199C199C199C199C199C199C199C1BBC199C1BBC199C1 %BBC199C1BBC199C1999F99C1BBC199C1BBC199C1BBC198C9FD0EFFCFBBFD %2BC199C1999999C1999999C1999999C199C199C199C199C199C199C199C1 %99FD11C199C199FD0BC1BAC9FD0DFFA0C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C19999989999 %99989999999899999998FD0499C1999F99C1999F99C1999F99C1999F99C1 %99C199C199C199C199C199C199C199C1999F99C199C199C199C199C199C1 %98C9FD0CFFC299C19FC199C19FC199C19FC199C199C199C199C199C199C1 %99C199C199C199C199C199C199C1999999C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C19FFD0FC199FD %0CC1CFFD0BFFA79999C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C19999989999999899999998999999 %989999C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %BBC199C1BBC199C1BBC199C199C199C1BBC199C1BBC199C199CFFD0BFF99 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C1999999C1999999C1999999C1999999C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C19FC1BBFD09C199 %FD0CC1CFFD0AFFC2989F99C1999F99C1999F99C1999F99C1999F99C1999F %99C1999F99C1999F99C1999F99C199C1FD0499989999999899999998FD04 %99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1 %999F99C199C199C199C199C199C199C199C199C199C199C199CFFD09FFCA %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %FD07C199FD0CC1FD0AFF99C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199999899999998999999 %989999C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C1C1C199C1BBC199C1BBC199FD04C1 %FD09FFC999C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C1999999C1999999C1999999C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C1C1C199FD07C19975754B27A8FD07FFA8C1999F99 %C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C199 %9F99C1999F99C199999899999998FD0499C1999F99C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F %99C199C199C199C14A27F827F805F8F8F852A8FD06FF9FC199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C1BBC175270027F82727272027F82752FD05FFCA98C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C1999998999999989999C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C198BB98C198C199C199C199C2A0A0A0 %C9A127F827F827F827F827F827F8F87DFD05FFC299C199C199C199C199C1 %99C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C1999999C199C199C199C199C199C199C199C199C199C199C199C1 %99C199C199C199C199C299C199C2A0C3A0C9A1CAA7CAA7CAA8CAA8CAA8A8 %2727F8272727F8272727F8274BFD06FFA0BB999F99C1999F99C1999F99C1 %999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C19999 %98FD0499C1999F99C1999F99C1999F98C1999998C198BB98C1999F99C199 %A09FA1A1A7A1A8A1A8A1A8A8A8A7A8A7A8A1A8A7A8A1A8A7A8A127F827F8 %27F827F827F827F8A8FD06FFCF99C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C29FC199C2A0C9A0C9A0C9A7CAA7CAA7CAA8 %CAA8CAA8CAA8CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA8CA27272027272720 %272727F852FD08FFC299C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C1989998BB99C199C199 %C2A0A0A0C3A0A7A1A8A7A8A1FD07A8A7A8A7A8A1A8A7A8A1A8A7A8A1A8A7 %A8A1A8A7A8A1A8A7A8A1A8A7A8A127F827F827F827F827F827A8FD08FFA1 %C199C199C199C199C199C199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C199C198C2A1C9A0C9A1CAA7CAA7CAA8CAA8CAA8CAA7 %CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8 %CAA7CAA8CAA7CAA8A8FD0427F8272727F82752FD09FFCF98C1999F99C199 %9F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999F99C1999998 %BB98C1A0C9CAFFAFFFA8A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7 %A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1 %CAA127F827F827F827F827F8A8FD0AFFC299C199C199C199C199C199C199 %C199C199C199C199C199C199C199C199C199C199C199C2C9CFFD0AFFA8A8 %A7A8A7CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CA %A8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8A8FD0427F827F827F87DFD0BFF %A8C199C199C199C199C199C199C199C199C199C199C199C199C199C199C1 %989999C9A7CFFD10FFA8A87DA7A1A8A7A8A7CAA7A8A1A8A7A8A1A8A7A8A1 %A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1CAA127F82727 %5252767CA1A8FD0CFF9FC199C199C199C199C199C199C199C199C199C199 %C199C199C199C199C2C9CFFD16FFA8A8A1A8A7A8A7CAA8CAA7CAA8CAA7CA %A8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7A8527D %7DA8A7CAA7A8A8FD0DFFC998C1999F99C1999F99C1999F99C1999F99C199 %9F98BB989999C9A7FD1CFFCFA7A87DA17DA8A1A8A1A8A7A8A1A8A7A8A1A8 %A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A7A8A1A8A1A77DA8A1A77DA7A1A1 %A7FD0EFFCAC199C199C199C199C199C199C199C199C199C199C2A0C9CAFD %23FFA8CAA1A8A1A8A7A8A7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CAA7CAA8CA %A7CAA8CAA7CAA7A8A1A8A1A8A1A8A1A8A8FD10FFA0C199C199C199C199C1 %99C199C199BB98C199C9CAFD29FFA8A77DA7A1A77DA8A1A8A1A8A7A8A7CA %A7A8A1A8A7A8A1A8A7A8A1CAA7A87DA8A1A77DA8A1A77DA7A1FD11FFCA98 %C199C199C199C199C199C198C2A0C9CAFD2FFFA8A8A1A7A1A8A1A8A1A8A7 %A8A7CAA8CAA7CAA8CAA7CAA8CAA7A8A1A8A1A8A1A8A1A8A1A8A1FD12FFCA %C198C1999F99C1999998C2A0CAA8FD33FFA8FFA8A87DA77DA77DA77DA77D %A8A1A8A1A8A7A8A1A8A1A77DA7A1A77DA7A1A77DA7A1FD14FFA0C199C199 %C199C1A0FD3DFFA8A8A1A8A1A8A1A8A1A8A1A8A7A8A7A8A1A8A1A8A1A8A1 %A8A1A8A1A8A1FD15FFCA98BB99C2A0CFFD41FFCFA7A8A1A17DA8A1A77DA8 %A1A77DA8A1A77DA8A1A77DA77DA17DCAFD16FFC9A7FD49FFA8A8A1A8A1A7 %A1A8A1A8A1A8A7A8A1FD04A8FFA8FD66FFA8CAA8A8A8FFA8FFA8FFFFFFA8 %FD12FFFF %%EndData endstream endobj 25 0 obj <</Length 65536>>stream
-%AI12_CompressedDatax$&?d& C;\;fJ-n[[YUZ(xd&,f #+3q98OxOq< ?wo ~7_{ˏ~/&G4M~Vۯ߼LG{4?oqwo^_^ޡݻ篞g/PWnC} 4`e߱=&7Ô?L/ޣvu&3%Co^|O߾yq7/߼W?>y~^|0;qv~c7/o^a|t/_/tqzWw0R<3ٯOaC)?l/Jo|ۿi[Lݘج{K̬̂1??J[x?~W~NguG|˻FѤS7_ܽD/ H1oɦ >Kz3 3y}vgӭw2IM~?WyOtҺ2!Lj}.6(^{_G<Ѽb |aoSl߿DŽkѽ_bٚO1';=I~R4!o;H]cձW?y=5w7_j|ӷR}To?~_^
-!}Ho_wg߾܎Ͽzz_~˧ߩO n_|=w.̙/|ܿ8~_xNuTOX[˷Zߥfi>$_>ksP3|q-y=?F?!]϶j~xx7/~tS/>\?߿cwwI|+r;鳶|0e> loq\߼3L/pba,H=;0?)vU\) ߀%%Ӧ\ \܌x[f`*nU-LDIo^iSi.繜5Jz7ѵ][*FAiUU*'-VmӯVuY[a^^Zd]fU͛V+ebe7g]k;la]/WkdYԬU)۵Z)*և:YeXtMe@CY#չk)7ܲԓŗYUeLIɭ̍zʵؔF2 ssλɝP-Vx>'O[L .C
-S
-p7v v)esU<s SH14S:t}b>sSʧ|o-&7 LNyni̕W*^rdNONtemwp
-D5CpqnX. K׌ucq7g\DW);2UnC|Ey x;Rٙ-خv8Pz? gx'H˗v؅0ܮH *`Cld!2r.y 9&*w"6`ټ.b/+>P<s r 4`
-fj=iv??yZ qE^\ZJYYa (rrgaoе)LN ,btU;ZNd6˻3C^/.҆YNavIBԩgMsН5ڣSC1ZSߜ|O3["䍈أ%l$"- FF/ӗr6Y8*ߩ))šs]q]; IxLnfI\JgeXr%>,"eXalX~PdS }bٛ2<duXE3Ϩr;.E9J\d('}(bs=U-l4W=9"}ZӬYAL6%Ts끼VJ{OX 2=ye[3UCwD翇d?Sԇos<;XԵ?ʏOBF7mLE߰s8҆+ H$" (" tAy\( !DʢJBFǭH|! ,DiȪ4$uN"e(rE"R,RQш‘Q ,e$JI OeSB%'ЈjFĥkK(2Qhؔ|J5t[듖|97nI?FյX4̲P,~)uuxIx" ?4 Qs E6< KCvD1<L\$9.ҢjU˭Tk]/R)[[hJܔ4lTyQ
-p*2:Za}S7zϢ-nM^_…/Y;lIr54
-rzb>l4맕aýE|r.VOoGEq3- -U
-ͪLTTJэEUZ*mXM]JY\9UDi%%2r5=Ҵъ %s(It8i4fCT
-a);12<L7@20{yDH?\~st-*X*;K>y?Ӌ+[ @c&*PV5m\86 ŸV+-7bU[#w)Zf{% 0<@jXp1frb=]9It=G9 [>EXy+3KoJO+ï~QQ0:1L<98Ilj> -Ѿ8Jl+u!3)]Hh% \hB#ڸLo{[Z&qk"fÊmIWCv8x}i؎u'^{߇qmCIJϞ=c@09Bk۱iccwt6sM&;XݸCI1T
-+tǵl⟿Z +R>qV#6Cxji7~zQfd @,zv4./_bS;;c4`&# 4؜6%0ySIRм m{=jP]||s|<:@> lm/zr._S 
-_rUXBa3|!<4S<0< Sy+De&W@AAr-^uUjKTˈXōuXᒗe?#uFnfVŜzQ27sPf'z3 mdq<9+r>3_<Uk]'
-@rO"i 嚀y0sfE :gx,>;ug{YʪHNEa십]ԕd1U w]<[ )8c(bb<;]=),IȥId,v+POD QuVoʬ*rk$V_ba_U[X.}7IʲC#rOL,lEkY, En%ʦ"ƞD1V] ֯$XJ:vl`{6VY=+2ҡY<Wbc~Z-CqŊ}سogu8rsm;nXu}!Ց?j6U615r#In
-wz·2_}q|t0>\v,нe|
-(Cq7o]ͷ`['sثj[d˧1rQNت8 ETԑ<}>S|efk Hʾ_
-M^A*V
-oDT7 F\'uY6@  ,[eh>O*r.V+÷h#exZ:i0$3QN
-ߑ6V<ϒ^XEH92kV'jX\+KdP8SGYр3ɡeNqV1 e'%:U9J1џP:vlu{L[5*F6Ԯ/+B ƪ-; eфaǓJږ߶<' Oo_KM ]"\EkF0EDϤE Ȕθϔog|VUu^v)H! {'xT:UjCITҒآ(ZJ(Z4KY薮lZJa\"6Bi(D9P{i{::6KOyíO0i5*alX!X%RK努Q>E(c4,Zۙ;^o;r%( />1]3HJW.=Cq Q; JliJB%۵C^ײҫjL[ExDZ䤵 nI˴~ԻzMj,v8'2<9> Oo_êD Oس&F
-
-0jhMMop-~v*fPj0<м4A͗ƪ]\ /0)zdp[_bݫjZL]kmrkX6ָ՚.XƬuɨ1i=d.LYO^IS)exZ 2< NO'
-O'
-xm7?a>Ykpi>d8$\09 f‡B'zgFxqO/e⎭cT1;ɸC0tmojj{ (qp͂C@z Nim)x?NvU!qnܺ//rvEi]ŧMi|T3ٷO'ؤ\L+u6u&٦|t,JtѲK]j=?Q`%֜k,pHyTak5u1'@IQAl P8MJ&7nJiQ<YOdF0DG3yvhCx/ew9ˣ/h-UPhnu&rSwOfc[x^$؝lxqq}csn<c&z} QPM5V' 5޿K9fKrC$ۊ-h45^73
-^.E/yjRKߗ i{ v?|'ȍʾGK6 ʅF|,x5奔v1ab,TrThv/̞ʽhj2~ s&pr|OsO!y"pQ-*X\ZY[z4]%zC@醒(MDisg'-tuh"Bm@L^u}DmAn$$y`0&gnճC7x'᥎(6Kft'8=nWlASuOx8SV*;Td>ٖIİX#!
-Ma\Qݙ>Y+|Z[1z[gz[1Ԙ۴mJUr5Y|Vnodw`xNRKisl\7P΍||TGYugnKE$%V`t
-6>+j::T\Phel銻PnC%oS5
-YSh
-fWX1V *:I2SOBI44!eVk?xܓ'cOLj4-oKYuUh% JLfd-ytu<+qeYmˇ_CUVN`7
- 6<žr[D\,-9n^$ D8aw2\0[ԡz*--ZLTFh7@K`nQ@밆#^MnRD_yrwQvpѹჲpb?McCa7Mt;HsM8)4y%qi$!wb-
-K gѢ_ \߹D!˔] bjQ"#ΐSm2a+|;rudȼ]A>Q?ulR0Ԝn`uEss9 +Q37fQ;NLthp) n)n6WZnE*:]yu}; ӕdqYJZ,=*SZ
-`E;p8O
-n2 ;aN(FXg `ᡭXbmZbw k7ax-(ÅS[/|um*][Wm!n;2._=11i8cT]#w-ՇI~ݔ÷Q~^/CQJ Rz$-Hi[Ȥ"k?hR{W5qn UVi+~
-
-whpC=C~ӷݿOVrbXݽ} ?9DaSt~;X43a{GOl
-DžI3^+0pl)=4/$MŽ'0Y:DHkuˉf$H˟^f<$j'ɲ'pe8l,XZd.T>S
-}[Ϲ0qufۿdf7_/ ʃs7_ٛ? ojõL{آ!TfEbѝ(xL(2f㴸˸$n
-,L"C"zJЄ \7T[ʤd + 6vBoeW]!DW1oHwm%H2kdRq'CՎXZ[i;Fx#B޵] yoeNl3_cD9D/*m%
-dބSy]- u•HJbcx[ w?* rYrBʟ:3̑nsS.eUdSik3G>fT9i\h?qsiC;+x#@E:PlXJŽKun|ƛy$ 8C(A]Z0Oׄm x{\F0TOEȓHfwaaJ@Cr`%@|R%RU#>Lo;yp"MfP"0=Xpn |9APr-
-23A(LOř\'"Dӂ3
-|=g
-gZh+6,QYޚYռ9>sǹ %ґ?l mm]㽃)Lp轑ChM
- SI8\Յ<%44.i+഻2>=ρo?Rݵ41?U58?!Yި&2<OYuf\1?d1 JY^UwR14Q@R'qA S"ݏV(d@DUwe%EA[ԕ
-Y BƸ4* hUNvv4N [i^:N"hw@SQAK'!S; - '?d ۅld
-eLQ-2ux5n wS(1&y Kٵ'؎Ԁ$FaqR'O>qňLeLf9m#p\ Kdve~e K¶#}0UOe$|xA*
- LTU$</k> ֎&&4yr($bx(5M0Ɉprwݗ#-F6<_
-4֣VԻs9)߲zNWQFm;-:ϱ?3RONYϹ4wJ?Y1F7lֵ, F8J\oY}68j @)7TەTEਟ
-ic c&N-pd<ttdpW #
-*NX F^ӎ^prfWY˕<
-
-`^71q9M(IDRΖ72 z\-o79 F4B!X9f6 :3m,o(a)HS oS-pC}78r!f.. k"'W og.mm B#Y%OňXHpd1 L
-/ -"UMgh=l1{u`3Mdh<1i*"h_wmw`{{*} '㜥4+q-PO UMcdm)Gt841Mb /71ru/TTØ\Bb
-c}[2>d?ѭLc̍w0SkY~x;(&68`d]@i U}q@3ŭOʨ4|nނ, xʀ1MO#iڸ&H-nqdq]$v0qTɣR;{#OR?WjJ'$q
-4"Fj0Z̝eHӐKaDcJj{ eY[El]lB
-yi/3Do:MpqyNjz7*<7%'DfWҹr""u:N#=չ`o6H{yvw#l}}29t48½eb)tsg(]vFy9Q
-wx7c""Ş/N7vCyl.D=y#ȼoJW+3@xsvޝbt։tymf{<<AtK>nХb%uV7K$3)ގI^c_SroT#xCAa#4[So+8ո{|*&D
-l
-1 fEh5X1FHXPIX X|5^ɓIr=t]F3}7Q0Yuoe%D>9tɆ/Ge#* BBu Vѫ!-W'0rǺ~,!^iTvtItu:+! H{D>GYƕn\/ iǩ'+z&;vʈ!5p O| ߩw{$${b[BPO;y,Ͼ YKfa5;-gLP>]yl?w"CuQ*v>ͫ֋БGqE{'{:
-豛ɗWi+vwf7V'˒Qv]j.gT쒑hL~^eY݄6:oCت(^@Úd7^_y
- DLsL^:~"r|ws5mn%n!#\
-얍y09ġxJxI&0!Sl <ཽAz#௑(k$2JS` L%NO;/< &*0yf0
-XOV:GKoe'o/^wDFFWfn
-8ݱ ɉ)Z\ɹxf#~2`gWuSq!nH "74w`>`ő<`z*Po1գguΐ!?穋H#o1)g 5k78'*%PbNHj2pWFpJO^6GA0SXb;VF
-/ƺ7EN)(ꦑ6~,VE VSӢRfn~:}t0%GQ Dj[1"FQQb3Q]?h+&@zLYB
-,%Mw'Ia$ Q=uYsTB -ݓU g&TQLQLgyiP6Ǝ}]7iR^!FKBᦢ5Jd2Ɲ:qu#U
-
-Gbgy@h <):o^i&망n(
-"deA53cK^3C"xfB+DuŅ*MfHV@ cX=dԥ bkug(]ꓚVI`4f !m :Ez8ӿR@LM7P[y=A
- D T C׊Vc}jxɠj)BН+e <*%2.Aܖnb;_G韬蓺VɕVv,]ߠwjڵm?cDtp4Gb@ +(•<j"y/R;θ:Q4rS%f6tw"zSv[NC*FJ""9XvZ4OZYե洣ԏ8^/\NMe4c ݲ
-X dp> .hۈ~$t$kUeGʀ<K^ԷxQ$d B(^먭ŞBע}*M694O
-XΛ
-u,_w<Yl
-r顰^SÂSi1hȤ3[IE8}R3f& VNHeAa*iq98Nq68.p̺h3hIi0TfġE" Zgy/롵 ! :x>-/ߢZ {[;=qUZ*Qu஺/[etl mѾQZ7nv`܆EU v
-d7GWc4zvM$A=Ne6o|5% 8@%&737`pT= ҙO6+6pү7hh 6M\ɳl'k_o1S]Lt&: =tJ$+ [TN5 Gt9CPM-d<.3%ԃqփqL;-"mնoXlo#z9xKcZ$i@5ύخ촨fL*J9JHm .g/SCނ1Z;ʌEUs.GT`rt*e&9ic]’c蘄]:7JY-'ZhjC=*[6$f|D(s WB.ͪܕaZӣ̑6 ţUn&2 jȢ;zr;;/\CBN(PtBSn`ߖ/5q;Z4tD=e7" 2 AtS 履Ւ-<`+p6H4]a^]țbӊ.
-8<
-y-30m] }RO3;uN#4f S>X)pÉꮅm3׭8mP d\K 6oѼЋaNt43ҌGS!xzFж^pݴt3zT9BET"C ":] È@:~$@":$:Jz^.8DׁCt
-6~)/v:R)hM'o
-|\oa\=y)t3!-m߈7p@y7E:B޵Ҕ=׼{R?G|?Va$T1Oب*Ed\5!soD 4@.3b$nJ{Us8^}]U~9)-ר>M!:4iR#e6ݏiXeiig#[%.hb7Ϡ=[/abrQkG0^3Y'{: Ė: virwb+VUcն$4M?ʼӽP짠<-1$[&mI1_VbFVcF2i@TkʸLŰA[#4S~^Ʀ5u<4O>NJE(پv
-s.MCoELIənܶx`;(VLG+qv^BdIkQdX佗ak4Y|X;;iӍ4h|^3\ĺ&qeߩiQfn~:\l(neGQj~ZߊU!<ji _0Ϥ.آ_+TBsG߭5rMqymv׊x-&o7_k^mOj߿率n,-GB"KV#9+(k-6s
-"'st'2r16T2!"}ؽHؿ7EU޴k醺c& C]JSfz)bM76P ;TĠزMVrr"d +LL$~IXb4Ow:մ zA0ödkE3ڭVZ0>n<VQ ܾ{M7P[Q `5uf4 ф֘+3ъ6F_BDbK-ɢUdV]|gRB9AmAk8Δʁh\Kעyjݶ<Pms ZNmeҶsS…Ũ[!?7?Ad${r $ж,41?P܃'D$-zT$x׃%)A*&h*c@4Fhh_2ja41zY b^Q\jo1 cq
-
-6@aae4έ’,MGq=,(zCݺ&u3FBw$l
-E{,6A2 xA @ɹkAv*«;- dCBDn}'dхt_"1chFZ@*̓dZި\yřLb
----8 "d/]T̴t>PI(v u 4O8oub){4W`Chr)8E h`hK}LZ*hE4i[4gcj#;DKeuk#i[Ni9sR ,i@`-~k9N.mm]
- ,0+\10WsZpyt{˵ jD$}4E} o~߼}wwᗿynovw_^߿~ֿgx۷o^_:7_m]iFϻ/ٛw n޽}qR0Y߾y|YڛgWqn^QпOw_޿./GEQ ɺQ<f
-ɵ,;}WCg_;1>1FF>gg|p4smYn^۬Ù߉|@c5eD!'1ծ뀑V+Fky>٩* ~ y#ogclJ)+J&H4
-f`E
-ZT:УRS9@3%O,#/hF1CvU@uyPk%d
-y }@Z7p 1W$DI!GaTI@SVPKLXsIшҏgPl>UBn>GRW9E&?Y#Њ
-lJFIVE [V
-81d:( iDd;YA'1-\ÐP 2mEy"V$QғLdQWn9"(s800Y<')HQ5YۑLK
-Bn
-TىVl K+<bT㤙SQ-B3Ŕ5Ip ^lF*b^^+]n%B2o-k5|nhQ!s陣KP2>nKv b@LjHE#
-&4240=#%sM9I $Q,*WNXYI*J GFO%]POH(ߢTseѲWT<0ƬF&v
-FB&?iRa}4J[1Ez.
-W aҏe
-
-/AxC!A]U8VwC !oOsᓗCj%\B[.|&HpxQ3t+d`X)dVǩ
-4+GNIeΥ3I bDI `xV4HE=sJeg %h>g8H\;nZne3ٙYL4tR9%\UصءIT|>T~>T*YIxYq;gn0+)["|=8:W4nDL_BQI>lC$;w$tд;#/%~ԥbœoG_0;hAr^9\o'“
-QWT &?H8 5`RoF9Hl Iev#Y B\j'ADUÒCTG|z!VXV."=X>w 8Fi$RJ[JW|_poe-v8GO| !
-IBHd(zS0w'<ziGa\Ɗ,Ag&B31eE)7\@50jVfX\5^)t=nKOBՖ @
-IEmla˴Rvg *t-#dD| n1w81ge/$R`i qE8+e^2e[5ע>)~-~(i"^Yш*W#CJ '~L#?ϸKOՀhJu38IL/EQYɭ@E'R]3D"
-!#.ZUzZi)Vy ~TD܄tYx w &:GX~i+;$2d9&Ee'i! VAY)VQAEṑHTjŭQaW]2Ĭ H
-j/P݉2L8zt?PsiFOIqK&W'5!4ĥj(YQ(
-XվUPdlV@Dw<%ߜbF=EQ30YUJY9A}7
-jO*ijI[9p>;2U%Dc&ƴ0'NˎcyB *¥$ @k[ _K@(w˚fIP},PǼ(gn$:PIc㘊O0gT@t;)-",$U 1=ȗN/m3x6i^dMf., &b HdIЊQH<hDe(h ;i!Xz<T$J%nR ֒|% 4J _$'1';q
-$uRƙv+q&EnP>ğ5\j"Gs`c~\|P$=Dz8N4jsM$P<spE
-28zi 5Q3CL*-B1e[c_aZFq"&+_w<H22U
-z$9FF
-ר^ `q$sA"'P'd#z3&iprēw nThH0I$jNy[8º8^+Qޓm@R}(`|ֈOE |id]RBR+:Q)2PL@(o$Tp0
-}
-%EEWg8չƩA]xnY!gŐIYW)¨{D*$q F'wc2xL=h+)WXQ/ Gf[4%XCJ損Pa^04yB
-3ٙĊL$-8hRdwrzjsKl
-`N_7y:x5u
-YOlOEa)J2jB
-PHEw21hH#u;(DMv,ٓ-  ;IdgzW{8C@_al=0` eC<+ܟkR<0pg3"L2bgCh49r0GGu'x,
-Oͪq.H(Erm
-%NX=f_'s36O4h <n4
-umɞK㾾C+RقiEE KY)D_XB@j!O7j2Z?x}pqזCZxA\M)4T/\ kWڂucϹ+M2NQ.tWVrcbuJz4=եH2S62Fti> 0ng=ܞq) l  {Fn^
-4
-2Ar+Pj#؂\͍i&YS~IY6e mCۨjk
-'-L#!<؍IMMΪn0ǟ` cu
- n-K#!!?FT 4ISiAKXZ^!TztAwJ6:7~:*GCb!1; 8[]>mS*|)겍@ .(W <:; :զ3
-h8qML(=\2)@xYȫ3{!n ؿ?
-mD=ߞ+#QZ)N,czA-\7t6lN B{7qes P)|ïMCcK-8>4 34Lh=^Q HW,7)ӣ3?P8
-!FRd% Hi&v * r*Y6zELS "XG}v `ͿMA7R-̫{f4-?BEf/3~bpGhvcPS|]rߘd 2J9|J6
-m!Dr< K9
-U!|j l_p$7G:j'Rdq! U~~־ Em;np A*&<8'cQiTr[LmG@^J).bf_yXz|+ǞaV'%Sf'\<]1)fv=%LVe%wb$T*돐Cʉ
-5\+T-=V &{6ϲs?X(露>4}<ZM7Jh]5y曲71RddYl=yEpw_L!;!N?P Gk6H~)H$(Ңa~=ЋorUO _7t~o }\vS)uIM
-1"z{`3:i+|R SC$2Z ֨yFZ y RuNYU@\da{@b4a$ 4}2*/I^2iN{8W SOeWi2SWPL&%fZp-*ޝYNg]JQ4@D+^]'@*r2N7jtHyqSQmV˨ͥ{* ݨIιEVRJ'+֎ ahRqC
-# Mr/5.iw~htaCƌKSAŸSϔ~DKV{%@H"`75KK-Ǎa3]
-NoU3髜 (<s5${ν} I+Ը_\k@C G߸׋
-nSVfNMԴG<qҘ<35\Ҏ]5ۖt0ɰB;/1'YV4%AN$ErrR:u`+R_.5luG&Bv.̯iUsh_jә!f?PzE2<vjɪ,uj-HRS
-`t\_(vkj3Wf̍~1ŝ8~qm@?]'8910xiJX^Z8%q:J9;Źk)wBop{iR$.$DElcydЍF/@A)Wg:"y7ztK(*uoef6bV
-Kucbb]Qh04B-z
-TKh<,ŕ0ݶd1uz$K1;:MQWw7w4s _??/?C4~QCi^rA忬^2[5A+cK|f58 }9j%B0^UYFHGQ`BYQpbfӹ"vc/,!tɰnE\L"I1=͊RߋGфP"f:ϵmCCV ] 1yleEY9\f+ *n/fr,i^/@%V*|:4f~ǵF*>U|\WFU:wX#=
-ψ5vW=JEאd;3]助Q2ztN+_`}{"}4*T*QГB~_d)봳4Fړ{f) $yضi9ؿ`W@hMZ,[P B0@Z,a$|3<CqrT J;vKև`NZuJ8Sl)~6?
-8O^AV
- M{
-1A-w݄)IXeYe`(aE[
-^Ŵr!ly@j 94pɠ>Y4st(?~N!$s
-ku{aR9'tv5e
-K'S>!1=@tPWfl;Mu8Z]oTXó.?@i d30P^6@(AG`Se
-?:2˴elX,&6IGt&s۠qJr6:Z$Q6D0N{+X POM#;
-
-@0*'7v ?b՘ᒏZ
-^qJ P{lnDX'a- oz.
-y䲕[$,@ 豨5d* A9.i!3~:Eguק+TB,UA2;èq߽(gjE>RZLk&}9EoB1ws44&䩡4"t}n U (as!Sf6CeU3<  3ޖ,8aEv~@3ڑ*BDzL%gƟS mA92@E h1tzE-h 6= |^qD*bT`[BDˋM9
-]l뫜%[U>C 8L޷8d
-G8x^+g
- X{3Y=aYLRIN+v\)3
-MH^ƒd_w
-8bʋң9rK֚FHU[O]Ad xހ?7L|'
-JytwFWr-ԼgT9ǁ77 MVDFO%a=WV8s{9DUpfB)R|N9E.6݊'5&%5*G*عJ pm}jH
-::S.1Y6C-.ncE0ڌ{`}6\hpYe
-o}un`׵\YZHiQסostqRj{6aΟȡ1K mFvʫRBP%D-Ά9 xg
- &\
-OX@(X8bZgw@C!'AQ{`w+9qVr6%}L
-u I)#Eq&GUӒJCxzC>s4fYHx{DdǒԱ p\lwMgn0.PQV<S72=rj륯pTխQd:35k3;wPgRlx _lBGR׼:T<sO=4
-\i7RN)m =.6ڡX#rՄ2hj*z.WƷbαsE#.NHVe_2E:몲D)RʦdUC-Lҋ!Zkq爵S/Bg/nYv#A*BIgZV
- WP<Cpsj
-.Z8zbgmNn1-)8Hwh4=]  S@ 6(
-f8Gq*ܵ 1 q,*l|XV
-7\%`7Ľ?#O MMV>żyH|+D3Sry,$GyЀ@@ceJ% =5tn+C'P|oUa$4{,g0 t _}8PHG PbΛS$@Ǣ*_A%$I)rmD1׎ʶFe^;^F
-AQe|(UXjno*I!CuԐEVAd\d[V%$M-<wiy/uO ,(9
-ŗw*8e⡩5D:O1+z+U 4x.GOmXHa#gs/m1@ei)QZǠbQ4:>V;C <36لdi$s̳8ȅ(ߧ5y- dnѽW "^m1$d,_zDD9Ƕ>4#XhD;uܦ$Ks9MGjToRn_Ds??O?ӿOO?OOO޾ͭ0'Ϸ`<១6`V1g ܪn17Zr7ŭa~|f{ 1S=V!osT^!<!# +I#*6(g}|щ|BȺb+[)>$;fqZvBIUsB0W0HQLslT Rg/?/zKԾ{#'A =fy_ݧo(?[.&ʧ}! 틐09
-a__$Z_ )Y=LٞG}okzJWGz)o#z>HBd|垦2oC?W-O˷<#Iʀ~6Ĵxm]<4O.)s6Wl[KG'xoξH}'Wݻp+Avos.~tqs6=| s~wB~Xryw6gj˓rmŎ"0ۂ} xf;'BOu>=hKPE:t{o/u1#D.;q2]N jendYG!,aq[m L1}QRP.C̲|>-tyahJG8402~~'woy| DQ
-+t/ksG55x/FQ6J7lq((Π4~8/moct: .? /d`!_>+/Bnz1uNi[s!˰!Afy[ _~V۶ܱ[Y9nQ2L^ї!#W~G/ݮ5(}O%0"(߲oyX3Đ|C7!Dn4\m&ᔿ NJa !X?YEŒf]"j7Fp;,=/u[{7.OG<[|0.Sy۶jpaEnZOnS
-mҝZ<'Y yF~FIDpFżvp<})?m-)e 4fZjOmIm]SlScⴎne$FV厍 +m 4uΧ6~g
-(=NZK*#69ON/scu/scdiS^V遼>H,a Q{HlpEJ|0#Ƕ1R.^8|)YnIak4OgA*&-yY v'v>T 7{Aέ.,̂r=*f *Qxdw'`V@ Gƿ棞Km{V.d9+`b|:g2=%Ǜ/BmVC.L{w>zYQ0wŲlg^\ko>"ۇVx:?Qo
-c؋1.qZ{Ɓ6C&im\#f>o2/r/
-1mu0~[2Xtч-TbW~ǖ;meq3d-yɟ?R.TIb%ݦgY+ Du}ڻ=5S$Vk&zʴ=]=htoGX,2_޳Oωg*QY<yoY{K@g Ԝ"=d_׷l
-:QF-,=-Ǜ=0SY_Foo6
-g7lQڷ]\]bi_4QMai  ,}z&GU?{zǓ3ȧcsR3|֯x- |:^jimJBwҞAbr#rzjxo֭9s<^QsdĴ=\UV.M}SpuL!\}NV=eE=H]o/W uI\mׁO3רn;ik*6sr n3רlhכ+w"x :rU
-+8FN*]+ J>JT=oWWGjCUw.iWb Neۻf4>we8&]8MH,W?e9?e5iQ쀄˛+ TtU~1{`_y1h>q žËm^="㵔7Wb/UCl4,U39\UiT 9\}w%Ai:yȵtܭy{k4Frկ*`r0nW,
-v| p5!)ެ_(cթm8iƑOW!)Zcێ"Ηe+ۈʲInåi6V$JyWQ\aTBv|WL2'(k#_{ۆӒNEMaU!<`zZÈtz}:ӻ{2N?RC&u^;: #Ӎz ~{֙s>3fX@t:TIo۾B:)"M<Luг y^[y,ug)V=\AX KJ= ض#>ڛ i3=oR^ádlz2}4=m:m)sQt;.(^^x~ۈ9ú9)ܛkԏnP0IZGn'6Ed6NқRnflV|->Ufa$.kOe\@ -G/϶-۾/qa։/`<:NBd,#'xrv+R$SwMf[l{lX ;ŶyMeU32l->L2 @1I)ļTn'L#-@n'LP`敍y8acNB&pGSj+Lo|`N8 O4 %ˉd:e9r%I W٥W{s1. wTbP4^xذe9
-G78oKBt^
-=U YD[".s^Z)& 4rS0(50x&6T0)o6JlL('F 0%׷ ﺝ0mcu\ }ZRUn(Pb! ezү oڑN+Ey(4+΀2yxb~E2I3.ٺfSs.3SuVggOOLɟ!cqeC\R)paĔVM o
-$ϮgH( ?ζD:oLF@ΗñIb+d64M /ME+P2 RAV49_\2P6ΧexT7CgDɥsiѦ
-z>&jkҷϥY}^A
-lWKl3K)᩼yXAA a[Wvݎ]fTɱS
-6S/R¿cT ?0hpj4 <LǴrL&>M͂//>3ı,
-9<
-v3}hw!\y;y:RpiwG-FQ$>AiO; f|8@iy
-6QdDZ$]w']Z
- ݟ&xv~ q(/jESSyQrlx}7.?."R7Z}EsD}iI҆@`?w7ට׋93t{GMmO?qJ=<lJ<ۘ*9$ :f0uYN2O+Hu\^~Ʀ
-= $ m'<
-} כ=0}}?)f ҫzsbSWOOǿ/?/l(oc˿9$B^}Y+^_:k[Vԕ#xȶG?{9~Z_I0udKr\ QM%vљ[2S1
-1xeV?à4E6S9 pMgi·VPz ո}*Q~{5~]>nj㯚E7Zy_(۝gYj۪f+}T $J,cۏoޛ <fan[jH #[מ(m=~绷8JF2P\7(~!stЃioQAja./cMcxuMzxAJ=qօ(-+<(jKrȐn;HZ.ERБzہL2i
-TR͎%^=M]oӷjo U.7e樟ooTŀYl_pܺ6o&n@nﶞBr[O6аsCZicWm6~UDF6[=BhZ=՚^vTXH-g٦ZG.-u3 ,Y=TDht7|V%73sdKY[|7+Wnqq
--j~0>f{ːYe=O2U5[ɲu͒l˹n'XdU1a2C/Tebʝ0@N|l+14(=djzui%,`}v{ ߬EEeU']:#ܼBb4꛻WE( k#"#Miu)vBC/.F/O׹eP()#pcqAW͸X.@)%C!&.,4@X@֗-BZs`xi/-c%gemLlY2-i\Klr/*y^f(zx]lvbwU,Р8C+xcj∐J۪
-uh&5ET!KT,~_O\.m51ށAhcmtiH/z;;QKcۆN^}@Q/x7 vX˵)̄GT&Md/6-O'}l0n+jmT5(l>=mԗrA z8 Qu58IuP]hI5_&H k28tFw[ roH*1;Lo~Gcin#SFdRK{352)_2Ůuys.b۱h@2*%џhE R yTߨ>i:@n!͆d 7!Tr+ng! /C!1~&okj>]Igz8 Yѐ,H0bϗO?Yv?Âm|4Rz=}ˋGOKZ%6={d,_~(K Ӟ/ӕCǻʷ$H/?x4r4inx켎N[r_%,O|,Lto wNQN 4,s/xѯq((۝S6))#oޗ Zownb@6WgDyXp=/7e[S`ӭ8c!LjJ
-7MA'K( ۉ3_1 h_2) :Y%,iC:Oq7D/G]_Nb=@ $k5sכ"D"ߌ\EK /&46v'[xfc䑊chsi2JLI:5e99K)`9ˁS vOj3yӰ1Cx\DB( <ޗ`zb^<ʄ
- LH
-V4C}H~s
-TbOd[3FՊ+=DRי+u3Ϝ[)w@3x8JhL-hZG(uA) x%f }ZQKѹa7 Cjb.uv4v[XVb:R X| 8Eu˅WS͜7Mm:B(:7RfYYWG:gxsc¢Y@vM}*0^Fo
-# ܄zMъYV!:{
-y\Nz{qQ7*=j7*]p?}Ă>K\j*h@>7,-k
-.E[Afx^nFVQ<C"ּuH3뮟/V/'Aպ‰k o P+E( xx@YjcIqEj
-sٛۗ^$clvN#\ ̍xee^KGfsVP1ĞNvj"&X:8=&4T!대WBDš_V
- N(3\C@Sy.J6\Z\{ I=D+Vc#7` 6g\Ո*+~#}E&tDIKRE(kM帿ܔqɊ9c<Z CE4{\K=qC_2'=wwf撾y)^9\*zh5{v:U'`c{EHGӇmlN\b۩@k8=t석 SԨnBomB%euZS e-1< @aK`H%dD$՝ev`]|3,``;w+(*s{- epV *{D`KL634`έ}@0,eicYmmY.": 3w97< ˆL8r}22x9jN5-HNgv oV{# `%@Ǽ^V{ 9I+A|u˚BG NX/QiM}Lz sЀ"9{b M`
-B&{ዠo"9zɒ}!H1oq1OcF] D_K}6\$RgCC-a*>Ih86|ƟcyϲR6icTPqtaijI#zkVRsa=?Cʤ%8L\{47T6^qj}h
-BZB6 36tB(qj_JϑG/B'e~5~+եL%NglfHtng[̙6h>8ה)3a'ё0#z!'Luѷ)';f[4 uTʪL
-&E"1@Ys'8˹B䮴jk_]%W_6J IRZ,u B&9 V5Wp9K[[[ZFV
-3 zOPB<k2]݁Ɍ\  3f"y>pc'Oj%`E6!h2&Q&ufv"b;ח]*\HhEi6
-%MGZ`v
-bFy~ {p:И7tC#+,<h2W! 5*,0K=1qQF$ K> o^LjQl"  Z+PG;6{
-^C19+lIoy
-4FDbe =;~[pp5WaBqrd (0]e/~1vm^젅@'U G8f
-bP~lhґ Z#;[ ͊pm/,:%f'4h5H͋G,NC:l؇(5ۙFh
-Bj hP3N
-dM#/P\p7DHq F +4| gJyk52=c
-{n=qXF$_q[V(Ʀ@e}CUz =PitSAfɴ ]MzT4=ۻvMM|)i`XXIc9!r;Iٱ\RfW
-"+MM
-Hm')5mZ͇9LېMǖ"8t8Ϥ ]V+NW F.-es"
-=RV% 5#uAj|@%Rk.#:ǣG5r1RR6T>t6qL5?P`[SwҔ~PͰ-]%xLQ.-]UBҘq*SE I&
-q
-"p Sh[9@l45/d 1i7Bj x(Xi^Q7J@=PGw+ԃS?{E' B 㡕͉sc{G-hE2;9ʹL@įF΀;U;[ !'F.@Ls%Rζm&3yox&T5-V/p#ly
-m
-Bn/\qgXSpҁ ܄[ 4{|?M0"q^F 抌8{^
-ld# p'>ܶC-S "=ܨ5yhaJ/ҕEbd>A5{tC.rudp 뛨:Q.
-3@ pa3a.@${.0N {W6Q:4{B8Gyd&.
- -g{BHkKi&-Ez\ %@O9GӤ}5>
-{IPoXC_`Ά\k+5-PZgK
- \PV9(rt
-%X*Gp(,%Ue?H[z㛓٫R߇f4zQBK['b9E``HT1oAĵU+^#Ek]1+V;+ͤr @4m;a ")+2MK0p %
-#D 5%) QdTdgD֔AW(-fFS~U/AB!P+!b{=t2IC"3MyocC!) _HMÔY:vbQ eኆ5e`'z*XR]ѫz9rsF٣%FB,5ri -|0J֑}h jRA+Q
-fsii1v)\ 'ÿ^KSD'g,pD%CP A:"DRo`g{QuJzj*9]05ԃ i.2 "|\
-x=1F_Cv<OL@ Eo(|0P_Նu T/D#/""jz ] %cZ $eI/}h`+ohēS
-1m
-2Oz@b}K G>cRhd-gT'jm$+9/SH_W9T
-2 /`0@xTJxgTH/ϠLC4}V0 $$kX0\,ZXWk %I!@LwEHP\η>LK٫uv5x|B05Nޏ[4`BDIL9^0t
-?dd4d|n:DtN߱q-GZN)HTk) W04JU* fZ 﫻Mֱ8sVu5O5-Dzᣌ(vP9)T6Tx.'/-/
-zWi+&## mQ2  S8=b8 m؅3@r^ŝ]=䒣$:Q׾@^014~]ԃDi l]%'U`0I,#;uG<Yb1rGVЦK`gðmI|8@yi^釸F+[YjI4uCM V9%SVIF{5da U@=W=4Rr]jgX`xQ)8 oy[=$Ezy#|XGO*b:y&.X,V:ځ&54H~T2<b)wП0v4.ΜCJբ%hjGk<8,K+TFP۽&'YfL\|PmӠJRsUd5CЋ D=}WnS+m
-sG2F/N}{R[k=0rƕ,'䏽fʆr+5ʬyZV=dP5MV+ tȧ:hY&}WO`jh3ﭜϘfDAQ/5%Gu
-4`ӝq^r"pO)w ع&3`fuCZt7k>=r%w|
-> ԡ3˭l7I|m
-JT ) )F^dEIRU=b9_EJ#C1#EzөqB(Hs9ԢMΔ(%7nzF+qbr6b؂Mλ0 !܊@ɍT:/M
-ra5qQ9!J)7ԫHwSe{\g* gIᠺK`f(MH~ KT* e~ ı FӔ@ !Bg^&
-ux5x EZ xY#4!A,# |"u5n#7 JAU}r)^[xbU=13e
-OJCDA BG8Z;0J(N5䝖9b-'n;Jj׫# ^Fw"ʾ^%SsX)HW=lTS[D9Pt2 D2Ca"јiK&Fg`])qLKVa!%u l){$9.`1b sߥPx!(=ٗ#*`זej1&0Շ"PA:ɘOjgTϱ%BSEےװc#PΌSdlb|?eV&NƣC̽S#(F7YyQ3be={(0JmQ9+_\,UkZptw2l#NNXPcՄ72.N
->@1UXfa9a(@>p w^oD&bp2ɋ.qc&ˢkZ)INV#MuU7(XÅ#NтH~D{Rr2֠ghjկd(q<!P]
-8!7{ 4|>P 1@N1:m6U[2=닿c)s!ș(rw
-4yeMrj5@qhcP/Pj(!C.SI*\d 4oe.PسW,݆ɘ%V=epnWg"2+p 9j\eD!i5ӞVP#z JT -5vE4Lft{V,cnwE* 6l9#SSh9$VXC\b) ۪`Y[/Yu 9YA\šnb'jI h/i/6D@iJC@%Z=VĉæK?{CWC`
-xطh^wCe [=
-ɏW)YMDRyD$Ujsn$y.f߱Y/f&`xq-dӫ|sM`\ u +P{'<T])&mg?ҭ8r
-L"ќ mاEm=NFI
-w(!Mj챙}ǜc-~SX@ܯrN9f;ЃPF/[vHlzmj܉`v<´B'Tdz s{b/K~'qwsT!]OL~2#eȓ v"Kb^LOF(wF H-Tԋ<$F؂ĽĴ\Pn)e}S jX2|()F'`2B{ /&O*k\6cͻ-Rpa+6K*lIQ\"2BSV^bi(aϳ%
-M\V)!d!B'h|ԍ(B
-,MQִ*R4!M,K x !rH<$@ H Li"S4zc9);{ړ]\0?])%{}ZIa9w@j 잤"v* Xl[B}!֦^uGT77hœޙ%ǜ2n QW7)7Ȏ,5mpa\~EOxzOM1gfFL]b$d`ثN[|[3LA5Pkcdh SDʂ6L]PGp rZu"9@^M A!Wuu1EPI7" H<IL4/kU!Dyк
-e_iZ0{
-;kAje_) 'E\3P3q7BzJo4K[k)hk3$':oIQ(!r\!:!L[1^x\1@
-M!"(cT|˱H {#K=?Cz~I%Yy„f+K<lyC< Z쁎M+oLjFSWU~!+].TrZaՇJ79+A-Rryf4?!R)S:c'"fllxmBb!بÉe4("rRt.D1rG}$?_uYgKH:sSIpfBV҄5[e!d^L1`6^J̛,n->.=X=e10&Rg>b--`|;`>40VIA(KHݣ+1iڥWW<!ٚgNcȋh\ ţG~z¢
-;lbZ[x^<r&;%?QiQ + &4cCdQsDe% FxB"zg,2.<<,͌*l%"xJM@0AxUmU-F_u'zh=ٜV+_IʵKyUu;Y*K
-ȂᓜХ]6 GHA'.3"Z~7S\fKABY\DZ.Wpcuxv/ ?J&(~BdxBaBv,QoKДSyrj aޫR߱pY)kI̤Y6}TFxb!*2ة-%/#%0"\
-NolIS^ǙSbU)K6ms$Lz3u4-;e`Y% ڴA5MbYkࢇJ Q$ܝ gHC -
-Fcs)eU*UoUF+z9I?tz0dl&ti;H#ּ9J X #xRQsLA/XݭX]WFm2rEGp?^f,4s K@O'u2\дpT/][}7,'??_|n~Wwo~O~ywG%_5chH1v
-υ2)?( (7! <'rɴr+,Pa.e.;.>y
-+Ib˩;B}Jh;O/ i~eRBdrR8cHA=X$4Y\L>("D7y+.mT>,Hނ<$#j<ItVDRB2!Hs}Za )0
-i5KWfFq>u{"eɷp`a%׌ƜAOD7=X&޹n$O.qb{؃D iRoRl6Cկ @YU.`Qd6`{e""R>AiWsXAm2^D!9jrZ@&QHx|`7%_Jx<X4GIq"=[tID$phÌ-xC7 eI
-hFux(cŻ,ыqyh
-.GQSC
-ѫ!dPPfD2ӍWUЈw[H8K{hzH#0'V%s_DnQ|?$D *#U..yr(mȺּqmvU~WMfd)~u[%ggK
-Tct9\\"$H"=lRW| 9 iŃS] lB*.=R|>U=h \<pᤗLxt!\>GF$ H/$b51h3Ov~?`Co9K7-,K"j5w])r#
-d] n*T_:Je)CI[uŅeZ5KZ"@R]ZVw{N
-v9ٛ+?M)dD_uO瑒90{q8v_m#DdӤf"qdTPv\ud4|*b/K=O769X7+!m)M0%)$Ԭ~xuٮPOz ~c"8h; Y%l&f;G6lI{~hb iyCuKۖ"`{u c:6|*PK!tʧ !2O&tUwa7Cߣ n &QUa*3w$W߯XlmA
-i;=&GaށRµ%܊%ރfGjǯ5} Xa@vuS +ᐰ1PWy-_C}7t`TdҘn6#-#*2^Z=qlȿi3砺L!OfA
-͍M-8ŐKƍ)I;JΑ}\.=]տE~+4PKUWmpqKAJD'Cu86 ^J'Vq}bH0RVXGJy
-{L-,;B/;@=W3^RMKy1Mצ* ۏgGoT/9lFNR E]RWW
-yu^඗覙 .p0ir0dUzQ`(lY; 1x#p63Y4]0ʤnId̃+23ҟ)*e~j6꯳k)?s3Ik2ih{5~'Z;F#Ě:/ɭ2ЇkA
-~)>Ct<8 jΰ(H*ֶv͎vP$G.d~UWKc
-|?
-oHDiQ`)Y_awxupKTff>">B5 8Ԝ.ݗFcQ>`EjR; B
-)׋ͬ`MA5}8=  [/4`C* )_K)ч
-E1_ :Pv:k;W/$M;~ZF"E K嶄5;vaCTn5WXA] m$hv 95B@\"pm{ldEA{0-%C6GwĞՕ؏:\-Q!P~`x6<QRaD6AηgZ$x0Ym]>p :X2X+y5*Uռb9IcR B&'QtbTj{PQi0 CH]I+Ps= ˫!VYby˓{\7Ce )!9P?ڟ&ܾv4&i.&'aY5*,o2cBC,ޛ_ғ<Òk\хԀّV
-5W⒢}E;Sr,1efY^P-cO
-=S9ST="~K=ĢH稙OH0וnվSww*)Aݡ7߉T Aۉj @)x\ mY7zPm #G8W!֓Qb^]>L]r~‘ʕP M܄eSU=CkC{oT\J%U(d!aIn;W/9(W{K<CnIծl1"Sڥ1ΰ/+g銒 AvڼdyUVR򎒧"ewݓy5ґh@HAtH*a rՓ74CױR : #^AaFQ RyzXûb
-<R8$z ELBFRqԞrB|B牔XlW,f1A+VӦu?[<>h;x!# #\W(C0Kþ#sYSp@hc"/P۪8.;)&W\CE(l%9
-*sEKV3Q).I/i
-
-̻t}7
-8A`b0G`K/R1)w\Sy>K
-bwd~k[ Pq VyAt1$DHR}P
-XͣJF e<w Y< kgT_G b{|L_"ֺTFJykLU̔痱#
-ʉ.1&t 'Lɴ-Ety/$Y@`k?R=T~( ,TmѪʯF{Ԭk&5T~+*$upqX+|G-CY"G3w/_d!/PɄr9m'2G
-B)1aj^($ !@*%(OGWFL[RM-;=J TD2zh,|y
-/P+Hx!v`^cAЀ%P[#Ģg 36:S9Fpa7Xo '
- lO͌(e
-Ri/}R fA噀.sDX0(&uґwMhb,F̻yF s4A:ɥ 1GJC6{ 2ʜ!Ez
-^t|v%ugK*k8#s tt]
-Rl䰊 _CV8Cᤴ:h%qu?__0CQZ$MwV?љւE{їn@ޥyb݈.rDPc3mwܢfT>A)dk0/G{29Wܷ&n=
-ZhT"ہLOszqe_Y/  *ɰ-GPQwݾ;9HĪ7 X9DjՔ훹2̓¨I\sl<.Y,w"{ΗS
-ؿ\/r] XROjd:4*pxu}TQϢ@א\-G^ bCXBô8L) ;(,\5вw!`o^i,u(eB +ZԂ'"Ԙd n g$̂ȄDP;17-RJ
-xmsG"IC%v7-Edဧd$ ʟO|eH%(g9";A}$f;dogDo"{ߐ$
-T Lq?DG६׶(#%}î_UF=jo?K#kELlL@>T@#
-1{Ű{I|ҫ1͆Uң J0jΣ
-)A&Uv4;+I2\a9N|q I@de]y]VnWI ' ^쾉gtfDZ)Vċ!Lwzln
-[gѐT QAf@I(E_+,9=q3K΀87zU_ C1א%9i ʁX+/2뼔'cO]xŘM,*)tqV
-ȝYRl4w4% ySG%uz+߁҆W'1 q>n\Qaر'E8◙,G2=x5C"`_qeD~IK"fm)'5}n'5kl#e^tˏJ0ebŧG<.F8(]!3u<yF Ug.FN
-@V빃.<yGgD@N-h;pv"GAucf6/IQVqC$7ZcYEw$,c4]>+H({T;f$[Pi/]&$U׮eU-#c J'v@T2XPviQ4z &=B} ʋ Q﷟M-Il?$A޹.C{T>85^
-!]Ԁ!Kn1%>?^.O4ChcƙtOaYÁɦ6et,S.%Bd剅ap~$,ݻdf"aGIP"w-<
-Vk/MKBN@"s:T}ܕLS-faG~IGl8д$yi~~r
-ݓVN6c{om~اzXf?dT&/R.b_%~5EZ`FSUbp;'q(uɲ,~TTo2MA-$DrX{,\Ҝ8-9}%lCfڙ%}z8:OboG$2
-ET^W?юs]g'P~0qoaGꦀlRA3`IV|Fp,N<J!HshNDjͰRWj:cJEyHt$Ԋ"?ïMe ~3Lb PM{
-E]<5R幈ZSQՖwJXsИe|[cI(X tJ5'CAfPP [l, 3a,C
-]+nah2A8t$[en2 BK%.kg(PIӁn*_xEұ W )?uɶCZdJu|^(8fQwGO%bR 2Qe'4)Chv,ě/C( C mbp @"~J%EMHctKTxhxN`dC
-Hpٽ QW`Kع~¥ƾj!=fZDKOLY88ntqZ9m-knj^%L_vH) Rv$~_ʗ ׀ޖT@KL_ho/<%XE> f埭[M)b]LnC@ 7"AdžbqXjv|['6i1"qvQK+2˦
-BV
-4
-+f]uײc ,"tPYM]Yʬn@y_:ph{]1J`cC!ֽ+J5ʒ{62@+`F;x@ۙ+6"!U@eԲdw
-.;m^K:VJev|8{iA=_̣jxD,j)[KeIG67L-L3nޑBr`&SRW>`bnb'ThZq:cJ])(-PtIqn_Ot:DX)pMLF83iVj(oj}"qBL"6(+)V.aDW(h^TIB JډO~bcng#ܔrhT~]j|A({ڭ #Nb
-=G}:bEWa"n#2+5x!Kxfs?r9#:ň*Bʴ~0Ywlazx d<f[k9YV!F 8nq:@BogwT/ovsAK ʣ*mH& T>/FR|0bH{:Wߵry9S"s%/:()uK*dtg-W&=W`}̭r ܦҥ| 8J( ̏$R
-$u,u^]yB}jB(b!Tn[} xBz5zX.ϸ*
-CNőudY~"A܎[]iGدs:Dwأ &[eͶ@|=>h<;8^W0]
-wGJ?uBqʛ~pR
-2ʖ?O+h\IiΩ|D4q ĝz En. Fˢq8X7y_ Q<s<rK
-9xn݋]snO~lܘ+]d:ţ  77O4tg[Sb:IB *h쯓|er>x^xb+U9+=#-uij^
-NPO5Ϗw'xyibYqiTUNSW [6^> k|ncw^A=;~f<8Wk'1{`jqĸrN %Kgh1C
-ୌ6W˵
-HٯUO*P\A1&12\3H=X8i+x)ΉFE[#*M& '8sŁ3h( _7`+3L76s>s\?)zXqa ~W]^}bm6_m{%q8CWϛw(;_w!T4kFعz7tsyi U||^_1c8|e79yL%zs#'qS4"2v(_
-ԝ<'ڮ◰;F8"xHD#hl2cѲohDcobfSkzij'#P_~- j)Y{Uc_?.׻95]9pz/aM4fј>l'YZNWl n9TpǷ &kjmB9mnbcl7;UF9|PhuA#)ϙJ?gs=ƹvD}'%WnV$[h9.7K73iO+4W+rNGNHŧ%z\ֽ\g >}DJ!oaBܾeEh^ y)϶ʟKcȠdg}|%ϔZ(4휠?Dd<Y=3/me51Op]P};oq 0@[|nأ}]<kp8G39s𠰗eVB-'0X9fhJ'J[+Wp~qLjB#:o d9m[Gs'H:殤#ļ6!w'xbCqEn
- XWK(m4%'x6tQ>PN^s;>2N$˒["ª
-p=k}+ɸ|\@zyظgA)9a;)ۻ:2=zyDL]2,vO(R;A:Cɷ6X4^H_2|</.<`dxpe%,a cwXi<cEU柟/=L*3֜=Sz<ˆ372
-"w*iiVk.0x^iyȭ<J!=)|J6uySWɇ"c^7>-?+<IW ֿ udew]q[/йfc;1o}v6%>69dN(<V{'n7{?gsԅGE˷<$fGg3}Ŵg@9끷wqs20%{w ެZb0
-E!jYES̩2} |F<kԩ>vL4=b :Hrn<]½+u/ZS0YFZDQ$i8MMjq_Q}QO3S O ߍQB30\R n(23 W9\!ٕ-͑''Fz]}9^տSA6'"#|2EĉM Oj'gE*S/AK$ s-u]gA3O\IchHzWc@X,, u?_1\jL +I뙪{}q%ڕtu2 d}ؕ29ۙ E=\{բmmfX=AC_jG^W~r'/F=MOLyb1Ȭ+skM*CaO姜p9}(g5WR͚+Y65nq"QQ x61Ո|JN=*
-}y·8A + P܋EΠo=_ש-@
-ٶg˙ IS,9U;(OkYN<kNLa>)2w,lA9ܘ;1NPj\s'fAcs̼HuhM:9oL)A=._g}sIm3K$lLSBi<2=|&~>|6TI_˾9U3D3xwBA8T!c 8HrYgx'ȒCwhl9fkJn+?8T!dt G'xmLJ߄un5+$I.! JN|sإ;'י<",d*<Vc~PsS5m,o_[y,0knN _g>?nwוdW䥮@IY=SW*~V3U*V ^~™2E. '*]#V+N0F6gV&g Ȱd]\tN%#2ΚJ~I
-/bH렽ƻhH o 'ȓH}}MۜąF` rRdJ4bCWT8 n|YpvE/p, GCu͚[Yя9Uצy]OQPߣ,_29I9=iNk Npbe r"^'Z/vئ Q,
-\g'H(t'yo
-/z_
-A{LXQ'xr^
-~Wf*Oz@fߧ
-O IH _7pZpZh) G_JW7NЫfd~:8;X;L4d2+ +LK^„_VPL;XU$Fը)bս 4M=8D|XK*v fP<x6
-?`2N2a',\+ PNK#2Վ>( J&0cUQdkZDb*fPPGG |jQTi5UL#`HhBBx*2x_}ʄ #U23o /w"/f&%sՍYCxS58F(Xg*KU6 (lõTTW . n6|@M2vBTLQ4zv
-TW9a&bh(
-3&S/㭎Û75$DfVi FJeB 蘚è5jd-Jn͸QFFRME]Z
-ex U9 J
-h'PUɍLj,rtu5Hkh F 5h5D苾T%-S3S5k`5ve*mIlR9Iwv3hоf q/՗]ƒT`WyMՁpLP_k*bGa]8AZ6iz&Qo&̔ %UFPGIQo ʽp/!/S5LT(' e* 2T2S~Ѓ$Tc\Bi
-EhJ !
-,[+z.*k[Ruؾ-̭>T:a+YpH d
- F}K-?
-jjbҗo~0R\H
-)@ß;Дǀfqqje :T[̠Q8}@]P[MkMRoi nXP*Ə؁NDk
-܁N-y{+5ybۯn4Eɮ
-<";U.'UE6U vڤ9鏵܄󐄍,Z5xZLфXPXRG j*U,Uo&$jND|CaCDn \PPal"f5RO}Q2SUVH':kՇbu }\cm]5
-%!j%mi ͌LjP<PL,Kg uPMjT-ƍ`˄z &}c4z9꼘܉!VB0RF&Ss7Ƶ?74IxXJ<l/j26XR"¥S"eBm('.eKn-*p jŋG'䙊S],~`M(@?Y'6T
-ňL-U-r#%4@1RM
-:e_+/~T*g,% U'Z4+
-M'4X ӼX![*-TD1l N\UR88LMpp.So[v%/uT& u R )A?BdXpZ^F͚o0!3Ds)N!@+͛Gm kWZ:{W:yyQp{"@on?/)D@_o9—-613u^TD^TΨ
-Cc±K@+[GJGg+&q_0aYcؐQxLb
-'2q_PY#)Ǡ_7n(aMvZ%eA9!Y$V,m$c]A{jY*nb%9r%ezihLѿ7YҒ57I,mS $R+˷Z3Zr~]ZeFbùkQy73,$8ڇgsGЁ(rGˊԲRjo@mXe!T!9ϡ`ܴlluHWtϹ bA#mc
-A榳irЂ\td>Q)̇E<̇e=Cn!/Nf="1Ssfl #>&w\C#١Cў9ĺ|JpoyIJa>4k,=$ W8
-G_]Uu&u/$)$3SIL`p9\\d>~;L#2#A oOIΆ"NŇN3,ds.C3^1C( \B4.n2KmÅgRG2ICA6lJtS7TtLD6(g48ԆGsrFπ9a<'S^a||t:(m$2 "y#<uXgO]:a28ĒqZȵk7>XǚՖ3h.uc͸kmHl$Vr~r61p
-AkޡB)fnZ:c
-|p.0m7 s;dIow6c65.=kR%|\l ZS _{yG fb2qS$ҫljLs<)D}S~IC)Ϙت)l|T6h]8 JF
-E<_lw̤Ӑ}Gp pMN]N 9ӆ>éȢq Z\ropЩ; Lm&
-,۾Y#[nV5_r}lꯋ)؏ +2WLyt@2yX:c{&ml*B:}]9.@EŠR_Dd;ZRzjɃ1_0kXk`R!'S"1
-X_dc0yc{V`>D4{_)j{&
-N,b맂|bܨ:p5!'٭ Gxv`~ |LȾ0ȾƘ2<]48,p CCg<oa{]DdCXSl]7l-35&rM9ÄeϠa;gC::q{)hgH!{G9"WIe~ڂ dž}J#K!΁lցSXc=$t@H'g6(kq®
-k#ԟDؔʇ l3E1g#^<Zd}=Ekn]pt)5A=裢sFT'Vǫ)7!Q!y#51鉮] ~!k
-qK[O#NAQHv"#yn#c,Z atC:;a\`h
-ߨǃ[=)jMb>Cx yH@-:Xe,멣illyLk!7G .p_%!Y ̧V`3[璥eĶ'+_  Μx[KE PE `'
-4F]*=)Ej>K_0I0>F6B:슱| 7U|)wO`s"<O}Ӈ3`UlE!?p:&atP1֌oHˀw',2I'frGmC9hn1c@MKp(}u|TΨ\lƞy@/႓Fcc'#8Lr4EOľ[Q@,9-Α
-THH KttRt̟wcK6=& 0_`' Ɇ˩Tb4Ld$举2yc:u *8o4l^9)z;+ooҋ&>sK£K ii$Z-/a$ox53 |v&wuTX8
-|z`l |X/$H߂L8<%bĄmj55Wt%ws d81[2(=O~=HIYGN"w@;$qNG!?9Ħ8$\ph> +|b y> {4x%N~p
-JAl)? O~9'=Jyk@)|o9> p!UBe~s >
-fy \|蚩\%L\`(٠D@ š|tdr
-wDE}*2"ͧ
-PY
-]yr<dDx ރ`yC21e:SO7{z2B2vT8Z=b6:V]?+$A(z zA|Q/0'$p|%ʔ1 d-uV18bvH
-^&f2̏*ހK; >@Α2r<9r:Ta*(8}G|02G5=xG|+|uڷ*Ύww_n >{/j*=|
-:j^G^1fZ3}U: 0q<)T!.Dpn#B
-y㍯ĶD@H2t,yz`:|^\RtS1U~l  Oe
-醻+54v UxZJ?(>42O,cVT\1_-֤l*Ϡn: y p#Kت٦udErGbq$vo'ax7+`-gPaa5/8p@H*jϛMW#<hzBKYdߑ缣( Ny
-.;2Av9:o1!iQB|%䊁| E/i bJ5-8!Ey
-J ל#]Yد~e&v2pEAmh;\dx6ukanmݫn8]N|,8fslkIn=
-`v3p.2YL웏
-\R+G<fq>%+p
-|=[fL9FkocgĊ w&jn
-u~4*G|K6>3Vx VW@.OP:q*UxސekAax ұ!7pE叧c&A^
-]p@5egK&Dn<Qۤ/1/W}lхSTb3w㲎.K.c
-8,x< 10X/Oy JɪKf<6"L+_%' q ;glg8'dψ[ߑgd8n:+q~6RQEgDUDEc UrD2Q4uf!{>ƴfC'>/[Qi3Z{Yp
-oWLZF}I:=
-N.,Xm@Oײ'
-3Wq<}/}E
-y[c_b>nP=VpW^n{J뗒߈tzY*߮F";Go{aBc.jTyuk:o>_>e>?Ϣ|~E..p3I{OOsy[i/Ͻwy~R\Yw6yEO_ǏNV*?,v];G:w=b~b= otu\Hcrs/_n>DxNjpÏx<[W_dm]ihX"sa>LUU|Q`dpr'#mn͍SY~g7(LsGc<sk%>YR1FhcO?r=w;Xy'#[}RqM{^xÝ}͝x~Aq͊c)dsO;ww3_])q~ɮ:חޝd?Ieov??{۽\lӽ=A몃Ww5Ty<i/p&YmP8kN4>_F`Noo l<tOŏv.8<=_jbӋS/~`:#W~rwM֎7JHY3;^OumXk`}=ˊ=vg)@=fAϺ=W"Ru#d2ۏϗ
-+zPeF|qeۮ'4VHn^)s{7{ߓ\9CMDouO!dg ⅛V+/.X"?+|ґt5o;Ǐ3Zƿȡ_lk,^'ԝ'A_]WaN_(g݌:u-m̶-{7ZwqkU;I9Iu=uίW?)~z|~$';}_ls߮w 1W]=gv#¶oxjNjL;DX{y?VK-U_Zl]z}GfS.N(_ew~YUWr?>~n]CGBU&t@WK6?̨(~XWSNl z߲Y9׳rd>X M2yu='/^w}wXl>ӿLY߳gGWŽ,O7wMq-.Zn>ۻ֢rثOVl9Mu7un\K%&pzяYnOW;>;Qp]PwȮҪ{eKގ/?›]!W:".މ,Vp^XMwËn܈*>z3fBY*G͕(`?tf;:Qx_~6'zkCՆ:edI5J27_o󘗏Sϓ Ϸ oe)({{z2?m+ K;rf4mw|y{%JW]^\RYp/`GtEVx < SQ%GкkPVByԻ9-n2E7]rGor.ݸdJk%.?yUwn9w+l)9w6?RʜOs&?NeĠF'{^A|ݻk%/ _)._Uy?q[zAۋ5IݹǗ.ρ%ߣy:w+쵸Sb܈-\lgq;Uy#ԋq?(}/
-F4$Y*nVwV_K̹]G|ocuW+Oy2kVl\ W}}ᝌzwlćq/nw7?۫kSAG{y;}mq~y~t;}+0~a+|ݍ,s/dQ%W5=py}u^7we[oqvOtTͨTz%,nYÆ2=7^*tϻr'Y=9C2&Z*=STY?©_;\^+wxwYUGH}p>ލ[~m>1}Kxh[ n%޾x+^b󫽥V vӛ^n^~^}/c/V HHQsǽܦ{]뉰ב`]̽Ʋu"ws]g샻 GZ:J"VT~r\IjOW).vx}ՑYMuO*J#_a^w!yJ=UURd2{W?E/~J>m*1 zWX͛n^kXz3īdNȎ]/bݞIWwR|%G.%ᅵPzr\鶫N/}wk֝쪓WcK/\.jG:!y
-u+qoA./o[y;ģ#"Sn岿{hRo<ݻ|Ktuګ$+%F_}'16[)14^!7VxDBLoMԉQk{k,*v.|Ϗeʫg7_L.-SOW[M;ŮOT!\TSx3rjն;nR8Ϧ<l?/v'oŠ? +,;?,JGJNѓ/./"#} ~!YlʕdN7dΨ)ɒIIa%#LѓL8G7fd#$2K_ʌ;֟zsG/#_A^GOv/_Nx9 7#N^)XQq3*nN]݂˩&V_M,^RŋCwo*;C >GkFwz-}ݣ[Fn=8~cU=?o8?2c_W>M2Kod/%zgw'&"*$>#п&HJIfѓ,5|gW<5]gso_e3]שg9nVuV\N-k\RR)ҋeSʿ[ː>.=})Njq7J,/Zʷ |X埽/V%8[.W$sI-'Yc淋!exֱk"gOד Jt轴$Z렖i㶡iK YD wWJV.+YZq!jZYmSʶ_H.;x>̅ңK!
-+*ֿ򭭻dޤyHGgJ ''ZmJaF%LHD(Y1{crx<U~>ⅸIeWː)>{%(N^)A6_-9p5ZJӶ29?b;ĕXkuSn a ~ a"~m_?v}߻n0oZ ,z2n͞[>/ޤ*sx|Ϊ{EmޓD%"( Q9CUb2DI3JT$&0ۆVYQn[y}κsLsyyS#59b1l ⦳ȸ/=q1W]įJX/B 1 }9~E߯وh
-4wCb^uG79!o>ZP_s)F4A^u%ν _4n9[sڎa6BV;bď?߃gM.B(2{=\u3
-jq|ohSAw=kiL~.g6ѰB8`dcDd5Ҝ 5ll4 \Wr(^yKo6+
-p&cOa_ٍw`zzvóip͙!£i|hel+?SGNEc qd 2̌!Syt\d7>=3g4eA8rڭ6 ؊^ ёOTQ %p{qŒ_]+y{xǷ
-~n;s;r-,? O2ײFFQx!n}D4FLt쐩4vds?<R[/zcƿ9z/ڮ](hu)mo^zr~k?={- t<s\#tg#x͵&qx,Mx3{d1~%ꎬlF,;3";Z,繁aӹukIrySK 87kj^܀f=^ ni|p9F| ~? Kc6,tıu|^'GϠI>sPd#BYEcWvJ4}I<l1rYNi;QƘqJ_ 'oTomm~p4|}3Pvdwܿ rR_͢јErQg1 Oԛ,g"s97@fFvx-Eˑrdjx`4F&ύC3|ʑ}a_9l] C{ Zq7r0Wrz_~(`.%ʷ>VL?sEd [ c \!ye眩D(0a
-zr88wλEĈ = ާ<}GU|]1>cDwdn+F]֢9T)MZ0fC}ժ3x|\K-zh8z\y%W5-ۣ"pes疟ƻ/B׏)܏W|WM+Ƨ-Wmÿo_>[ʏ!?V:q/Zqyw
-*:)4L5!0ӌGN¹4Z&
-F6hG^ќh=vGhb-Ԗ$tU]qWpy(BɍjVʤ?.L믳}^+
-bM !'9&w_U1>KnJٝ_p߼(.chpÖ⡚fΏ&[/R6{yDo
-\. D <UhYlҺkF. 3=~$b:eOd!iz߅5"/'!uk!ثx߸zmK0qޞB }~˽mQ&?`G1Zh[E;XF06M<w#r;+CnB߯B/|KXFp:A}֡†{5g a ۞Y`uK=B$e)~WFS@P%A%cz81u3Wo50D)?I7zbdi0X yαF٢)xdԩ ?| "ĉ"$|/D>ƾ@(& d~#Ċn \iKN\|J^:ݷtK!o֒m?x1-7SgSg3ʏ]S(o]
-yt?Mэr`/e=eCRU-t_1i ':z4@56_&$:+*9mף>vNjOdn$D梄՚uEy%~Ml
->'%ܓC%r)Ԟ_e5L-7rŹqܙag?ٝʕ;P'u&M_I?8f̞+CK
-53N $B
-1??,þ{C'Ox|x䭗ɵw?m
-{ChH}v~7Ƿ炓j4z_|R 7b" J !JAt@?ۊisTեd ی'I$FktR qmB4AԜތs>-v}$u"o*B>{̃w#sSW?+<)R>}PP:|}RJY%)n6WVa}в =爐{dmc i\]WKTGR/$Ԯoܨ֛&&76SMvl 4a+훈'0[jX p~^|_?G-o`*E`Q1a+v~0irbc8
 s0^qQd;?':&G K-Y;ڃzfU)}^~ionsv?З>F0ަ=Un/XzջcFx^pkOv'm۟-~\":"20hr'4zZ`id^(4~n䆜1eO,̕ъlHG#dٕTi'"GasVFo+ іhɢHע]xJJn̓T*8<cf.<yN*4 qV!>t;J qoy7Ln (aR`UQ{QҚ33̞tJ 9cdWxz#++)!2U:Sf)m4_zqtE{mQ;ߺG^r_d_IlASyޚ竂n^S^^;UPYz>Exl:c2Tc2
-1F&#q=Py"wiS[~<y +8sLWkRb zj&]m&_Nc
-Xx6
-6ucyybZQ5lCٍc?}´_Nמ#r+F*[YVm)m\H=^J
-BB
-gޯ;m`(y*V?>y*93'Kn6r[ĒDz4ʿ*OHhYh̅(+4Sr#sMBVe֌;//}GԱ$ݯWzf+쫕Cr;zI:ͩ,&~2f?jshd7a-`ץ~{m^(< g':#m>eퟐ퉖Μ\(
-1˨+L^d!þPyvlӥo[#S'+.}k2gKҽuƲ/mŗ ȋO =O'L=:#ya;! Ia̼|?>'wtrY 3u=/b禎lmXBГ.yJ6^4vC}40d۟9GUJ'o22635GgBq
-PiHRG
-WDNi=\6̢=<r"Ua!I=SBg@opxq_Z~kWYN]c;'YTj4J_7'g졷 uٰM{'SelŇ~u Ӫy4(e
-(;e&Ӂ/ZLd5KT[bb;z@KOZnZTkog<w"ev1\F.ےj݂7d{W` $=?Jw}J s[b-Et/.
-Cf}!}s[ݲooyX >#=f|i
-Sk%aZ4M1FϿhG蔊Ѳ]8ü @3tDMUJ担|3$뽻 4 T*o\LnXo"zA<i ]>}퓝/w `l:=9X.'u?]}h:]kJ嵎dw(zm(}*M݃WUdju?q,XyU
-۪PšJzp s^+:c q`
-hR=Oq qdI>+iVYB/rcӨ`TW*]Aa>"%S5t#Gf:}]L2jgj3WOa;dzi[L#zCy$;^L{b|Ͼ .|E{/Ճ>^.W*Dϟ QՀ-zSݾR1ÜywBOim>2?G~,DoЖ٠VHӖk:\HxlTr!' TX'*Rʌ 3*:C KRu@+,V|`}Hӫ}=AאI2⳷3}]'E]=U}Ӄ̎Ѓ4w``zg15g<aG'IƒUglɭF^_/vEΎ^_}RivFM10AGG+pUP~$s'OzgEP >8AS"$ZH.-//du-ù펽oi+$UjeTe^de6nD5.bd>{!eν
-a/OfpLtv[IctDt<DH:#-qEG1wīꌰ-L`[a?処S:TR>߃A61 >,2 /k;>:4dOOI;AԲJ
-I;IO%d :L]]@7:8*l<IG_VIS[=Bd0e.Z6orssC~ 6r'A^"#F Yz1hmZ?S$P|~1ԍ} TbS{
-irl-e嵎M,~C%;GO -kZЕ;lۮ3^KSR}VV=8[!督tDqx_# WiR[ %kw@s'LC U~oJ0"A^q󚇼J஁Jd*(baY@?ۧA)sJt/5]͜ЋgSIO^N8_Ot+ΠOϣNaJ&HwZI69FLmѕx2$$ Z]IŔ9H4ZꂑlN%[~Ԗj~ 4q^1IE-7tج﷑m{ ~n'뺹z+q R}TJ?\M6Prc!cl37ט_I~rtKF
-Kw$M]@ Lk"E:ii\(~@ NtY^ܖya
-6̭lf9I6łhl`ŋvLds[,dF:!SN(#z;ے)[5ρ>|ШԆ>i*૾C'Rj Lq0_߹Jvqv}pu?[m<0 A{
-k=D kXS<]/CeJt{gf@w↬B;j޲  XW7Ug<[9~o)􏃞?hGJxiPڀ
-B*h' #.b4o2hSrE}4MKcGJkJ5A94U3/}މ=Jq]Z(}GG|cpl֋>M
-t4h{Hwum3/hu2C&˒)q,LVٔj4q}وIb̬5 %4n*Jw^:W5jpzb./@cM).̾OÏܾR@3NP^[s @{ 4GOie0g@ÌLR>Wny [ @l`AHA]&U[;.
-<ܑңD˛C^^^9*QB_>d _̑D톃/K֔tu峖 o\kGLP&k° ClX6hO jFb@+
-%ϦךkRF@V~v[zF <ХM%B sGxǏL!аgpNY<6$P[,xMm4
-tXRCi5LAnH?M '{^'^ѧ<G|ֱd-?w' S
-9{<;]<؆S .y{ϙ KخPwzu3Rj9!|?m=jMN<^LצbZjy8\"iRt9C!tVcfӾ)LJă*+kg<sQ᳁>bh qw]Al}Y-Gsms{9cLb!꾸 UVvIOO!]1H18YzǁIPu& Y\b^hcȵ_Z8o|.5`lեlUԘ\r0(Z*&@Yyh6hm*vߓлd֕Bc5 tdYdwaXԙh1F1<+U/:Vp``- ؝_{)7lv86ے5_=w_z*)1]W Q^mL-Cу oYLbk7(D/'<G^6AW;N 1mӁd8aJwL±nӋ/7&&x/-`Ҟ$'a?qTXar&7)uTb:C[Ć9pC˗BpO(R;h1]O@Ǘ\#\׊%,#ⴀQzƁ0W6-p-}C~lӕ%|^8Б璋 zg6w2t^w"[ZW&s)h2kpl2FN:t N]z.2^+(q*Zd5
-~<Hɸ`5c z[ ztZ-?2rಂ(a+nҔv[|B)vŭ L<.7YyWnbvYtJhE:lBmg'3Lb7EnA֙mې5~|f%Ѯ{*5/0`]Õ6xZol3J`FX3L׭U+@'D\džxRț ?tT͹uZ0aI|gY8h=Fyǝnvu!ܫf3ۿwz^JN%e6DnHuv'A s}TF}uq uZ t &<~}# lw6JKJ􎁭ʪT%;q+YlU^+-D +]+0;;jyفbDSvQbq\"h*s:'(Ӷ*
-`!OXxF|ŶAw}䭃N彶P8NYqt0C8})Ӈ-3sCѪ3@Zܽʝ;S=W-n)5zD.ߐ
-Ź {47M,MqҰT-{_"/$30.L\4HL`[R.^|`mUOfC+"50Հ2({Ơq6p zm{(?9t1VgCj)F ΦS@stwDaxݞp;-A;xze>SzdSsTlي3'#NNQ\-ѕ==|i.X`}:
-
-H- n̨cK h甠1To|4ĵr#/714.?l<x$zvgq&, g(udpR%CG\iUBXmk
-†'}@lv̍16N]m X6Ԍ|Z^=Ed
-E3I.0C4YcEJ`gEdTewMמWLSxFtnWf8P̬02
-YqG=??
-4lieFM}ӂ:}B uSy*?ux! ME4mX0[_c 1YTVGh sqGoЖ2ja;$uţ=HbLtx& D(yes.!?w/Βr
-5Ov$X#(
-P
-Z\J1_f\]gIa PՃ}#U; [7׊YiIXN8f; { R`gAbgV YK?Y,c5!Rj)0wA_r – gB; z~>񊒮ɠM}k4_<Tg< tLXLcvw}+Y`<NX`Zo1m Dz x$#r$"ՠv
-GŦG
-0F΁k>kz3U^50*[}ȩ@ 7uLf!FB;96η]T9 1yzAYeu[s_.\Lvr"=ӨŶt$쬜V`gi\T$sy;@7&,%𓁝U8R;+eATr^`m}oo@N,0ejV uFՀK9"`jdXx<='^? Bv൯2RQH~$-G#wB զ7x]X
-Arkȝ鸶n=d- Z΋bhþGE%U7|((Ą Txr8\%Y ag_o+{> ,|}:2g$*M.; ֗9@J*)
-X^fm;K^l`WsaqX7QwZ 9'ܘvk]rqUtp"wb9<?4Z[ZO9`}s`~- cɵ[@Xk_0PxD5eK{٘L).
-WI_Ϩ6`Q$T ۠+3Ve,0O'sR>':pbuH\R!BJ!a=KAStL 15م5O\4X/a
-Ø0 ٺp_r>r}1Nb7=\\nxвfȚXϪY֋ /Y|K FV󕹭V$~-3ͧZ|eݓI5_k"µ{.ɥF\\
-,2C[s|6 XiYx";s8S- c]Qfu{&=Z8UsֳƖrgHB֬gk6\){  SxոﹻJ.Mڗt=vp]Qy|77Orc'\T
-dnz3"ENK|o
-{ݸܑHzQQg&UQgpNM}bhu,R$1c8/"X)T#,O{mo"`
-&5{9\RÆ&iS}=ޗDl25>:kRqt4-HZu`/ oxj!+ze߅ͤ1XĤ}3C.%O/6"yJv8eQ5';zvxb.\C=/ǩ0Up\!>L' 8o?=[ϖ9[B>!y(57=cw> n/g-
-ɝ]St-rplgyߪ|TEA%Wpl>y}%p3a"nDzTx}r&C^%1Ϛ޲ϖH^ZL5_^T66Kl\|{H
-vOWHo2VX8媶c$M3ue*dLσk|iJ)y4&Pu< rf bL^9Y
-'A<-aϖnifP;<pW=GOl){>˨73 ~Ŝ6V@[XPnBXM>p^a0ǹ-LJO#+`:;cT|
-"A\-d꿜9!b>O~(aʌȽRM?1i8߆m,:+tP'66EW] B/ڂRuL qas6uM&vZӆ|r]u|Vo
-97~alE%j'\Jg_p_s53Qq`L(3$csOǧt|:>Oǧt|:>Oǧt|:>Oǧt|:>Oǧt|:>SBC X/ދגuIS:'%E%G'ć$[;·X?/$=")h^} eֶ'ΰuޜs%!ֶ/jl-JߔF 20-,~jqH2~J7]"sӷmpk]kmE3 Y;
-D[#td Vyr<p}ݒy[/0:aü9 ~k×#:6qSr6_gs"R"\9_k6@nmGyɟâ%sspVZ_/^
-Zj}4A)2QLVSחʩ(Ϭ52|=Ӷ*Y*AAZe
-zD+쇋MաSk)񊆳K'9;.>MzIa8h6B6@L0 4(uZg2tPEt&cru٤}Te7a>PC4-KVmf2iOGkk@CBm#zfɫQ6q9zlB.9z37[Ht/.[C_$3=-ԗ*X`{ ؞w2h3>\|.](6VwL֤֗$)GǍEjqY]\\Pp>I<ߔ)>QCL֤C¯QQ/;Qk T<Ĕ
-~+?esF@?W~:b*\-R#K3
-t$ s=|=Й z{AIlLHb="QC~4(AS@Oe2XIׁVUF7em&gx|t kI4U$C/#KC)a,_}b.NBo7uM {DYV=3Db4ep0gB scd>vej’~fU)>zHR#bo/+S*MeF<sZDg <M;*\SlYlHYqDEnxQ! tymwONC [j=a%]no|v|}(ߠ ~*<`}']QqZ;:`W>"'A %c-zOd<~>ItXLD
-{%SL@tz@CC\m :nRĪˡ'*_
-^ zDW^+}!EL.h.ȓFoRvM8*ʺl'm2G=-gPUsl :'*J
-4**ߤظ|2u1hkZ -u#Ub|]^;tEh#@<j>i ,Ķ}Чђ#m=dԙF%sWMzx..G)gN6+xm#Vv-sAS@YY{2
-2=S|b!ѓz]WbHbzz9&_ G|*A$[Mtב た}p=@O]ʪԀF㸰&GjdM.4Ct@c~RDCNa z
-
-ob>n˦A/5s*"M/-+nӡöDG.,Yþ9yh:o6~x 誱D
-bآHw#9g;p{{~~b˜s}c>umh- -]'8΢0k0k&Ff(.<} ;>4(hs)S^*]=Kc)Et[@n 
-`N{)/Oy^Yc3zN(Nz? 0$? ||G`5lg`QCpE4Ȁ<
-*;2F`\bǵW
-h3g.O
-WLA/ p!m =xq9 '
-s-Yy=C~ِuB1 k @>
-{<fQWZ(֊Ҟs
-Iī1FBaX9bHТ<h& en3p<P%N>
-_%>
-Z1Tоחc?O0p, ŶA
-!FY/{-`/~S$b|.#n[ը_dlˍ(<sc*nZ >f7t阒TJ^
-]Is!p%#+&ԩjԄ 媠2K\X 40.{bej e@\:+S~Ih"?({9^ ʟf#ӁFhV[ -&C^=aЁ]xgccg}&9HsWNbC O" w}2`=rmH/FM\SCg@-/ ߀^aMx(O`|S.sqOzH>W~DQˀvz}VKAxu5޸
-TCE<97Z=fND~e;G AA Z#rg
-WAW[Ș?~uõ'M X 럻NDUng2~(D<ZO+땾4:j9iJ0DqtBn*fY 뷜 r
-) 3@뱁 |@VYҴ kY8|u&u <
-Q>@&EF|!Zq< Q
-̛ iZM=|koN/ Y 9-ƄZ
-_>G/71W"DcކhX-I/:OΆ_ Is0_4Gcb蹘">hlq+s1yBk˱^DaJ(Pxdvj =?99"KyJ|V~HKq`n9g
-A<(wQnPaE~)m[1ᝤO ?.?`ln/ G ➠
-ixq[<p9v.uc1`PB
-zX"(@'kC.匥XRȌ! 1@s <):ťD?t{١,)GAGRTp=(ιDJ(ZQcB =/cv3
-=8_<+:*{ ^]۰"F;e(j_|݀ +c 4OXKɸ|1Aǖ?~ }cB_tZ|wPg3~x` ! zLX1a569&Oa k¨ӱ,gwc99mŞ1)+T*En Й߆9/hi_aޛg=&}6a3C:_=4ђޓ >Axu2<5t!!>ycr&iDz(N:ZkAzX|
-Ό|"F1J". .N)d Qmýwxr8l\Mo!9!fzLX8?Z=&n~y)[D5%1s$
-pK#%spŐX\xd,\Fo(xB( F zFJ/xU\W,* +:mt%~+
-56TN)S3^nDyk)P
-+\\YJ=[sa]_
-csX
->Xa)J TQg+UuORTa|'
-?|'/S!-r q5rQj&Z^XK4#nPO^<:Q@eAK&%|.p2Ή@NmQxFxP{.+P}Gu^|axZX.9b}eX;eE!h3宒d,5! (a}%
-|yf.o=:/x]#q>ĕl:Xq(F2w4wO@\%_P'`?^5t-P%YK
-@\@>
-~X}9Gdg{@?bjhh5Ox
-Ç|
-7YZĚS(cx$ar}b1zEh,@a)l:FM{m[c{Q?2@M`||hO[1yq,yf$ 2 HGm
- zK//lh&K.Q,#lk(pҗ #=ScRy[i/
-iLX&h[`DzTӸ֡蓉jӂoYkՎFe?$55):p2jj>}
-R.`VX*l
-4v͞OFn":@_.OfL<HO:duv_UṢ1ѭƼe|9i8Kཫ螁$˄Aֳ)jkuiV`Z9iZ)ccR|WRջ?#
-~ ePIջKsNLV֧$u8繴fe<FS1/?^ڮIjVH݁8Z{x+uc t-{JkG_m: j2^mH2~#oɄʝ'Tj
-h3y=@z
-[wY5gƢ7'Ϛ0Z-tߕܭ1f4 DwJrM Z
-}iLvg5j32ڣ%lUJ׀'T>hwLl!̥Lr>A feV3j!oփZP״|zmFdÊB 8DV]d Һ\񧙴K<|3wa\|)]\o^iHWa N+j/z'"YXiI{fҌ$J]TwIiڏr.W*j&UE|J%Jj?] \-a!x9Wa8?/(A}dn07؜6i浙STXKѩh!yoUш;`m{]|QHtY,ɭ9dW|N҄Io&ӻTѡ1DŽ^q 1F_fjz0bS_zެ25Tj
->6 忤&eX >(W{]z]G=Gq}֋@7K(a_vFxK[N rO>l#77!_|
-K[ĥ&]0yn֬dhຂQ"閰,Imj'̬%>/6JŷEVJr5k2٫ڬU[FGož[
-ߴwgJG}y[vt~)>üd~>FqzX*dʔuYJJ}$}Ee5E&!3>هbqn){eZuȫjV飊#ҧe;- }ˈޡ'F4
-R7jw?걷H*O>ꢨ>)0ے-8Ǽ:T|8Tv^ .jWD  tA!Je>\<$h,y59Sa˼=LeҢP 4q.Gxakx&Hޔ_4wQ_?ZͿ]MG3C>Y
-bz%jI3[H{UǥolK\n_b'~QsBrI$j7XJ&496_ a­b+q5OŃ%O_|د}@x4xkV4Wy`\x嘣d.⾦#ĚtJڛڎ~Z2ٗi*FK2'W=GK,~hmR$.mn>)*n=')T9T\o7e_vӯ;Q<VVA9(k'^lFޝrFTQQ[,DW"j5vK4!K~5T|9Fh/l|
-5z#DW|8K27z ȰW먨ڭ:y Ҽ2KiNac*3Ụ61䃔|Ų/[E yuOZwx VsqEETcUqēv>;2F4P+nXӯLgjz-n%X6Y']mLh͒0=_Oi"mJ66] S>ne
- 1kˏ4-?,PǫhaU軩N|!H=mcDN7s:^NNjLO?0Ѹ{]k4|?髊s&CD[V 2h $ބ<1Uu9*̲9%ZpWNԱ[1`qsΗ2aRY5]'K+_<9/yq~2Z^DZoϼy'ƽU–7qgwQΪ
-Ĺ%oϚ4G6d }j&Qaɛ BT_~1zT:WGE
-[-k }`MnV)'Zo%\mW!Zr;Gf$KLuuOlLa;\u܍wo
-LuYJh^G;>+v-q-:ޞ% loVW]Z7X˫anD_Fq/+v/u
-M* (O;{\^s|^#w(OAeE^E2(_II>IѹQzo9=לO6I
-ʶlaޙ6
-λ׆^qe]jLjr{5E a GPvpnjqH~l$ر*"6'&=jG}eT䨳)Ǜ"=oͺEJzC$%ͭ~Gn]GfMQg2SO7g%p7`C=Ϣ}Ȟln7ѷ#ef}"9 #j#c]#_6xg~ۢdMTǤMQbCcd]"~urƺ=XqB~̌rg~pV*O{'勓^ '֍jZfӤ8$.n5=r/ѱ:*%;j[mcl2@Xֵۉ*]% g2"m+cnuC9y<ܬ0ڼ+'BsR_KMx≶tGpܘmYqcccbT7;^-g_ܡ;S'8{V1~JkewLZ[${7"J"N6eDw܈`<[էèa;ߍJ%{7;o]sd;ÝC}})!, 嬒JAQrGZ-;guJSLQӥ' v9 vQM^ɢePMDSwyR~y=|1}6y^b}ƭ{5[U[ eq)[QiP_ڝJ"_zn
-/
-="C /#p13VkU~n,E񡥾 ob߻ɲn.o
-Kߞ5Zinh:rX5WX8\O(silt(WMطODh4n;w)s9,[
-dJK iks7+V([ -}>3vUqBAV[gKwYo=b
-:-v /( {1"-:+ֻ2 ѭ2$!Wm<nq.DŽ>4jSt)b0C>7@k8ޘm1Y鞂N;%/rE!S;n
-Xip"BIa1b1CE$"1PA,DfD5 W|j<&N w+gc"D/lt5u{}s*0.WTZG7(/F]-=.v|!J[Ǒ8G.t/|Z&knuY~iI\p9o-j ۰SXTXf9nzFN󚂶lW"&(b1@%>r?^z,'yx˄"b/JW?*727*BoYzgԕ{nQ/
-\"s \"rbEQoK}*ٯ䯟\/DǼjF5bhts.Nqb(sJ_8t#rj7L F N$FMD? fNYMrU@ucsB9갸9zlVGTasշQYܢP +r 5yYSwΑŞQmQ_[>X7;GΝ/{=w]Bi t DgO@4ET|?\_{h.{Pk~[?e;zAf-#d.Zb^BX$aoc+Bg<nKD5;Ew9D?\c {Nc91Fw;=SXPXqZ5I;@}**I
-Nx'#iI[̓"
-\߼t~7ҵ"4&7:[vrțI2WJUtUs[uk3&99|q| C8?
-Ͻy8 FPV@$XLQO,eAl5MӨ4ϝݏ\#d'ZFlH.^W/j[}-;^~Q0{}uֵMu5ˉDBz)tԼY3pt\{$3c>';QrkGh9-CVGGqx!5&-}Kt"7nMj_uF){R*K( r bƄixnwyuwpMc~H9_$jĂebEb8q؞<Ϝ[I/|e<^ž-pM(+pK)-vNz^[RX[EPѕnhr:m__P6,/c:{cѻa3I8MC9ii#/&&/"YMT8@Tv!v}=B[8!Ԅ(h
-S''ZGL
-ߏ@(GJ,xf%?[n3oxJ(`{/<Pk}\5Ǖ2׌JJRD]ʹǿ \/JĔIh)7ČˉiVƬ!H̜Xa? gb#<l0UnW@/SK.ǽw-+t-P^9{\
-P>}I{Fq+ש导 9b,~~?1?QqBb696s6%,Q'-2$f-sԉ bN(˱e[n AQz\,#hw
-~AX{Ǩ7Qo5F~[i'<9g84b42!75v91k:b̽Ē5bS sR̥$1s1CQ=
-m_b{;ps[?rG] <#5SuCT[S<̹ZǴ*z䷥NKr{_еxMELG ͫihM^OLDc8 F-"f_m#0k+OU&ļĂ}}bO fOv6C@_X&<M`{е=|${j\i11!6sܮYf||j"8r('=q=($ht5XÕXBW!yz Tp+ ®7N犓#ž=Iz\3=?E!7֪1>2{܇}|yYd֬uv-`DTZ6N E(G949]N]bEĴq PnD䕄tiJkL Ă '{
-G%Ejp[&/q(LDׂ/%-t*Ĭj(W(
-3Q L4\;k71g^b
-1w1oM,xXJmt+!y/~Wm zy ,L/*t~M/~9m
-VsP=^XaM,fF,Y#CCr5耚;{;”Ă4`XzXHcGo 7[SV z9 H󭰓uч:Dl̊M}'TӵӞ(ڈԲ2ې
-b}Axm#Ly28ᯀA _N1ah>*SGDL@Xs[xR1lwf읶=k;.=ǯ|j.b-j;k;-Re(lc|$95w-t=QZb!j9SA4C|2V5;e-pF !r};r1<ގ^wuy#x<~o-Foӣb¾ܚ}n"flnf-S t8n'r.VD
-HK7hxm|m>Pi4q.`O{ o턶:Q>F2QAd1W|*l9w0wIZT1z!1g ؔG8 aIˉ[f$Am AI_9KOa j9R#usz`3Nq adC R7+8L?rּ6B7ϭ9J-ԵG,?db5Wc$}'ٛtImLuLnc2@]hP1vQuEyq\byԉ B,XCӳ!5|wݷZ% '/=<_(8:V偢+Ni*p#^:X 4 zm 9(EGi9QWHv5z-^^-eDALxvNUI6͌-j>!~_z(k`7u2CQ]A*AsY,ۋy~LE5c:7i%}s(_ Qݥ|s ܠe{mvMb Fz9iLnM>ԛ+>TpBS1xvl4 яԳvg$y1f 'Nﻤ̣v1׿K_7^\ gd7Ulzg6-~b<k37˶ Ҁa*٪/j^8{6wz?ӁXc[<ھoWSFwIi3; &mtTu;_?4 ߭]A b7Y> z)n&/m)[8)1)-򔾨=%i [ydf~2d BQam w0
-WT#VX-o[ш_
-( uai  RgRb6I3ihsSi<mTxXb*'nqs1 G W{՘m,]U/`\Q4%OV0.)vW[s}t 3ghk%zI̘DL
-$*jwphns뚹PV6 4 %<Bdugs@Bhh*7{yOihZ߀"DR3yӳvMRz\[I36]ӻGE>> (+?"7O\SE|Kg]lyfB-a62W{waJfû?ԌU6+]o1U9qF}.+ e 3r)M1 3C
-Sٺضd9gVB;hx $};bݥ%_#>wiF>էE?\Camg)shxoga&75ɇy׾lQa~ &VIm· lgagSחsUܧЦ_Jli.ٍ\nHSݩ:BdAf*}xhfn1srBtqгM´Tj j/r
-1[\9&cf W_:q/<7./5ܜc\zᕁn\GeB^T>fXrr6kz{^>s3g[꣊p_R4g>/:/wsEgbTw(ڝan^Irz-_o[_nn6HO ^=Zlp/wb^g>E"&ՌᓪFN,]x_/Žg ݟ} Ӟ=_(; yX`~P?)u٣{<<+?WY<~ftyf~Q IօZ{XrI:c5[ܺv#ظr!:NdX!G%ڪ ŎČ
-I,Dh%'y矩…)|rF{k($U3j Own|ܐG}oߋ݋4)L:ۙ\: ']{eiG*5޹ 7i6ݩqٸOs@`9KmxK4l4hW>930g8rmpOoV/kDc%iW8Jɫ,Jx&K/׵<\wWOpز.u7rmO7qO7}?^u~P7;~oxpVx{?ׁ? ,&nm<0{͞O܇ ckFe B4׏f0MgU.܊p7w<.<ˆ-!tx~ )&Yue&<w?{~aNCb_c,| je%ڞn G2l􃿹pL\}˵=?n:t͎{=4-,qY7{f]vi\{hvcnޒC';B{3Z֟sZ{@sb\tP>4[<pKgI͓%J\}jR?yr c/fp ډ|y,]ۧs?{7 Н{w+-yw/uE{dXy1n
-afOĬ?t_䲾#eq`8^ox?w_𵷖-x1‘f2'Q~+X~ewrR l][ ?y~+8 zZcp\bɅy 3oM=ot.fvNK_WLb+F1|D->ڑbYgh%/6`?ՇgQO~7}Jd__&b~Mx[2;Gzmį;0ܡhcTI*mWI޾ɖ;6k6/ޠٵiKCkt>Ֆѹ#4[mp%h'78I7CqjppE
-07's{f-6A |fxth&ld8 sRũ{(/]g|<RxϞgŒYbvBٿUOVGs \[l~Z_vq>QW|y>if՚=[kKcYIp4:aL%d~SDv/soX0JN 757nۤBjTxn6X|Zvl<⤘44uRY=rbVDҒLiGQvS|P3 Ny<sШJƜ4 [K\G{"줬X/ݩ;^no]/H%B:B7;!ɤa͝~4x^ J "Ts?r;7WVrW'W0r ȑCڑ:\j=l?Yw+:hfFI%3M)Ngrk GZ>V4 [+OҸQfB*]l=n]_!6oI{f8Nrp0>ҍo}Gӌ>+7~q>,]}
-&Z8~g]ybfm}Dr'K'wD.g>ېnd\1f c*F!q4Ux`taEΟM7 ͸pEfʘb!s,/D+qRJ~t꣄BB_;Z, nq@Hs1 \.\7ۡ!uN#VQs?]x!1`$4\3=WՋ_3_P#@3*?=_,tJhπ ³:?+w/{uݯ6a@L&6{:y .,pwY- t`&l\d
-Feu0ӟMl |Z>EiavЊbr0 qpäˡKM%U…ߴQ(0 B)o-jxfĢ3gQWFZB۟;\b@.j.2<;12Gz)V4I&'p{%␉q2)1oZ:x_B[.==zu,4gB"ҌJt!>=_o_X6]K;BbXfR`xS0oĠa!bfD>tO1ut< 5'Q<d 0
-"V&x+n>fr3}@_9ZNHHV~fx6۷A7QjuTmiU_Zf'}'xVϙF҆lxo֨Ո/ʟœjx
-~̗Z,>vNb+GWŧ5C_o}~͆y5hth WVriC*!A/?g*'<@6G?[c8l8R+/-&‚}!y=|9w'KkՀ;z0i{]E┱<@Le1=lN>0īdM(OYʱ
-Fl-eL
-)NBD>
- )1K/lM,.gp֗'AW`1zWN"L~phեc1-BRbtLU'=)9.{Qx)7W.e=ssb.\mRF NN`۟m3xm$jB;.4[4炒p\D+WO<;5lXVͼ-:GșBBhCK8‰jF-}3P4}">y<h I]vB|Sl}ǗI~)\70wgo^{_7]
-?w^o+UNN Lf99UC˛4GHI6_i3(~ek!(
-`O6mY5r]oS7Y-bh-mPk
--s^6S>Aqg7{_SѩbHe˱eR%|rݽuЊG 4h%)7bF$1k2U.^mkzty+XJr=Zy 9S)(P<Z]r7nǞJ#w'TkfȮ]Y)v}Cn:Xn#`nE:w<".
-
-:bW8s\ ~c#/8P3]9JT-4;pg^{;'h2z*,8B|(褋%7]z)('cv1T`Aq34z zۂ7+ҟ,91G9&Bs~eT5 ZHs/Z0 bڰ{ Q}F.W^bE|B=4Ÿ|YʲCnރ g 'g=A`챘1
-||O.' 9:&v]ӝ·Q󂙅
-g _֛rz+5#t~M脢'B׹,VC׮BwwBZ9^?luZseE|3XP:[>
-G.#FP_䝜䜚AS+@ q a[:)\>ؿxZzu1_h `^Pw9z[k]-:CBs/JIn1t<qz]<w2vE `BB]VS]/]\?nq/{ThN>9ӉSw`w=w{Mw7Z塾foxs<!(
-qY1JA!6Xwj\HAhBYu?ګx81`gʷ'X--b9 Q;0NHS`D9#HSl`@$cWX!qtq f$Tr
-:IK.;1+u'rde ,g,CLZjytf|5^w%Ьy4Fژ)0e
-jطl5xH\{n~m<ny<Fw ;k1 M5m;]d>4u_nw̓5Ӄj\zrZ$?Tkk*f'a=\0X쉅즩Z kŅB]cy2{5w#vNR!&zz5,#>Sl !6J`09(e8|4Xħj4MRlwt:0~H>yr}7)(gehޠW
--n)Q`|3 rR
-'/L,#}-_ Uck]h+,q1f";dabICo_:^- mb!h|>ŧ* 3`K# Ycƣ؉|krk V"b
-y<pVR1;K/H,fOre}n/& O ɷQH?b>Y. "j;׬V-*I `T]_F}T&>Bb$#m#=Yuo1q!,7aO:덧(+/-;r-;Klb#2βpZT̥&6!bgO;+2+;+ ;+abTYގ충9 X`b>&@gu̞jfR!g _qe}l]K%"ێd!Vқ&G?\%&9` /j5"~]g5y`0˩N#"~Ei.?'JW6UA-$2\7Q-/,n'%ZFN%[q}/\d쬤Y6FbgY\^!~ZujOAl<[S=vt鱷|x,KCZaZrŖO7˝v n[ <p>jNg/JhܣZzy1j114͖kS6#X-kKYlwWNdˆe'Yq!y߰_sJ%]sʳKܚs[ӋwWJ/,RbXr:ţV&nLQ3~CrÑ լ
-0-pĎF{` 28Au"sx.ri,_]}ᚊEbXN 4#vR MJ'=[{LO6D;5L
-8?bݵed`ˤS,+~)yԞ'~eOp<dN=2l/%Կol-Y}`gg`C*)euO@= VY>{{b|;K>oe1ߐ<rMlA>,Zeﻸk\=XsԆk'-\FX}
-]쎩`nȅ31cB}D+QrLaĀaT[ bGڋI#S.=g&߈"q` Ả%w|
-4RTՐ\> Xf5} /*rٵ<>t/.FOCj(v?!DZ굲WĨɮD/pސE䏠~¿Ć;nm"^[|\hw}PbR8ҔYcxU1l# k61Y= @ 8CڋK똍mPB= ; W=bkTd|mG<;wFÞZ~m)L)}Ih>2<z` ^3|>Kص/陃nRpp\nTR錡˩a 6Cz4:Q# C~%%X=9L̈R3 |+_"&Qō׀99Z(18
--\OebE#F!6!e+Ezjzۘ%kƞ1Ä]_[!oƻܒ\C%{7Ǖ2 kK{9$F<k$֍Ź7s_+JמbMAWoZ?ߪ #9,磜/PrOK<zsb'bf (&Y?\JI.MyJIvgbo;z}8uJ9Taq|^Q;ΰ#n7)Fu/V/-Oh%X*3q>0
-XQv_A`m v|lGd 2j/A>Bj0 f;/'Og.sC9|Nj|ۣMyJ9%UB~=ҁzb}%:q|]~EzJIb֘o2яM9r4#?I.'[ -PK[L81ř2?e*6Nƫ+Ď϶J>a)qX,+sZ>^O5'cI|͙\ǧr?XYT1<|L1"F)C|8!)k&V6G>C.Mk_RSJb9)c5yFK{k5:N< ]\wIoJ)6d`LkuLY92VE<o
-xZqfK-읅XWx/VC <et,j'ǜ(΃|0Lg bf 1U>ܢGZ:XMYAWLX5.\3#O#X賳5$k'ȋ`Z%49Z>'~(OT<JYN>
-n"8/E9Wi*.,!&8{ґΙdk Ĥ'spXO
-'\{ۭKyH'; r1ݻ98#؃Qi]_]_oooooooooooooooooooooooooooooooooooooooo??/^g?uX{9>\bvDžDE&;oė9]KYbM]\ٿ3ط8/f?|˴~Mՙ}36$8$}QhM~ɺ V,]bWZzuKW-__/%//9d/G{opY;ǘŞd ~p~ٮ$wg^q^Lo?^:W-_vyڕoO`?IZ:̡W[ykً\4]lAsOg>wYgVhCf,k92Aڀ+/5|f}=ƃ30Ƙ{].ޚ}{4@22"rm)VZσ>,ôI>ݼ w4ZlQ߿ߗ~[
-1ヒ!ebH "cv4cԕdzs0L-Gc8zqLC~t`?c`<'i˪129"Ö$(g%4FDIxI4 ~#HAX!I"Dgؑ4B`#żьS!Gi!
-#c!$ n!V8 oǒ $tKBBU5DㇱbWWKO.0dwO(b&[AZ{l߃P\#I(}70Cl$9qUcZ'!8{!Rt8>dMh&>> L8>O!fKG2CF2̞Af^Z?3w/U%Fps<_
-ݞ/荡ti0>-cv@9Vdk9rW=Z(́h6Ys i^_3Hu@H`)-$k545B/Y Վqs={5+I5NjFdCN3 Ng$9R'؏hÇ$Z-@"jCfDlGLHIӘIe:l'n1&dgH*sdI2udw
-򃐁}B,H+ ˲c3G`Ҙql
-|<%(Æ$NȕT$g
-[CFqb`$$f E12o(=HԐxti'Fe19"И^r8sT6cQ4IE1y#tv/=qḡ"mi$ѐ>]/%&QFxAVRzd)"K4߳ݍ=֛!R+G[0v/,9Cxwф1FZdL`"[f^QU>ȵ0~#D~`-2{YH6:Cd)0AO(FLՐH Kh Ok&Ռ5Ė;vjX FQ)$:XcUJQ1Hf`T[Bc@<INj\#FIJ/a,ݧ reu(6FQdv]!A|/E E49@%)tg ild31*Tvİ;GctƏ1Z7=4_4eCB5xm?EXi4:JcG
-NZS fC478
-YS cE 1Y#)5q碞
-F00QNKϴ%l I NŨQ;^ YWUHFv/aa> y
-18
-n]Ըj -55z=$?Jo2!فaf_agwO[ 0S,oC^6&Yak #R4^sH/`P1rCՁWY?]{5n`l&8ǖ󍱄<ɠK2Ga)HPbG7BjT MHZ9 c-9'44<ӆ|Xb  Ҩ4ojڱcZ;S!)Q/,oRKNχ/2$8B
-K -[!a4UM-.-'׎ ɐA
-9N$
-˅l;|Wl(\K>Ƌc,~f %foZht_JQgA#//,62UkWGbV>H QHy@SH#_LH'fB^
-AՂYRt|*d7h<׶~j
-Mz f\P@֜<7dX;X;(Ll⭰HJMXnQdVC[&|b֣t>qG+$!dkc``Q@G:ctKj $xmpsPsC}gg!&\F) RlH'efE[b,).Ʌ$[C2ZVd-ћ"xxK/J`z '$t)$}8$ V{< gi}eVO:mqӟun&Sc-% 7R+JG.
-=R` 1#7άCǧ@FИrjT-O5d  S o5EYd 9NYn )q*ǒe1  `ggK5W$\0~'|"YPv.dd@מy|'5-p Ŕ8RQ x 2ڧ4q B>?j H5pc$ւzY\p}&[~Vִ~^
-2²m%SȐqDql- 4p(c8joVx|4޲JYC::9%|R-i1%|',)Q/2}
-{rzJe'cvtߐ
-f05[AiɇBT9BPS:Uk<=C5j!$Q;咞Y|->J,~&?5PJ {_AxOK5wWBP+X > X"OIқ& ?B҆Cv\hb|+I1Yh7G- =.w<)w\Iŕ)KIK@:S~>+Kţukˀ]pכufWXS`u?Iȇ&Gdhm2G)Afu dѷCd?5$ A$Sn-GW_F0daqc*G}ͥL9(% s8lC Wfvߙ^7A-=g@rQH$.o$OZ?Yǝ/_ ca^j9FkEXOP~)GȩOIE_R2z}襰|!Bob*cLrC,e~j}Ce@1ɓ$QL5B>bj#_ GA6e
-{.Bۓ|Ǔ-RGHn%QhdLk/B$6裆[HR,,V8ez]D8&S.\77ȵC#cF*ͦz=tE\|~Psk\zexl4 '{mf.6jq&@2Y `OP{n~
-/gQ[p0Hq6e~GB7 ݯ\~f 7H)(krÖՎ[㐥{S*C2g^ H'z^m$:ߒ^GF9-S咡9v^@us&& 1c@_S~f!jzbDub{
-Q<C)Hg)8aO^L+#^'DW: wD; 934Ւ,C 3Օ,fC:MX
-߉Fې4?syKl
-T2GDd!'BL(c8["n#$DTq?0hT s f<ߑ{3AB7ZPpzr)=RV?8p,'E&}I ,䏥k G뀍2]wLEw|{fQBDoAK=7 @g|w."mI>COg%'B/Fa}`.m9|H0`!p@֮<Ѝ'( '@M5}Q,[lVo,%
-9p3|I#HPMw5ҡF7䡤ߴiEppJQnQ}f9Jݵ3!{
- $7Z=Q[JWWH_A~{(dKf+=o=p\BB_l $qGDL P.l
-!!rMH_oւoS=a{lXI=GL=:^-<7Ov JީYrFda=Q kK8>[0EԍE]juԿ@x"CM Jn* d>!/+4|FEAƝԪ!{w{j\vոxJS| r/GK?cMDյ8[K{W?\FJ'Ylȶ8sHߺb "w$Dp!!.W25[O<Ξ\Ӑ4ـPצ `X3q梠o6|O Θ;)jQLHn,O_-E6}`tZq$ѻ 3-;
-K]'>z=`{ݔ?v=?ƹ`sk߇4zJBG+p`;'RQxj${QwhO䂵 TY*&w=jMK|rR_턽|m~‹jYW#3쌈#@7Vйb%~
-!cgpEReWrf`O/aذGv/qV >yjLHʴQX}jRsc$
-}|jTǑG[n./}?SxT&±B`iov)t>&5|V9raR88OU`O{YJBӁ/G=obr|D-^lldXx~pЄoci$՜["1P84ߛ*մsŶϷ(w _`N߱vO]9LZc1[$yS ?ADӳpF
-/D3Mg>P gguYƊ+KAo>D+Sa{CQଂLʁoPa,J#D 32,!rԌh zƩj٩8+ሜ S}߷Bd1;>؈ $ɷ&*>=84*WuSn RVu‘3scq&„#bO; Q;A؝7B*Ȅ,8pCtqvk]/| YJ氚a0.$
- }TԔӎc r] p&c{~bp*}c!<i8m윂=Z>| 1@wNb etΠ\jrFQyo<,2NeD>{nE/<7*,"tI.΁gXE}
-[YccbBE?`&g|/壇<CJ*M~$5Fk-'\
-Kz)ϭ83{ńgot|l8/~b yyG]O6qy:+"ɄfIm^[sh(Fh?ΉP̿'Pu
-}?,N
--:c(}BMg,[DYgEfr)S"tMk?X)rc71gs Aq@;\TsgJg*n.:y[a8'9R~X9ruM@beWH yXJxsrQ0r:^;%{v]
-$@ 7V
-wE bOvM3˭B5oU
-ŎAQK/--(0ӧym7
-GfH+w@qX\GGa>^%$u'HEf P^
-y'sWgz<]uvooOO߂u_xtJW#}K8<LA֯zpͯ"|.>7=Z6t<'v|&WbvoS^fR~s)jE߼ꉾ};C&`<O(S<tIJn}{P4XMr[m&}ۥj߈"< ՛t[Ag+ER5\}{ʵb{/koT}O (P&iz@XKK݁-PA R+u{of<wzk4iʚ{n3c}PG6GFٌqWismry f M^i3ԑKkSCY`Y԰kCDސ>q3bh%KgSу^ mƂ.~,?lv|,XX=LPE {+;ω+k]^:=-=!)yd΀>:7*h;l\.P:̨.-9E$A 5}I^tߔ.ou$$ D9Zx.]Ev2E;P"ydQv(>ٯ%!LvCm1ÍpeI9ї-- ';u3A<&,i7뭒z"i(&|˚/H_tHwTY*r2TvJ|^|v
-P1<~ZCktN!jvz)7nm
-•]N_\f&zxTNX苐x:,uģ!~mI:J}& &+O϶xoW_h9Yg/骼,.V?B"wTK:]t^A=SZ(2֣Etrj#>:F }&cN!jN?2o~5
->S0[=CR5UoOU!N5Β=#bAbbP  {4͊l8GGG[„=[>;=7x'}"
-P٨.Ci(>*~Tkх=ɻjG/%ɍ:d[u >ؓB0ap ^Q43[wTٴۢYQEq6(ۄU:qև9N¤]ogOPhE(CK_ %:tT̕lϊ MpV>x-f2@G-hqiO^Z skbY#꒗fUG8O,.ou2( WoDeg$%Β:wE$EEW=6ě^ fh5vŵ35ҷW|?a+?Od谨9@W!^/[C. *0*~|%>|tG[%"m&?5NA.~3z۸&zbcA^ZXc-)h1ޯ4-3'u'س>za#zrRIq%V{8'a^uڈkj\E^Ҷ}%1G?u^O={?zUh>PQ lp"^Q坧z/1V/uJoJ:לИw5=XgnHQ9:'l8hG|&REymA1 ߆b"^ǝd]E2`gV=6aws}FC|)e) y%&K˞qv]εfgv<L5m. DqݎZMDޔ;5I_ל$;DPݭ>ǻr%U#k:6J]Ck
-ػqh}]$õWqdˈ3c~#$~3{pV!,|#?n7RYd<HdhG|٢4V[B ?
->dM9a÷#d_'qJW_uWrFpP1ߏu\K̬IHM
-iz=#զ~KMsg+D3Īa֌䣝qC?Ev8?K>\GElC+o{w`ך.* _+~igZS# s~Ɣmm7aOG1IcR=OT>4V875y'4fJ:.M]g͇Ke-/G_6G߬퍽TRRs9|sBj`>I>1<k9.yb/yW(~bKm'&AQƙ{ɮ=?tt4[钞 1~$†Xߏr3<㗌7oǽN8qdǀ+Y{>g[6HtAJV6kydu'ɪIѮڲ]Zen1a1תdwb"+[K.D׸DU48E;ETŸk**\T\ LoJ0~!i{"Ú8%xw ȇ"ѣ :#-%{A2FvP$ÍOՑȀ;H:\e6X+#;z`>` ǥm$ufe> !͗3϶\}', p p߭x玘zunF׭NcQsdQs:טB82k㲫ҫ}jCކs+UFhFD{}w*|ZJBͻbD[O sG+CZ6Q]W_,% !5L]y y0dPDkM8y+l¢x¸ mq)^ 9۶ ٷ-4ů981Kv-n18r,L|VWP!K=ڝ+BwH.oN'qu+Юオ}#"BS/7=SXU`rbI@|v_[S,ȚiG#cXvw2#BC;o]-Z/Ug}#qBǫZ1^1w\cJZ2[${[3OfObCj/'$W^+u?՜{9#h{L:.ܲL2!*i b!k˶m9'sS(H|k5,}ՙ} ;s;r̤9f>zPr^wsLiSEkƐm'"s2=m'mI"|Xo^bdobROM-ɯY^h3!6fHQ+ssVO}Ǿ|0`Fmx]+qYwSc3b/^IК) [nQSd%t˕4Ϻ )7}qjN>yt:ڲ8ަ0=-3)(ӫ!:xWN[Eǝo:ڦA]WnC{bbBOb@Sp
-=|s72cxotQdle /aj|d0n*Cbڮ܈!G O0Z{<l R*w)|w7{OYv_u/C%('>--sʅ>9b1#<Jk
-NS|gw#|YaKlx[@{U{md_ 3G? ݚ`ރ`Muؼ
-a^Y> 1'. (ǢWп=kuy)r8l,UY`>Ps>_;n.4w}Ga~>sofisl``Ftvfkf`1s{Ɗ~ެT/{2跕.QOKcҪ}+/ՆFH͎,bBtx2РkkTBCp8C>- W/z7 L3;0tAakдRo /^Z0L$0LT*+UMLA('i$.icty__g`uW p+b]hRج~|e/^+{\!{S}'cw7ŞљU>q5IL}._΄Ɉ;١FYn^-jb~jm~J^?oڶV,Z )` "{WRw9 ϊIo?)M׀[E`,* %> ſ /X|).?[ػE>/zy;
-/['E> OJ<zƿ|O"؈@wMdBxe`|Xk5vݬIefvjܞasA~Ɲ`Tdzgڜ<
-چ8?{?6'B:ӕy}N,yfFn(4;&,(xǵXT۷dơ Օ0 bmerj778Eu"S-
-e0k`߾W?P{|gǰ=3xޟR7kVv1m%a?dq/tmveOd6{71l.Ji{VPW<ϸ'q)%qd̜έ/?P9c}cvdQwĩr1 ?36-.?oSdTy=/N|PQ/sEOMX,Z_UJpݪv;~zCiL|o|w"O f*,
-0Uq9 L̞֪yG(ie6Qo=`"
-}e #נ*en17agrV|%xdPTǭ
-}|_.,:P}e+{#-#]Ω
-o_~)hT銪pQS~%L@ez2~1i+=X~:`+.Δ? cIH|{Ť"Ībw)Şy%-} R8z\LXIn_~ gqipUplgmsVhx`2TiKU$` wLVlx",[]}\%Y\B /0+/wm|#Qfs,\~ٶ0Nۅ83(spL3g9V97y$``vx֊8qLUm0w&~<8Yb-[^ My[/oJ[ߔ>Tx$Ը% 7$46Tx#Y3tSmϘ&wYcyW9U7oo3Tm _&K7ف5`]=} ՚eNGᦼ@>X;S}[lWG2sݍY]u]ͮ+=`-XN߶͟mx,?(+
- +8f(,-SNe`m[9;}j@䀹[`;X kdO[,uZ%,;X.::]hL9̽`{=1===-g̾9S|CE
-@uئg'È={± `ެ`R ,v <xZ^`3X},v1`=S՟0kǙPߢg/=Ooz]TjsɉŰNhre!E_]Tì3gӿ\ 0z)X6q1ˀRAڦ
-ϐ۷̞ L\}#<f@
-DN1x8Z\p{PXTnbJuAC0­p3 }
-[n
-6`g
-[#{&~fԴ>0QƆ;ߊkʉcךRbڛˉ'Rbc2.D 8G& 1Skưi@ٜ"r/g(-9|8U:S69K 25zx rh"gjO=fVOۜA}xUMsA50k52&ӼOIKIУӭ2Tϡ嚏QZ=5-v3# Y|m3#Dy``:CAX;U6Q` l *M(nr#jŽI;'p/өh^ɚ ~2YZ*FFװu1"62bP΂ڕ sgڨ.ƚ
-lz"$ێ]W0e@%Zff-}!Mw(lX=vוxUN9ءuV˜:P_J| Z/bQlj^Dj<#?8iP0=nN=lNJmo;N8%8Dazi\+X3v+u?Xwl<` m`j~' vb!r>Bͬ/թc AæfsEoN?\ ;J/} o0ۍ+!5e$F}|o*N;hq3a폣Too]DjMx%KRUm0 Ser0oNb تkva~`OU]:]V1gDzaָ?ڜ83Gu3\ ;#1X3з bڄ1*f U'<gX׍=w϶f뾓b8'yYvK|>NnS-TVn<eZiwP*zWcmk1{5mY~gLb̫>,F4@y}l׫btm99%U>CFczL^cn` >Jt#ժND"r2_|"j:`!`KZ"pQ5 ~+̛m*< XSW;h4M~X
->łs>1ֆ-42c^3c)a\Lz*`x <킚߭/GƉ3c'/p1?qYx4J *`/c/wwLDJŒW!^s*m] }|F
-Wr+r>l*-
-0V9/ZA_W._ 1?jÏhr^&&KFO[}%ԃ1v!m!߻ɕyOK.?4&mruCaBGl?}8(k%X4p6,h<AvN>{K!l$} ?XΚ,\ڃǬ`X_Akt# eмY+=-0
-382;c%_q
-yc{ѱf.ĢMG= lT!#c K1%Kh}:d˭DffEƮvzAp^<jM4:p{+FCr
-*?q,S~@kq<R5^Bf^Iޏ&IW[B=]`q 3.EL~&wيkj~ b 0J[2ym%~^bڂW+ ٳcJBJ쾗>ٓSEM؋Wx7kt''uh׃YbORR s"JN#AU٠9[g񽥢{6v,%&! x1ss
-^\2g *sl|Dd=-} x\^(5'| nݎ'<&Ly6E4{]%w<oDWieeӊ2OIQ9Qmsu47gsZ(߇qu\Y<M9d0>7 iry$090Z/c I)h tv5m@ؽB,;'wSl+
-V6g=T,NyNCҏͰ|,.?b,8qO&L w#~|B*vu<3Sٲ1bjvެf=`txwC{n}uf[f012͌Q)cy1%chtI1K{
-`E@s.`
-]d.7[I|=T^yAbAg-{,BaGul "82IxuIQY``\HQE7b>)sqeZ&׿$Un^SskR7IH_S]0$vn&/:FNr;]+Vw#8p[qh/bIU~ kio
-!},+y=rϘG&C<Ca-m]Ig>7-AG5AM
-]Aӕ)y"?*WοM@ #C4aN7T13W:=Fgᙕ¬=Āޮ ٤_" 폧._Y<^hK>z-͢GtmC<_O\~:A<7?bxh*-r86xg7t隊vBPxVrB8e)jt
- M ־C@k~`le9\&9✺4Md}\ mE/SwKr{
-}m3LIXtH7.i0-auRǠtY :$OڨMO9B&h|6IK~7\g
-OLDbx"C[>X  +0a\ xR^2]qψ :ho\ڪk8)W||
-~>l:~A6C | ~auaOJ<ͨ؃a鰈WM1e.3;oṟ%OVW/%1n庂`rn"8o{a1&1cs weذS{ω|sy+蓎Y([IEq<b%y-<1Qk$ǝBM{}kHNEMZ'6%OmE<K\E{(K Y."bb<f"'}QǕm2qU{_ yLp6q6wjzo%Y߾rX6aX>Y6ʯLҗ"nB{$nk䯡N*4 Y!8?M=}xPQ j
->SwpՎHG84.QO7b)M}A=vYM\A4!u
-{ɷ>Ľoq\tԹ8^p칈xwDOGۍh
-7bHŽ{NM"2a<Y짏 +\U#25=\<_mh0m0~:jYt7|X*2z~?>tTIDUœ &fb!wVbVeY{y7 u9`۪`Ì`M`СC@߈c
-pz<< tVFA_mZD?`~\Tf!<]11{DprzGrFl YFy&EL,FPIBv[\,6E Ó>#W RJM]V[C_Ve2+gģOx1)cl6-\ jFo
-
-b_lƣn$ 
-8DA?E twey"v,p mz3g%CG8=}Xo܉ 1a^82?8wؑ߭e”=G{JL%jeIM`DP_h ڛo-_5iӄ>9yÚ(߁)X`çКWl%rZ+3wYsM̜5C]GR^h kK{IӊHeX9*N13'q]ѳćƙv/%KI 1pU<0w)rhP's; >W*jijZ5D7ĝ6 wP&xh;B
-r[K9HϘXݵ[bah*p9(cCjxlvaGKT448`@@:HK 0,$;ET.$ 69ݺXVoe2KX<DF<وQ[pWJG\A^6pK*gsփa.{u0eI:OONdy;AVӱîck}G*1h4QA!6L0+9 {NL<"%5]rFKW";]ZCxO5ףKtBqxA k!„w۰;CحOز{&tSCl?r,~?x)ùfa]PAk¬dvw. `dHl4RRĦ|EXpm"k"䭥"mEld^Y{eiX!H*&j^"2n<r}@(t+D~C=6]e~hyK'A\=n6ۉFh/.~=o.RBIDF&ӫbW\a`rC2Eu4f)@|cvK
-j=\BLyP>(=Lj . aq0 1Ckm%4BXtH8S^ga}AB_AfQ3Y§Ĺ I)8H醰:S ǃI_j:'tCxHi3!71\FVn(@5bF!|c5y1}1b=[{iNGQ]Af>4gÌB3='Q> Pނ]?DZtwM`-j2D^[l149| .<8FxcmuU%> LhY:(Ѿ) Gq^' lt )`LXC銛VD,g_[ƲT㥼t`
-::tgr )rGW|ዳw˭}GǚF%]̻"^9*߮'Ѿ| =(50| k0*QqZ<nktb)IFHXrRgqVѐk % - UӤC,;DĊB%O:E:Eq[rZjqx3!zQ0'~~K,C {"6*&bk978j E\عigL$s Ro9q𰣒1B
- N2 XG `q4P>S *ˈڅtP
-` Ⱥnˌr8!j>X-Xjʻ8৽' l0?ucJaJn1~Wd'oBBHXˑ6cQ !SyvʎyfbvTld.@1( pSJH)hϨ9H sÊ۹Gd<<V.csӉ.c1SD!V{*xu97ҨGdTS̻{f'_oZ<s3'ӛ5R z7Q,[%'>=T#+af}Q1Щh
-wIj#~#gnf V{}Xj`. sH-!&7O#~)bgay6
-@mcvHn6Ғzo=.K^_1wOL0:+ظ\gcG*
-)! !D6%Î:a2g`~bccc
-b}z3JGZ]#qT|
-a@|j'9cljtxzRt+K;sωdzE9,UrK=iS[`usB־HMO$ OĎz7l`Q_8*s)Xh]+w=vm 崐W7'TYa@e[$̹@'V EףBTFb1$aZ^bМxI%wEc}87 aeldxv0F'uu@O ;a34wlG,o}ue~<f~NeCH%֤#mBvM؜UB|02dV_{,6J(ލgG: yb%H@\=z>ӫK8Ehq\9HY*
-[tɜA"oАm,)r6`ycJSO6-]tИ4&"}e5O!R|=F*CҕdI2H Q:\Xg@|c+{s=XKƖ> $Y\ZJ!'¹Q䓴P9WU(ӤS+mbs2WX41dΰ!7h-:)AظKW#ĥC2f2;<Ki8S;!vXi#ު8l'nm4*Q/whBYmZ8Q_kȸiϸ#O®wk|!3%럵!q.d⤓
-V!߀9d;_ꙶX
-
-Ywע>D%N#]>dzmij8z
-)k9\@qi^!Bφ+#%1HP
-+Pd#⨣Ph[yTt$A4lb˶ni;O<GB_I5Uj2jIG7FMT"9=靶
-Vf/Dgd{igX;sO m!y1j6"E蜨)kױH_^pAaJoAၹ+a9먘EiuڈKeu"#ڪc˝ǢgH
---_y5q[kuCwm̮+'^@k|suLüuIV9
-圬^1Eby؊X6Sc.WΎA96EڍY,طig#,{M{GX {jg'al|HpJBSBeR
-m(eV1vMlT"gBLo{rF:[0NiH5rrj:h7XAyZ=,L'&Ҷ?YܬPR^34w؝ YGc{.j|HyNBQ⓮jgE/ s 刴Ez&cN 酡8$;?OH;e:NꖾPb'3{4Pt t,%^/qw"kߑ/wx8~~-sbV#&OB[=qrJӴJ:[7ew;߹͚;/}44n)E^ًϏAk£R”QGYB etTn.sQC~Յ1Lh'tgcO64/]KdBDh}Q
-8|_lQ|X;v/u/>7q|4f=b抽 It=w i|sA(o\bٓ]DֲmIu:VXܔC2&7R4PN
-P͊Ч_mCzH;Lv
-T0h"[Zj$DR8"]:jרN3X>jN:$
-p'7,YTy-=\N󠝥e(jƃjSVS,%֣g,?va--%ہy\8
-@FϾ
-k-E\Arrۀ>xPm|F t '
-hsn1e 6簇1R|4hR\I
--&aErY{EqN~,8[M6MN4pǘol|{+]!U |2rlTĈ cb{@_|#zb\ejU{~HBS}Kc$kTg5Oa=%U_<?:JT,(<eT>R⩹"UfpҰ*CS/,p
-$n x
-XMy߲oa4ubT>l.Rbc̫КUx E|
-&Q99M9@rYԢ8{gmhm~rI'g9+{AGkbѩTB`tPF/vu֬!j3СVa փ-<L89vO&qڵPd@#DGpmľscfQl@5{PCӧqE~ $TOм%bģӱ>@  ,.Bž򼻋f1Ƥ3灥Dd} /ңkBĿ+-gu&+
-+EaT&2﹤8I޲xœ'P޿{ϸM
-$GAP6|bGf&I5ko/Л|p;{ aGu>3|M 3 9.;p[yb~Զ1MV-;K@O lI{'aŢW.rgoH?9WF8WSxL]h:S=aW ̧tnQN>7꼢fBp(8zA8sX{F'EA-d3/8=uR=1BuɽҵR&V<5BE6F{`
-^G Ov6)f&c+tA_#{  .ƥ㳩&8f>d"ӸI 3gs^#aKOTcM:;|aaWu*OeF;}80GhFM_z|=_z|=_z|=_z|=_z|=?wl[gZۤzbK]::sW{Z`ur<mo^\oko[y,7m,NכE^:o΂Ezsm򤅍mK K-~yK}?o9,Z^p΢K9xz1}{7qYgCLg޴z#cֻyr-4.zi%u&n$_ͣ8oƑ<Go<=#=Q9Oo^o3yD\?9%^Hn;ql[z5_\|=nullzHt6ΞO~.X`a(O^
-̆u持Ș˶kXF.οڦ&xXar49in0u͘ML*k6vӒ9F764dL2 Kfʫ%l3%y f9ckl14v޽AҢI 2&Up @/% vfnڴ3a(gMh4UM@ =[{h_p8%?% _EG~WG(hW[#b҃|g0n(郭Oo 4K+TrFDK M`kY ѼGoyFn{ Eރ\wFPZȬ4,GIq+&Lr`m<AA=R_};3*a=qiy}p_3-nA)H@DM9ߠI t#>H((,&M ĀLM3%4"2Fj$ck!h(l=%?s- gAX:D;Dm) YMQ  ùClܵ fF޽I])C92Uf]Z6鰕Hp [݋UbzK.AEϨ!i _.6sRGHc!z iPIIJ7;p[߱"7sIkĴ Icë%(JX%
-.@ n}/ծ@&C P @w{FcqdDDPiO0eH3z︧/mAC/7hh]
-V1g|Se.i'2z\p42cCGGC!sFTb@$--X ʷi \y~J-|7\-:
-AfZM bwhă-TL2Z__<DFa.yKpb|RᝑhLV\aw{Mԧ_ B
-7ƃ q?@n4 9Ĺ^V ٟE L~`
-d vb_ @=7Mr^ cONLv6yKi+u z1o&%M ~rV(m{ɵ .A8{Q( 3t)"<`qԞAzC~ݣY
-Q>9chs#vCJ@pw.%"NmGAl CYchs9)JŠИL4|ż&1o@,#Roq
-7]4I%zM(ß 1gft6A&=S чs3A䎆`v8\P7x(@ M y@FϹG@\ LJ
-
-0;$։[
-!w&(3Me$WQXi\sc-;k$qqh
-:SFKWpU dޢsH>l's֣/i@UXħ\{& oF {@MBrq HT!S|b0 nǜɵ F j+l #T]dApqze,Pl
- 3 %sH}$6#9%c&hPL<|خ_ob"_\ v>1eV;{9F|,$E:D
-ڱ)fq#) p+1TZ= &
-'
-NQk!#w%U6R>"?w4!le֟(Y,rE=! .v_tPܴV([ "2FWB!/D D\K^=C?=O8˺XƠ02Į0)9㞾"rN?ԍMb Hu{[퍜dU W=3(/& Bz$!ul4y~Gq[`_&+C;#i$Ԩzh)hQ @v֣,S∢o}2Ph,|O 34Q8p%<'~s`њ>jHzd}Se@"-Z
-$_jJOS}G)J$͡b@hxd*)yuנ"+Mkll"(A rf7uM=CQ_D9?1B4v9|Kx!N gf%/VqY sa".
-~cs+!LG۝<LHb'9zb~jiG^}{)%RG i@It@ti,"Yi,)?U:|q&$X;}$dlC9o^O;n1xl!T6! aO.gTy=HstA+
-Z >ELFrx޷ք1{PBIF޳Hax_.C[S-*E՛ S삷 Z br:ag0-wF!?ڔD쐒s03;RQ
-pB )qRA]=r,% /Ty:͛k 5|5 g OςOT[ʥ^%æÇ(HmC )#ʿ>w +ȹ9\܉[ 4Ԯ$=|@q$ Bnl
-+I)Lrׂ5bӵAƀH&q +.&%17o 'ٔƼsş:0ST4Éy [!<1XO
--@I <@p)B.,>Bm$W #Dآ?|}12E|9oB 8s'_| 
-vbw3$_[ZwLe<+`%nB]T '69Wr2*v@6ݴV+9@
-ȁfX;h¿JzG$5XG ˕[hcmG$Mw'O ]%HIQ1Gԍ@Gl
-e ٥b1zER
->Wu"k?{lM,4 ֳyjB[`A.K<D)QOž(SBx9j -FD8P$˯_!&\C=c  h_-/x̢G4.M 6޸]Hn؅|֮M'>V.ifvۤy5>Q@<ĺ k.=.etJ:@yw_꟢+_bJרA~ؚ|кG
-~
-B-$֣Lݽɷ*3?.J׊7~viQA/i$=.0R?]]G*ݨIdۗM !%;RA2P7djwqG +/}-Zͦ_OQ^<=Ct+Q?1
-9=<ȩ!2/+ kE.خibjo1eHޯ<ȇ)/BuFYܐY&ⰨZ8@,WĨa  LIsz!j!H
- 37Vty̩؅f[ja %\]Co輸״>ݫ/ƛkЦ_ܴqDg ?@a!-2/󮯠~Ne\\e_[ H)|}~Ajh^uTJ<qf>_l
-~G|*v#v!؅۟bY+-I.քIgjs- 5CGh5J<:+\{m(ui1$!p,[յBr47%#*1I#!N
-dW3b\Xq.`1o%j
-\;5GO♝C_bѣBͅt? eso-2χ؅Ck`ϑ*";et2\4%iu1Ci= 㴆]w0Q[Q7sk~Ic3Q{Q™t:aj
-/@."z.sK hA
-ˑ<%% 4?)m[5AOCz16g{H> "5AWJ,kȦݞ
-},RGY t)qJmC[[w|2S&qʤ3 ˖?_Qe%yk{|Y5c7cjtk]' _PD#?\
-<Kxs
-h3}OWC0C"%O:8Z}WP&a
-HQ
-B}&tEiXPG fA\whӇ}ػsT_:yj*_a0ಘj}3̇@ &y_:*rJ~9{ օOPX{b͏qc:{{[KabDuYh#Oxܑ`*=!fpP>f0t֢8l
-O +QWL )~2,ɧf#g0UkQ "Maj=G˄ki] CMqniX+7"=f 1~Y/`5 an/b_o5-v% U8н)b]96M/KEg|3GVD>]
-H}#t+}&M?~w
-;Fݣ{QPGY:쩷qڒj>!>t<vsh)H^iA|,p1Rq=B
-Rԫ{ATz؃xq[
-Q\
->QI4/ ɉ33S7b_R|%dOLP&oa/|ՅKbN) 46W&uGԌ#K'PD♢Olt5jDܰ/z~u!byPaOXGb`lهSL  !Nce&YEJ.;CYq
-I#4.*;כE-+ݧEQ$f-:*ɏ-F #ŝɧKk>b([VN"U9Ц4/(^.}V.B+kW4:8-{Fh3;7 9<Q/ۧu@n{xګrhwQQ#`O2|pi#.ͣ#~x"xz<|.0O3}"x4z`\]P~&;cogφG_YHןK7Zwp$F>*KнA̒өBy|iZ
-:qkyܺ\̻
-/{P{RQx3bʕؗ(~F4$؞z~cȕ[ϕ<_u< D\yJbem?ski]O9?SQٹ+n_K
-WұF;O-i_iyaǶlů; +_C
-kZg!zOo|%d?^0_TOMכQON!h6j<<DMOv]Lq7_[Vn/1\@;36Lo
-c/|K%JmTMʂ⧛ҶuqU^?[%k7T!? &\\*p2 eΨaB֎R!*b;i~oƟ~;RVS{s;`BQaYUNss#c(?D~Wc'3fN=ʂ?!'%噦mVWkvgdOVZM`s\yKkNئjBu^*6(VĚJy5>c~e$?a'#űO&*[^+73/G54[{9j~5X~g^v߬W~gRm.ߡ<ޠqUo6 h\!HqR8Zɗ_`_|V-3^Z;ުunז*H~Pofv1_ڀ??b]|쉩f H͸E!<f@,-{֢ղyW閛u;IeWE/ܻOBkR9v|~8W4Y|"A՜bzʧ >J_
-7_;J5;k-XG.[>W.|W^VlpLv["2P3:2U{,>`ky
-&[޹-TtmduK۬īOW[\dE~{J]ʑVŞ{ ;m[m;ݹoݸ?;(nVq7Kٵ_ܣWn統qb# k[q0],SδY'[xkPDuI8G_cYTp鹵㟌#ӝsT_mG];\.ŕwؤVT|!{'N 쭶m\s- cKͼNn˗Vqf6P˰I}9W?m~
-;u{_ݣ,xK97G3]_ZTe,ߖ%7:'UwX N͇~ҕ&g6Q4XeۍX7LD7^ߴTvSyo6۟/?^ [_pEHjSU]˳3En:][SyV7IζIr?ݸkmeUXfuQ|p={ꣂJz[u$KvN@[vO'n'nVZ{Vj3z孇w,*^-H8o״ؿ7m^|z(U1U|+k^&^Y<Wkb%'cKscݫd{;D~wz}"OxNbgyn#7z[KթFܹJ~_oJW.<swȏn$?#N<Q5Zx˳E_ʷ}w-W8Nꨏk!Vfn{{5B|O=ZKUg[~}|!kߌPv +'(J_d07oC쒅\`Zi wvλ6oNz''omd`ɰt;S.Ϗ{qȲ&q?ڮ}`ӛ;mʣ" :\n 9A',?JW~jdÐ>vk/Q}u:\}{⶗ײ>g((+zqa
-MVv)/t9+e<9˿qgv]w^(|ۘ!tI/c|٘tn87S٥
-3gܫ!m//dkNeIㅦUJ݆mst+ -Ol- oJ)^ZdTtgo>فlw3,}鱿b"~FBٙ|꽅\kCsOv(C[V>)K?)r/QQŲ6LY[$\xc-Yf\yʝs?ʕOj÷Thr6I|e6swkQQ䓤'IE%yQOʔ51绬W4dT63e͊N|X՜L͛{Wkg7{K-v?n&~j2ƥ@G.GJ]ٚRwyÿ965ڽb}&{\a;RE)wTJ_ar#m*l+ת΋zМYY>$ =)}o?lNmxZK~kI?Lm`femhVrm\[Ky⇦Wnq\q-cYpgߊ⹮O\/YoP۵[-Yxſ||$M\~x&z0mx`qK/&gUۃTwaM)%ͱeګm{y9[^˹_Ϸu$ǧ#37qD
-. ˎjHU}bR-?n{p(yUytaMU˽$ΚLnZyŻRuL:Vyutk(D&'?VY?n>sEQR_6pފB[kgkI#Vo_x3]Mksק}۲
-> /r*Qw= u:^ޖTќ$D}1  8]{䯾Zw&( u^mDc,SGz-z"=|->hcnk]'dץ4D&%/߄0ovNS򣸂{Q9{Ed<"U\V[HMcn#F.R$=N>H9|KPhWJ2?[y?^wzYK`㹊?^v0{.w9̼Ć܂Y"rܛK<Ks۫ժ7wRl^_R+ߴ*_&)۟ ئ8o?lmj<ڪ\۫ _Jֶ7rO7޾kL:mڬɬ=ⱟ}ɼOoF\64mq… >LG7x2avҽe7ݒnn}7gnw{5F7F%Ȩ[ڒ6TFݿoj}79v(
-|UUST(,Ϸ5L!Qhn vOBo[R<Z*3|
->w78ӻ9yu6oؽ:,i|YHSF\ٮ@u+uv<ݞ4Px7?'6 O~\%-oaʁqkW}GCrL}BnyM={aLLC|_g[֮ N Q_{yNhoCޏȱ}Ib{ yoW'c۞Oq }
-mn{#Zry]hSnJi*$ސxh_v^^e2xv7uV40,YYd53oя%yKL@voPTZLYneߎPJ̉&*Ox&U}.*H+,AXr",Z!׈~wڱN -F>/6VYk(231{2]f3<3~FYFd6KUaZW̔㘱1.3Dft/=f\)9qW2Mݘ5#7][OmݟݬF޾q&0V_ua99Qy1 Ea wr1 SߏxE/Pܦ6=)d.̠dӁ?l
-<4bQ ]äz~-68۽ Udѓ=F2:
-Qyzhq27ՄO κ[ېX''s螎$?ۓU񏖎̴1ӈ#sCJ^f
-=.lzsnH C Ee~V_dF s \S/cڛK0GbEwSeU{RƏ~m9S|%.Ȝ7
--|t+&м3CJoG2O"]hAm̩ 9kӘj|]PH` ]2NÉOKbf>3df$fhYhM̌!7W˿DpĄSm凫mjc._YJ| 0>[oۼ2ӻ=3n /`dFk Jg<!^ 4>3zB˙1ÿgF\[̌Йnj36`3 $]L^YjY@4n֣I.ҀN\*$ٝ"+:ͣЊ !{67!ZS׽d`Fi1C{"? &OXK&0#{Mc 71p3z:imf%2_5Fx}#(Z|Ko=Ww'aPyw䝸uk|Hݫg]?&|D|/#|?(7d_Č]Č3V=3~)3f3f)3jzfwqS9faC`ΪsW2$gQr'65fٹ5j3s{E bf=u^PFߺ.sJќp9C ~/ =>ghd03Rs434fй?1w0ّ3vȌ`FO3'0#Ggf\fE/7붵i=VWTx)!5
-Iϻq/PaPM~y5= *&5{rb՘S6 zy{=!Ìό85lݡ[ƌ5|3bOMbMs]q̢m't55K?u? zjD[dd= *|X1y Kĥ}kV010-!y5̹ZsAd >gk[YBs5IcV%nwk}f:_LW3m.jHȕٷ5^{nFȈ{ϰu{R"vQ{/(vAXkU ґARl ņ]cXc&{[v.9g=?Hu͙k˘?i^wȹpin\/F_4tӢw[=>3,g=n7{D*{A Q䜆{'!۶ߌ3,&Hj:̰K9iv,3nI3s53ֽ4qaFx2Ťq=cxcX!p5?:;\*|x j 74]!uÛytRÅJ#CLc)͵#eJb#N Ϗ$9f@r~VNLQ7GI@{|ǩ(f8f"fL`#3ʷuإՒÆ $}u<n熺5+t-ɹ}q_ɮܖ7OswܼEicoߥOdYOӗd\'c8>MF0Lc5ؠ3Y:f @f_fP7f(OfЌf2jYGMl|d0d-,[ϿE=^[uu}C'[vF>S{mA^wڿUM>
-'yָ\Ha=qƌr! N|Rf`?IkÇ,b ]8 reV0ffjfL_qxV3Z.8mˮfy4(8UQ~aM_^.zhK%[7~ S|l :N+I_=/ a뚫ٌ_ϫ'Y^ҒfYC~d #x(fg3%;QŌq rT@̛ :
-f5CÌsKa0ӄ&yG&꾱aR  ˣgkķm길ڦ'C~c͛9_ʮk^9=29́ |ؙNec87\aɥ ! 6?o~oZ<{/4L\~C/D?ܐe95OvRk7kxy混}^$߽mZaȌ 7=ُL೙Q̔S>3seytzy97-j=kf]Ͳӆ-=hpr}:}a}C b w5"gy%sm
-A,cx"'~be.3/_ҘA$  d/Kfqcf7qg<ۆ9n-~on~fo.zm×6"_ !ޥK?]- {Wƫc+/K|
-lI+HsP쏡W:1O`SUC{XL=*f%LU3SӘic<3~3a'3e媍楞5?ykaW5?^TKo~ Mrs RAP2&JK_]꣭//lUpmsJew6޺VVwF;7U=<#j 3l\f fW<•1|fa\k~jA4[borU?f~J_
- *_ : _^4x|2/+W}yʢէ A7oc_hHS_i T0bDXnvC^<JϴV1:uؒq1ȅ7UM5KEy뾲]nDloo ˞4Ê,jlUnm݅`p:epiT<1^ٷi[+SXc_O}u>v.M'tO>6Pzh:w ^Sf)a6cZۦ ɳHg3f8/}ot)5+jH
-! \M!@ξ5}kS4H M/*ˎ:(:sVGb, C*N8ߟw-|NRob&Wwn
-z~p^5ռЇTg -n5NO>C\}wFq \?˒>&Ù;QÌLf\zѡ~۰'bs;,h|O6o_^1(6R$0UJ3Wo9+|\.=~<:GaòLc 76֖ 5̓}^|/.]}FF޷Kxp{qw!:S9U{F_B=H̘2eK
-Y~A!!k]_J_ޕo3wL&0),+okEtd=i U]rસh f8凿y}%rb݇_b2>΄r/nwZ-8C^B6qUPVfE)̨!4Ft?ҌkBx6rPs) K|fг}Tuo7ޟYpu/ſkūn<-Nr9mQ-2j<_^ʖkUln<S8Zn;-l,]9Nj(xA!7OO|=Wq{]5}1GhָfojCX;1ɝ,J:k>R_[ +B3]B 1͵_>Nb@2j(`0f2\鲳⃕o$Of^=ѱBx9Xo<bYBKw'xenߗs_y)<|ytvLkh^3}<3OX}ޟ
-ޖ`/Nܫ*i#%A-re;ef ư^LXBeTNʡ :ً[R<v\q
-GAG~P0ؘ̆3"̗dpފ-PU|77 igq$68m7a%qy2pAGUw8(QtwVt@]{~"1O_n,wr x00*_TJF 5fBI0+3MRoęlv9WW2WezKwVy:EwykW-3s!K+L,6Lޤ u
-ƭJ_'DJ7+R]2A nfZ۰g'e
- `
-z0s\,^!ʎ+0XVoAo-ùsړuGNjkt= sG'm@0
-y&GԿU3x9a瓹"Ү0
-hy4E|]| />R&pLUyc'3K&f1!pBaE}Ob|aw+G/ޗKNn>'7
-eb6 ?U[osq yBn
-DBh:݉a7BˋlWwv?Uu g& NV?\mS}e J-avcK̖.U0^J4Qoa3~:Շqx-^ޣE#'{z2n1>Z3}IhJmHIǘв ҕG?c_k?[eF]?2W'V[~w]~*}%^̭=0+>_>:l<{5ߘvn`O\At?tAWC?]CE[+w2?jz>[?}
-jakTe0@*h&2[5P;7!O%r~TRuO˄S q.cS
-i\և.¹w*c=]jy"#GS
-OZ
-Ɓm}N5gjUflH_i̿R{uü
- ?yɟ~)+렎+P^`S6󻆂GR1w$[!G'з"t
--2k#$2P#kOLn.ڟ.|'Z΃ >N> "Tվ7B-=o?y!?UއM̷yz L8ꃱk3T-Pu:+0=~3~42f:p,f匏 ܛ6Iox{*o_% O4aA6X`|1"4q[/͕:,;%[ ? U{`btgZ
-nޟ7ߝk(¯~Y8*H>"B}^ ؚS\:^/PW7Sƾl2,ӔKhZg> 3}8feR7 4"׮?AvS讁C^3A
-zE Cn880B(4H(mu`۞,}4Ui$xbF+hJOgRf g FUǨw};}p;%'wn1'2TXmVYAA&9
-L=uH8{?+V v NLޟ #>|r-_d;R,;n4 }8|V;y;B>H?+Q` vE NDo"ׄK_.hNm˖t WUfb{Zb5 6˜rZnVw ;d.[,2YЛإ TZnF2i5kN1%eDdY3SU0P;8:B#E뢳,;G76_m_w4h~U}R 4#OT꽯T\Ɵ~-h<NМ{B<RU\I,jzC{OeN{ F;R~5gvݱ|aulnn4gs?Oh}'=j}1e~歷N!..N|uX,grm|3MPvT4Lȩ[o/n8)mB:9$x鮑b!%8O̵K(og݇^`5J"}INN?'ZqF`%XIm0_~pWznt8)^au%y }ƊIo܄ Nwql
-,㉯Xg'740  1p'XaKġ12J9UeyA,nxH sad t(3*C>·K/@`xa6.3:|jk6$Ƅ mcJvybV{&8H$Q4{!MC>x!gA!+)g19JRfd3:e\T?Xa,NcI`F i5^j)r$ IUƐ})BRéyჩvv=6Ki>
->xKOِgcM叟W%O5<8BH(e+Mw Rj`65?nȟ?~4QEduI&>vuV\䐚dCRT35ṁ2jo>GwTk>Bمe-#ɧg*1xkqdMfJYCNkbNļ: -GƙI*} Pˌk*K/+T< z`i6J$Ò(tmrAJI4Nll\sp2=ڔ5} } ;r30Cnva`j<Y9@䛯6G%tSL
-+6" ZRz؄a^*0#ne9*kwVUتBH~Bؿh,Ϩֻۉ͔6 tthuIޖjm!?0(nsV@yRXl<9]}OqStvR&3G<]' f@R)\{hʰs{sBt>{\2 g'O"#Ė[q+-4 \T9ka棐Hθ̟:p3Hgg kk*ΨA'>؏~,fRٶ (ܫP_4\ˋےaGj ] 'X[@AF=t4qZF-MщyRRfFJ-WZ/.7~8v-D&n:_l/v ͵]Ƿ: aڲ[t
-X|ڽwUoUlX)9>Z{2t=|W~4w=q,cĘ
-K1В#OE\iT" XqQØa- l"q^T1uX>O?s_xڟ ;\-DMVT1,Cp|cˁNN7_+}\|뼫麭~"4%#tEuC5'fחɭ7܉mМ6BŮQ$M<*[hbm{IݯnuR𠅊4?fXF k;.چ[mC/g-\P m-w]׈ԵJfШ֟whivTs\ m-qg-CRlzgvwj-ɟGP^ߑ
-+^Gw!w=
-Jztऋkov"RTYp6G}`|x
-6NWI(fm?Yܚ^עC_,?`3˕LNӶ,uS=lO}=DvTg(i(X]vwԇ\G;jPmBhSPmxʥ3lO,m˩9Yb[Кkjȩ|ZS>I."zA_^|o|4^g#~ 4ëĚ}ƳΚ;JϽxZ/%1r;?o=u'_P@!H P{$^oGkNL\pUd)X2usBI MDmZAs=^l]$W=TsM<Z{5PrrmZ,%hWof.Ľ?ĸr+Ƀ /E:Ya&RxXˢJk#qVbVB Loʽr~eqCgi<+B.8nvm< ,u}W<3%Y1=,n?|kBk|#S~4cѳM5>EЎ&Yhg58{a}PʀvQ*g :]0!m|YEyjgE;/7NK\mIurR uбor
-kD@="%I[kɲD{GCS6os- .|uv[$'~`v͆S5Mm#]w<k`qKvyOIwܐb PSd+¾U9
--TAH[ۇ O4ZN$fv֎;λXKS; V?Yέ^쿵Jz3E|ѧ#1w׮C+6l8rxv/E^a ^u|h0frM.Wɫ3]==+v,Ifq=)J
-#@;8!G~ץM/eSjF9"\H4$ .媮1@];Y˭%Rwd6u8BBn<9SM ׶o!PJwo.es.G$ߺL_i.*$qHp홠%OLɃ|ۅjgQOvU,?EmTnMv/A?Y%=YJS;+c‰Ԓ9/㋶; $eT8
-CVp|t3PdKz8ǻhɵYQ}^modBr!&_Γj5Z'ħCM}4'5yd~/<'P1j}ScuDox_a@w O!RWmn?OabLCN/+IܖOKj9ja󉛼?#=.BO?,T;4MYgmje_5jm+6 \>&8[z<w`co8]ʲ^&o,l$׾1bE[B%|ŹЀka؟Ck8/Y`cߣjw 7}4'8g_kIҶ닐Iїvֽ%o4OH*
-z3͸jga} T_iMXm͡Qx`cg])Ю$Xc8MtmSz9>v1-x.bz\5'f-8XׇŘB :RY+=wh ߻i6Ξj8ǭZխrU_]?pMŊG16B-Fƈ4?SdTaFbx..w`h'KLvdܫX>_JE,t&Ju{~HA.8+hAc$kTgkn4q6[5xzttٛS}fĝfǧkH
- oh
-P<3ߐPMh\&@  hzCy yq_EΏXj:MhX4Nn
-:_z~_۲D'tO2:e;Fʫ*>DH̷})sH`w>wvD|H{GKT; Z!XZO쳲9_hghgɛ?#6]A[I69\}h uyW;FQ=cgH[/ΣZO_HhUuOn=jOLt>]wj.{!*L=8kwyEtm+\Dj,Zk;>EnDre$*Rh9|ɫmͲev|j D.z(HIuضcauc`]`T4RW4]6hnGDŽ3t;W_&XEè %MɸA5Vۈ4G8:^zmD4坣-m!\Wԣ/ljRe ʮ3r=ۤFCOul;z<n#m86kڣbeRp)ܿ5E CtސŗZϦurݩ;QQ,JTI>2GJjg9XזryߎZ BzxT Ry5x WA|r۠;EXCj;K5 ܵOM&ȇCO]]uLRϢo ]_.#3|Ձ%9rt^7)8Z37]Xn֯4HNM5Ww9BwK$gc &Q 1KKzQ-OY5Nз%IT}f9s ,֢83hmzjj?.|0kbLK62k*(^/4ZFBg k%;<&$mСpiӅܒΣ=t?
-c&q4ڵyϗiRJk!i2`_xECfCtk!՝>1Cl|횽㩦94oIGs>@Su4gg󻞸sM]oqeV4&?8 ~&S7Օ:{BĿMpOO:y&TS*Ze< y2ŚDe6 DC^{&~ @ۿ\$n8sK\$x {=
-b%g6DΊ>%^B h֫nth ^Xh=X NL
-D2*8'VVȫ]s=zNӬ?0kQRbK5HF嶺i<73
-bi+M`O_`ɂ%yh'[aRnx4~ u0lz/4ȠWwd*[ NFw_NxZ/v^C=ԪnAo{~g!|f=%XT㱛v5tbpj}Wѽ'Xk
-BrǝlMf{:$vv7nFb={6ɑG`͝=c,3Vts@NH̦A2?e췪;Vz0zləb%Ҧ.O/+F
-v:r͟|bE0Ǥ.G~ \۵\ӕE,)gYhKᰇdJCW[i VZ$wzh2l\ָ)MRVQ_.$>u8]#57p/S1AjA.;$oJ Զ1Mm yZs@O li˻w
-5[vFIu=GЂ`O={%>EnMg'T[:XͩOp&yŚ C1ǥzO:WЊ:;c rJyl@Əgb
-ϕk{zb0yNYُ+%94;N$6Vv8hQ2ܧ]g: u:?l8>^w` B7/EsrmtE#h\>:jsMjdD1=7{i|؊N2N%_J_H{ AGn,tzHH#+mtx?x?x?x?x?ر CSCmDon>sUR#SlmOwKI]
-δe~,Eg0vSW4]&ÒM5$.TX]Y{l:2=&[RYmI~HRJhEfo9j>VB>?mh$BR"DfM8M1HD
-f&DǰbJ.4DJ4|L9B1oIy=U͆0#-yU&:F 9Hc$@ϽrX:lWAG(g~^T)=J*h*U؊u:{!w.V)К2;)&(:]L9Ow@>5chcA`VE)UF~J-ڒ] R%9k
-K _ioA紸_Pxo,R0l 2jHe֬h u }y;!F{FN7tIBTve.ZV767R[7;Yr;k27k;b˨a?R\aiJ0 [k7];+HvL tP*II+4g'R2tA+4UmABW< c"'Q"dlR`NJ}SKl5QTy5r\b9\ >`*F&$^򺪃55Ǧ26 |K9:@"BjH;JaڢxyrӍE`
-z(BrZGƂ:N%Ѡ(P%<Ke]f+n)UVf]$x%F;̤ä+iK|'|ӥ$V%cjʑJ^i(3~bz>b"3Ȝ7RrzU|?Zň^+A( !ڈ9[YJo/EPRL RX[l"iJGblVo2+Vd?hYJq.e6>Je.T}v@)]p6.12%Oǒbqd*;tR^z
-U쟠pjnZJq9Nn"k%>LthG*+167:a3~Z*)9]=357ukS+iRl^1ϭ]{kc@D;:Fj [_ۉ~ɅrQptNt#qS7A+12.59n&muo]WAwd,a!> 2o.7!`W
-_ŀĊy&_ϰ2y=I|x2ā^f6t og?BdSh->dyi._-tGюq~e֚ څ&D?^ 3֠c&ؒ I6PI #ٖ#hRJ72*̳@7r:`[r,O2p0yI+E䰌O_{&2'/hCЄkjߤ]s`|.c(XbT"
-7JX#04':R5Mݶ f cpB>C)9 TLF_:`kvYWw.a.IN*9vܖM0Wrs,ѥG}* 6pIdVP"0|tz|FPWcH\XY` j*eO"1FE1@`m<h'TaM
-?)$"79etpӮLj h(=4$EۆS{;~>7c@BPu#ƐSIU7ҘjӫS (S͠#>s(} TVd(mI#:wi# Lc %9
-:![ImYHm lz%w%6B8}բ~5c.{Km@bWµ\~/H|ՀiICtn
-WD;J9̓N,9K5
-t&~TttkWs:AC(OƓ2k_d>js՗_#0K <!>5smi%GA7lt IY\2?(1BrB:O)>
-RRGI㕶GR1y?:Ca3"Dώ||ڵLrHUv@% ǧMUj6R_If?
- ;2*̑RfK/eݣA?
-Y.oEIUw9
- 5#~>
-$J1 1I% 2˜'ZOiUu_F:k]ɒZ1ZB|7!u{J&uJcC aBL&$/f_u}(~Bh)dF$xe-*RL6!$Z!iJaz dz#Œ:] UԸdU 5":
-6 vY$y`RR?l0q
-sYJ?,[<A)%kJ]Ubuzww"^CG_u5^4ANVoe:P4q@I>#y5T (5Plۤ>-}$qӏ!Yf(3͠
-E9pjFRゾ  y՟o E cq
-*B7aÇS>E|lQ:%kOEA &z/m2@ZA4ԇ-+@*U'A[}$Xjsj{uChӉor1U=X뙔P4JS{9|sw~˨cӵy @3c+kn"Ua5g)o`BLnoDžm_/4Uk [{r&[n̗?pۿtVHJqpԥZ%OJi~Lu'&Kg de.؞zU u?ǯ|COѹI<XOʤnv{0?sQӁ@sk9/2 ]N sn,X)kj"
-z6AvD[UN@i.]̫:C@OrҾ($%Zp~ dwvXc˂ƍ<׊koWպݍVlkY
-"ȍK/
-&lФ!_85wg9(
-Kק@~>&s6^W1ǟ`Ҵu'IX 㝳FVn]R~(M<@$ԫr㑼7<csܓ*ԩd\F^r
-}!`(:PB4>_[VEд&v~,u4u7A
-7
-ܹqƱ+
-MM(
-0>~J:`9U̟MVh5NY
-hyqGSEy_7|!ryg%_(򺱂ly&N "c(BSQk,Diط;85XERrNqh)؇ل
-C><|(àHe[<%0.:LӃ\s<Ԏ/$cw߬1ɐdpN q!5PCgS2!0W2?m@ B|fNi1'Ĥ!5qt(I!Җ߿=&+,BFa˹rg.#bv}A%Z&sUq ؆NvWJGMuːǛN 2N__^o
-{OˡF\r-㔡LvoQWs2#$kPǮi- )tݾ7r 1ǾK};En?NF0(xZN Z? @ wh2?/5sQ&F2A&q~4N wc<!}w&L5ǡ17L}&f3R#`^.؆ʏ}=2~/s
-gMgȩo B\ jRdl,AMA=8L8T j6_jWFM|EvkcrA5}⓹
-TȨ]tPzP+߅njףUDD6Pt7U\p7P3%uLrS@܊(ALNcnMx&vO5 蕀<p~ \>|Xxr&9OP&ڎEK3OQ ǀ?jĘ-~S.E4e;IM{
-rXb@ɳab*W+?9^MYM0chg ԁ )>ۥD. V0@z;s} N-gPH'URJAe9< { qW5!585l72+́ی
-8
-E<=q*J=.^S_$ıe\?@aZ/jR*y $\r
-ypȭH4{8;6qo#y)9eI=r
-LŇ)\=0Fl63.JD`nqVI(nI ɟ'J:ba;Q>i+ %q^A A7-c95SiL|:X&ub(ڑݼ*%ujBߏ.C_0=\MبMl
-`v3]e^ j\rSA}jC^k2W P0O.MNxP>8#\vQsA rRg|UKz#`f*=P>r=
-\C!py芝3oN \}೾Z8F*(JdKКAIU{mK)1D攚rpAvJ05۠dīDXF.oQO<20p (K=ozz\L/J3?\׀rkK1g
-.ܤ|W೸ w6
-xm\\O7uA!f.=G>1uh>~hA8l&uP1ҕE[
-ꍢ~S5c_E.N
-
-iq땄"ԮἋ[!;Se "|ru 9h:J.s#zcu (G꩷8=rKӊ3&Nُ%[qP(aӁymp@y z7Sz})L@ơ{:b*:J^ Tc9>}+5􉚺/x)PX|=g5K@ K╳ )P0+0`%pqSO`/L`fP}]ʠj$.F<P~$/rP#p 32l/r+W:1TΠ/itPfPS# T8徐 (짹Xcto0-(LR׽\O4WBP׼jRT@F/DtQZ֭C6pR? uT̏@[~c 9G((Ll0&cwRq*:vj@%sحFlzX頷ˡiYTb>qJ!(sFx 8<C%Uױܳ*NI@Г >/8rKq^I0uLB.n圹n&n~ҡn n~f0"_3%>r'}"~2m@%<k:,}]wVCBtk3v^[*;i;\*gr LBFiQ.>TN'őE22$cwC~Fr3eqջA3 }:Oou@sIͪ&6%"J4d=O2]| ׬
-v&񼳊˥rY+GR*z*
-aԴJkg4Di HxDLNk2] zG=zf>D?޽֝Dw-yLaIVZt_wY5̽&^Z qv&K66 UNF44zt@ z 谢"^90o'@>x7߬jiV!*Pp^/qk1u\M5|!" +.|_dIun]AW,i>rpYdU)|CH&%
-3Y
-퀠Z\uF|*z2}'K]$51_"yYBj YJ _])ӡc߳ xkU6֑6-u\bIg15m(jǹR(xB#}G7a&E<o? ~VwXf)NZdl.aJsoiՈф0a)~y"?hHsj,~TiF'k jw]Rl
-5 "*ֳO9ѧK2$ w>>'2y/ ysDy@|1$0Z$N>
-O?SL¿/D$W^h)iVlHkc@,
-GdG([$k1YlĵiT40'j_h%{Q~F|T+iK3ZIzJԬ'N6bҺ'A͊~9%/VD~_<x8]OAJd|QF'j\&˒Z_Quiѕ,,?@~vdO[QoY&?Җ#tQBz@}LR\o#{pN"ݫ13);yUⳒ2"0uf@SsK; 9cQzCƲjCe7vMl!C—d7skIsN
-~7 Re¶c^h`ێyQ3Gɂo
-_}鲮3Ҷʲ+TV%)ytP̣v$ɜyDZ('{\q[^ M2nvQmzDGCNAf ]$'bua:~w+>+;Α/$tN |+&|"* ]rAa>X2'lfkXKEÆ~{Kj> x49_q)Wo]C!_|{I]E?^#]M_3M< #zUvue-c"k" ]Jl%/kNH6&VIF8$bL":_UM1Q͂(W2X+Sws k͐nN
-(
-.qN9𛓤f咞_i{7Uq 3AK!a}DҀ4YAI1A~%o2k)6_i>).nYZTi--7ʿ*~|AmI^9U%$cIi~YIAYLMRv
-.Gl&kB{Ⱥd}U뢾Fo悒?̈_,_R>^ 6xJ?UZv=|j*>^u[<"*z2VQ'~`i,,4T4ʜ~&a~ϻU8$iQv "!hO˼jTT\V;ɚ*w{f·Q^E=%-+u,\d6`on;1g.F]
-;y5#t /qrwCH~&vL[@&|Pn 1z v ^,0NB 1k`і'7-><`pQU軹CV]bHC=SDQ
-b %uNݍИ|Qi}'5n3)h"fuy^?37w[gFm"b޻yx j:$T`H~NdFSag¥nuem!7|F7 XsX2㻶0ktEYyӎD !U/Ѳ*/ˎQGڟFVZ\$t vV'LO~7>&w' šoG:'ؓOեWLTo6NaQoɖr
-(15b-FHTI>>~scB0'GA“d8?-| ( ؕb7[Ӵ:4MKS!o|Ԗj=iZQ"-p=1OR/\˗_O<$G><9"ZQ+Pa:Xr16ֽ7έ769ң7QR|k;oNpzxpKxZ<>vC^or0^>.GyQ% 'H /I7e7S̭fF/ k|v93\sjq'K;%
-k~%*~56exI][S?kx8`wns.<E$ɘ` ~X#+?gh۽OC=Дl(I+w߫ ɫ
-,m_TeTPaTRcPYmP.*)SjVWy!)´uxۢ멜)'C@&ŏ;n|4jJntRo㢴Ot~pJ>R=.^ J9i'xxל5&
-0+wx9=`0ioGw n v _e'/*h
-|hX?YZ>]bsXrsX|KGOS?`EĒ]sf%Ůf E!ⷍgDJ$I(yvHZxQRc/ҚZw
-Djyyk\z ~-iXr1>D8" C$_vg4:EFԺƞiI`:꜏vdE6Ƹ{GF:oWÕUiӫ+baY%Rc홡->&YuUQ~III}
- yUla^^偑NUqn>ޱTgVodɯ3:#<-̮.W\\`coYCP,퓍|3}2ϴIgmDe]k`zUir>$)~͕Y/=Qg/?9?
-]Vz24l}|crYOEs1@W%zAE/~9dTz)=tsFYz_y.~՚v;q7̢ܤ=n<xPm{As} Ӻ׬QFOYMM7ohR?y#252%̲Wa'kjJY~+giA+{{V|r'|q0la%Mˍ%6fUZW&_M+siLvWv[q]\CJcUHMedװoC꣰~)/.ʎ]T{-=*a/nľ<ز;'d[FȈzH:ѧf/-0*b 09OUw~?%ZwDR="GOɦˎ[!tScCtLchjNWB u[Gy;C8C||A_l}VIu`%*¾έ;BGGopNXjCDQ P&x2_J情rA_jFvQov^a@C[vE*;M*hÖ=hڠC0+OhmVE~iwt(
-I~u-<ϰ7y`OUN7Gz{<M*eEb\X#2KX& ?n1/()oZk
-f~4\7g%/F)Egh&9RƟ='F+
-2ŝ)l<4ƿ5MP&+A+y!iТy[ʕhz .*V$=(zY;y[oKm+w /VR#..wW#_ ?LNtruQt9?>Cď>:[SS&:ܟNY/o{ԋ[?(Gf-F35@84Ac5 #eh4e~ kvxZMڴe[8*ntp'joT[Ф|7BW9iaOob,Q(S\>8%,#/u&Ku/}?H6=ݪf;5ehHzi5(.]&h4F.E> )pxco_)rm$FHoբ"Wy<w<Sjhd|y./9N!O^;dyI1m>OzOOΗZ#^7z)01\5cz Tᵍ¯J[8|+ ~oF ?ND#&fYS֠u[U38n G5oZ54K(1EAn~=O6:dsGoKUpc7761@g5^H
- xMӱMşj0nuan,{3Y\Rjy]e4a:z<d~-/Bd] xcYl`_*p ||Іb2bo, :XƸ=!ZgvY)x_#޳E:hs$.VTf{$?Wؽ7nžD<-rz1<79K<ЀwrRpkaiwo:ĕ^*w[(_f)Llp *OS"g?aG⟏9}a:BSF,As#$zVio79į+DKZ(3 aˀWb?Ԅm˔3;c^_c4uck#-_H/?{]_߃*uX|IC>HϵɛЪcwGhf
-YC-U&^tCbhMK:EN1M.Mcj_u
-9,#LnTqg ۷߽#hn;S˅h%Y;lO;3kyεawss߸Dw)wI(-v{QSP./ ˥/wyx`
-}jԻ<ȲBwN9cC|?콻\U_^&g9?2'}T4w4o4{^4w&^,@#hB]4o9]-޲%^: pK'Nr"g bۇ:95 vWXy'uyC>p $4Ca=v=e=;k/ZVo?mq4w]DY4kPDsp?[Gj'h~`C)OyZ-kLqK oJ"*"kl#jbkJb
-)M]}J4sZ|vSw#ii{[a-EOzh;e+*FÇnx}YQ.!\{}R[CB[KxiԲ{_ZϦ*FS1Cj>s-@N״Qьk6U}c4Bs6*g}h7ZDdhLaw3TKٍToKn^!1k{! qam]mvy竣C4߲fOo_ =DJHiB9O{!1+?{7n=[ܙ{тEZ8Z
--rFK5Uk4_iVCԞ+yQWy!A]z_=9/) 8gˮpyHWWKg^op)c߿) _l38ۜߧ+[f[[}#&B3cX)5G,'В=hQZZUQ;n]vFqIiKI}CtWvk+s ~Vb:Smtm|Y]l\kɏkV=_d 5xgstşҤ^)6`;i>]#ZHiZ9_xր ;oU+M6lqݳ;8:j16\eYc[gJ\wcBG=-,ok?x-}_RG u:W L|Y7{7;g/-)hQB&Gr6<vI?+`7iw<f[ӶGosyEO߸ J`Lb~Q
-ܞ_,54s&RZa;h qo*n󫙸;_5O%u_%.)*G׋Y'oT:qg4?a7a| k1xR͊t|J60(ZAXT}^F俩30?n<l.ʞT䷜~'"DM8]{6uB7hj3x L廣5:к=G-$ZFX֨
-3l'vݗEZU^kb˚_;X~wU훕[Iu^|[R֘WR
-\0pic>T;}n*L݇gǘV7ת؊R
-pU T
-%  k<"t+ᗳZN_\ܬg^%eKw2Wg3ϝdR>*f7l04TȚʼMn]]0W]x6H6{ 3?XkENvn6]rd5-920a m#*D=χOٯ{F
-
-=m_]SGf ŃZwvd,2pԛ9|"6?kj|;s1u}[ߴmQnH)lCfvQ -~\V~ЛnV>([W1ngwjFzAP50xbMY?S6<8⌢ɁӊzhǪh߶mHgȃF M}_vs |oIϔ<ϤeR{o%x*|0v߲HUfSNaJsO(yA[$ J?\"yrPZY}wl{AB"BTϋ,bH[3c/eO:1^! |J)})T3kD;TѾf(LnRuk,!x&OxN5],uMT”&U8sͥ k_*xD`0<F4
- +1jgux uﲛ XPU!mc)2^V_ /F{i })VEjk =hD}HW x$,N4sI\bvc%<$u 827 ̳*n|ڇ$R&Tʋ7§ N&k>OgRܳ.61J<3q"%f0O虵8nq _UMJ7RTn|al3ԤowSgæ|A&DL^
-b,:4LMeڶtڳAsGu ϲ,=%i0~?֊fJtQ@eRNs}\J4ѳk okfšģ|o􏪂_Qz((}^  ymG1Lgq.3zj1tQgtQg.M6fϖI*-lG.7&)To=Rx5Yީƈ133`n1}pEEI:db0j/Ң3 dwn j2>vK^
-i#. q>c@MWfa1KF蒒z͘DN_̿>8C|YEx~+}Vw̴}=+51k}D[pQZVOX?CZ4)8f3pمj4^?؈3
-+D/\:ӌ:j=8=\t `, :MyTArN*KR}: wEϜV=6{YzJ׆g(y6Jj2jwo% +7Êכ؆N;1],89EC-n S,'<lY-;-0 <SBqLLdS̕"BeLJsA dK\&f*^aB. *>2zHAjQyM2:"nWNκ߽ԵDxVN U{K0[O(w'\
-ZR!̹?4<0KsHKQ<(ȟ`[rŗ_:xn1O{f-'N8!ιq<`LZ>#Wqe}ԭ}ѭ۾eD=s„kjpY^){!oOZOCy_.LP'RL2R~RN[U"j7mK֣]6#]#_6LgD!-3FVSa xFf-¬?P 87*Lb~2YfvgQKMF;b]3}19fbn
-9uRQv#?j_02zCsl;u nYAߴV}K'n3I)cY=a.'L2rmhOЮ0^r
-i;-qD^]9t0/!8=L?}y,Hq+QqMۃDG-2Z&J̋/Lɳᛐ\AD duGBAj^"Lj6&Rh/y|9EuDof=89tD?q3f#`$8Ҟ+Z/qO9IFe:P 6ŦIrXFG#idi4-cq1w !JrJ!ޔ۾~㾵֩3#Ygʌ8֜}Z{U^{-:֞O: cG6rEӟtyw+Jų ۶ț56t'[x5<K>Nóx~-nM_3wwUج=0XâIQkHqZvT9tm_uSfͼe}B_kؐ
-;}19+1F`ɡdhSL\^ZKrŮo+O=lT^YENXXc*'9iim=6ۄ2g7}^1NA1
-<Ű#_.dž_6ǰTwFÓWk^csu lyP?1?Ǝ`tspmПn<s޿ޓn;hNYHY8}/ؔ{_
-<7|d/uI[;Ü>z0&Ptk;alI1cR,m=C_qFR{?y[~ 3|^;M|Ow>" ~<BY|Ϟ(QӂR:y_̿ [޼ag.:
-s6a|(c#wn;r=S*a><uMŢ+0.Le71/Vsf''cb,:YL]yӃ_\rG xhrpcׁ}K>;ػHwn, Ƽ7:'vN#~%AsvBbbn&1Z |k"o}˟FѸvB1xijh~z
-<.g07H
-a:#gBKws[,1uЦ@9vx﹯c{<׹xSCm=;&W>aѲI  ladʱ Xڣc r?#rזs0.#yP1wdKWc:aZg/XwbF->bC P.X̧<]7H紆ۓoOiy12ʆ?TB˞\x[xc01!ԾD!ջ,rF]su0m1l?x1QE-wNE`Y|̉:Vdu%AGж`V /8Eao<{%7a3<ÏR̻U9;1w_OZ~Mr׻<ц?PG~EKL9=1k8; .{'EuהW+eoZPV߶|y`VR4$߮kOb@kf/hbgR^y m
-<F:]K/_6o{;l3j0,pV0w^}ESz@hkNܜDxI*a|aLZ_,زH7 u\ZBG^AqAtMxU9=
-˅9B .gjdb|C-b1F`3B~[ k`F_,GwD_](
-aMZbT\`ǦSz'aG(&1u ;N\Bx=Nw7e;XG|3>QNW| #0V39rwql+S)sȡĞ.9GḌ?3Gy|Jh*r7tzd2i` ߾/}G/yBlۼYs`>ʂK6cɷE;'N&ͫ S]&_%RJ2.:.l_2tY'cRe[ΎݽskF0gT_e
-c1o}A~x 9zt@?V7ܹ eR[=8NQ'o|˛bDWZ~?;b? ?{߭<8I,оo¸_K֓)04yal0@_{Sc\8ͧ7<盞<k1`n |PI6xe(В5aC`\w*O}v}d2Ɗ<jgBy.<~{5.$}xOȁ?m< ͍ 1ڷ}rރb,C 8Ťsl5ޗ"<+rO6ÿ>|s]Ƶ;.| x*j2d7={ȺiOs3BG1?|o pI1tpKIw)>\% Xm+N 'T07B c~3%][W* $:&aɔwٔ9"vÚ?S"k
-i]\Xzo9e=sw(Tq!|37pYC4uq& keOTC"+]Haog͋9p]6 |O`/BOF}Y$뇹f}SOo8&B+{qyƸMwmfg{\s=&<aeGuG>Fvv`/UFƺ ox
-{[Ӣ2?rugkn ozm
-o>zŷ{ڦ7}?>F3]m`b 19HbwEknQc̭ 4m|pgE]OnΟ b!|x=9z,[kjȝzT pMķqK&@mZe-
-[-MD|fa21rɸ700﴿ 8?[`
-=NCy eoˀ<?˗J'[&ҷr?TFrgaT>3wr=wVM;eotXf󙾆l;ƽƕ{79[=(Ϡ| 0/ Ų||y+Qgw%OkaC~~ƒGؖo_yIc~0e oc)`]~Q -rg)w'7Fѣ_܆>hP.uWXh$rIF,\_œ_Sb_$ ?ҵG~ 4ny:]Z}uu<?(o̦<,ʎ(&xk<|>(oI0}xоOo5s\v
-ܿHЦВ'B mQv1Wl<N ֻNh|:ڷ+>s O?ڵC.8ȸW燻7ߘ>2}~@.rqKHF\< vz2\]o3qcQ~5{.FӼiضoO9pp}S)l-PSw#`7('
-]wq| u}<"`x̋y~B;ߚNcsˬ"YtU_ߌ3|_oءOǏ6yj`zK#==}`Sp_*K;ς |y3
-=4<5/XAZs4ʝBp=N/κW˝ybhO
-2qI9[P>=!|ƃQGv#xWtV0ߖS>n< u=浘|`ַ+<?1)F쥏?$6[}]d/n< ԓjeLJO5؝yPcKNi\urxrܵ\`Vz`c0ucGQU4}B/vŘs# 3?zE+_WsiQKm^PrQnzk"э.ǜ(C0Q럸sV9/h6ʁ7(3 ꡑ FC}ؠ^''
-zc=vWhقzWwQcƘ#YhjiXއ
-׸ބ׮#>7ܽ<\yr{Rto_O?-l|賿 p&5;&O}_M91-|n{u"{B́z{|?TwL]o Lzkϣ.p)w?vA{='=Ǣ#}0:hD_A9U@۴}XA7$#`އ<59-<aO:ۍg羸s
-?DJ{qh$pSgYˉ0
-{c;_p<ieǼs|Fxi$SN,Ѩ#a7:D761-7'"Աh汄('>}~y"<Ak sí|<iy5/ |y;^@}Vc\6
-s唋g30w!{mUa?x.yP>zE畱?aܫ\_KM'ֈ>@[^z-7{OwG74x,فc昖xυ;5y%G3ҝ"\os
-u Z0șG3V[ iﰡ}~]郭wPc1Ȳ x{~&c_s7{/9xx}E V1C}'G{f
-C{<rЎ{N=MU\ڠ=<kqLu!|SѮz6]C^D|`3F_v~}m>htG= [0fÝ+N9f.A_HSb(w-DW+lG?q.ȿQ[&# &|S+v9)0+C9c`[\k9xwYk&?Ə0)8sbqXtn=3OP/16uHaP?<N|YW
-:g>x.mt0+}['pn?<kxKW+M/t-Ƶ{/!
- 89-]xkޚZk2s<8(֢I'??/ ?<EN!AM<= |܃ͧSi^g~܏q?~܏q?~܏q?~܏q?~܏q?gʔٝmxy)fd ˧4OJfxwgB jfyfxL<33r4Cu:xrgz}"L*Ϟd'
-mW@Q۳.wDj^Nvf**4pUP O9vy 4E.L%2
-4Qǰ+Z;1{ Лw^ޕLt:-cY(ΞL|HZKRs >N1UV)J[l!2v"udgYL[ӎ>CC{ vJǚqū-qіCs, 8dGD(jD;;"ls◙dfqG"|cd܏I.tE([Jrx,Ht/J %KO%*t.vGãQI8UөDbm:?"_.`V[d*|Lmu-1"%u;ޖuNENww-Nҋ1[/ws~Vȹ۸i#i.OCu8vڤX'9R[L/U#rp,@"8F1Z[ &"%se$S)Gm&
-;U2VIOwhiq7.+>)EJ;(Ջ㝝/JȖ_pԑw5T$ 8J[̂xW$cɻd.v+]97:G}vġ*[%sq\Bq&^o8DZTq>|8?3[^2wE w)Uc;ܧA:f?ڳ"|Y{z=R}qwdJg"pCk<պ AVxwr2iGz Lw:Јvgdg"[w{赵%3ɥ gBۓT!>ש1LɎQ)wxqiufs%$یc73+WǙq8S-v:|rLgZǍ8bb8:ΰLjq
-E>UƵWj|`J
-\ڟ#%t 4._;_q#&o%Umv7
-bEZ]Zk{ K/8^`[2?=9O[2,AvE }gG--%g;Yܑ8JIEꔒ$ASǐ=8vsυ,%4wv&Y;3 Q*{7K9<{sv-s-ξg)ݦd{{oO: wWnvLº/Ш#חH˜bJ.Z+Z1xcs: /y<E5_ąL_s72oDs&dg[rQzd:NLw;$srr:w..).9tIঠ[WLjW$;z3dYO1[$ۿ1+5^zdt%ZA#;t"^J^KP, ^
-E9"nx"sa-z9ߡ9eT2SOb>P"ԍpUl"tD]ѱJRndq٪nuZ cۆqժr^oq-;z},sPڇms!AXE>W{݉uqZke# sDZP,3:/WF+0SeɶGwD!>Y㣎ej!=ʨV\= L[,}[
-QOi/(e9"G Xȥw.֙xNOY];؝i_&idn Tgʌc7ގL|iًqxObNwDgs "Ԩ#gh"hij-lҡ*0LuO `~
-&5^/DqLڹN*n4%7Ҁȹє{hJ#қd80%p
-vX`2nmq±F(.#lFXX ëx!ӆ-^h{SoiOTA(hI[htW5QqO/|Tz RSsJoJ}8:阤ӥ]5HX!Fd_k
-t'wn6u{v[u_vQGnN_p~pBm(u$ M?\l<v .8V"7J3dGo[45F֬$ښB6G(Z,?"t?W{(ua<!d-f/Jw&
-E e`+=iO4bʓOʥ=^֥SPjjKW8O 5rsζd,sD5#"d'툰cH+E/;D3JIKgT2SOf"7]:GņH!5K1Zq%T&,bhYHtȵ4~S85Ґ6[stuRzLӮ+Lx|eGr8GӬ\(3` :jH,F1%ո%u87W!E*Sb%QƩksTq ;f|z;}
- 8&s {3 {}ȱ^JPwc6J[\<Ԟ螓.Ubgx'oI%jf>9Tí$nJtU
-Cxػ;<E!*pMbd(i)h ,]9 ƫLk$C1mJ
-)Xyvg
-A"B;
-
-YTvQ%*Z_F&Rx*_h^${r+2H
-+" p(H9)yYgy
-,EdAd endstream endobj 29 0 obj <</Length 65536>>stream
-TU喻Snn;
-'qJVD p) 멀j*^xlI
-k%hUYI)W<V/bT^
-AQ=*໼<#JTq*A<:Udó^^Vw"I
-aMZUxAF2!Y8Z7`E<x׀>0:YU"C0%Ydh-v1/Z h&{U
-r}LD@<g1@#MAlwPR^
-iêH](N"
-;<DfH,MC`jڌ
-[06Aܦ47<7y(,nJs'S+;ӝDCUy$+CL"NS@ã0z$EE^h@U'^
-dթRI--XIsm}Z\~0 gwz5\N6ͬ [sjӐL~L&ٜ^
-Vb65@Yp&Ƴ8 ð({q)ty~$((F7qk
-F"ʳwN'AQ^PkjʍתZ,/w<0kID!ÕFGSelᐻS
-#1e*r,
-
-G
-l&!3*Wh5WkԔWlwYoK&`ӨS+T`v T-*GD
-Bʲx@m$+Pu,qif],$)u,Qy/jU䪆9 ǔ
-}e)MjkS*Uni'1o#>lH49c_Qe9 zJe_Yx_ne$mx9c6Ҭyױ8<XF?QŮj$6y"_H0QΎtN%3xw^,ˮڡWTZx45
-<܀ߒLfe E ˵oo"Z5a՞fAQ:Vr$<A20/tͪ0&ZVBTm˻i$d6Frzm嶗d
->4&8XMp)_E"8 I]T6E(F@p E!Ʊ N&-(dK<ʪxU9 S5HNeC"#`".fPqя mi]\ ۠DaINC҂#y4^-Ia?1[765T6
-QnSIADGnH9i_c/)rЀօmQtqel
-s,#^
-Ί飡yMtM0CJ7jP?-ztƢk|q?V-ngdc־]o0eǻU9reN#{kSx
-JW .UÄC0`[(8cenxfkxX鮶c:Z[Y ΘY Dt0QGƄ
-
-I"f{Cw0lm+0mxU_j.'\p"065mk]~2
-s 9˲Xr$lapV*X0h?s~ cgN%B~#G^"k~
-!9TDZM~ cؽey[B]NF>tTcYԘY  v0@( J^CbZ
-)xRADgNez'`#YTAY@S@,kkmEEx0H ?b=Qz`B{Е5si;hY
-8LquXGyH@
-F( c͋cp·h B
-jj<cx W9/V @ ЪaWex6Bd. bHб
- Ԅ~hYq$*ґ *Ê^ lP%$Ŏer;h3[Q( .6Zja^`p(J
-VR2cw gf&g6F?^`/RD?N?;L^
-,qV UȴXjn` 0BӬܤ;1j2B16 `r\j! 9qtA#*h#k5,_6u|>y΂LeEr
-V,-gbc,|:򨄤J٤=j`0pWT
-(X &z{B԰+\ 3Ne,
-
-E"C'2:Y~oȄ$AemN_㭶̢vQu(9q0lJX4bHQ|As_е_uXߪ2Xq~܏g ǡ~f+zyjz Omw1
-m!nPɼ+wC@vh[+Pa{ndoRy,6K;~Ɂ`:M* uCmt(1Qo`JI tMI7j(֐jdfMv fy۰AT ߲jltsCby[:@:M޶ Z l-dowRO6Ⓑ·1ml!(5D7XP6aED7ֱdZ XMlp![H6Z:F`kUȦl%Cc6,`ɦfv(M66Cl,eéj9u;(E·,u6Cؒ)YdʶT?rf3!lX,eʦfQv(W66 az )[MuH[[6}N!moY*oqipN7,N7, N7,N73jd[dj'ddJj'd[ejce\Aӱ4K94K 5K+SM| LɁrӾ%ݑ8Kd"I ^jJ 9`<R^H  <AdA(!WeY;9y4/d_Nr)qFcQmxV
-(=c-u9Bxd%'֋=L6TƜ3' KX4m'?HV53%(\V< =ͺlM<1ZɬQXAlFeT3VAmk^[s!U~K\{|~~F>CaU{<dU{-]Jef˚.Fq쪆;1]'S EkMW${h ӯ©GOW k:f0'h*9U/0_O{iP^Uh#YU*XD</WU: ].M#<V!ď6hYO;[yYa{W2K7 [^?]#i,UbHlvb0ɪCx]MhcvD U PTK~.)n4n)5$`/u"I#R/HNmbSO(J6tzU9g]i0WcZF#"Շwvj!_]5t)s-feLnX1J`HI)`l6V m,ʬ_r3J4jUÍ`4q1UY,pƠ5.mvƨ3F193(֐ʒ]Ҳ!
-38EAr`0ױZhOkk4vUÎYIeZ(a9g&Cevj
-`_aqAw^rũe`['n<kv$ zU8r4B8U ;N0e٩:GQI+~8O eY
-sf˛wJPY w>CvU$ONXx:02Nu7A.eDQB_0byé^*dЖNqHlAjLnΆ .K`~"@*6/I6粄QEmEdm7uhiRێܦ <|*k[;Nr^U; `(;Q'-'hɸ1o D-5m#;lU]noQE3x:aCjL'k;5ŴӿcBݨnۺc
-"
-M,
-'[]F7^@xȽXsjZ=L{pGPpMY
-_;o>_>#en1
-0Gi^=$).<%"y\(I*KNAu d=>f%xQk A;WD`c
-t<TH#tS7 VsbYQO`S1xQ1;Ktùk9UQ-qu2/ w
-dlO9gpT%Rы /ܤAKed oLH@3 7Ve@
-#'*j@)a)(>iTA3NEsgt*:a^f'(ZN
-HҘ*24ꑼNcxt181<GF~ETCrU~NdKQg\Mx1%m=j@/0%pj;Cx!N,065(H;>8aL
-2-@ 2NQ/8Z H B;bqK
-*I[ASEܚWQ x@VD{P0'\4`ڀC?>>
-F`i$$4x}{M*i}f
-[ƽ$dn#ĵh
-qkm6
- nwp@Ud"Y2. 2,b\b!R[sXWi+~`G_iy:) gB]v1mV!-:S{ԨHZU-LOs@*bU4Urә;[cg~KjFt5Bcߦxsf m!:B8jq
-ڿ0[5ZUIF96xՏOCCHAe%UBS0'YPǪxT + .a%Eai` ~jf7·X%ڵw0JuԊwJ^p8 %F
-}fJ55vCby;onOks=0YND:'Ak]t1v8+inʬ'TٿXg# jZuSTw7u/z%
-*e2: d7]~Xt
-(0' |CuqTEb4 NYEǻ[SlM)"@<su\w.MO5 @\_"1}ǫtoV_ siͰjo;btT<B y*5WuìJ%d Lj<)5c4bui%A* chitL餕M螶d+PCnth
-U, lU*6LN< -<"R>}Dk/~yL؋?~6&tvYޓL^`^*Kcc&0őNYzj df( {jmo,AĬdOW*ާNAn 5Sk#fTjsfװޱ(īJ6 `DN'bţr+Z\W h8+NH&y$%SR=DwpIJMIp̾`,:-gao]I闱(ŭ򺳱g#D /32/q"uxNdJ,:;A#]PV5%GZLD=;9SQN\u%
-FLLuJJ(~qL*՛,L3ĸȊ,'rxJ2'<+`MV׏gluH9, |=%1ϓlk,'2"fP;)YxPv䘮H eו&!X ֖PSA5Ɏ'zJA&p*.ELdI6܍y;x]l@à|"1*z#qzCT<栣QH>L3\Z~dPyOYQ00yeEa)ωfplM_xLj w^yXI Β,q"O Gxm N^I|&gHd3MM3{xn g̵U]]]QY
-#>,CBX$tbz.%<\ZB&[
-{)-ޮ7ioU)\aoKp`ED3KcܮMoxs_?𻙻b+a75a+tKs-OGuxDwpbo3@&Gvtmw+j\dN)5$ϨAgӠH_-t/!MD#j@H*H|l E>'ڡ8(aH2;@1?Yz@'fvx=jZ)_lj38g`j/kؿDkc,N;d<6@r S Y >Y-F1Y_'J0~S\ڞ#o/M`PmG'8Ym}40!ht7/8t~7z>lGVh$Jl(?dsBn;~MCA޼1H)nH6~@K#G)A&}Lnϔ?*)e+գ
-$>qO{QZ- G $ 9ހ$Z?  :1*\P"p'SVIobE-rQ*
-0B/<V$Ec!L(F `ѵl
-LL+ A i?10!E3UN
-  Ez{/Aa^X?ꉢpG!AxA" H@rAPyD$  ^d!xIq|$*.UYWP)^Ac’?>Tx}~
-Q
-"Pa]hJ'G'`!nF p2xdG`s kL֥BD|$^
- !Ų>^䌁KPddRay
-nǷ/XieNz}X3'Ë5Ff8
-!}.6
-.k_VB Xh%NX1ȋ5ʢ
-k
-bO/%&,,
-''] >0hO.X^A\{)I첸ע~Jh}D=.Hc CN;kЕ0`w/:HcФt{H"rJHy0TVؚ PG*
- ݠcGOXHLGHKZ Cl|[lܞ, /&A`]c4whe ڏ b
-p8 tX.^b
-g͂, v
-QSdr/F_ p%Y!GoSz{ۮ2 V >""(e)rCiD^K((Fe9f.\Jq.#6ș h;0QvȸgB&@ha{e
-h9
-XDSeHd`Kd75Z,Rr }_h(y4*ϋQ2oM2b4ȵzvs;. A6D ~X@X|n;a _b{-yytyc<"QFLq4t}h,Xvwjୋ
-h~~a.R[ NHv@jbۉD^aF;| S?xB!O)v
-Mg5PgtG7p5 o7 x7[3o{G]1oN!v"Q uKfM'<!^-$զ<T۞@hSˣ |V_m;ڍnQ6mf8Oďcf)p
-8v`c;'
-0D@s!dL5w! a's!rW=7r愶׀tg!x%(Mޣxf2vbN6٠7i)~,45T
-tj/N] oEso]a@U^:;q[䷆4qjrNыX661T Jo ?%;Q= PM{ b7E=FHDS&Oj6̑+yQO`s>*5@ÒM,|5Ih^pKbw1.1?!/b0Uk#ҖX=|}|[p6ŎҟLTf-YQyPmٛvtV51}M3hXۮQ
-Fi$fbAS%(%!9;ux /X3`
-gՑ]w :1u?LMyd_6EP.*}DAC:?b6QPr?Ba
-L|vaj8Ww.V_C.:(h<>n&L%)jZytZLL
-mJ)a3iRmъOD,5p&\[pE.!Xwg>=WnBor^,Nz?Fr@v~a5^ߞ7WU}*mi=zSt{Q\/C*Aq{Z xҌfsCGm8)M.Uex3AViB6r݋X[zr{#ۖͲ(2fx6S)@@D3F$cZv8:5r
-o{(ˏh7x#JI`U eȬxg q9ֽoNIWJ"%@dc|0QCz.cÉA}o 6d ) ĭ|\?.,Nqʩ81OyVa V
-% )I]jw<f^sqsVJw7嗔v)xd@ e4}䋨l&2WiVgJ
-[1Rr` &jZ1qKv<gH׹r1S
-?=Bt!X+&uX̛TpgFqPumЙ}z<Tl@sf͹毿lint֢3տ
-$|0nfy,d|?z|
-E5&Ze7!u& |QߑD9O(ڼ1,>Q#}=g{IvMu>H4mGՕ}Yч Դ_X_gS_3fMB |g&=Z3e3I;eKzlɛҥI1a;ݔJ*m| -_qlB7]g*s%=eqM㘛<ԸΎw# ?aR~ώm!4;wxRe0$w뽛%;D}xgNf<|u<1+Wgҹ*7yX'l$[tiJ͢#S)Ȕxg^,(* g|M|ӣygS;||aS vjO8R0t$]taXܘ›\M}vP Z"@.nHfq.An]xO\n}zzJL<\y/Ftu:0ӥ>mJ+znl7vvx^bo!k]kl
-ՍAWrrst53]=3]PG]={t
-P^]ah~ 6Fx+^77y2ҭkT^+z&Yћ:}z;Rw޵3}J/I {U^1K/o;_Դg%VX˯:Jo5yM,]_q@gҰyoj@[i5̾6 7N7{3D>cClH|yP{}QcY oЫѤ4|RaUOM ;sbbWF351:>~|}2J1&-Ƽ72VmEmw(g|j^bWJScw0n9I>DoL&}8X^M}oe )roĸaMJ)j35wL4Ѧi3,ͺaġfy1}/,a1std<W5??1'#ynm1.kyZonK!jI>KZj;K{fXi2;˲\x;XTguOV:HޚɆaaqS.m'Kz%9<)GƔ1]w;[=ڞc+f&@}-~)尻/;}s{k랽uE>6ysP#bwviw&g%vu䴾N*[wF\gf9yyoƹ.9wL1 WUZ׮xmW\sw}:L #Rqn
-|c"{6lS#*㚡>Z|Ef ZTlYPTC=9
-L^*,^[>ۇ7x֘d4ƽIoWϳO9|c;nFηw~ܾیޟKLGO&igh=yGȏ<Mztx
-v̌G3A0 ,-=15g۵ nTہH> RI_9JϠԨT &ͭM!3?FFX3duB^2.ꌦЬMߘbrp:mمrx.ZюV?O}"^mGuIEc-zߛ-c))1gE}^?W`c|rw]uSv =՜'`xjŇ&,v&=N|ZzӤ%2LdiCldΐlS}oT9jԸkOaŪ۝~kOGcL2`e_u̾d-]6c_r-\vProA%mDʧkyiŤlbYx|
-ܶh;P(6ӷ5՗])mSSSaIgFZ,4gT3;>Ag^~2򚮺+p5%~e5jC}?Ƈ@vAVOy?z+๫/ yFj4uWG3м4k!k9ُA|)m3<oQU*9ٶ%S;1?&}{;eSa ?MAad:~
-<zshZ{n:CeV~!;K; ث-:нL&{soLoPQ~[7Lף ݪyܝ1wc`%a9=cڻڽx;jpV뷆Zk}4hȗT is0 e6 }Np} a<ǽ/-L H
-Okeko3߫-<{x Ve>?ڠxu,?7Bt4/V:w"y,:r?-cx\vlqe-|] <Dtdu1mXdCUæxج+ =Vuq[kngr;ib'w:q1i\,9ZF[t9-#}<>yyq6u" -#Wg_*|Ė} ׹_Bbž4u}x}ʷna ΢$NAAMO%PcLD>s6:NKd㦗ihM1͔=Mݾ=Bj.֜vvtn1v&>Voj
-X :{׾iG-ޓ5W]6&+]1sZ-YϽ3ҏ ms.T~TÀfJD|إ?'an{<1eبONx7jf v[&cYSyӟoI߳˙X˻D:bMҾ1D/ٙ krۅy-ڹtZs +1=~k3hK)4NN)L
-aNW<rgi
-'"~B>vz# ljp&;`SW0 w!&e1P_rzF0Τ1z,WÉ Lh`%1ߘ4pPw}a`: ţ:ŝ $pK%>%,өG+ C-PiTgV$~
-׳x[!޲X.%G*]7>\B(;{]zpB[$i'd?IٶBR<^U7"5Emp]Y좃'Z{* ,%?qN4&Rs5ᬾXYvg%po<}TLb3LsW< Hk-
-:Q|D=jy>@sW̗7 Y[O:䐝h~.#YT*#Zs
-/Ims<,0霉lK M1/JZv~G]B,\? dϾ{<J .2@T!sG?R֝7݋:Lrgr]n o{sc sYh+I/MbנKLocU!4/&X{D5) 0X[Wdr< '<ڛE ~n-MNb=ځbBf9Ky@XJ1Hp4LayC6xdSI=oD3OH7I?f<l@P{46wpQmu'%[T˃~zwNA١0pǧ97ctvׇ.\3OgW)n\{M.A oYxǑ#!vig?،GWrY/Ak,0i93-8{x[GΔՕ[Cwn ֜S65 AX>gOӹi&Ffcm8k- ȹ|E2)=tpp.npgJ&f_G3> =<*;3{e~W
-
-nfNg˫.MXӨda::1JCʗr]Xz"& iiZgEOwbJ] :[:|;ȠYFu qYhȣh䂉+mdhs\4R~b!r<SLX<#>H,z#+a@5D.h)'C1gz <6 bc+_/cG9<^g[Hθd"8Rj2,r-tݎGYw֐_wh 3Ps,AZ!EP=3C(FI/$v{ZV|\£y cc_KlE"|7 !o&<C/ޚXi0fE`o7qhN/*>m
-HX m_` w4 BZ^Vo>ҭǷVKSӗyXxMJiXcٞ9=<85
-c.LәXjkg}wÅjN0Q38iQ$&0`
-1k=Qq9{/D"!~5Ir!&vzJ9uzyQcߘt<?u }:!9+OiP'ڱb~]Q;PwWyo
-V t6G9;hދ tnw1@KTpB4 ,Dйݳk J(5n
-%D@h}ߢNt q.W}4o8a{HuHi\Np~z!A2o#^#FMnXjz
-Z!*4@OD <}Zv(8|~*mہ9yܱOǖGhI}bbc%ri|+m{tO_ӡb?L](s_e[Tby6֕{Pze)_Ib(˽m֙ v٧D?}Z<:h <L~s=u4vwӔ;"^GΞ8?|κKCK?z컟=$cވ<̔U vl?n[VLSOo'^=y|[=e\<?G` ^ X\ⵁ<ފT+ Oz3GN Yoln@n73X
-fu<ǟK-势eZ҆n橪?IkKúDԩ4a s#.ZhyXMYG2csъOE,{IedY4qcYYs
-y B[qR;G1AZ%5?3/1>Nv|7<_C>I
->k̟gX
-gV-~$VugJYʽ~]OyIqq)O%EeK(zlQcka' eͬ葦]U+ ,3dp#WҴtb[nUx:bxp޻VF\&H"vFbQjn37b4PZ$%aw{ |a3rOiirnȞђ8qoӵ#z'㠎tgΤt/]/u):Е=Aq. t?/&[dfJR O(zD_$/ypB>'Y, 2N +rJ_q9%ÜUb`35UK7k7hzZÜPNK>+^wEY]Ysh1
-]\ᓳ$SnymT@<LP,A #)>dHA1]@(-ђ{ۛղVP8
-Ɋ"$ˢЂqC04Bf0I%T7N^A
-~ )}]rO )m'ռ [g!oE]%X47oRYSVy7:a퉳ts/G|M?뽓/љ`:%*`iZ)+; )|zcR_ r_'cD\N&RЗ@%nnhxOD0JdzD;zX%ڍ$%iUZ_h0kR\/.bl??h~vIiscJV[6Y[sGt_Ɩ/y12K:3NBg-UB$+f \-K <(0k&9 ޏ6^~~{qE;75%vpgfu!ρ 6_]?yLw?ZY؅6l_e+`Qg?_tZ !K-} p?T/'UPYb cm(Ѕ}b ~t$$$8])H:a[)ҩa'jQ:%s(=$"\5sгQ\iH$8GuySPK)G_A1Qɧlz|暌QHaqwm ݜ=Z31\*F(\gb |wk,b-7&4r42t,毬$= npnsuV7s%]T7cOny _]VЉ*]C\Ae/tՂW)WRC\A'~PC\A'A rBU5ttZjq?X
-g:
-:l *j-/_ $Jvрd7mV/NM_HKZ:_Zm:v֊tUK1sR :S6>S<>Qrh'zd*U"WJ(I̡\U4IdD ܞ
-Wc ׇdǫ:.n4 3! bN9iĘ-v۶zIjnOZfAU3*u&L"/wlԗZ6^U))WڷƪCu%}.Cgjy`#
-Iرɚ]U`<KI\jvi;_QW1ViE0ʦe%:5!*є?xYÜ0)9Z[%ff~Bt{L3uN1aS->ȳDń_*q zJ.mE:-tR^NԅLsP#KtAuICqu58{'Oٛ5;{rsх(0ϧS5}k ur4i*qS2(QUwJ5r7*e<񀔏<p"ߚk 9ogD? ׅw$\%RR):Q{Im {uş׻=Y.#_f' 6*+!WFd( )JŬӊrvzQJ;ܢ/["0K ,a ǧRc ?#2ЁU!2Dd.Aeh\EZ}愈d<G[q*уUX.eq-Ʋa 5d2y =X~'C YUrz}3_P|tjAf/3Tq]|=ź:^BzxHolKTY7X.;po)]wᤲk߮ApJW?\$N-~= 玲q]zJ v4Z~NmJW#k9Е0'RζԒZkʉT[f@
-'HT}h#텵p?Puɠ.Pq|@2ߙwLƳ~lR"<~ GO!tx]e`#z_/J2n#C?Rhb ,s\ Ңm*>S>Iա>U&,w*R{w E+R{J߯T~NE*7*RQ+RQ/Qv % Dԫl.nPT
-'-~+fF)z)B)W?(A%pQA)t|LQ2 ~RT6WUˉB{,Vq&z"Ȩ3a.vsWѸt:/r)w^,{=GQ p^8<n4hӆ! l3V={ Hlkϙm<T=H9#B2qbIU!/Qz; <j|
-?MZyR*vzdfRTUzr@?\APq-VȱEnit3LoU*v#"K
-;`rn/JUgK
-u) \Mr@G=<ܿdk\yr@vxVarƟ8>iljF-}eM=l5:˴!zbBPbRncŎEGT3G=CU5KJ}1ԒS<X7ovDL %䮊½5HTC3!SDN1O;?\"';>{.:>4]Yj??Nzɍ/"Mwzr;tߋ\[M'j:N*&(^/?n|5T,^:'tpkVUIurB7龩ڧ9_SM'UK1j:X߫]j:)㆟;;tRt2ARn5qzcj:Ȇa5+;UM'g[n5vNԕxOEk~N:
-2UrHP*
-4.'ܘJbU.+$H!+apDZLݑŝ#͕#s۲.5ws4߹NvZ%Uri+Ӕ |gsl2t͝jDq6Ew?掭}SNѦ \yII^gQMlriO]tAj2:<+F5ihQ0O\_PH"Cԑ 9Y [
-J%\s6t?9
-:Ӗѭ،e߯T>|+(p87tT/̮o@E%dz-;LSa결SQgr11V0.YR6Hz߫RrKU]fP+zr9ԣW*SN'_oI\vU> &Ey?^uQxۋRV)l??N8.WQC!U;62li(d wJ; %+{ou7)U>`WnS'vSON7|*p'KR{Ew]ÝSQ k_f:S7sn:t+W>?Brι|Cn^z
-SGVTtv.v"&(΋eL7eLZ,Ѯi1-eLAN]E)dT趟VeȪeUj)bDWb~UELrDDM{aT~a(qXS7j\SnSŐrtW]I)ou~h}׎T0U=ܔf+o}04T=׸Jj\2# h|NFƍ)}h4 r5\ݗ}z)KLfb'A]TPwcZ?T%-z𶇏)ɢ2<.WGL&W* Ƣnc%rGYB=vz:x@i; c>#U9ڬw/ )7&D`s2OR&6|s V\
-2
-(Zˣ}RL>(VtvQ.,erm0{ws{}ܴ03
-TSz4
-z}I&nKCMjOG_*R\gζ_igP2~nÒ]qzJoڼ״9okKF%򷒍qufolMq]<<MLMN.~|sgn%3l }{6LMiŃt{'qv[)yÓ8m8]_cfoZm?iLޏ/ oRIbzX:~c 񌡹3S+:~S˜I،MoU~s/4ߌ* wl9-],eN}&]&r6Ӿ~Sw{ͺԁNlJXM].~[=c3yd]9~+YWYG7到t
-/SfH{{ZVOC>qc;.l;\*/T^SdAOr;鱲#6HM-AيSm4H-b+Wmb9M:D:q+/}ȡmbIK[-Fda*yK"b_Dk堲a-}ŭU_<hpxv{ikڠp`Sh(fc}f~i4qGk-6=qM{4Vnw䀷+IK~ʽ-lTRܚO[L\(`+gcrFV7_2/뗲F Ŗ"ekfC%K`~(.]8D屳kK7.`;Jw`-n9s`}G-Ə,Kl߫eRqb)Rw0ˋRP1G,Q.+heDihUMXƷ}ln{G!JB߱biՎ"KVmQBZJf__]g-e?-+XG늌RR ));K\ݒu8_w0~|`OqoIJbcPbӻnsY]^6Tۻ̼K=v8XY,M\z:ST/\JRYűm+wwmڲHJ||ejJnl۩opA9Yg?`gl
-<j9{[QsSK6m?v:ݕHLg8 cX/_v+wGΘ\Ol7۶ V۴@`\ytY~ų~U^+:cMsZ8oO1:s7v>rڪZhU͕%Eumɴ-0}|dl!],)>+*>_.}$>ْ3{+9V(':5qN)"hMDIZBœؔB%I>Au>}my%M Z!KG՗1]Mݡ-n:>fV))Yy^Rlyɧѹ٣MRCլτ\~v65ƶ\J̥ɚ|XȔ,n]ߠ5^_ngoeqBVhՂ%
--V6] ,-𸾝T`֏)$Qs~'ִqWVe\v=h 7򇬪BZ]"ķV`Z*uY>ɰgyڋ>lHe"쨴
-/-mˌwn)b*;K蚦Fokj\V RB߻,_C'^ܶqM2Dh&wg8f{%mqUu[6= 651ڲҍL3_g]_,5/rgytg.KiXwķsIߵۼoyzl{,評WEdJi[F)e# Qm]oŞ>HV[VQ|1SMc+.[Giء
-;bW%2S/-Vy2<p8a$W0W[:c\=V |I}}I'~{?i\Ct-{z V:[VZ)Sf2݌yj}qEcK,L\ڳ65 f!ZF?JbB6ulYM饄|- r՗ڸ:iv,I86,ZSRZYSS܉m-gNi,]M-'Nԝx'N4zy7YYq'<,jզf<b2k抓k!q#'KnL?\F]k.=xcE2}.- ..rmI=l/+Nln,3΍Ek)ɕ{6Y^|cšM+w*/n-9oX,uLx-ċOV[eŁԛ_AEXS]ZP^NmǷ`w٦ǩ|y48Ҽ:%3W 34=fkMxZɓZأ6?Vx3~EX2,~CֿMo12e-!؁B~8RL^q{ybۍe{ݭK3&ְ5F.m\/lnhR.j妇~1ͧpoMB6>/=o&>m0 Od5lUkv]'*{ 5Pj<Mr]E}x=¢ ,6.tvXGJJք Ȼ衲 keZ=BzWMe\/P?gZA`cC_n!Fr,Z,rUcrrK롒R<;Rj;P4tgX+&%]{6xVR=%UJ!N\?ɩ:dEY7A O
-g]4U$Y=K>R㽤l}܃ftζijk.'|$0~V'Nݛ)+7)0lםm2N’q>esoMn붷+c yg~;Pݮl h u.}C7:f0XqKY|38u3\xW񒹌ij!,z&-qt11S–⩤KR>%5H͖T67|0IW}i q?1V(Iؔ8T^218?1VT0Ky5K ;.`d c,M(5olKyKJjWiFY_X7AUԧ=_:в 9;˦ه ť'rhEkQcM=$pTaDr/؇ q☴zٜFıeG#FжrՕLQ&}]{lEƆ#J͖U,[V' Ok[#0|--rCnۉ&pvYYcR-4-Rqz_M%1*T0g0ÜU7g}^<q0t\Zwt\윙'-%L4%LFrB&M IhMCRHd)!4&LB}iK
-4%KڒB
-'K !ǒISBE1mI!L
-Օc0|o&n;Elf}SyİN/ AfeJBKtGJXw\4+.c,&6`zf nd +,_dذFuNP!3#ؽ?6@, ?8_ r#c/!ڪLU.Wt =`BivbE^ڰE2V6V6z*2f׉ֶ V6n>qLS͑O,*JuZOiOʕJmEw=E%MM-g9ti:UCmM}³A#z.4&?*>ROџ
-T>u|Kg.9zgˮ]7#kx9mQ~p仧ɇ*qՓOgq; 9wb$<rE'w؉fOE=%E%W^du隒UOMv횢kK׮^j5+<VYSYb5oE=]N
-%2رUi=\钒558
-=
-.&;kEfa$ד(ʊS 
-
-B
- =2i<M6^#
-
-jLjyU]׺Ct-"vɣQ5ATيeuQbo*
-19rC._K"
-F3)7
->?.
-JKfX&m^9I͡
-|a|
-a
-ZNJ
-uv.0]S1?|TE{
-훓V
->5
-cJ\L~ea"42
-,zG$pVi]ҀOA
--2$f+F-6Gc
-d̀ ~`БVH2rt1YX/+&0W*:wEK
-RiqDf$q\<0-y:4շb4&GvNAẌ09tQr$5
-
-qHJ`栞;3$Ru wH#]DFRU@}٣Qy+'Z<`rHq__+[&dӬ L B $]Ԍs[㖢
-20NcQìH5/\y癤|O<* yտwF\ѷ`ݲ뿲÷W,ďfJ]| 94&*~Nh>;='+eo$OqYzg춆[= 4`2"j?>!>5ʕ'Hkz0$G$w&xb9RjYzL{}|k !4&_>Ue}$'K`AOc$iAY(<&Ɗ?C@Rx2SvK0iL]!/YveyriGEELj`JKG=o_x@n8d1E%8{r壚'wgqQWxIAKUA0Uo]E'ouKГGΰ&#SfX+
-'#O`V/`탞gC09rZv嘘TdI'L!8:xI'AL? |F"CIpv_<(
-4=ؚZQ
- .r eTg@3OI'@4+tJArf /6Z}{=wwP˛Г`J4˕Y|L3Ynci
-ϳ&}V \n
-%8Iߕ4 QnA++ `7t1Y*.ުA͖8y 1`3DLjh8&ӣzvk8I!Ch'A0A^/!1Y RbW9I+YE=qX8}2qSj}sWBF)9uKIROolxn԰e{L!8|M)>m $3^'& jn)&$]&8$f{XLZ4X$Xƾ] 8h+dߌ#twW(c s>so@|&&*V5-JFoDqP8zcH rG"#yp| ߻"$B(G\>V=)B-8݀ 8i9JW"ϡ¹Ih zYfTNIɶ0YQL7Һ.sa(L&M+ܟkܿ,pEUs\!?_=v;3`21JA0
-=v`
-na(4-|U5c
-u_>#3wL6x
-^M(ΆV-X'w> vĜ?-PQBOf5e!\bTf6]O2!n' uB~0dGP^(=wg:i꿡_;qрI犬 ?K4Br=a;Ѱ"P<׻6a&$3x_]/SL)1o,*L=Wd OSUtg7*9>]&k¸ܿ,!1!|2-v&p"y͈&S'yD&փn n6Xja E(G $WDL~UP!Iev񓀳9.aPCFPBOfyaU9ߕBG攙Oe,rR d123M1@FE7 P$/z<%~z2&뗏{<fCL:NTDqi!ı{psaN^\'[21@ӇmQu&&G5v.LΖD60&L'ú#;*]s(G|!@}s3*g\90Z#qd8:a AIDQ:kГ6I09r^|f+ʕω\0JAB=qdӇ hy9j^oUuEzpUۋJ;$)В{9ZU
-t0q'Vî^'A&Ĝ
-G<w]>`U͇U$0. &:qzRГ$Mכٲl?|ҰʅUDLI#{X$o1enz`l^Ü&tz_G$R6GcГ (&٩&_#`2S/CTD : Q=" &+ݟ:y2 ==~7Tʯո:J'{M
-mG}z*߼,@*I#`gO˟!Ji' =Aq:xQBpti$$Q|$;DL~iXW
-q "B_Qf99(rh>{ۥ `2#mJ'9L]U\1'A0s>=#$)9<`rD&q&3ŒQaﱈnn\$_:}eݺ5oƜ'k7ې}qea Y=DvH9 = GބOyQ2y~]gR=I_w M"z$2NתVQLN-LkȚ0락|cI0ʯtH;Io(p{sw ʘ;Z^Ü&\fGP3޷;;e5ۮHI2j򏞔>sHz4VbҙЍ[ ΠNg띕$Wm1!0Gww `2s zMZ5NL뮅B0N`>ˬ%$eN=˕P寞Iop2`/8NyyZ'm .
-v~ׅ &Dzs 8 znŭ[A (!Q7$e6'vKRLLF<%}VDd&S32qZ/0N:EZ U
-g7:<#޷;H
-D$Q
-੔1{%Vv2
-=<E tY!":/*1 LJ09ɿh>ul!ġm-T6Ua -$j^o$dBJ3`{ 4L\Ǫh8ʘ;d$עL:G}*<`rXIzfʳTL*KqIGj8 '9YW;&b_>鋱rqg5VƼ3L#'L /GEt<y
-
-rt=Yn'AL (3v19y(Wde̅(āqiH0x?qS$OyNa(FzCRf&_
-%/WNOp
-F? A.F'}>Ĝ#{l'}0-W4`Q3Pg7N_A<]d
-YIs2B̽9ϾwQp^ixmiݼ! pd[` i9JG[;H p36'=˕h7Ήt6՞8N: zJ/ 7yWXF*fVS W5'pXu} #`zR/; 10p= .>Ayv)yUp/NOɟ˟9! &0!#'{ȊRq8 (?_7 e&PQM?ͲoP4"쓎^v#rbY)Ḿ$LPoN[r>@%_FEA  @!"65Mv>"'y7=U4`f5v_71'vx 턥a7 H]\a"]V9o]!wR*A&_? `stǢ` @"Ham?`VM<`?)}ZOg;Nc
- e'B%كn3}eJMm3?:0 heT-"N, A7j in~ |DNw[*fD$j8zv; yFn} !ۤѨeȋɿ/B;Ep]%DCUc
-co8ATD$H$ͽʁ|i4*Ƌ*IكKRMT4DN&΀ij^-FI3A^W%X=M{$ɅM<(JK5x+6`&L *2=A'*&_uJf$*'C 1?Z ':(P1$p[t = $(_]ndbz?%OE=TR!p=8hrGAǒwTQ&ӊI.cnu/HGcc.5k򏟔>St8MqZΔ$q C.&_ɓ҈6IwzE h:x8| *+;GE'Z,mAd !jdTUhDE[x@J8EuII.((N_YF/0=Y;Oh’ɁZ.J7)Y&z(m[cC(\^V!)HV%fV{qIɖ(> ’I=$PLr2mou ju|s.)mcBF2t; zk;4 DuAc&'-ODyǏ,~1v.)%{6y缧M_[ ےX\%JdbDZ-ﲭ}I
-m#8Sx7WU~& I
-
-;EKf[ҚWrQʿyȎnG6/sfX
-
-g'+]a>۠|V_v+eJo}2vV
-$_~4m]h25 ^"W$QcsR>#[ ' Fes9d-n%}
-[ ??ye.
-Qf"v[D)7*=
-ƀ
-zcB&3s rQUFQxFɾؽÕLP܁+hn'3ZLjyn.7
-ɀmAd.Wb`&XՠɾXr8F
-xs_.|%o!ƞUeaR)ELlnK^QTTFml]n)9
--D-!EiѪA3iwUy[X6in d2"nSeS-֖>Z
-dI"![xi
-Np<>R?$vM%,U`5* ?QʘL 4dŠ&SAe^4w}3SJtc C-Ehy+z "{Q*7jwȇB
-ypO
-[%r>W߼ֺG5Pz+
-zk20BWJ0l52 CEE3'.4yj,RnmHׯi@/ukg*L+t[EEjZ싥R6F9ϒ֊hIJ:x=UrB+<v;l"6j6
-Le&ODPRhD̢zMI|VM2mC r6@&MGyMBE#`UL!
- _CcJa^rP
- MTFΐK2 8X_by~݃ty 2iz{8얮I/qJ!{5f%((A)*J龕mh @eGBfd/c8c JyABRJ.*ͬL%v %h[&7I
-e>ɖ->RjUF+7*3AȤI!pYw.z^%XJ٨|>[,|OXJ!&視7:EJ}eM)i2 4%%NyTKpPGW؎98D \ V\#VVpR]>
-{QAas#6~=X*nWN[aGs>nWz?*:;&
-½2ǀiGnmSYgFowK9 VH.2YH@<t[ aP/N?'*e\J 9΀o x~JT`N {/"Ei
-:ϕrPUڦX ʠ7HQu|[2
-Zj z!`
-%o?PX-LA,yƋ/ƔRPGhC'oFfm]QC_iU1p(%
-"<W[ ¸јR5fRJ^.|\QwZ'BKVҽ |K~
-Qxa7^eGӱ y_8?Y'eˬ2
-@&p쨲t $/D9- w0A9WʷaEYy5zZJf`/%ker(DLb"IދqM~qs^<#ѓ7oE-d'Z=b9ݢ[Ƞ%I H~*g-y㬷uh8Ӑ#ydUR&)3J7" n TLTXɓy2 ҂ ^4^mȱQGYo=#ן G7$V <hv:6T'B-#-u͓ ?!<`HG+-h8c ʛߊnd=qh@& 9s[C>)+o27C46ǀ
-CGNlC'=t29c{)J=V ;4s74 2I^Ӹ2 2f)^X<’lPH㎆K@su*M^[' 8{K/a_"Z.| ݀8  Q
-0qYO>r?ͭFOqN)e[7]Ɓ ޿[C36Q LwLz/
-031-]i+\)ŔRc6K:ˬ*kB E|wE̦zCW"0 Vj<uyS ^^m/@rORHh r+{i.o
-G%&Mqnި-R=Vk9IHIvQdqAe:1މ-)Ca-loWk.4&9#~ud=kRaCSB_N^\Y 
-z/0/>U76g/K9mt=j{Jp
-B) L~>z
-Q@'mxMzp~;17j!+e?ǻX]J(%2LB&A%oi ~? _
-; x+xhA}
-`2Ȑ:{QKޗmd^mvI$Bf)+XV B=]UOc8{E2ug_Qa@Db]2Đ=’>uǁ16W_AIe)&?L^.c`0'm^DwX(Z:fh]J(%ȘD `h!O-I JAD){O"RzD)y!f.27B/y.\o>熞."O'_n*TYJ"4~gC&P8\kIFoCXPͻ >B
-ɣhi S^2
-^T Z|2 .<#ҩK י 1TPT.\m
-@v!uaCFE=ˣ{@d'x+RB) `{&c p!>9Ʃ ʍp7QPR"K d[)U
-yA(E?SãZP0HK|E;.T9N4PN2'n<v>;S_pxsJGlyо$|O/Y_8Ĩۻ!UK
-O"r&OxVW#%!8ΤTdՙ;gxL .ϳa4܄g;
-&HQ (D c2
-
-NBXNӍvAf^◯4Xn$"u:'ȋ9 `ne!FՠtIZ>ȍ6H]2v[ǯ 7aA'NtEF۔ ҕᐳ?Z|2DX"%
-] |2c"
-C9>yaAQQ'擣I%&`:z\kp(2 U`Wh1wvQ Iث] Yc
-+f>++=R)b!:& =$/(; jQ0~*g /3Ƌ?BF'IWÂI<pb9Ή''KNvDP)(
-/D)/AxPhs|ȂE jkkc)J,y# tqD;
-(H
-.(7v]'Kag%OmJ,E DDHN]
-/D LZ5(,_D|aM%{֮-^)JҍnǺA
-=K<,y# *_tKHN|$H72ӋJ<ƹs9H]=BMC x,ulamLNxRHqDؑZO[&#jLU'XqNqWi)o[ 'Xr/ǻO
-Q.^UA|_F1m|^gw  .51UYop1
-Do}v:zK;%l<3{?a܂;q0qd1v'o+nj^\H|rŲ'){' Jߊ:$s.yRDL~ o{f:I 薆CRvŃ䒵sٽUغg)J2T߼/br eyؖuU5| E]kK'q*1m|Э$0{)=C*Ҡ;'s婭6)2BI>4Xk҉l<1tHS\SM _K=?yFYJzʓ= 4>-ˏ֎F9VE ݵ2z*'>vNrD^O33U)\%-.wՠp1
-++%y4*Ƿ׶.|{l&ڶq-˳94~gVI@.3pɛ(>Wo_[Gnϼ
-{|ɛɹy[( -xO9MN3d+<Wyzh(@V/>UjdR>Q} L#ח6>OrU̖O'$fRtQ\1ٳC^gʋJ%|[(O78_z'qVҺ.%o' ŒJ/<Lp2U@zִ17•8Ϊ;!j|-!9d \GCˡaeKءF7!o=wmshdQ oCqKeS+O޵a>yʺ/b e!+;9
-dMNrOM RriD{LmnNi-^_ɞ9irǦ5KI1d
-s]FW[뺅Owg|;GWJv՛w^'ɗ+O^[v]\zw _'(
-; =7]T[;sD;6!yj[tr46Oj0%v6<9߽,!8v;α}>4{G:l+xn\n$vNI(^mƻw%
-Gd~8!-[dR.amߴG7O֧?H.79Yhuk=MHO#޼7|@F=vN>RA0{U.G~ۜm+O8} ݸ_^G/hvCګϒtwx'L'ݱd?}V8OHq'Mך]g]eeOuUuZ~2"|NNm{(
-yk tw,
-snt$z,`20Y],s$u{n(z9UR29Ds`Fn
-3$=dR\ow֭D,}v35M?}io*>L)4emWmeO<?1
-wet34f}Wֻ7[J2Tkm҄'/9H7γ#Uy&Z'*}_|jeOsFغh'ͦ6+ͮ/q7-]Wbf 'MEѓ8R$'Cne)oJۧvKmsV޽Opu-w~[/EI;v{gR)H =Lsg,/>㧝|%ҺG/(“w4/&mj϶P_Kܛ{<? 4s.2>DI
-vny$
-K+}r!y1~jvT<\R3Nrʇ7(e\ab\ ]<+y=~E59N'#$ǢHiΎؕ-[K~yuLF͢~rE?bzr!_Гqxg+682udshcR_<ԾF@<~{׍W)Ma?X2
-՜}`zr߽go[y'RS%rHAyg3=y_O
- SOZ-&er"3q
-:q
-ԓk"I/>Y_&
-)w:+v[mXjv
->ݲ-Wtk[y… 'x[F tUM7 տ-UH=3z\;/榠dz7_jY+Kv j[G-TjʓG=>LQOx4v0rf]~ Г^\O >- HR2i4/ iKH CuAks}`~=Ϋn麋Fi.Bk^J#D)'-l Mj,8>ޛURXR alϕd`GB_~J]zE'b8N\|mƎoyp2^/
-!mYHyϸ:(g_i䤾~`O.+̳y=97۳Vʟ/qU-OvrxHyR9>A,adla's DfJT'.|/V 8 @b)oԵ-R귛T*w/
-/9;^P[|m7]pQxn_KerZf@I_Xцf]9>pQs3Qv=8Ɉt:-IbΓ\]J?S
-o,?;
-؅(`j>GSHU^6m M&)Wb ax2;:ՆIN\OX-\zҩ'Oj`
-CRVT?גPUtR&,r6M2]i
-A4$¯&jޖM]~bv/|0
-{3q'xdAj?D4
-ER!]y%|!ԓ-YLOj zҁ`=
-(|%lɌd21>ȦZa=Xⶓr
--O`
-E
-f )ÅI,y,S/]F xvyR,NI/<Uc&
-a%oHG]?d06_c=.*w|d_rD> 6
-Im2C8-Fʹ[hVp./ГvZ<8ei2d7
-?L
-(с >~:w4ۭ4VHv
-/v >N
-'X2 =tcHʘU)/t5Г,G3Q'
-208 Zvcq;P{ܖhHNH|Q.P{$5ۡ'X|,w
-Nkaޜ wtӑG{*"JH ڨ=7]!~Q|
-w|@D)ྔ EXa/n_ww+
-]Œ,
-c"P@mH:!'|do<a~+o2jХ2*Yr*9jFZ-H00KΝ
-g'U:Rn۔x;0.&0D65gS=}QO|'{<IP5_o[
-6XH
-7>psߐZ_[w7pot F.+$%3a)Z‡س?Ii&aϦz&JGN
-R
-oɦb=2eGȹo!;=ֿf|D܂sڱ8$%G|['ћc Uk0]DCXf(MjKڑ&j
-q$AE)icl.KR[93v:(09=N(a a5=A1:!)}|7]z`E)uMГ
-#[=JI痔Es˧+m<ٍ7
-B
-N/k<8V;H;-box;cM9\R,{Cs*)rȈg
-RZ:@ʗ2i3'Rܢl'
- J&>(ٝ<7
-djx0yM,^C
-Z51zlxMYjO2I0 n<stQBjp# LGǗIi00 nueGD`i_Ib6]YzC%3_rlrʗG侇IJ'lFJ|(~ I)^'nP7|9
-o2ѣ3̱%R ~4+,>Bқ-}J~wKi7'}i%Iuz3<4̙$# 'q CLUY9kR`D =H%Sp2 
-[@*m,!!)k2)ɮty`=V^9z==$
-:XYy<(aTΚYUTC>]aamoL
-x;З׌<^g
-3-%'+bI Ocz7/z
-eCeܙOCBRX7'(47+AARR4)D
- 9{JOkQtp[{otS9QKѥ%Wmnc|a1}~I?.R(h|ӈ1qM T⨢qzr*zRmQdg>It
-I ѵnrKIIt$A2}f.1~ϐ}?V?jkJybU-7Js:#Ì*'''&]Ib$& J}.;krSPE е굱.^6Hwwk~iH)i&)%}CT<@Yzy8?o>WK*1gRF뵜GOF|%R޾ )S5n
-uyZ]ZM//_!!8 ĈӢcJ'u֞EF/L.\L~r)?[+Tݤb}B/:F3;n 'CII̙VI!S9ҨHy &Qw׮mD!nehiӾ{ 1fCڇoOQ6wŕ{-凶3h
-F}7׊12`r'Gד<8iԍw(
-&t禇ڥgPˆ^>beR/]R{^)fϗkݣ8x#%@Oɘ{Nx}$#J1
-=I[gi)R
-Np6fǴ᫓L gOd41 ܌uȏbƚ':̗ݛ+Њd߽@Q2}T"ӍΛ?"t#D#H4' IxWNWK+
-Zr
-fk=]Q|fd
-N
-2S9<?lK~{D=}e,`o
-
-:CH_sT%[dzwogb_W>O=>ܷ/~.
->β9K>]>]񺵆tͷn٨tv55mww]L[ncb?:^`û?{}q
-tas۶mzJ*xo^O$/?9"mvfƙ,
-]r˽߰
-ٴ._5dB\B\#톶m=B+
-ʏ$ ҏ-,%17r!o
-ƣF6eTK#2I'Β;yF;Q SYk4Ŷ^#xeI9j%Ӗ];|]POc2SLC(8cӧvw_O?=y,M榦̿-cmOnܓ;/MT܊ .n#ݜ ͫ3ty`<D{Q2#=+x˄7HXX(=_:z`sVOikfR38NLR}V οҋo_莕6/m哥<ػ{}%;8okݢ{eƹ>ۖ%;WqM]QA2
-#@'EbFFt pAVnjAzxꞭb0Qy@OO"m}駟~}/*s5_rǍW7XM>A|˟^d ~E:{k/=c5ײԳ{ks&8,/owk,{gN6w } g+] _EU3Qkmg4<Q\0VD\O]fLҌ<~LșӧN.to~uW^xQֳ|7^|)$Tί9GFg맯ޭ#x xWOAO"AQH[P}n)\r/8С!c;IU6Gӧ[C&yN
-
-W?Yҟ^̻;cH.Pz0'J7g?:k~c{g.r#n?y[6F>]i}Cθ_5 =sGv=oW{ {ÃlRݢ8ό
-%@Bc܀GI@dl5wclq{l|3wSI73=!}m#:eN}129!1wY\tW]=>k/Lzfx{KGl!\GL 7sǥkbny~D˨OoDr7D-V+_~gRD 0-$nXsH= ,zY,7.6)'^3'ŬƊynn, XX[5IY.+G:՛usG?᧿O?r޿Lsy\W!_̇\VUz9顱&%DBVaUOQ𧼇Uxѕ%
-cT FJbSi }E3s F+?(\4T2i!nxKXXm$ E|rMƭxt<0μvʼnOg̷x*Z0}1#5v+1g2hNfeх;<5s%;zQ'qkJ.i՞
-#Uրtuy9{gQΛrLo ]Q틼id4_`^{tB¸ λ庫ͯS{Rud?Y4].2ﱞZǚcxN&S1K2g&W0>9,)Fv^?=ܿrVΛY7p}ˀnqwyḎo%tyok~uO=O:&s0.xНtֱMJ9oP'i`pPaƚ[;XQxLx yʋ$kzYFjNK򘿗.La\>>ǒ?ǦnA⹛0D +,i9n?&X^Ͷl1q~fu$Z{0EcOw]%?uN 6]!//<ondJ܎j>^QHKsSk]`.a3%fn:?C QwC-6,7#pU: Q^ŜܬH} ʊ8+gSObJ!]]Iޤ<  ABJzk8vL7pF˛wv/Ʈ^ȇC̴Df b{Ug`ʒ{|l[*'G|=C{@XZ`7m^N27r[J _{>0s~@-DZeq2fsֳ)9qZ9oEsIDu QŠT϶`Ğ=P<!2^̜I{p'ѕ2xԤbX7%n䑟?3q
-V')'sj
-azy SXa_{ɉ܍ ww=3'K@2EuEiAb)*k Hok^-.n.u,l/'ֱ-RqVs]9XQx+MЇ sȸޡLJ粃P^.U›w2jH
-QeUGO[ +޾4'Y*2JgNA림w2\(^]}Ըm>9,,@uXM OfGfOod%8 -+--%%K.?3YX]^M rҍN˝ &Nn&B;/LG&| ?J}"E_M=sO_7hF̠=๙U҃>^D}ˠggeCԱZi},na} g_校ۼ^nWAX /wOjմkDCVoQ 5@sΖ8+<t@z•!eKzxZ/8UX-\5fԾ]s2dsGG#SC!r@+!wOL79mr~N\k#.jwt#^9o&
-hg=2 Z{leM3nKrGF+ݸً
-F{?" NH8\\m
-1 }ypܐ=۷QCW.1D]垙fќeYZJX*($FM#&WD_ªkm ~›NMb>6Ѹ]!j_wU,gÇթYc^i^oYܳfD|PU^D/]17\ f3aj}"R:?{K$wOJ<\s&>s#yad}ț 2-~䧕*W͟(g;Nz#^RT d=[|Sq!X/VfUnҗU(~YKx'#[&H~̺7#sR|5$H
-/`FzcV ryA6s?,˜E+xf3K&t}\t Cx#t[[Ar#_{Rh$?J;i7n!BH
-+>yXg,\?j2&wtI RMqWQBk`[jv/F|z;x{+
-
-̙'{?qDqx s2yF;q
-bs݊Jn^0yG-Ju'82$y09ϫо]iy/qIN6A|!ݒƒy
-#y`Jaq ćFNg^<&Bw
-kW$PDž
- sMg]4GYA%yKjwoqqskK6xD>LDm}vsLJ5[Cniy6YIȝx8
-o,g}Z>"ҟv #+Jo|uk#
-#
-ObԤCdāܖZu ⮉|)I0b;4tsYWÍ
-GYbewi^VSExn[SZ{jߓ9_VEJT^%%˿&xa70
-
-o)XfKϙ{ۄJΤ4xѣp/wzzj;M
-}Oi:t(+u#EI{'Ή "P}"u艇@s &
-#
-(}/L.^_7
-pH=e".e{ )vn,9ŀM^WvR.f_ծod88]ynj,?ԗYV7pFQrrZrQbU k5S
-M_{oUNNa&?_TQ
-nAL
-b&
-ڏ@p ý(z>[ɞGJkQZ#8>u_J >ܨ@f.m16] aw
-?aQP2=`ܸ঵+
-NaSǩ_OGb<݋r¡tᢞ~qϮtf[t(03%`SVxQ ߯ M<la<+JI0M7{υn^5DZ (ϢEnHn\p1<
- H|P<
-LjU^n.I:5\ub⺂ 'cSx!*IՊJKEŅ##/OGd}({ RFڐ+}{aq6.K>m
-n_(0=GjyOfeQ}ZƮ5[U'6d,1[8߽~SZGbߏ{rf@pz/7y U6@USM=, fW 1{^)?j1#On޸ܜM\Ra ]KlV ~!_\6=s8]H;_/jC9L=0cPIc6bVw.Nm:r٤Y+ubӯyȀ9\VG/kM*}3ImYUEvd͝v]qCx탯ʹjM|(Ο&SԶ5\ubBo߯NC{a֣F6yVAXW_&Iwp
-a=`.o:{k-;S[LփE?N ؘqMs*g1rHVvD0P
-Iد%Oŝjn1EWƮۍhex.Tql/#SدWM1~*[>ycrS"hm2w7Bc-vwpՉM
-ɗ9{{jn1,w-,u,'!$3>vS}-ši<$uW6
-~"DC}M=>:ȓm-}goM2L~~׿WhVYCJ!vq[+݈4{7<$?rf^:5c=o,!.{kĢ34+Wgwq)n5$?WW תP>n9[YXtqoXV0‘~cn[!2bFjeL*rpoy 0l_{#C*Hfo+#7Qؕ4CH]^U\Lf7C+2IP~{N7 k|ߗ~΃|&6ݠSCFPn?W t0cU1gs H_^H=db)5
-`.NZ:!Ups60YMt׷&5U٧򙜯+ɰBmZ.j{6^hC!B^o3w[4dc P؃r.0q:;C:vcvqh.{u&M^}h đ.q<1g(KxHcpdGT3>Fe}2 Eп0G=Ƽ2{XMgŢ {¥l`cv+֋DпXt(- ^J}^BO N0kA,-6D )8𼇲P6Ʀޠ!]_U]nn [=0mZW8l]ƽ/0:Z+?AZuث? <4CP:T#< c{e:_U(ׇcXH88w?#
-GۯA{H|%uD <DϾ?C+56}TkxūeY ]T>HK~rWkbApѳOv{mX7MҘIUcٿ}d"ݵhf'{?٪rQItC4v2b[- !mycNGLb(r/7$k 'R^іaONS~wY7*>_&Jߘ&lw;hfTJ{&1On"Hq2n7~:v?E=ĘBu(T[CI/^^xj'¢)!!^TnD5x:JuܯUWvZbHL=jĦSp잣耸4H]yHWMJ&Ʊ4b&3oS[wǦk:({C=$nr$ݏko<Gd2$ :pՉM+oSO~"N;l#C=] IƬVqdӰsTC Őد4L
-]XtH'rܰu'fl+?(Ħy/юhܜ<ͨ&x6oHcӯTRo|ߡ>vggXZd=||mM%
-G< 2^
-{rR$#6(C') &4Zb7*M1v3@Ul9AdA:f¼U/+-9;D'8ZrRIeކBtEyc ˜ *6c
-*-U*Z!Z0o@Qؓt% ♃9
-@Ul?^%w2\ PTj `_ؽUa
-ɍN@2
-SIԉdJ7.QǼz亁0w2^fO.ơ3q' rQ@]Q!7aހ8Al #qyuIG?
-#jTq'=dwNTro@afie̛IdutMsIǧp'8*rc6PnW&f"$82\0U-rʁCTƢU&PGb"-!#BpEvVžn亁qUjLҩr*c/P%Zb, s'&,'8*$C2
-$?Fy :PprQ߀~Mߣs)c$K(wz"Np쵼t7p? tŦÑX(&Vt
-rGqMYxnkVm\l1Y=JթJ?}߳Ak d++on3L]o[سh*irg.  D33VOI*;C&B$J{vE^Ξchao~Bv Ozyt9< ٽƁ?_OMl2W܅Yb2F"wۨcí+a@b}?ks6gjQo :,zӛ.a`D%m78r
-J!4|d\ǿDn
-h{S#-:W>
-m@p@IZyj֍twp$P y#\p(E7&yџ*j8P ?)0~LbBp@+ 2!@Z6DaoR`3!8
-:yǑ
- 2I!$ش#&ewpO-cӣō<wNT5piC +CչSE&(Ǣ#յse Aބ܀tQCGQgP nOL6o]b=v xHpl<lpݺtfzSGP8r耞ݺvn!}d
-
-fj 8 tqқI~ tšOg-Н2鍹p'tcD\9%@_l@fp'شh<z3HϕŢw{maހXuCהForƗ
-֛Ia 
-lzl\!@T`ӣGXontĐ_D65z3H4*Gv||$FD ̲DУ4I75
-AFm "w)1w2r/#%8 G2.l<<2,zA:D#1^prQ7uTG` gP[n>0BbVo&qeIzBo :qlp@
-C1x ZaІ3ygmXJi[Nٚ]eA; fmh+1w2 D56m.ReX6 wD7][x 辋 +C~N
-MLo
-
-
-Wp^cL`
-}MbFF|7vn%P<ܨ]98sp0߆Ș܍1y2ǧ$ಾES\_7ްzw7$#龻7@;c7 =w@
-%?}sYȖ`JO#6%LI7\@wդ ]KOu|pB9B c׀ p\<h<<ޘo]𬨣N{KXic4pmtdmz6|}Gǜ!&phglB14\Hm>U Fp_{%̏yȏ lⴓC.(YPQ,|9w`b@m16t=9J|ppΐ_
- ct,+
-_l}8rr'_j-AUoif~tn=R],
-GUV!prׂu/cp0?r讵`2z+y,*|Wm%` HN~a!dl4L)\9,֌[ȃx7 8g1!Ot9zK?f
-oH5 Xb=-%=}h6-ePsX>{ 01rlB7VڟBC:dX
-?gOBP涋mL=C)
-~КVQGKf ytETmTdE8Y?^MՓ$8qJ\02&VQG_<26OGݴoX &9&Lz<9p(dl^K/r3"]0^2܋|% ?~ЛN-"ŖΟc#Ǣ
-G&ǀx47L:0{[ixgyrlKs4?yx9r4.|
-ل 39xSp"'Tn덷 j8f)ްl(D
-oH}+OnSuR?]
-u_p]kW 0, k&3%߼n})R R<P`^W];Ƣ)Bk ܥK( oSMv&?Վ4:dC )_n.+8y]gBpzCmC]
-Q*(-Z_۲rh2r>
-WE>!pr@͍˿<su,o=zI;afE577t1f6ŃGѫl
-5Ĵ09)0ɯC7vlv]gOYVvbtOxT$AYw\ww)L)FmlxG'O?>r׮1H^ҋ/P6dd2T\ 6#ܥ*#FƏI]ç/঍?/0iml3R
-Mڐr#rM7AԱc}m߸᧫V2(&C@S
-_Zv׿Xnt8<]>xG~~݆9_u!ԍd~Z@.]Zaz1M †8/xs3ݵ 1qK]17|s|@
-G#_o/-m5YQgM ңKf}]\{Ւ>X" Lƈ0y0psDB9z|(1/ bJS_JCqZ3V6 /+ՆgF/-)6*t5fMsRs"Kc(N4S_>U$P&)+mE <LQ>GceQk\~']6Tgmm6Լ^Wc5g*cbE Ćx:)>n%ӶZפmЬ7g袲YzGsW`.#-ɘ7+Fkmj}|֛#W?k¦FCAQ]rCF˺ڼx}A`lN6}[Mb[fLQe5E&;Őܬ.]ї9یMٵm%re|v`-Ԣj-2R樾
-C2l27kʲB]_zuEkFV\L6ڠQw>j0#ݽ˴5EZr%}n\bj{RuD93rx G^r0&ϤꯏfΡ@ݗѮh rfENMݘST4
-mIT:VQ
-}Vowö^5ݍ{cs"fjZL}wQc02c;ӝ>Rl[)qW6z]P"~`s+[EbZBDQnSMC(ΑXߝ:؝[d2csbm֖ ߥ,mj0QoӒX3@ggT*+ kkʛu9jg8^ng2R' )UUҟѕnHoo.p4$GMΠFh2s\^m1e^#<tNZ`TimYPG>t ~TP:-Jԓ+\e6ZU*SSuԷv)6Z,EI}v^ұ/МߝC40w#d*]Ѣn+ ڢWeO16UeFVk]Uݥ+Փf!r؃&ܙs͚5GPF[SRBY.ĤkY-Ime)U&92ͨn.6W-3[Zcu ZmkIF[\e'yP'+RB兆h&+ٸ^Zҥ5e)v}JSTȭv9QNhlNXƩ]ָ3Ra6%SJ][i[M9efBJwŕJ
-"'9h,dRLQZJӔjcIAǪ|٘֘ڣcIi)-2IUV:<QA}Ue!}&k #5`\S<GԍivU)_eeLd0S舰FTsVSs͊eiφ5mQVnPNc5l
-p*EwmlعU{
-xTs4>
-LL<m*9|yd.T,u<Ʋ
-x_Ts4Ur>*\q3<WnwvK-=
-p(mC鱙Tke_mo*bC"OmZU r7;ʖ
-cި
-p'Hc<WR6zlfX.xV9U r}<s`ǦS
-\rnvl
-k__괭>Q5 J,(I endstream endobj 15 0 obj [/ICCBased 19 0 R] endobj 6 0 obj [5 0 R] endobj 32 0 obj <</CreationDate(D:20160615142312-04'00')/Creator(Adobe Illustrator CC 2015 \(Macintosh\))/ModDate(D:20160615142312-04'00')/Producer(Adobe PDF library 15.00)/Title(metamask_icon)>> endobj xref 0 33 0000000000 65535 f
-0000000016 00000 n
-0000000144 00000 n
-0000047649 00000 n
-0000000000 00000 f
-0000163121 00000 n
-0000593503 00000 n
-0000047700 00000 n
-0000048109 00000 n
-0000048283 00000 n
-0000163420 00000 n
-0000139682 00000 n
-0000163307 00000 n
-0000049181 00000 n
-0000048344 00000 n
-0000593468 00000 n
-0000048620 00000 n
-0000048668 00000 n
-0000139717 00000 n
-0000160473 00000 n
-0000163191 00000 n
-0000163222 00000 n
-0000163494 00000 n
-0000163800 00000 n
-0000165099 00000 n
-0000187851 00000 n
-0000253439 00000 n
-0000319027 00000 n
-0000384615 00000 n
-0000450203 00000 n
-0000515791 00000 n
-0000581379 00000 n
-0000593526 00000 n
-trailer <</Size 33/Root 1 0 R/Info 32 0 R/ID[<858D18969ABF4CF88593CFB9A20C1759><B33F39DA517C42B9A50D10EC91C85574>]>> startxref 593722 %%EOF \ No newline at end of file
diff --git a/responsive-ui/design/chromeStorePics/promo1400560.png b/responsive-ui/design/chromeStorePics/promo1400560.png
deleted file mode 100644
index d3637ecc8..000000000
--- a/responsive-ui/design/chromeStorePics/promo1400560.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/promo440280.png b/responsive-ui/design/chromeStorePics/promo440280.png
deleted file mode 100644
index c1f92b1c0..000000000
--- a/responsive-ui/design/chromeStorePics/promo440280.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/promo920680.png b/responsive-ui/design/chromeStorePics/promo920680.png
deleted file mode 100644
index 726bd810a..000000000
--- a/responsive-ui/design/chromeStorePics/promo920680.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/screen_dao_accounts.png b/responsive-ui/design/chromeStorePics/screen_dao_accounts.png
deleted file mode 100644
index 1a2e8052c..000000000
--- a/responsive-ui/design/chromeStorePics/screen_dao_accounts.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/screen_dao_locked.png b/responsive-ui/design/chromeStorePics/screen_dao_locked.png
deleted file mode 100644
index 6592c17e4..000000000
--- a/responsive-ui/design/chromeStorePics/screen_dao_locked.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/screen_dao_notification.png b/responsive-ui/design/chromeStorePics/screen_dao_notification.png
deleted file mode 100644
index baeb2ec39..000000000
--- a/responsive-ui/design/chromeStorePics/screen_dao_notification.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/screen_wei_account.png b/responsive-ui/design/chromeStorePics/screen_wei_account.png
deleted file mode 100644
index 23301e4bf..000000000
--- a/responsive-ui/design/chromeStorePics/screen_wei_account.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/chromeStorePics/screen_wei_notification.png b/responsive-ui/design/chromeStorePics/screen_wei_notification.png
deleted file mode 100644
index 7a763e5df..000000000
--- a/responsive-ui/design/chromeStorePics/screen_wei_notification.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/metamask-logo-eyes.png b/responsive-ui/design/metamask-logo-eyes.png
deleted file mode 100644
index c29331b28..000000000
--- a/responsive-ui/design/metamask-logo-eyes.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/wireframes/1st_time_use.png b/responsive-ui/design/wireframes/1st_time_use.png
deleted file mode 100644
index c18ced5e2..000000000
--- a/responsive-ui/design/wireframes/1st_time_use.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/wireframes/metamask_wfs_jan_13.pdf b/responsive-ui/design/wireframes/metamask_wfs_jan_13.pdf
deleted file mode 100644
index c77c9274a..000000000
--- a/responsive-ui/design/wireframes/metamask_wfs_jan_13.pdf
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/wireframes/metamask_wfs_jan_13.png b/responsive-ui/design/wireframes/metamask_wfs_jan_13.png
deleted file mode 100644
index d71d7bdb4..000000000
--- a/responsive-ui/design/wireframes/metamask_wfs_jan_13.png
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/design/wireframes/metamask_wfs_jan_18.pdf b/responsive-ui/design/wireframes/metamask_wfs_jan_18.pdf
deleted file mode 100644
index 592ba8532..000000000
--- a/responsive-ui/design/wireframes/metamask_wfs_jan_18.pdf
+++ /dev/null
Binary files differ
diff --git a/responsive-ui/example.js b/responsive-ui/example.js
deleted file mode 100644
index 4627c0e9c..000000000
--- a/responsive-ui/example.js
+++ /dev/null
@@ -1,123 +0,0 @@
-const injectCss = require('inject-css')
-const MetaMaskUi = require('./index.js')
-const MetaMaskUiCss = require('./css.js')
-const EventEmitter = require('events').EventEmitter
-
-// account management
-
-var identities = {
- '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111': {
- name: 'Walrus',
- img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
- address: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
- balance: 220,
- txCount: 4,
- },
- '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222': {
- name: 'Tardus',
- img: 'QmQYaRdrf2EhRhJWaHnts8Meu1mZiXrNib5W1P6cYmXWRL',
- address: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
- balance: 10.005,
- txCount: 16,
- },
- '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333': {
- name: 'Gambler',
- img: 'QmW6hcwYzXrNkuHrpvo58YeZvbZxUddv69ATSHY3BHpPdd',
- address: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333',
- balance: 0.000001,
- txCount: 1,
- },
-}
-
-var unapprovedTxs = {}
-addUnconfTx({
- from: '0x222462427bcc9133bb46e88bcbe39cd7ef0e7222',
- to: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
- value: '0x123',
-})
-addUnconfTx({
- from: '0x1113462427bcc9133bb46e88bcbe39cd7ef0e111',
- to: '0x333462427bcc9133bb46e88bcbe39cd7ef0e7333',
- value: '0x0000',
- data: '0x000462427bcc9133bb46e88bcbe39cd7ef0e7000',
-})
-
-function addUnconfTx (txParams) {
- var time = (new Date()).getTime()
- var id = createRandomId()
- unapprovedTxs[id] = {
- id: id,
- txParams: txParams,
- time: time,
- }
-}
-
-var isUnlocked = false
-var selectedAccount = null
-
-function getState () {
- return {
- isUnlocked: isUnlocked,
- identities: isUnlocked ? identities : {},
- unapprovedTxs: isUnlocked ? unapprovedTxs : {},
- selectedAccount: selectedAccount,
- }
-}
-
-var accountManager = new EventEmitter()
-
-accountManager.getState = function (cb) {
- cb(null, getState())
-}
-
-accountManager.setLocked = function () {
- isUnlocked = false
- this._didUpdate()
-}
-
-accountManager.submitPassword = function (password, cb) {
- if (password === 'test') {
- isUnlocked = true
- cb(null, getState())
- this._didUpdate()
- } else {
- cb(new Error('Bad password -- try "test"'))
- }
-}
-
-accountManager.setSelectedAccount = function (address, cb) {
- selectedAccount = address
- cb(null, getState())
- this._didUpdate()
-}
-
-accountManager.signTransaction = function (txParams, cb) {
- alert('signing tx....')
-}
-
-accountManager._didUpdate = function () {
- this.emit('update', getState())
-}
-
-// start app
-
-var container = document.getElementById('app-content')
-
-var css = MetaMaskUiCss()
-injectCss(css)
-
-MetaMaskUi({
- container: container,
- accountManager: accountManager,
-})
-
-// util
-
-function createRandomId () {
- // 13 time digits
- var datePart = new Date().getTime() * Math.pow(10, 3)
- // 3 random digits
- var extraPart = Math.floor(Math.random() * Math.pow(10, 3))
- // 16 digits
- return datePart + extraPart
-}
diff --git a/responsive-ui/index.html b/responsive-ui/index.html
deleted file mode 100644
index 9dfaefbb3..000000000
--- a/responsive-ui/index.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <meta charset="utf-8">
- <title>MetaMask</title>
- </head>
- <body>
-
- <!-- app content -->
- <div id="app-content"></div>
- <script src="./bundle.js" type="text/javascript" charset="utf-8"></script>
-
- <!-- design reference -->
- <link rel="stylesheet" type="text/css" href="./app/css/debug.css">
- <div id="design-container">
- <img id="design-img" src="./design/metamask_wfs_jan_13.png">
- </div>
-
- </body>
-</html>
diff --git a/responsive-ui/index.js b/responsive-ui/index.js
deleted file mode 100644
index a729138d3..000000000
--- a/responsive-ui/index.js
+++ /dev/null
@@ -1,58 +0,0 @@
-const render = require('react-dom').render
-const h = require('react-hyperscript')
-const Root = require('./app/root')
-const actions = require('./app/actions')
-const configureStore = require('./app/store')
-const txHelper = require('./lib/tx-helper')
-global.log = require('loglevel')
-
-module.exports = launchMetamaskUi
-
-
-log.setLevel(global.METAMASK_DEBUG ? 'debug' : 'warn')
-
-function launchMetamaskUi (opts, cb) {
- var accountManager = opts.accountManager
- actions._setBackgroundConnection(accountManager)
- // check if we are unlocked first
- accountManager.getState(function (err, metamaskState) {
- if (err) return cb(err)
- const store = startApp(metamaskState, accountManager, opts)
- cb(null, store)
- })
-}
-
-function startApp (metamaskState, accountManager, opts) {
- // parse opts
- const store = configureStore({
-
- // metamaskState represents the cross-tab state
- metamask: metamaskState,
-
- // appState represents the current tab's popup state
- appState: {},
-
- // Which blockchain we are using:
- networkVersion: opts.networkVersion,
- })
-
- // if unconfirmed txs, start on txConf page
- const unapprovedTxsAll = txHelper(metamaskState.unapprovedTxs, metamaskState.unapprovedMsgs, metamaskState.unapprovedPersonalMsgs, metamaskState.network)
- if (unapprovedTxsAll.length > 0) {
- store.dispatch(actions.showConfTxPage())
- }
-
- accountManager.on('update', function (metamaskState) {
- store.dispatch(actions.updateMetamaskState(metamaskState))
- })
-
- // start app
- render(
- h(Root, {
- // inject initial state
- store: store,
- }
- ), opts.container)
-
- return store
-}
diff --git a/responsive-ui/lib/account-link.js b/responsive-ui/lib/account-link.js
deleted file mode 100644
index d061d0ad1..000000000
--- a/responsive-ui/lib/account-link.js
+++ /dev/null
@@ -1,26 +0,0 @@
-module.exports = function (address, network) {
- const net = parseInt(network)
- let link
- switch (net) {
- case 1: // main net
- link = `http://etherscan.io/address/${address}`
- break
- case 2: // morden test net
- link = `http://morden.etherscan.io/address/${address}`
- break
- case 3: // ropsten test net
- link = `http://ropsten.etherscan.io/address/${address}`
- break
- case 4: // rinkeby test net
- link = `http://rinkeby.etherscan.io/address/${address}`
- break
- case 42: // kovan test net
- link = `http://kovan.etherscan.io/address/${address}`
- break
- default:
- link = ''
- break
- }
-
- return link
-}
diff --git a/responsive-ui/lib/contract-namer.js b/responsive-ui/lib/contract-namer.js
deleted file mode 100644
index f05e770cc..000000000
--- a/responsive-ui/lib/contract-namer.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/* CONTRACT NAMER
- *
- * Takes an address,
- * Returns a nicname if we have one stored,
- * otherwise returns null.
- */
-
-const contractMap = require('eth-contract-metadata')
-const ethUtil = require('ethereumjs-util')
-
-module.exports = function (addr, identities = {}) {
- const checksummed = ethUtil.toChecksumAddress(addr)
- if (contractMap[checksummed] && contractMap[checksummed].name) {
- return contractMap[checksummed].name
- }
-
- const address = addr.toLowerCase()
- const ids = hashFromIdentities(identities)
- return addrFromHash(address, ids)
-}
-
-function hashFromIdentities (identities) {
- const result = {}
- for (const key in identities) {
- result[key] = identities[key].name
- }
- return result
-}
-
-function addrFromHash (addr, hash) {
- const address = addr.toLowerCase()
- return hash[address] || null
-}
diff --git a/responsive-ui/lib/etherscan-prefix-for-network.js b/responsive-ui/lib/etherscan-prefix-for-network.js
deleted file mode 100644
index 2c1904f1c..000000000
--- a/responsive-ui/lib/etherscan-prefix-for-network.js
+++ /dev/null
@@ -1,21 +0,0 @@
-module.exports = function (network) {
- const net = parseInt(network)
- let prefix
- switch (net) {
- case 1: // main net
- prefix = ''
- break
- case 3: // ropsten test net
- prefix = 'ropsten.'
- break
- case 4: // rinkeby test net
- prefix = 'rinkeby.'
- break
- case 42: // kovan test net
- prefix = 'kovan.'
- break
- default:
- prefix = ''
- }
- return prefix
-}
diff --git a/responsive-ui/lib/explorer-link.js b/responsive-ui/lib/explorer-link.js
deleted file mode 100644
index 3b82ecd5f..000000000
--- a/responsive-ui/lib/explorer-link.js
+++ /dev/null
@@ -1,6 +0,0 @@
-const prefixForNetwork = require('./etherscan-prefix-for-network')
-
-module.exports = function (hash, network) {
- const prefix = prefixForNetwork(network)
- return `http://${prefix}etherscan.io/tx/${hash}`
-}
diff --git a/responsive-ui/lib/icon-factory.js b/responsive-ui/lib/icon-factory.js
deleted file mode 100644
index 27a74de66..000000000
--- a/responsive-ui/lib/icon-factory.js
+++ /dev/null
@@ -1,65 +0,0 @@
-var iconFactory
-const isValidAddress = require('ethereumjs-util').isValidAddress
-const toChecksumAddress = require('ethereumjs-util').toChecksumAddress
-const contractMap = require('eth-contract-metadata')
-
-module.exports = function (jazzicon) {
- if (!iconFactory) {
- iconFactory = new IconFactory(jazzicon)
- }
- return iconFactory
-}
-
-function IconFactory (jazzicon) {
- this.jazzicon = jazzicon
- this.cache = {}
-}
-
-IconFactory.prototype.iconForAddress = function (address, diameter) {
- const addr = toChecksumAddress(address)
- if (iconExistsFor(addr)) {
- return imageElFor(addr)
- }
-
- return this.generateIdenticonSvg(address, diameter)
-}
-
-// returns svg dom element
-IconFactory.prototype.generateIdenticonSvg = function (address, diameter) {
- var cacheId = `${address}:${diameter}`
- // check cache, lazily generate and populate cache
- var identicon = this.cache[cacheId] || (this.cache[cacheId] = this.generateNewIdenticon(address, diameter))
- // create a clean copy so you can modify it
- var cleanCopy = identicon.cloneNode(true)
- return cleanCopy
-}
-
-// creates a new identicon
-IconFactory.prototype.generateNewIdenticon = function (address, diameter) {
- var numericRepresentation = jsNumberForAddress(address)
- var identicon = this.jazzicon(diameter, numericRepresentation)
- return identicon
-}
-
-// util
-
-function iconExistsFor (address) {
- return contractMap[address] && isValidAddress(address) && contractMap[address].logo
-}
-
-function imageElFor (address) {
- const contract = contractMap[address]
- const fileName = contract.logo
- const path = `images/contract/${fileName}`
- const img = document.createElement('img')
- img.src = path
- img.style.width = '75%'
- return img
-}
-
-function jsNumberForAddress (address) {
- var addr = address.slice(2, 10)
- var seed = parseInt(addr, 16)
- return seed
-}
-
diff --git a/responsive-ui/lib/lost-accounts-notice.js b/responsive-ui/lib/lost-accounts-notice.js
deleted file mode 100644
index 948b13db6..000000000
--- a/responsive-ui/lib/lost-accounts-notice.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const summary = require('../app/util').addressSummary
-
-module.exports = function (lostAccounts) {
- return {
- date: new Date().toDateString(),
- title: 'Account Problem Caught',
- body: `MetaMask has fixed a bug where some accounts were previously mis-generated. This was a rare issue, but you were affected!
-
-We have successfully imported the accounts that were mis-generated, but they will no longer be recovered with your normal seed phrase.
-
-We have marked the affected accounts as "Loose", and recommend you transfer ether and tokens away from those accounts, or export & back them up elsewhere.
-
-Your affected accounts are:
-${lostAccounts.map(acct => ` - ${summary(acct)}`).join('\n')}
-
-These accounts have been marked as "Loose" so they will be easy to recognize in the account list.
-
-For more information, please read [our blog post.][1]
-
-[1]: https://medium.com/metamask/metamask-3-migration-guide-914b79533cdd#.7d8ktj4h3
- `,
- }
-}
diff --git a/responsive-ui/lib/persistent-form.js b/responsive-ui/lib/persistent-form.js
deleted file mode 100644
index d4dc20b03..000000000
--- a/responsive-ui/lib/persistent-form.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const defaultKey = 'persistent-form-default'
-const eventName = 'keyup'
-
-module.exports = PersistentForm
-
-function PersistentForm () {
- Component.call(this)
-}
-
-inherits(PersistentForm, Component)
-
-PersistentForm.prototype.componentDidMount = function () {
- const fields = document.querySelectorAll('[data-persistent-formid]')
- const store = this.getPersistentStore()
-
- for (var i = 0; i < fields.length; i++) {
- const field = fields[i]
- const key = field.getAttribute('data-persistent-formid')
- const cached = store[key]
- if (cached !== undefined) {
- field.value = cached
- }
-
- field.addEventListener(eventName, this.persistentFieldDidUpdate.bind(this))
- }
-}
-
-PersistentForm.prototype.getPersistentStore = function () {
- let store = window.localStorage[this.persistentFormParentId || defaultKey]
- if (store && store !== 'null') {
- store = JSON.parse(store)
- } else {
- store = {}
- }
- return store
-}
-
-PersistentForm.prototype.setPersistentStore = function (newStore) {
- window.localStorage[this.persistentFormParentId || defaultKey] = JSON.stringify(newStore)
-}
-
-PersistentForm.prototype.persistentFieldDidUpdate = function (event) {
- const field = event.target
- const store = this.getPersistentStore()
- const key = field.getAttribute('data-persistent-formid')
- const val = field.value
- store[key] = val
- this.setPersistentStore(store)
-}
-
-PersistentForm.prototype.componentWillUnmount = function () {
- const fields = document.querySelectorAll('[data-persistent-formid]')
- for (var i = 0; i < fields.length; i++) {
- const field = fields[i]
- field.removeEventListener(eventName, this.persistentFieldDidUpdate.bind(this))
- }
- this.setPersistentStore({})
-}
-
diff --git a/responsive-ui/lib/tx-helper.js b/responsive-ui/lib/tx-helper.js
deleted file mode 100644
index ec19daf64..000000000
--- a/responsive-ui/lib/tx-helper.js
+++ /dev/null
@@ -1,17 +0,0 @@
-const valuesFor = require('../app/util').valuesFor
-
-module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, network) {
- log.debug('tx-helper called with params:')
- log.debug({ unapprovedTxs, unapprovedMsgs, personalMsgs, network })
-
- const txValues = network ? valuesFor(unapprovedTxs).filter(txMeta => txMeta.metamaskNetworkId === network) : valuesFor(unapprovedTxs)
- log.debug(`tx helper found ${txValues.length} unapproved txs`)
- const msgValues = valuesFor(unapprovedMsgs)
- log.debug(`tx helper found ${msgValues.length} unsigned messages`)
- let allValues = txValues.concat(msgValues)
- const personalValues = valuesFor(personalMsgs)
- log.debug(`tx helper found ${personalValues.length} unsigned personal messages`)
- allValues = allValues.concat(personalValues)
-
- return allValues.sort(txMeta => txMeta.time)
-}
diff --git a/test/unit/responsive/components/dropdown-test.js b/test/unit/responsive/components/dropdown-test.js
index 0472c541b..3ad2c390e 100644
--- a/test/unit/responsive/components/dropdown-test.js
+++ b/test/unit/responsive/components/dropdown-test.js
@@ -5,8 +5,8 @@ const h = require('react-hyperscript');
const ReactTestUtils = require('react-addons-test-utils');
const sinon = require('sinon');
const path = require('path');
-const Dropdown = require(path.join(__dirname, '..', '..', '..', '..', 'responsive-ui', 'app', 'components', 'dropdown.js')).Dropdown;
-const DropdownMenuItem = require(path.join(__dirname, '..', '..', '..', '..', 'responsive-ui', 'app', 'components', 'dropdown.js')).DropdownMenuItem;
+const Dropdown = require(path.join(__dirname, '..', '..', '..', '..', 'ui', 'app', 'components', 'dropdown.js')).Dropdown;
+const DropdownMenuItem = require(path.join(__dirname, '..', '..', '..', '..', 'ui', 'app', 'components', 'dropdown.js')).DropdownMenuItem;
describe('Dropdown components', function () {
let onClickOutside;
diff --git a/responsive-ui/.gitignore b/ui/.gitignore
index c6b1254b5..c6b1254b5 100644
--- a/responsive-ui/.gitignore
+++ b/ui/.gitignore
diff --git a/ui/app/account-detail.js b/ui/app/account-detail.js
index bed05a7fb..18c867153 100644
--- a/ui/app/account-detail.js
+++ b/ui/app/account-detail.js
@@ -3,21 +3,18 @@ const extend = require('xtend')
const Component = require('react').Component
const h = require('react-hyperscript')
const connect = require('react-redux').connect
-const CopyButton = require('./components/copyButton')
-const AccountInfoLink = require('./components/account-info-link')
const actions = require('./actions')
const ReactCSSTransitionGroup = require('react-addons-css-transition-group')
const valuesFor = require('./util').valuesFor
-
const Identicon = require('./components/identicon')
const EthBalance = require('./components/eth-balance')
const TransactionList = require('./components/transaction-list')
const ExportAccountView = require('./components/account-export')
const ethUtil = require('ethereumjs-util')
const EditableLabel = require('./components/editable-label')
-const Tooltip = require('./components/tooltip')
const TabBar = require('./components/tab-bar')
const TokenList = require('./components/token-list')
+const AccountDropdowns = require('./components/account-dropdowns').AccountDropdowns
module.exports = connect(mapStateToProps)(AccountDetailScreen)
@@ -54,12 +51,18 @@ AccountDetailScreen.prototype.render = function () {
return (
- h('.account-detail-section', [
+ h('.account-detail-section', {
+ style: {
+ height: '100%',
+ maxWidth: '850px',
+ },
+ }, [
// identicon, label, balance, etc
h('.account-data-subsection', {
style: {
margin: '0 20px',
+ flex: '1 0 auto',
},
}, [
@@ -84,6 +87,7 @@ AccountDetailScreen.prototype.render = function () {
style: {
lineHeight: '10px',
marginLeft: '15px',
+ width: '100%',
},
}, [
h(EditableLabel, {
@@ -98,7 +102,42 @@ AccountDetailScreen.prototype.render = function () {
// What is shown when not editing + edit text:
h('label.editing-label', [h('.edit-text', 'edit')]),
- h('h2.font-medium.color-forest', {name: 'edit'}, identity && identity.name),
+ h(
+ 'div',
+ {
+ style: {
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ },
+ },
+ [
+ h(
+ 'h2.font-medium.color-forest',
+ {
+ name: 'edit',
+ style: {
+ },
+ },
+ [
+ identity && identity.name,
+ ]
+ ),
+ h(
+ AccountDropdowns,
+ {
+ style: {
+ marginRight: '8px',
+ marginLeft: 'auto',
+ cursor: 'pointer',
+ },
+ selected,
+ network,
+ identities: props.identities,
+ },
+ ),
+ ]
+ ),
]),
h('.flex-row', {
style: {
@@ -124,56 +163,6 @@ AccountDetailScreen.prototype.render = function () {
color: '#AEAEAE',
},
}, checksumAddress),
-
- // copy and export
-
- h('.flex-row', {
- style: {
- justifyContent: 'flex-end',
- },
- }, [
-
- h(AccountInfoLink, { selected, network }),
-
- h(CopyButton, {
- value: checksumAddress,
- }),
-
- h(Tooltip, {
- title: 'QR Code',
- }, [
- h('i.fa.fa-qrcode.pointer.pop-hover', {
- onClick: () => props.dispatch(actions.showQrView(selected, identity ? identity.name : '')),
- style: {
- fontSize: '18px',
- position: 'relative',
- color: 'rgb(247, 134, 28)',
- top: '5px',
- marginLeft: '3px',
- marginRight: '3px',
- },
- }),
- ]),
-
- h(Tooltip, {
- title: 'Export Private Key',
- }, [
- h('div', {
- style: {
- display: 'flex',
- alignItems: 'center',
- },
- }, [
- h('img.cursor-pointer.color-orange', {
- src: 'images/key-32.png',
- onClick: () => this.requestAccountExport(selected),
- style: {
- height: '19px',
- },
- }),
- ]),
- ]),
- ]),
]),
// account ballence
@@ -197,14 +186,11 @@ AccountDetailScreen.prototype.render = function () {
},
}),
+ h('.flex-grow'),
+
h('button', {
onClick: () => props.dispatch(actions.buyEthView(selected)),
- style: {
- marginBottom: '20px',
- marginRight: '8px',
- position: 'absolute',
- left: '219px',
- },
+ style: { marginRight: '10px' },
}, 'BUY'),
h('button', {
@@ -254,7 +240,11 @@ AccountDetailScreen.prototype.subview = function () {
AccountDetailScreen.prototype.tabSections = function () {
const { currentAccountTab } = this.props
- return h('section.tabSection', [
+ return h('section.tabSection', {
+ style: {
+ height: '100%',
+ },
+ }, [
h(TabBar, {
tabs: [
@@ -305,7 +295,3 @@ AccountDetailScreen.prototype.transactionList = function () {
},
})
}
-
-AccountDetailScreen.prototype.requestAccountExport = function () {
- this.props.dispatch(actions.requestExportAccount())
-}
diff --git a/ui/app/accounts/account-list-item.js b/ui/app/accounts/account-list-item.js
deleted file mode 100644
index 10a0b6cc7..000000000
--- a/ui/app/accounts/account-list-item.js
+++ /dev/null
@@ -1,91 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const ethUtil = require('ethereumjs-util')
-
-const EthBalance = require('../components/eth-balance')
-const CopyButton = require('../components/copyButton')
-const Identicon = require('../components/identicon')
-
-module.exports = AccountListItem
-
-inherits(AccountListItem, Component)
-function AccountListItem () {
- Component.call(this)
-}
-
-AccountListItem.prototype.render = function () {
- const { identity, selectedAddress, accounts, onShowDetail,
- conversionRate, currentCurrency } = this.props
-
- const checksumAddress = identity && identity.address && ethUtil.toChecksumAddress(identity.address)
- const isSelected = selectedAddress === identity.address
- const account = accounts[identity.address]
- const selectedClass = isSelected ? '.selected' : ''
-
- return (
- h(`.accounts-list-option.flex-row.flex-space-between.pointer.hover-white${selectedClass}`, {
- key: `account-panel-${identity.address}`,
- onClick: (event) => onShowDetail(identity.address, event),
- }, [
-
- h('.identicon-wrapper.flex-column.flex-center.select-none', [
- this.pendingOrNot(),
- this.indicateIfLoose(),
- h(Identicon, {
- address: identity.address,
- imageify: true,
- }),
- ]),
-
- // account address, balance
- h('.identity-data.flex-column.flex-justify-center.flex-grow.select-none', {
- style: {
- width: '200px',
- },
- }, [
- h('span', identity.name),
- h('span.font-small', {
- style: {
- overflow: 'hidden',
- textOverflow: 'ellipsis',
- },
- }, checksumAddress),
- h(EthBalance, {
- value: account && account.balance,
- currentCurrency,
- conversionRate,
- style: {
- lineHeight: '7px',
- marginTop: '10px',
- },
- }),
- ]),
-
- // copy button
- h('.identity-copy.flex-column', {
- style: {
- margin: '0 20px',
- },
- }, [
- h(CopyButton, {
- value: checksumAddress,
- }),
- ]),
- ])
- )
-}
-
-AccountListItem.prototype.indicateIfLoose = function () {
- try { // Sometimes keyrings aren't loaded yet:
- const type = this.props.keyring.type
- const isLoose = type !== 'HD Key Tree'
- return isLoose ? h('.keyring-label', 'LOOSE') : null
- } catch (e) { return }
-}
-
-AccountListItem.prototype.pendingOrNot = function () {
- const pending = this.props.pending
- if (pending.length === 0) return null
- return h('.pending-dot', pending.length)
-}
diff --git a/ui/app/accounts/index.js b/ui/app/accounts/index.js
deleted file mode 100644
index ac2615cd7..000000000
--- a/ui/app/accounts/index.js
+++ /dev/null
@@ -1,164 +0,0 @@
-const inherits = require('util').inherits
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const connect = require('react-redux').connect
-const actions = require('../actions')
-const valuesFor = require('../util').valuesFor
-const findDOMNode = require('react-dom').findDOMNode
-const AccountListItem = require('./account-list-item')
-
-module.exports = connect(mapStateToProps)(AccountsScreen)
-
-function mapStateToProps (state) {
- const pendingTxs = valuesFor(state.metamask.unapprovedTxs)
- .filter(txMeta => txMeta.metamaskNetworkId === state.metamask.network)
- const pendingMsgs = valuesFor(state.metamask.unapprovedMsgs)
- const pending = pendingTxs.concat(pendingMsgs)
-
- return {
- accounts: state.metamask.accounts,
- identities: state.metamask.identities,
- unapprovedTxs: state.metamask.unapprovedTxs,
- selectedAddress: state.metamask.selectedAddress,
- scrollToBottom: state.appState.scrollToBottom,
- pending,
- keyrings: state.metamask.keyrings,
- conversionRate: state.metamask.conversionRate,
- currentCurrency: state.metamask.currentCurrency,
- }
-}
-
-inherits(AccountsScreen, Component)
-function AccountsScreen () {
- Component.call(this)
-}
-
-AccountsScreen.prototype.render = function () {
- const props = this.props
- const { keyrings, conversionRate, currentCurrency } = props
- const identityList = valuesFor(props.identities)
- const unapprovedTxList = valuesFor(props.unapprovedTxs)
-
- return (
-
- h('.accounts-section.flex-grow', [
-
- // subtitle and nav
- h('.section-title.flex-center', [
- h('i.fa.fa-arrow-left.fa-lg.cursor-pointer', {
- onClick: this.goHome.bind(this),
- }),
- h('h2.page-subtitle', 'Select Account'),
- ]),
-
- h('hr.horizontal-line'),
-
- // identity selection
- h('section.identity-section', {
- style: {
- height: '418px',
- overflowY: 'auto',
- overflowX: 'hidden',
- },
- },
- [
- identityList.map((identity) => {
- const pending = this.props.pending.filter((txOrMsg) => {
- if ('txParams' in txOrMsg) {
- return txOrMsg.txParams.from === identity.address
- } else if ('msgParams' in txOrMsg) {
- return txOrMsg.msgParams.from === identity.address
- } else {
- return false
- }
- })
-
- const simpleAddress = identity.address.substring(2).toLowerCase()
- const keyring = keyrings.find((kr) => {
- return kr.accounts.includes(simpleAddress) ||
- kr.accounts.includes(identity.address)
- })
-
- return h(AccountListItem, {
- key: `acct-panel-${identity.address}`,
- identity,
- selectedAddress: this.props.selectedAddress,
- conversionRate,
- currentCurrency,
- accounts: this.props.accounts,
- onShowDetail: this.onShowDetail.bind(this),
- pending,
- keyring,
- })
- }),
-
- h('hr.horizontal-line'),
- h('div.footer.hover-white.pointer', {
- key: 'reveal-account-bar',
- onClick: () => {
- this.addNewAccount()
- },
- style: {
- display: 'flex',
- height: '40px',
- padding: '10px',
- justifyContent: 'center',
- alignItems: 'center',
- },
- }, [
- h('i.fa.fa-plus.fa-lg', {key: ''}),
- ]),
- h('hr.horizontal-line'),
- ]),
-
- unapprovedTxList.length ? (
-
- h('.unconftx-link.flex-row.flex-center', {
- onClick: this.navigateToConfTx.bind(this),
- }, [
- h('span', 'Unconfirmed Txs'),
- h('i.fa.fa-arrow-right.fa-lg'),
- ])
-
- ) : (
- null
- ),
- ])
- )
-}
-
-// If a new account was revealed, scroll to the bottom
-AccountsScreen.prototype.componentDidUpdate = function () {
- const scrollToBottom = this.props.scrollToBottom
-
- if (scrollToBottom) {
- var container = findDOMNode(this)
- var scrollable = container.querySelector('.identity-section')
- scrollable.scrollTop = scrollable.scrollHeight
- }
-}
-
-AccountsScreen.prototype.navigateToConfTx = function () {
- event.stopPropagation()
- this.props.dispatch(actions.showConfTxPage())
-}
-
-AccountsScreen.prototype.onShowDetail = function (address, event) {
- event.stopPropagation()
- this.props.dispatch(actions.showAccountDetail(address))
-}
-
-AccountsScreen.prototype.addNewAccount = function () {
- this.props.dispatch(actions.addNewAccount(0))
-}
-
-/* An optional view proposed in this design:
- * https://consensys.quip.com/zZVrAysM5znY
-AccountsScreen.prototype.addNewAccount = function () {
- this.props.dispatch(actions.navigateToNewAccountScreen())
-}
-*/
-
-AccountsScreen.prototype.goHome = function () {
- this.props.dispatch(actions.goHome())
-}
diff --git a/ui/app/add-token.js b/ui/app/add-token.js
index 15ef7a852..b303b5c0d 100644
--- a/ui/app/add-token.js
+++ b/ui/app/add-token.js
@@ -86,7 +86,7 @@ AddTokenScreen.prototype.render = function () {
h('div', [
h('span', {
style: { fontWeight: 'bold', paddingRight: '10px'},
- }, 'Token Symbol'),
+ }, 'Token Sybmol'),
]),
h('div', { style: {display: 'flex'} }, [
diff --git a/ui/app/app.js b/ui/app/app.js
index 1a63002e1..d1a20f079 100644
--- a/ui/app/app.js
+++ b/ui/app/app.js
@@ -10,7 +10,6 @@ const NewKeyChainScreen = require('./new-keychain')
// unlock
const UnlockScreen = require('./unlock')
// accounts
-const AccountsScreen = require('./accounts')
const AccountDetailScreen = require('./account-detail')
const SendTransactionScreen = require('./send')
const ConfirmTxScreen = require('./conf-tx')
@@ -24,10 +23,9 @@ const Import = require('./accounts/import')
const InfoScreen = require('./info')
const Loading = require('./components/loading')
const SandwichExpando = require('sandwich-expando')
-const MenuDroppo = require('menu-droppo')
-const DropMenuItem = require('./components/drop-menu-item')
+const Dropdown = require('./components/dropdown').Dropdown
+const DropdownMenuItem = require('./components/dropdown').DropdownMenuItem
const NetworkIndicator = require('./components/network')
-const Tooltip = require('./components/tooltip')
const BuyView = require('./components/buy-button-subview')
const QrView = require('./components/qr-code')
const HDCreateVaultComplete = require('./keychains/hd/create-vault-complete')
@@ -79,6 +77,8 @@ App.prototype.render = function () {
// Windows was showing a vertical scroll bar:
overflow: 'hidden',
position: 'relative',
+ height: '100%',
+ alignItems: 'center',
},
}, [
@@ -95,8 +95,8 @@ App.prototype.render = function () {
// panel content
h('.app-primary.flex-grow' + (transForward ? '.from-right' : '.from-left'), {
style: {
- height: '380px',
- width: '360px',
+ height: '100%',
+ maxWidth: '850px',
},
}, [
h(ReactCSSTransitionGroup, {
@@ -123,14 +123,18 @@ App.prototype.renderAppBar = function () {
return (
- h('div', [
+ h('div', {
+ style: {
+ width: '100%'
+ },
+ }, [
h('.app-header.flex-row.flex-space-between', {
style: {
alignItems: 'center',
visibility: props.isUnlocked ? 'visible' : 'none',
background: props.isUnlocked ? 'white' : 'none',
- height: '36px',
+ height: '38px',
position: 'relative',
zIndex: 12,
},
@@ -178,21 +182,6 @@ App.prototype.renderAppBar = function () {
},
}, [
- // small accounts nav
- props.isUnlocked && h(Tooltip, { title: 'Switch Accounts' }, [
- h('img.cursor-pointer.color-orange', {
- src: 'images/switch_acc.svg',
- style: {
- width: '23.5px',
- marginRight: '8px',
- },
- onClick: (event) => {
- event.stopPropagation()
- this.props.dispatch(actions.showAccountsPage())
- },
- }),
- ]),
-
// hamburger
props.isUnlocked && h(SandwichExpando, {
width: 16,
@@ -214,11 +203,12 @@ App.prototype.renderAppBar = function () {
App.prototype.renderNetworkDropdown = function () {
const props = this.props
+ const { provider: { type: providerType, rpcTarget: activeNetwork } } = props
const rpcList = props.frequentRpcList
const state = this.state || {}
const isOpen = state.isNetworkMenuOpen
- return h(MenuDroppo, {
+ return h(Dropdown, {
isOpen,
onClickOutside: (event) => {
this.setState({ isNetworkMenuOpen: !isOpen })
@@ -226,72 +216,92 @@ App.prototype.renderNetworkDropdown = function () {
zIndex: 11,
style: {
position: 'absolute',
- left: 0,
+ left: '2px',
top: '36px',
},
- innerStyle: {
- background: 'white',
- boxShadow: '1px 1px 2px rgba(0,0,0,0.1)',
- },
- }, [ // DROP MENU ITEMS
- h('style', `
- .drop-menu-item:hover { background:rgb(235, 235, 235); }
- .drop-menu-item i { margin: 11px; }
- `),
-
- h(DropMenuItem, {
- label: 'Main Ethereum Network',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setProviderType('mainnet')),
- icon: h('.menu-icon.diamond'),
- activeNetworkRender: props.network,
- provider: props.provider,
- }),
-
- h(DropMenuItem, {
- label: 'Ropsten Test Network',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setProviderType('ropsten')),
- icon: h('.menu-icon.red-dot'),
- activeNetworkRender: props.network,
- provider: props.provider,
- }),
-
- h(DropMenuItem, {
- label: 'Kovan Test Network',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false}),
- action: () => props.dispatch(actions.setProviderType('kovan')),
- icon: h('.menu-icon.hollow-diamond'),
- activeNetworkRender: props.network,
- provider: props.provider,
- }),
-
- h(DropMenuItem, {
- label: 'Rinkeby Test Network',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false}),
- action: () => props.dispatch(actions.setProviderType('rinkeby')),
- icon: h('.menu-icon.golden-square'),
- activeNetworkRender: props.network,
- provider: props.provider,
- }),
-
- h(DropMenuItem, {
- label: 'Localhost 8545',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setDefaultRpcTarget(rpcList)),
- icon: h('i.fa.fa-question-circle.fa-lg'),
- activeNetworkRender: props.provider.rpcTarget,
- }),
+ innerStyle: {},
+ }, [
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('mainnet')),
+ },
+ [
+ h('.menu-icon.diamond'),
+ 'Main Ethereum Network',
+ providerType === 'mainnet' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('ropsten')),
+ },
+ [
+ h('.menu-icon.red-dot'),
+ 'Ropsten Test Network',
+ providerType === 'ropsten' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('kovan')),
+ },
+ [
+ h('.menu-icon.hollow-diamond'),
+ 'Kovan Test Network',
+ providerType === 'kovan' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setProviderType('rinkeby')),
+ },
+ [
+ h('.menu-icon.golden-square'),
+ 'Rinkeby Test Network',
+ providerType === 'rinkeby' ? h('.check', '✓') : null,
+ ]
+ ),
+
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => props.dispatch(actions.setDefaultRpcTarget(rpcList)),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Localhost 8545',
+ activeNetwork === 'http://localhost:8545' ? h('.check', '✓') : null,
+ ]
+ ),
this.renderCustomOption(props.provider),
this.renderCommonRpc(rpcList, props.provider),
- h(DropMenuItem, {
- label: 'Custom RPC',
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => this.props.dispatch(actions.showConfigPage()),
- icon: h('i.fa.fa-question-circle.fa-lg'),
- }),
+ h(
+ DropdownMenuItem,
+ {
+ closeMenu: () => this.setState({ isNetworkMenuOpen: !isOpen }),
+ onClick: () => this.props.dispatch(actions.showConfigPage()),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ 'Custom RPC',
+ activeNetwork === 'custom' ? h('.check', '✓') : null,
+ ]
+ ),
])
}
@@ -300,7 +310,7 @@ App.prototype.renderDropdown = function () {
const state = this.state || {}
const isOpen = state.isMainMenuOpen
- return h(MenuDroppo, {
+ return h(Dropdown, {
isOpen: isOpen,
zIndex: 11,
onClickOutside: (event) => {
@@ -308,46 +318,30 @@ App.prototype.renderDropdown = function () {
},
style: {
position: 'absolute',
- right: 0,
- top: '36px',
+ right: '2px',
+ top: '38px',
},
- innerStyle: {
- background: 'white',
- boxShadow: '1px 1px 2px rgba(0,0,0,0.1)',
- },
- }, [ // DROP MENU ITEMS
- h('style', `
- .drop-menu-item:hover { background:rgb(235, 235, 235); }
- .drop-menu-item i { margin: 11px; }
- `),
-
- h(DropMenuItem, {
- label: 'Settings',
+ innerStyle: {},
+ }, [
+ h(DropdownMenuItem, {
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- action: () => this.props.dispatch(actions.showConfigPage()),
- icon: h('i.fa.fa-gear.fa-lg'),
- }),
+ onClick: () => { this.props.dispatch(actions.showConfigPage()) },
+ }, 'Settings'),
- h(DropMenuItem, {
- label: 'Import Account',
+ h(DropdownMenuItem, {
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- action: () => this.props.dispatch(actions.showImportPage()),
- icon: h('i.fa.fa-arrow-circle-o-up.fa-lg'),
- }),
+ onClick: () => { this.props.dispatch(actions.showImportPage()) },
+ }, 'Import Account'),
- h(DropMenuItem, {
- label: 'Lock',
+ h(DropdownMenuItem, {
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- action: () => this.props.dispatch(actions.lockMetamask()),
- icon: h('i.fa.fa-lock.fa-lg'),
- }),
+ onClick: () => { this.props.dispatch(actions.lockMetamask()) },
+ }, 'Lock'),
- h(DropMenuItem, {
- label: 'Info/Help',
+ h(DropdownMenuItem, {
closeMenu: () => this.setState({ isMainMenuOpen: !isOpen }),
- action: () => this.props.dispatch(actions.showInfoPage()),
- icon: h('i.fa.fa-question.fa-lg'),
- }),
+ onClick: () => { this.props.dispatch(actions.showInfoPage()) },
+ }, 'Info/Help'),
])
}
@@ -433,10 +427,6 @@ App.prototype.renderPrimary = function () {
// show current view
switch (props.currentView.name) {
- case 'accounts':
- log.debug('rendering accounts screen')
- return h(AccountsScreen, {key: 'accounts'})
-
case 'accountDetail':
log.debug('rendering account detail screen')
return h(AccountDetailScreen, {key: 'account-detail'})
@@ -539,13 +529,18 @@ App.prototype.renderCustomOption = function (provider) {
return null
default:
- return h(DropMenuItem, {
- label,
- key: rpcTarget,
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- icon: h('i.fa.fa-question-circle.fa-lg'),
- activeNetworkRender: 'custom',
- })
+ return h(
+ DropdownMenuItem,
+ {
+ key: rpcTarget,
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ label,
+ h('.check', '✓'),
+ ]
+ )
}
}
@@ -578,14 +573,19 @@ App.prototype.renderCommonRpc = function (rpcList, provider) {
if ((rpc === 'http://localhost:8545') || (rpc === rpcTarget)) {
return null
} else {
- return h(DropMenuItem, {
- label: rpc,
- key: rpc,
- closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
- action: () => props.dispatch(actions.setRpcTarget(rpc)),
- icon: h('i.fa.fa-question-circle.fa-lg'),
- activeNetworkRender: rpc,
- })
+ return h(
+ DropdownMenuItem,
+ {
+ key: rpc,
+ closeMenu: () => this.setState({ isNetworkMenuOpen: false }),
+ action: () => props.dispatch(actions.setRpcTarget(rpc)),
+ },
+ [
+ h('i.fa.fa-question-circle.fa-lg.menu-icon'),
+ rpc,
+ h('.check', '✓'),
+ ]
+ )
}
})
}
diff --git a/responsive-ui/app/components/account-dropdowns.js b/ui/app/components/account-dropdowns.js
index d1d319477..d1d319477 100644
--- a/responsive-ui/app/components/account-dropdowns.js
+++ b/ui/app/components/account-dropdowns.js
diff --git a/ui/app/components/account-info-link.js b/ui/app/components/account-info-link.js
deleted file mode 100644
index 6526ab502..000000000
--- a/ui/app/components/account-info-link.js
+++ /dev/null
@@ -1,41 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-const Tooltip = require('./tooltip')
-const genAccountLink = require('../../lib/account-link')
-
-module.exports = AccountInfoLink
-
-inherits(AccountInfoLink, Component)
-function AccountInfoLink () {
- Component.call(this)
-}
-
-AccountInfoLink.prototype.render = function () {
- const { selected, network } = this.props
- const title = 'View account on Etherscan'
- const url = genAccountLink(selected, network)
-
- if (!url) {
- return null
- }
-
- return h('.account-info-link', {
- style: {
- display: 'flex',
- alignItems: 'center',
- },
- }, [
-
- h(Tooltip, {
- title,
- }, [
- h('i.fa.fa-info-circle.cursor-pointer.color-orange', {
- style: {
- margin: '5px',
- },
- onClick () { global.platform.openWindow({ url }) },
- }),
- ]),
- ])
-}
diff --git a/ui/app/components/drop-menu-item.js b/ui/app/components/drop-menu-item.js
deleted file mode 100644
index e42948209..000000000
--- a/ui/app/components/drop-menu-item.js
+++ /dev/null
@@ -1,59 +0,0 @@
-const Component = require('react').Component
-const h = require('react-hyperscript')
-const inherits = require('util').inherits
-
-module.exports = DropMenuItem
-
-inherits(DropMenuItem, Component)
-function DropMenuItem () {
- Component.call(this)
-}
-
-DropMenuItem.prototype.render = function () {
- return h('li.drop-menu-item', {
- onClick: () => {
- this.props.closeMenu()
- this.props.action()
- },
- style: {
- listStyle: 'none',
- padding: '6px 16px 6px 5px',
- fontFamily: 'Montserrat Regular',
- color: 'rgb(125, 128, 130)',
- cursor: 'pointer',
- display: 'flex',
- justifyContent: 'flex-start',
- },
- }, [
- this.props.icon,
- this.props.label,
- this.activeNetworkRender(),
- ])
-}
-
-DropMenuItem.prototype.activeNetworkRender = function () {
- const activeNetwork = this.props.activeNetworkRender
- const { provider } = this.props
- const providerType = provider ? provider.type : null
- if (activeNetwork === undefined) return
-
- switch (this.props.label) {
- case 'Main Ethereum Network':
- if (providerType === 'mainnet') return h('.check', '✓')
- break
- case 'Ropsten Test Network':
- if (providerType === 'ropsten') return h('.check', '✓')
- break
- case 'Kovan Test Network':
- if (providerType === 'kovan') return h('.check', '✓')
- break
- case 'Rinkeby Test Network':
- if (providerType === 'rinkeby') return h('.check', '✓')
- break
- case 'Localhost 8545':
- if (activeNetwork === 'http://localhost:8545') return h('.check', '✓')
- break
- default:
- if (activeNetwork === 'custom') return h('.check', '✓')
- }
-}
diff --git a/responsive-ui/app/components/dropdown.js b/ui/app/components/dropdown.js
index e77b4c40c..e77b4c40c 100644
--- a/responsive-ui/app/components/dropdown.js
+++ b/ui/app/components/dropdown.js
diff --git a/ui/app/components/editable-label.js b/ui/app/components/editable-label.js
index 41936f5e0..167be7eaf 100644
--- a/ui/app/components/editable-label.js
+++ b/ui/app/components/editable-label.js
@@ -30,7 +30,12 @@ EditableLabel.prototype.render = function () {
} else {
return h('div.name-label', {
onClick: (event) => {
- this.setState({ isEditingLabel: true })
+ const nameAttribute = event.target.getAttribute('name')
+ // checks for class to handle smaller CTA above the account name
+ const classAttribute = event.target.getAttribute('class')
+ if (nameAttribute === 'edit' || classAttribute === 'edit-text') {
+ this.setState({ isEditingLabel: true })
+ }
},
}, this.props.children)
}
diff --git a/ui/app/components/pending-tx.js b/ui/app/components/pending-tx.js
index 5324ccd64..d7d602f31 100644
--- a/ui/app/components/pending-tx.js
+++ b/ui/app/components/pending-tx.js
@@ -15,7 +15,7 @@ const addressSummary = util.addressSummary
const nameForAddress = require('../../lib/contract-namer')
const BNInput = require('./bn-as-decimal-input')
-const MIN_GAS_PRICE_GWEI_BN = new BN(1)
+const MIN_GAS_PRICE_GWEI_BN = new BN(2)
const GWEI_FACTOR = new BN(1e9)
const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR)
const MIN_GAS_LIMIT_BN = new BN(21000)
diff --git a/ui/app/components/transaction-list.js b/ui/app/components/transaction-list.js
index 3b4ba741e..ae6aaec8c 100644
--- a/ui/app/components/transaction-list.js
+++ b/ui/app/components/transaction-list.js
@@ -24,7 +24,11 @@ TransactionList.prototype.render = function () {
return (
- h('section.transaction-list', [
+ h('section.transaction-list', {
+ style: {
+ height: '100%',
+ },
+ }, [
h('style', `
.transaction-list .transaction-list-item:not(:last-of-type) {
@@ -39,7 +43,7 @@ TransactionList.prototype.render = function () {
h('.tx-list', {
style: {
overflowY: 'auto',
- height: '300px',
+ height: '100%',
padding: '0 20px',
textAlign: 'center',
},
diff --git a/ui/app/css/index.css b/ui/app/css/index.css
index 808aafb4c..2ae92bbd6 100644
--- a/ui/app/css/index.css
+++ b/ui/app/css/index.css
@@ -19,6 +19,15 @@ html, body {
font-weight: 300;
line-height: 1.4em;
background: #F7F7F7;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.css-transition-group {
+ flex: 1;
+ height: 100%;
}
input:focus, textarea:focus {
@@ -28,8 +37,7 @@ input:focus, textarea:focus {
#app-content {
overflow-x: hidden;
min-width: 357px;
- width: 360px;
- height: 500px;
+ height: 100%;
}
button, input[type="submit"] {
@@ -403,7 +411,8 @@ input.large-input {
/* account detail screen */
.account-detail-section {
-
+ display: flex;
+ flex-wrap: wrap;
}
.name-label{
diff --git a/ui/app/css/lib.css b/ui/app/css/lib.css
index 910a24ee2..b0ca958a2 100644
--- a/ui/app/css/lib.css
+++ b/ui/app/css/lib.css
@@ -232,6 +232,10 @@ hr.horizontal-line {
align-items: center;
}
+.tabSection {
+ min-width: 350px;
+}
+
.menu-icon {
display: inline-block;
height: 9px;
diff --git a/ui/app/info.js b/ui/app/info.js
index cb2e41f5b..e8470de97 100644
--- a/ui/app/info.js
+++ b/ui/app/info.js
@@ -97,17 +97,11 @@ InfoScreen.prototype.render = function () {
paddingLeft: '30px',
}},
[
- h('div.fa.fa-support', [
- h('a.info', {
- href: 'http://metamask.consensyssupport.happyfox.com',
- target: '_blank',
- }, 'Visit our Support Center'),
- ]),
h('div.fa.fa-github', [
h('a.info', {
- href: 'https://github.com/MetaMask/metamask-extension/issues/new',
+ href: 'https://github.com/MetaMask/faq',
target: '_blank',
- }, 'Found a bug? Report it!'),
+ }, 'Need Help? Read our FAQ!'),
]),
h('div', [
h('a', {
diff --git a/ui/app/keychains/hd/create-vault-complete.js b/ui/app/keychains/hd/create-vault-complete.js
index a318a9b50..c32751fff 100644
--- a/ui/app/keychains/hd/create-vault-complete.js
+++ b/ui/app/keychains/hd/create-vault-complete.js
@@ -47,8 +47,6 @@ CreateVaultCompleteScreen.prototype.render = function () {
h('div', {
style: {
- width: '360px',
- height: '78px',
fontSize: '1em',
marginTop: '10px',
textAlign: 'center',
diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js
index afc62e7b6..ec19daf64 100644
--- a/ui/lib/tx-helper.js
+++ b/ui/lib/tx-helper.js
@@ -12,10 +12,6 @@ module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, network)
const personalValues = valuesFor(personalMsgs)
log.debug(`tx helper found ${personalValues.length} unsigned personal messages`)
allValues = allValues.concat(personalValues)
- allValues = allValues.sort((a, b) => {
- return a.time > b.time
- })
- return allValues
+ return allValues.sort(txMeta => txMeta.time)
}
-