Repository: joincivil/Civil Branch: master Commit: b337712f3b97 Files: 1466 Total size: 8.9 MB Directory structure: gitextract_g8jrarxw/ ├── .circleci/ │ └── config.yml ├── .dockerignore ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .prettierignore ├── .prettierrc.yaml ├── .releaserc ├── .vscode/ │ ├── launch.json │ └── settings.json ├── Dockerfile-dapp ├── README.md ├── commitlint.config.js ├── lerna.json ├── package.json ├── packages/ │ ├── artifacts/ │ │ ├── package.json │ │ └── v1/ │ │ ├── ACL.json │ │ ├── AddressRegistry.json │ │ ├── AttributeStore.json │ │ ├── CVLToken.json │ │ ├── CivilPLCRVoting.json │ │ ├── CivilParameterizer.json │ │ ├── CivilTCR.json │ │ ├── CivilTokenController.json │ │ ├── ContractAddressRegistry.json │ │ ├── CreateNewsroomInGroup.json │ │ ├── DLL.json │ │ ├── DummyACL.json │ │ ├── DummyTokenTelemetry.json │ │ ├── ECRecovery.json │ │ ├── ERC1404.json │ │ ├── ERC20.json │ │ ├── ERC20Detailed.json │ │ ├── EventStorage.json │ │ ├── Factory.json │ │ ├── Government.json │ │ ├── IERC20.json │ │ ├── IGovernment.json │ │ ├── IMultiSigWalletFactory.json │ │ ├── Managed.json │ │ ├── ManagedWhitelist.json │ │ ├── MessagesAndCodes.json │ │ ├── Migrations.json │ │ ├── MultiSigWallet.json │ │ ├── MultiSigWalletFactory.json │ │ ├── Newsroom.json │ │ ├── NewsroomFactory.json │ │ ├── NoOpTokenController.json │ │ ├── Ownable.json │ │ ├── PLCRVoting.json │ │ ├── Parameterizer.json │ │ ├── RBAC.json │ │ ├── RestrictedAddressRegistry.json │ │ ├── Roles.json │ │ ├── RootCommits.json │ │ ├── SafeMath.json │ │ ├── TokenTelemetryI.json │ │ ├── UniswapExchange.json │ │ ├── UniswapFactory.json │ │ └── Whitelist.json │ ├── components/ │ │ ├── .babelrc │ │ ├── .gitignore │ │ ├── .releaserc │ │ ├── .storybook/ │ │ │ ├── config.ts │ │ │ ├── preview-head.html │ │ │ ├── register-context.ts │ │ │ └── webpack.config.js │ │ ├── LICENSE │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── src/ │ │ │ ├── Account/ │ │ │ │ ├── Auth/ │ │ │ │ │ ├── AuthStyledComponents.tsx │ │ │ │ │ ├── AuthTextComponents.tsx │ │ │ │ │ ├── ConfirmEmailToken.tsx │ │ │ │ │ ├── EmailAuth.stories.tsx │ │ │ │ │ ├── EmailAuth.tsx │ │ │ │ │ ├── EmailSent.tsx │ │ │ │ │ ├── EthAuth.tsx │ │ │ │ │ ├── UserSetAvatar.stories.tsx │ │ │ │ │ ├── UserSetAvatar.tsx │ │ │ │ │ ├── UserSetEmail.stories.tsx │ │ │ │ │ ├── UserSetEmail.tsx │ │ │ │ │ ├── UserSetHandle.tsx │ │ │ │ │ ├── VerifyToken.stories.tsx │ │ │ │ │ ├── VerifyToken.tsx │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ ├── EmailAuth.stories.storyshot │ │ │ │ │ ├── EthAuth.stories.storyshot │ │ │ │ │ ├── UserSetAvatar.stories.storyshot │ │ │ │ │ ├── UserSetEmail.stories.storyshot │ │ │ │ │ └── VerifyToken.stories.storyshot │ │ │ │ ├── LoadUser.tsx │ │ │ │ └── index.ts │ │ │ ├── AddressWithCopyButton.tsx │ │ │ ├── AddressWithMetaMaskIcon.tsx │ │ │ ├── ApplicationPhaseStatusLabels.stories.tsx │ │ │ ├── ApplicationPhaseStatusLabels.tsx │ │ │ ├── AuthenticatedRoute.tsx │ │ │ ├── BrowserCompatible/ │ │ │ │ ├── BrowserCompatible.stories.tsx │ │ │ │ ├── BrowserCompatible.tsx │ │ │ │ ├── BrowserCompatibleStyledComponents.tsx │ │ │ │ ├── BrowserCompatibleTextComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── BrowserCompatible.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── Button.stories.tsx │ │ │ ├── Button.tsx │ │ │ ├── Card/ │ │ │ │ ├── Card.stories.tsx │ │ │ │ ├── Card.tsx │ │ │ │ ├── CardStyledComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Card.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── CardTransactionButton.tsx │ │ │ ├── ChallengeResultsChart/ │ │ │ │ ├── ChallengeResults.stories.tsx │ │ │ │ ├── ChallengeResults.tsx │ │ │ │ ├── ChallengeResultsChartTextComponents.tsx │ │ │ │ ├── UserVotingSummary.tsx │ │ │ │ ├── VoteTypeSummaryRow.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ChallengeResults.stories.storyshot │ │ │ │ ├── constants.ts │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ ├── types.d.ts │ │ │ │ └── types.ts │ │ │ ├── ChevronAnchor.stories.tsx │ │ │ ├── ChevronAnchor.tsx │ │ │ ├── ChevronAnchorLeft.tsx │ │ │ ├── ClaimRewards.tsx │ │ │ ├── ClipLoader.tsx │ │ │ ├── Collapsable.stories.tsx │ │ │ ├── Collapsable.tsx │ │ │ ├── Comments/ │ │ │ │ ├── CommentsCount.tsx │ │ │ │ ├── CommentsStyledComponents.tsx │ │ │ │ └── index.ts │ │ │ ├── Contributors/ │ │ │ │ ├── ContributorCount.tsx │ │ │ │ ├── Contributors.stories.tsx │ │ │ │ ├── Contributors.tsx │ │ │ │ ├── ContributorsDefaultAvatar.tsx │ │ │ │ ├── ContributorsStyledComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Contributors.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── CopyToClipboard/ │ │ │ │ ├── CopyStyledComponents.tsx │ │ │ │ ├── CopyURL.stories.tsx │ │ │ │ ├── CopyURL.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── CopyURL.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── CurrencyConverter/ │ │ │ │ ├── CurrencyConverted.tsx │ │ │ │ ├── CurrencyConverter.stories.tsx │ │ │ │ ├── CurrencyConverter.tsx │ │ │ │ ├── CurrencyConverterStyledComponents.tsx │ │ │ │ ├── CurrencyConverterTextComponents.tsx │ │ │ │ ├── UsdEthConverter.tsx │ │ │ │ ├── UsdEthCvlConverter.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── CurrencyConverter.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── DAppMessageContent/ │ │ │ │ ├── ErrorLoadingData.tsx │ │ │ │ ├── ErrorNotFound.tsx │ │ │ │ ├── InsufficientCVL.tsx │ │ │ │ ├── WrongNetwork.tsx │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ ├── textComponents.tsx │ │ │ │ └── types.ts │ │ │ ├── DetailTransactionButton.stories.tsx │ │ │ ├── DetailTransactionButton.tsx │ │ │ ├── DetailsButtonComponent.tsx │ │ │ ├── EmailSignup/ │ │ │ │ ├── EmailSignup.stories.tsx │ │ │ │ ├── EmailSignup.tsx │ │ │ │ ├── EmailSignupSuccess.tsx │ │ │ │ ├── EmailStyledComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── EmailSignup.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── EthAddressViewer/ │ │ │ │ ├── EthAddressViewer.stories.tsx │ │ │ │ ├── EthAddressViewer.tsx │ │ │ │ ├── StyledEthAddressViewer.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── EthAddressViewer.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── ExecuteOnMount.tsx │ │ │ ├── FullscreenModal.tsx │ │ │ ├── GasEstimate.tsx │ │ │ ├── Heading.stories.tsx │ │ │ ├── Heading.tsx │ │ │ ├── HelmetHelper.tsx │ │ │ ├── Hero/ │ │ │ │ ├── Hero.stories.tsx │ │ │ │ ├── Hero.tsx │ │ │ │ ├── HeroStyledComponents.tsx │ │ │ │ ├── HeroTextComponents.tsx │ │ │ │ ├── HomepageHero.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Hero.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── Layout/ │ │ │ │ ├── index.ts │ │ │ │ └── styledComponents.tsx │ │ │ ├── ListingDetailHeader/ │ │ │ │ ├── EthereumInfoModal.tsx │ │ │ │ ├── ListingDetailHeader.stories.tsx │ │ │ │ ├── ListingDetailHeader.tsx │ │ │ │ ├── ListingDetailHeaderStyledComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ListingDetailHeader.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── ListingDetailPhaseCard/ │ │ │ │ ├── AppealAwaitingDecisionCard.tsx │ │ │ │ ├── AppealChallengeCommitVoteCard.tsx │ │ │ │ ├── AppealChallengeResolveCard.tsx │ │ │ │ ├── AppealChallengeRevealVoteCard.tsx │ │ │ │ ├── AppealDecisionCard.tsx │ │ │ │ ├── AppealDecisionDetail.tsx │ │ │ │ ├── AppealResolveCard.tsx │ │ │ │ ├── ChallengeCommitVoteCard.tsx │ │ │ │ ├── ChallengePhaseDetail.tsx │ │ │ │ ├── ChallengeRequestAppealCard.tsx │ │ │ │ ├── ChallengeResolveCard.tsx │ │ │ │ ├── ChallengeRevealVoteCard.tsx │ │ │ │ ├── CommitVote.tsx │ │ │ │ ├── CompleteChallengeResults.tsx │ │ │ │ ├── InApplicationCard.tsx │ │ │ │ ├── InApplicationResolveCard.tsx │ │ │ │ ├── ListingDetailsPhaseCard.stories.tsx │ │ │ │ ├── NeedHelp.tsx │ │ │ │ ├── RejectedCard.tsx │ │ │ │ ├── RevealVote.tsx │ │ │ │ ├── SaltField.tsx │ │ │ │ ├── VoteButton.tsx │ │ │ │ ├── WhitelistedCard.tsx │ │ │ │ ├── WithdrawnCard.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ListingDetailsPhaseCard.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ ├── textComponents.tsx │ │ │ │ └── types.ts │ │ │ ├── ListingHistoryEvent/ │ │ │ │ ├── AppealGrantedEvent.tsx │ │ │ │ ├── AppealRequestedEvent.tsx │ │ │ │ ├── ApplicationEvent.tsx │ │ │ │ ├── ChallengeEvent.tsx │ │ │ │ ├── ChallengeFailedEvent.tsx │ │ │ │ ├── ChallengeSucceededEvent.tsx │ │ │ │ ├── DepositEvent.tsx │ │ │ │ ├── EventDate.tsx │ │ │ │ ├── GrantedAppealChallengedEvent.tsx │ │ │ │ ├── ListingHistoryEvent.stories.tsx │ │ │ │ ├── ListingHistoryEvent.tsx │ │ │ │ ├── ListingWithdrawnEvent.tsx │ │ │ │ ├── RejectedEvent.tsx │ │ │ │ ├── TouchAndRemovedEvent.tsx │ │ │ │ ├── WhitelistedEvent.tsx │ │ │ │ ├── WithdrawalEvent.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ListingHistoryEvent.stories.storyshot │ │ │ │ ├── constants.ts │ │ │ │ ├── index.tsx │ │ │ │ └── types.ts │ │ │ ├── ListingSummary/ │ │ │ │ ├── AppealJudgementBanner.tsx │ │ │ │ ├── ChallengeOrAppealStatementSummary.tsx │ │ │ │ ├── ChallengeResults.tsx │ │ │ │ ├── ChallengeResultsBanner.tsx │ │ │ │ ├── DepositOrStakeAmount.tsx │ │ │ │ ├── ListingPhaseLabel.tsx │ │ │ │ ├── ListingSummary.stories.tsx │ │ │ │ ├── ListingSummary.tsx │ │ │ │ ├── ListingSummaryApproved.tsx │ │ │ │ ├── ListingSummaryBase.tsx │ │ │ │ ├── ListingSummaryList.tsx │ │ │ │ ├── ListingSummaryReadyToUpdate.tsx │ │ │ │ ├── ListingSummaryRejected.tsx │ │ │ │ ├── ListingSummaryUnderChallenge.tsx │ │ │ │ ├── NewsroomInfo.tsx │ │ │ │ ├── NewsroomTagline.tsx │ │ │ │ ├── PhaseCountdownOrTimestamp.tsx │ │ │ │ ├── SummaryActionButton.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ListingSummary.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ ├── textComponents.tsx │ │ │ │ └── types.ts │ │ │ ├── LoadingIndicator.stories.tsx │ │ │ ├── LoadingIndicator.tsx │ │ │ ├── LoadingMessage.stories.tsx │ │ │ ├── LoadingMessage.tsx │ │ │ ├── Message.stories.tsx │ │ │ ├── Message.tsx │ │ │ ├── MetaMaskLogoButton.tsx │ │ │ ├── MetaMaskModal.stories.tsx │ │ │ ├── MetaMaskModal.tsx │ │ │ ├── Modal.stories.tsx │ │ │ ├── Modal.tsx │ │ │ ├── ModalContent.stories.tsx │ │ │ ├── ModalContent.tsx │ │ │ ├── NavBar/ │ │ │ │ └── __snapshots__/ │ │ │ │ └── NavBar.stories.storyshot │ │ │ ├── Notice/ │ │ │ │ ├── Notice.stories.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Notice.stories.storyshot │ │ │ │ └── index.tsx │ │ │ ├── Parameterizer/ │ │ │ │ ├── ChallengeProposal.tsx │ │ │ │ ├── ChallengeProposalCommitVote.tsx │ │ │ │ ├── ChallengeProposalRevealVote.tsx │ │ │ │ ├── ChallengeProposalReviewVote.tsx │ │ │ │ ├── CreateGovtProposal.tsx │ │ │ │ ├── CreateProposal.tsx │ │ │ │ ├── Parameterizer.stories.tsx │ │ │ │ ├── ParameterizerStyledComponents.tsx │ │ │ │ ├── ParameterizerTableCell.tsx │ │ │ │ ├── ProcessProposal.tsx │ │ │ │ ├── ResolveChallengeProposal.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Parameterizer.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── textComponents.tsx │ │ │ ├── Payments/ │ │ │ │ ├── AvatarLogin.tsx │ │ │ │ ├── PaymentIntentsStripeForm.tsx │ │ │ │ ├── Payments.stories.tsx │ │ │ │ ├── Payments.tsx │ │ │ │ ├── PaymentsAmount.tsx │ │ │ │ ├── PaymentsApplePay.tsx │ │ │ │ ├── PaymentsEth.tsx │ │ │ │ ├── PaymentsEthForm.tsx │ │ │ │ ├── PaymentsEthUpdateAmount.tsx │ │ │ │ ├── PaymentsEthWrapper.tsx │ │ │ │ ├── PaymentsFormWrapper.tsx │ │ │ │ ├── PaymentsGooglePay.tsx │ │ │ │ ├── PaymentsInputValidationUI.tsx │ │ │ │ ├── PaymentsLoadStripePayRequest.tsx │ │ │ │ ├── PaymentsLoginOrGuest.tsx │ │ │ │ ├── PaymentsModal.tsx │ │ │ │ ├── PaymentsRadio.tsx │ │ │ │ ├── PaymentsRequest.tsx │ │ │ │ ├── PaymentsSelectType.tsx │ │ │ │ ├── PaymentsStripe.tsx │ │ │ │ ├── PaymentsStripeCardComponent.tsx │ │ │ │ ├── PaymentsStripeForm.tsx │ │ │ │ ├── PaymentsStripeFormSavedCard.tsx │ │ │ │ ├── PaymentsStyledComponents.tsx │ │ │ │ ├── PaymentsSuccess.tsx │ │ │ │ ├── PaymentsTextComponents.tsx │ │ │ │ ├── PaymentsWrapper.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Payments.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ ├── queries.ts │ │ │ │ └── types.ts │ │ │ ├── PhaseCountdown/ │ │ │ │ ├── PhaseCountdown.stories.tsx │ │ │ │ ├── ProgressBarCountdownTimer.tsx │ │ │ │ ├── SmallProgressBarCountdownTimer.tsx │ │ │ │ ├── TextCountdownTimer.tsx │ │ │ │ ├── TwoPhaseProgressBarCountdownTimer.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── PhaseCountdown.stories.storyshot │ │ │ │ ├── constants.ts │ │ │ │ ├── index.tsx │ │ │ │ ├── styledComponents.tsx │ │ │ │ ├── textComponents.tsx │ │ │ │ └── types.ts │ │ │ ├── ProgressModalContent.tsx │ │ │ ├── QuestionToolTip.stories.tsx │ │ │ ├── QuestionToolTip.tsx │ │ │ ├── RegistryEmpty/ │ │ │ │ ├── index.ts │ │ │ │ └── styledComponents.tsx │ │ │ ├── RescueTokens.tsx │ │ │ ├── ReviewVote/ │ │ │ │ ├── ReviewVote.stories.tsx │ │ │ │ ├── ReviewVoteModal.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── ReviewVote.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ └── textComponents.tsx │ │ │ ├── Share/ │ │ │ │ ├── Share.stories.tsx │ │ │ │ └── __snapshots__/ │ │ │ │ └── Share.stories.storyshot │ │ │ ├── SignConstitutionButton.stories.tsx │ │ │ ├── SignConstitutionButton.tsx │ │ │ ├── SnackBar/ │ │ │ │ ├── SnackBar.tsx │ │ │ │ ├── index.ts │ │ │ │ └── styledComponents.tsx │ │ │ ├── StepProcess/ │ │ │ │ ├── StepHeader.tsx │ │ │ │ ├── StepProcess.stories.tsx │ │ │ │ ├── StepProcess.tsx │ │ │ │ ├── StepProcessTopNav/ │ │ │ │ │ ├── Step.tsx │ │ │ │ │ ├── StepProcessTopNav.stories.tsx │ │ │ │ │ ├── StepProcessTopNav.tsx │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── StepProcessTopNav.stories.storyshot │ │ │ │ │ └── index.ts │ │ │ │ ├── StepProcessTopNavNoButtons/ │ │ │ │ │ ├── Step.tsx │ │ │ │ │ ├── StepProcessTopNav.stories.tsx │ │ │ │ │ ├── StepProcessTopNavNoButtons.tsx │ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ │ └── StepProcessTopNav.stories.storyshot │ │ │ │ │ └── index.ts │ │ │ │ ├── StepStyled.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── StepProcess.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── StoryFeed/ │ │ │ │ ├── StoryNewsroomStatus.tsx │ │ │ │ └── index.ts │ │ │ ├── TCRUserDashboard/ │ │ │ │ ├── Dashboard.tsx │ │ │ │ ├── DashboardActivity.tsx │ │ │ │ ├── DashboardActivityItem.tsx │ │ │ │ ├── DashboardActivityItemCTAButton.tsx │ │ │ │ ├── DashboardActivityItemTask.tsx │ │ │ │ ├── DashboardActivityItemTitle.tsx │ │ │ │ ├── DashboardActivityProposalItemCTAButton.tsx │ │ │ │ ├── DashboardActivitySelectableItem.tsx │ │ │ │ ├── DashboardActivityTabTitle.tsx │ │ │ │ ├── DashboardNewsroom.tsx │ │ │ │ ├── DashboardNewsroomProceeds.tsx │ │ │ │ ├── DashboardNewsroomStripeConnect.tsx │ │ │ │ ├── DashboardNewsroomSubmitLink.tsx │ │ │ │ ├── DashboardStyledComponents.tsx │ │ │ │ ├── DashboardTextComponents.tsx │ │ │ │ ├── DashboardTransferTokenForm.tsx │ │ │ │ ├── DashboardTypes.ts │ │ │ │ ├── DashboardUserInfoSummary.tsx │ │ │ │ ├── DashboardUserProfileSummary.tsx │ │ │ │ ├── NoNewsrooms.tsx │ │ │ │ └── index.ts │ │ │ ├── Table/ │ │ │ │ ├── Table.stories.tsx │ │ │ │ ├── Table.tsx │ │ │ │ ├── TableCell.tsx │ │ │ │ ├── TableHeader.tsx │ │ │ │ ├── Tr.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Table.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ ├── styledComponents.tsx │ │ │ │ └── types.ts │ │ │ ├── Tabs/ │ │ │ │ ├── Tab.tsx │ │ │ │ ├── TabTitles.tsx │ │ │ │ ├── Tabs.stories.tsx │ │ │ │ ├── Tabs.tsx │ │ │ │ ├── TabsStyled.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Tabs.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── textComponents.tsx │ │ │ ├── Tokens/ │ │ │ │ ├── EthereumTransactionButton.tsx │ │ │ │ ├── TokenPurchaseSummary.tsx │ │ │ │ ├── Tokens.tsx │ │ │ │ ├── TokensAccount.stories.tsx │ │ │ │ ├── TokensAccountBuy.tsx │ │ │ │ ├── TokensAccountFaq.tsx │ │ │ │ ├── TokensAccountHelp.tsx │ │ │ │ ├── TokensAccountPaypal.tsx │ │ │ │ ├── TokensAccountProgress.tsx │ │ │ │ ├── TokensAccountRequirement.tsx │ │ │ │ ├── TokensAccountSignup.tsx │ │ │ │ ├── TokensStyledComponents.tsx │ │ │ │ ├── TokensTextComponents.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── TokensAccount.stories.storyshot │ │ │ │ ├── buy/ │ │ │ │ │ ├── AirswapBuyCVL.tsx │ │ │ │ │ ├── AirswapBuySection.tsx │ │ │ │ │ ├── TokensTabBuy.stories.tsx │ │ │ │ │ ├── TokensTabBuy.tsx │ │ │ │ │ ├── TokensTabBuyActive.tsx │ │ │ │ │ ├── TokensTabBuyComplete.tsx │ │ │ │ │ ├── UniswapBuy.tsx │ │ │ │ │ ├── UniswapBuySection.tsx │ │ │ │ │ └── __snapshots__/ │ │ │ │ │ └── TokensTabBuy.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── sell/ │ │ │ │ ├── TokensTabSell.stories.tsx │ │ │ │ ├── TokensTabSell.tsx │ │ │ │ ├── TokensTabSellActive.tsx │ │ │ │ ├── TokensTabSellComplete.tsx │ │ │ │ ├── UniswapCvlEthConverter.tsx │ │ │ │ ├── UniswapSell.tsx │ │ │ │ ├── UniswapSellSection.tsx │ │ │ │ └── __snapshots__/ │ │ │ │ └── TokensTabSell.stories.storyshot │ │ │ ├── ToolTip.tsx │ │ │ ├── TransactionButton.tsx │ │ │ ├── Tutorial/ │ │ │ │ ├── Tutorial.stories.tsx │ │ │ │ ├── TutorialFooter.tsx │ │ │ │ ├── TutorialInfo.tsx │ │ │ │ ├── TutorialProgress.tsx │ │ │ │ ├── TutorialQuestion.tsx │ │ │ │ ├── TutorialRadio.tsx │ │ │ │ ├── TutorialStyledComponents.tsx │ │ │ │ ├── TutorialTextComponents.tsx │ │ │ │ ├── TutorialTopicCompleted.tsx │ │ │ │ ├── TutorialTopicIntro.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── Tutorial.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── UserStatement/ │ │ │ │ ├── RequestAppealStatement.tsx │ │ │ │ ├── SubmitAppealChallengeStatement.tsx │ │ │ │ ├── SubmitChallengeStatement.tsx │ │ │ │ ├── UserStatement.stories.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── UserStatement.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── styledComponents.tsx │ │ │ ├── ViewTransactionLink.stories.tsx │ │ │ ├── ViewTransactionLink.tsx │ │ │ ├── WalletOnboarding.stories.tsx │ │ │ ├── WalletOnboarding.tsx │ │ │ ├── WalletOnboardingV2/ │ │ │ │ ├── WalletOnboardingV2.connected.stories.tsx │ │ │ │ ├── WalletOnboardingV2.decorator.stories.tsx │ │ │ │ ├── WalletOnboardingV2.disabled.stories.tsx │ │ │ │ ├── WalletOnboardingV2.locked.stories.tsx │ │ │ │ ├── WalletOnboardingV2.mismatch.stories.tsx │ │ │ │ ├── WalletOnboardingV2.network.stories.tsx │ │ │ │ ├── WalletOnboardingV2.provider.stories.tsx │ │ │ │ ├── WalletOnboardingV2.save.stories.tsx │ │ │ │ ├── WalletOnboardingV2.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ ├── WalletOnboardingV2.connected.stories.storyshot │ │ │ │ │ ├── WalletOnboardingV2.disabled.stories.storyshot │ │ │ │ │ ├── WalletOnboardingV2.locked.stories.storyshot │ │ │ │ │ ├── WalletOnboardingV2.mismatch.stories.storyshot │ │ │ │ │ ├── WalletOnboardingV2.network.stories.storyshot │ │ │ │ │ ├── WalletOnboardingV2.provider.stories.storyshot │ │ │ │ │ └── WalletOnboardingV2.save.stories.storyshot │ │ │ │ └── index.ts │ │ │ ├── WithNewsroomChannelHOC.tsx │ │ │ ├── __mocks__/ │ │ │ │ └── fileMock.js │ │ │ ├── __snapshots__/ │ │ │ │ ├── ApplicationPhaseStatusLabels.stories.storyshot │ │ │ │ ├── Button.stories.storyshot │ │ │ │ ├── ChevronAnchor.stories.storyshot │ │ │ │ ├── ClipLoader.stories.storyshot │ │ │ │ ├── Collapsable.stories.storyshot │ │ │ │ ├── DetailTransactionButton.stories.storyshot │ │ │ │ ├── Heading.stories.storyshot │ │ │ │ ├── LoadingIndicator.stories.storyshot │ │ │ │ ├── LoadingMessage.stories.storyshot │ │ │ │ ├── Message.stories.storyshot │ │ │ │ ├── MetaMaskModal.stories.storyshot │ │ │ │ ├── Modal.stories.storyshot │ │ │ │ ├── ModalContent.stories.storyshot │ │ │ │ ├── QuestionToolTip.stories.storyshot │ │ │ │ ├── ViewTransactionLink.stories.storyshot │ │ │ │ └── WalletOnboarding.stories.storyshot │ │ │ ├── __test__/ │ │ │ │ ├── setupTests.ts │ │ │ │ └── storyshot.test.ts │ │ │ ├── containers/ │ │ │ │ ├── ButtonActions.tsx │ │ │ │ ├── PaddedSection.tsx │ │ │ │ └── index.tsx │ │ │ ├── context/ │ │ │ │ ├── AuthService.ts │ │ │ │ ├── CivilContext.ts │ │ │ │ ├── CivilProvider.tsx │ │ │ │ ├── IdentityParentPlugin.ts │ │ │ │ └── index.ts │ │ │ ├── features/ │ │ │ │ ├── FeatureFlag.tsx │ │ │ │ └── index.ts │ │ │ ├── hooks/ │ │ │ │ ├── useAsyncEffect.ts │ │ │ │ ├── useIntervalEffect.ts │ │ │ │ └── useStateWithLocalStorage.ts │ │ │ ├── icons/ │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── icon.stories.storyshot │ │ │ │ ├── index.ts │ │ │ │ └── logos/ │ │ │ │ ├── Paypal.tsx │ │ │ │ └── index.ts │ │ │ ├── imageUrls.ts │ │ │ ├── index.ts │ │ │ ├── input/ │ │ │ │ ├── AddressInput.stories.tsx │ │ │ │ ├── AddressInput.tsx │ │ │ │ ├── Checkbox.tsx │ │ │ │ ├── Dropdown.stories.tsx │ │ │ │ ├── Dropdown.tsx │ │ │ │ ├── ImageFileToDataUri.tsx │ │ │ │ ├── Input.stories.tsx │ │ │ │ ├── Input.tsx │ │ │ │ ├── InputGroup.tsx │ │ │ │ ├── InputWithButton.tsx │ │ │ │ ├── RadioInput.tsx │ │ │ │ ├── SaltInput.tsx │ │ │ │ ├── SimpleImageFileToDataUri.tsx │ │ │ │ ├── SlideCheckbox.tsx │ │ │ │ ├── SubmitLink.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ ├── AddressInput.stories.storyshot │ │ │ │ │ ├── Dropdown.stories.storyshot │ │ │ │ │ ├── Input.stories.storyshot │ │ │ │ │ └── checkbox.stories.storyshot │ │ │ │ ├── checkbox.stories.tsx │ │ │ │ └── index.ts │ │ │ ├── onboardingStyledComponents.tsx │ │ │ ├── styleConstants.ts │ │ │ ├── theme.ts │ │ │ └── types.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── contracts/ │ │ ├── .doxityrc │ │ ├── .gitignore │ │ ├── .soliumignore │ │ ├── .soliumrc.json │ │ ├── README.md │ │ ├── conf/ │ │ │ └── config.json │ │ ├── contracts/ │ │ │ ├── Migrations.sol │ │ │ ├── RootCommits/ │ │ │ │ └── RootCommits.sol │ │ │ ├── installed_contracts/ │ │ │ │ ├── AttributeStore.sol │ │ │ │ ├── DLL.sol │ │ │ │ ├── PLCRVoting.sol │ │ │ │ └── Parameterizer.sol │ │ │ ├── interfaces/ │ │ │ │ ├── IGovernment.sol │ │ │ │ └── IMultiSigWalletFactory.sol │ │ │ ├── multisig/ │ │ │ │ ├── Factory.sol │ │ │ │ ├── MultiSigWallet.sol │ │ │ │ └── MultiSigWalletFactory.sol │ │ │ ├── newsroom/ │ │ │ │ ├── ACL.sol │ │ │ │ ├── EventStorage.sol │ │ │ │ ├── Newsroom.sol │ │ │ │ └── NewsroomFactory.sol │ │ │ ├── proof-of-use/ │ │ │ │ └── telemetry/ │ │ │ │ └── TokenTelemetryI.sol │ │ │ ├── tcr/ │ │ │ │ ├── AddressRegistry.sol │ │ │ │ ├── CivilPLCRVoting.sol │ │ │ │ ├── CivilParameterizer.sol │ │ │ │ ├── CivilTCR.sol │ │ │ │ ├── ContractAddressRegistry.sol │ │ │ │ ├── Government.sol │ │ │ │ └── RestrictedAddressRegistry.sol │ │ │ ├── test/ │ │ │ │ ├── DummyACL.sol │ │ │ │ └── DummyTokenTelemetry.sol │ │ │ ├── token/ │ │ │ │ ├── CVLToken.sol │ │ │ │ ├── CivilTokenController.sol │ │ │ │ ├── ERC1404/ │ │ │ │ │ ├── ERC1404.sol │ │ │ │ │ └── MessagesAndCodes.sol │ │ │ │ ├── Managed.sol │ │ │ │ ├── ManagedWhitelist.sol │ │ │ │ └── NoOpTokenController.sol │ │ │ ├── ux/ │ │ │ │ └── CreateNewsroomInGroup.sol │ │ │ └── zeppelin-solidity/ │ │ │ ├── ECRecovery.sol │ │ │ ├── README.md │ │ │ ├── access/ │ │ │ │ ├── Whitelist.sol │ │ │ │ └── rbac/ │ │ │ │ ├── RBAC.sol │ │ │ │ └── Roles.sol │ │ │ ├── license/ │ │ │ │ └── LICENSE │ │ │ ├── math/ │ │ │ │ └── SafeMath.sol │ │ │ ├── ownership/ │ │ │ │ └── Ownable.sol │ │ │ └── token/ │ │ │ └── ERC20/ │ │ │ ├── ERC20.sol │ │ │ ├── ERC20Detailed.sol │ │ │ └── IERC20.sol │ │ ├── docs/ │ │ │ ├── CivilTCR.md │ │ │ └── Newsroom.md │ │ ├── ethpm.json │ │ ├── licenses/ │ │ │ ├── LICENSE-general │ │ │ └── LICENSE-tcr │ │ ├── migrations/ │ │ │ ├── 10_government.ts │ │ │ ├── 11_deploy_ecrecovery.ts │ │ │ ├── 12_registry.ts │ │ │ ├── 14_multisig_factory.ts │ │ │ ├── 15_newsroom_factory.ts │ │ │ ├── 16_add_test_listings.ts │ │ │ ├── 17_deploy_eventstorage.ts │ │ │ ├── 19_create_newsroom_in_group.ts │ │ │ ├── 1_migrations.ts │ │ │ ├── 20_government_take2.ts │ │ │ ├── 21_deploy_root_commits.ts │ │ │ ├── 2_optional_for_test.ts │ │ │ ├── 3_deploy_libs.ts │ │ │ ├── 8_deploy_plcr.ts │ │ │ ├── 9_deploy_parameterizer.ts │ │ │ └── utils/ │ │ │ ├── consts.ts │ │ │ └── index.ts │ │ ├── package.json │ │ ├── test/ │ │ │ ├── .gitkeep │ │ │ ├── global_hooks.ts │ │ │ ├── modules.d.ts │ │ │ ├── multisig/ │ │ │ │ └── multsigwallet.ts │ │ │ ├── newsroom/ │ │ │ │ ├── ACL.ts │ │ │ │ ├── eventStorage.ts │ │ │ │ ├── newsroom.ts │ │ │ │ └── newsroomFactory.ts │ │ │ ├── tcr/ │ │ │ │ ├── contractRegistry/ │ │ │ │ │ └── apply.ts │ │ │ │ ├── government/ │ │ │ │ │ ├── get.ts │ │ │ │ │ ├── getAppellate.ts │ │ │ │ │ ├── getGovernmentController.ts │ │ │ │ │ ├── processProposal.ts │ │ │ │ │ ├── proposeReparameterization.ts │ │ │ │ │ ├── setAppellate.ts │ │ │ │ │ └── setNewConstitution.ts │ │ │ │ ├── parameterizer/ │ │ │ │ │ ├── canBeSet.ts │ │ │ │ │ ├── challengeCanBeResolved.ts │ │ │ │ │ ├── challengeReparameterization.ts │ │ │ │ │ ├── claimReward.ts │ │ │ │ │ ├── get.ts │ │ │ │ │ ├── processProposal.ts │ │ │ │ │ ├── propExists.ts │ │ │ │ │ ├── proposeReparameterization.ts │ │ │ │ │ ├── voterReward.ts │ │ │ │ │ └── voting.ts │ │ │ │ ├── plcrVoting/ │ │ │ │ │ ├── commitVote.ts │ │ │ │ │ ├── didCommit.ts │ │ │ │ │ ├── didReveal.ts │ │ │ │ │ └── revealVote.ts │ │ │ │ ├── registry/ │ │ │ │ │ ├── appWasMade.ts │ │ │ │ │ ├── apply.ts │ │ │ │ │ ├── challenge.ts │ │ │ │ │ ├── claimReward.ts │ │ │ │ │ ├── deposit.ts │ │ │ │ │ ├── exit.ts │ │ │ │ │ ├── hasClaimedTokens.ts │ │ │ │ │ ├── isWhitelisted.ts │ │ │ │ │ ├── tokenClaims.ts │ │ │ │ │ ├── updateStatus.ts │ │ │ │ │ ├── userStories.ts │ │ │ │ │ └── withdraw.ts │ │ │ │ ├── registryWithAppeals/ │ │ │ │ │ ├── allUserRewards.ts │ │ │ │ │ ├── appealCanBeResolved.ts │ │ │ │ │ ├── appealChallengeCanBeResolved.ts │ │ │ │ │ ├── appealChallengeReward.ts │ │ │ │ │ ├── apply.ts │ │ │ │ │ ├── challenge.ts │ │ │ │ │ ├── challengeCanBeResolved.ts │ │ │ │ │ ├── challengeGrantedAppeal.ts │ │ │ │ │ ├── checkAppealChallengeVoteOutcomes.ts │ │ │ │ │ ├── claimAppealChallengeReward.ts │ │ │ │ │ ├── claimReward.ts │ │ │ │ │ ├── grantAppeal.ts │ │ │ │ │ ├── hasClaimedChallengeAppealTokens.ts │ │ │ │ │ ├── isWhitelisted.ts │ │ │ │ │ ├── requestAppeal.ts │ │ │ │ │ ├── transferGovernment.ts │ │ │ │ │ ├── updateStatus.ts │ │ │ │ │ └── voterReward.ts │ │ │ │ └── restrictedRegistry/ │ │ │ │ └── apply.ts │ │ │ ├── token/ │ │ │ │ ├── CVLToken.ts │ │ │ │ ├── CivilTokenController.ts │ │ │ │ └── DisbursementHander.ts │ │ │ └── utils/ │ │ │ ├── constants.ts │ │ │ ├── contractutils.ts │ │ │ ├── coverage.ts │ │ │ └── getethapi.ts │ │ ├── truffle-config.js │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── core/ │ │ ├── .gitignore │ │ ├── .npmignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── doc/ │ │ │ └── examples/ │ │ │ ├── example.ts │ │ │ └── low-level/ │ │ │ ├── multisig.ts │ │ │ └── typed_contracts.ts │ │ ├── package.json │ │ ├── src/ │ │ │ ├── FeatureFlagService.ts │ │ │ ├── UniswapService.ts │ │ │ ├── civil.ts │ │ │ ├── content/ │ │ │ │ ├── contentprovider.ts │ │ │ │ ├── eventstorageprovider.ts │ │ │ │ ├── fallbackprovider.ts │ │ │ │ ├── index.ts │ │ │ │ ├── inmemoryprovider.ts │ │ │ │ └── ipfsprovider.ts │ │ │ ├── contracts/ │ │ │ │ ├── basecontract.ts │ │ │ │ ├── basewrapper.ts │ │ │ │ ├── interfaces/ │ │ │ │ │ ├── contract.ts │ │ │ │ │ └── ownable.ts │ │ │ │ ├── multisig/ │ │ │ │ │ ├── basemultisigproxy.ts │ │ │ │ │ ├── multisig.ts │ │ │ │ │ └── multisigtransaction.ts │ │ │ │ ├── newsroom.ts │ │ │ │ ├── tcr/ │ │ │ │ │ ├── appeal.ts │ │ │ │ │ ├── appealChallenge.ts │ │ │ │ │ ├── challenge.ts │ │ │ │ │ ├── civilTCR.ts │ │ │ │ │ ├── council.ts │ │ │ │ │ ├── cvltoken.ts │ │ │ │ │ ├── government.ts │ │ │ │ │ ├── listing.ts │ │ │ │ │ ├── parameterizer.ts │ │ │ │ │ └── voting.ts │ │ │ │ └── utils/ │ │ │ │ └── contracts.ts │ │ │ ├── globals.d.ts │ │ │ ├── index.ts │ │ │ ├── templates/ │ │ │ │ ├── artifacts.handlebars │ │ │ │ ├── contract/ │ │ │ │ │ ├── contract.handlebars │ │ │ │ │ ├── multisigproxy.handlebars │ │ │ │ │ └── partials/ │ │ │ │ │ ├── call.handlebars │ │ │ │ │ ├── constructor.handlebars │ │ │ │ │ ├── event.handlebars │ │ │ │ │ ├── event_types.handlebars │ │ │ │ │ ├── params.handlebars │ │ │ │ │ ├── proxy_tx.handlebars │ │ │ │ │ ├── return_type.handlebars │ │ │ │ │ ├── tx.handlebars │ │ │ │ │ └── typed_inputs.handlebars │ │ │ │ └── events.handlebars │ │ │ ├── types.ts │ │ │ └── utils/ │ │ │ ├── ethersHelpers.ts │ │ │ └── events.ts │ │ ├── test/ │ │ │ └── .gitkeep │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── dapp/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── config-overrides.js │ │ ├── devops/ │ │ │ ├── nginx.conf │ │ │ └── start.sh │ │ ├── package.json │ │ ├── public/ │ │ │ ├── .well-known/ │ │ │ │ └── apple-developer-merchantid-domain-association │ │ │ ├── index.html │ │ │ └── manifest.json │ │ ├── src/ │ │ │ ├── App.test.tsx │ │ │ ├── App.tsx │ │ │ ├── apis/ │ │ │ │ └── CivilHelper.tsx │ │ │ ├── components/ │ │ │ │ ├── Auth/ │ │ │ │ │ ├── AuthButtonContent.tsx │ │ │ │ │ ├── AuthLogout.tsx │ │ │ │ │ ├── AuthWeb3.tsx │ │ │ │ │ ├── AuthWeb3Login.tsx │ │ │ │ │ ├── AuthWeb3Signup.tsx │ │ │ │ │ ├── CheckEmail.tsx │ │ │ │ │ ├── ConfirmEmail.tsx │ │ │ │ │ ├── Eth.tsx │ │ │ │ │ ├── Login.tsx │ │ │ │ │ ├── SetAvatar.tsx │ │ │ │ │ ├── SetEmail.tsx │ │ │ │ │ ├── SetUsername.tsx │ │ │ │ │ ├── Signup.tsx │ │ │ │ │ ├── VerifyToken.tsx │ │ │ │ │ ├── authStyledComponents.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── Boosts/ │ │ │ │ │ ├── Boost.tsx │ │ │ │ │ ├── BoostFeedPage.tsx │ │ │ │ │ ├── BoostStyledComponents.tsx │ │ │ │ │ ├── BoostSuccess.tsx │ │ │ │ │ └── BoostSuccessComponent.tsx │ │ │ │ ├── ContractAddresses.tsx │ │ │ │ ├── Dashboard/ │ │ │ │ │ ├── Account/ │ │ │ │ │ │ ├── Account.tsx │ │ │ │ │ │ ├── AccountAddCard.tsx │ │ │ │ │ │ ├── AccountPayments.tsx │ │ │ │ │ │ ├── AccountProfile.tsx │ │ │ │ │ │ ├── AccountStyledComponents.tsx │ │ │ │ │ │ ├── AccountTextComponents.tsx │ │ │ │ │ │ ├── AccountTransactions.tsx │ │ │ │ │ │ ├── AccountUserAvatarUpdate.tsx │ │ │ │ │ │ └── AccountUserEmailUpdate.tsx │ │ │ │ │ ├── ActivityListItemRescueTokens.tsx │ │ │ │ │ ├── ChallengeSummary.tsx │ │ │ │ │ ├── ChallengesWithRewardsToClaim.tsx │ │ │ │ │ ├── ChallengesWithTokensToRescue.tsx │ │ │ │ │ ├── ClaimRewardsItem/ │ │ │ │ │ │ ├── ClaimRewardsItem.tsx │ │ │ │ │ │ ├── ClaimRewardsItemWrapper.tsx │ │ │ │ │ │ ├── ClaimRewardsViewComponents.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── Dashboard.tsx │ │ │ │ │ ├── DashboardActivity.tsx │ │ │ │ │ ├── DashboardPage.tsx │ │ │ │ │ ├── DepositTokens.tsx │ │ │ │ │ ├── ManageNewsroom/ │ │ │ │ │ │ ├── ManageNewsroom.tsx │ │ │ │ │ │ ├── ManageNewsroomChannelPage.tsx │ │ │ │ │ │ ├── ManageNewsroomStyledComponents.tsx │ │ │ │ │ │ ├── ManageNewsroomTextComponents.tsx │ │ │ │ │ │ └── WithNewsroomChannelAdminList.tsx │ │ │ │ │ ├── MyChallengeItem/ │ │ │ │ │ │ ├── MyChallengesItem.tsx │ │ │ │ │ │ ├── MyChallengesItemComponent.tsx │ │ │ │ │ │ ├── MyChallengesItemTypes.ts │ │ │ │ │ │ ├── MyChallengesItemWrapper.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── MyChallenges.tsx │ │ │ │ │ ├── MyTasks.tsx │ │ │ │ │ ├── MyTasksItem/ │ │ │ │ │ │ ├── MyTasksItem.tsx │ │ │ │ │ │ ├── MyTasksItemComponent.tsx │ │ │ │ │ │ ├── MyTasksItemTypes.ts │ │ │ │ │ │ ├── MyTasksItemWrapper.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── MyTasksItemPhaseCountdown.tsx │ │ │ │ │ ├── MyTasksList.tsx │ │ │ │ │ ├── MyTasksProposalItem/ │ │ │ │ │ │ ├── MyTasksProposalItem.tsx │ │ │ │ │ │ ├── MyTasksProposalItemComponent.tsx │ │ │ │ │ │ ├── MyTasksProposalItemTypes.ts │ │ │ │ │ │ ├── MyTasksProposalItemWrapper.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── NewsroomsList.tsx │ │ │ │ │ ├── NewsroomsListItem.tsx │ │ │ │ │ ├── NewsroomsListItemComponent.tsx │ │ │ │ │ ├── PhaseCountdownTimer.tsx │ │ │ │ │ ├── ProposalChallengeSummary.tsx │ │ │ │ │ ├── ReclaimTokens.tsx │ │ │ │ │ ├── RescueTokensItem/ │ │ │ │ │ │ ├── RescueTokensItem.tsx │ │ │ │ │ │ ├── RescueTokensItemWrapper.tsx │ │ │ │ │ │ ├── RescueTokensViewComponents.tsx │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ └── types.ts │ │ │ │ │ ├── TransferCivilTokens.tsx │ │ │ │ │ ├── UserInfoSummary.tsx │ │ │ │ │ ├── UserManagement/ │ │ │ │ │ │ ├── UserManagementNotification.tsx │ │ │ │ │ │ ├── UserManagementPageLayout.tsx │ │ │ │ │ │ ├── UserManagementSection.tsx │ │ │ │ │ │ ├── UserManagementStyledComponents.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── UserProfileSummary.tsx │ │ │ │ │ ├── WinningChallengeResults.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── GetStarted.tsx │ │ │ │ ├── GlobalNav.tsx │ │ │ │ ├── Main.tsx │ │ │ │ ├── Parameterizer/ │ │ │ │ │ ├── ChallengeProposal.tsx │ │ │ │ │ ├── ChallengeProposalCommitVote.tsx │ │ │ │ │ ├── ChallengeProposalDetail.tsx │ │ │ │ │ ├── ChallengeProposalResolve.tsx │ │ │ │ │ ├── ChallengeProposalRevealVote.tsx │ │ │ │ │ ├── CreateGovtProposal.tsx │ │ │ │ │ ├── CreateProposal.tsx │ │ │ │ │ ├── GovernmentReparameterization.tsx │ │ │ │ │ ├── Parameter.tsx │ │ │ │ │ ├── ProcessProposal.tsx │ │ │ │ │ ├── Proposal.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── proposeReparameterization.tsx │ │ │ │ ├── SignUpNewsroom.tsx │ │ │ │ ├── StoryFeed/ │ │ │ │ │ ├── CivilComment.tsx │ │ │ │ │ ├── MoreComments.tsx │ │ │ │ │ ├── PostComments.tsx │ │ │ │ │ ├── Story.tsx │ │ │ │ │ ├── StoryBoost.tsx │ │ │ │ │ ├── StoryDetails.tsx │ │ │ │ │ ├── StoryFeed.tsx │ │ │ │ │ ├── StoryFeedItem.tsx │ │ │ │ │ ├── StoryFeedMarquee.tsx │ │ │ │ │ ├── StoryFeedPage.tsx │ │ │ │ │ ├── StoryFeedStyledComponents.tsx │ │ │ │ │ ├── StoryFeedTextComponents.tsx │ │ │ │ │ ├── StoryModal.tsx │ │ │ │ │ ├── StoryNewsroomDetails.tsx │ │ │ │ │ ├── StoryRegistryDetails.tsx │ │ │ │ │ ├── queries.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── Sunset/ │ │ │ │ │ └── Sunset.tsx │ │ │ │ ├── Tokens/ │ │ │ │ │ ├── StorefrontPage.tsx │ │ │ │ │ ├── Tokens.tsx │ │ │ │ │ └── index.ts │ │ │ │ ├── Web3AuthWrapper.tsx │ │ │ │ ├── WrongNetwork.tsx │ │ │ │ ├── council/ │ │ │ │ │ ├── Government.tsx │ │ │ │ │ └── SetAppellate.tsx │ │ │ │ ├── errors/ │ │ │ │ │ └── ErrorBoundry.tsx │ │ │ │ ├── footer/ │ │ │ │ │ └── Footer.tsx │ │ │ │ ├── header/ │ │ │ │ │ ├── NavBar.tsx │ │ │ │ │ ├── NavBarTypes.ts │ │ │ │ │ ├── NavDrawer.tsx │ │ │ │ │ ├── NavDropDown.tsx │ │ │ │ │ ├── NavErrorBar.tsx │ │ │ │ │ ├── NavLink.tsx │ │ │ │ │ ├── NavMenu.tsx │ │ │ │ │ ├── NavMenuResponsiveToggleButton.tsx │ │ │ │ │ ├── UserAccount.tsx │ │ │ │ │ ├── UserAccountContainer.tsx │ │ │ │ │ ├── UserNotificationBar.tsx │ │ │ │ │ ├── styledComponents.tsx │ │ │ │ │ └── textComponents.tsx │ │ │ │ ├── listing/ │ │ │ │ │ ├── AppealAwaitingDecision.tsx │ │ │ │ │ ├── AppealChallengeCommitVote.tsx │ │ │ │ │ ├── AppealChallengeDetail.tsx │ │ │ │ │ ├── AppealChallengeResolve.tsx │ │ │ │ │ ├── AppealChallengeRevealVote.tsx │ │ │ │ │ ├── AppealDetail.tsx │ │ │ │ │ ├── AppealResolve.tsx │ │ │ │ │ ├── AppealSubmitChallenge.tsx │ │ │ │ │ ├── ApplicationUpdateStatus.tsx │ │ │ │ │ ├── Challenge.tsx │ │ │ │ │ ├── ChallengeCommitVote.tsx │ │ │ │ │ ├── ChallengeDetail.tsx │ │ │ │ │ ├── ChallengeResolve.tsx │ │ │ │ │ ├── ChallengeRevealVote.tsx │ │ │ │ │ ├── ChallengeRewardsDetail.tsx │ │ │ │ │ ├── ChallengesWithTokensToRescue.tsx │ │ │ │ │ ├── EmailSignup.tsx │ │ │ │ │ ├── Listing.tsx │ │ │ │ │ ├── ListingChallengeStatement.tsx │ │ │ │ │ ├── ListingCharter.tsx │ │ │ │ │ ├── ListingCharterRosterMember.tsx │ │ │ │ │ ├── ListingDiscourse.tsx │ │ │ │ │ ├── ListingEvent.tsx │ │ │ │ │ ├── ListingHeader.tsx │ │ │ │ │ ├── ListingHistory.tsx │ │ │ │ │ ├── ListingOwnerActions.tsx │ │ │ │ │ ├── ListingPhaseActions.tsx │ │ │ │ │ ├── ListingRedux.tsx │ │ │ │ │ ├── RequestAppeal.tsx │ │ │ │ │ ├── RevealVoteDetail.tsx │ │ │ │ │ ├── SubmitAppealChallenge.tsx │ │ │ │ │ ├── SubmitChallenge/ │ │ │ │ │ │ ├── InsufficientBalanceSnackBar.tsx │ │ │ │ │ │ ├── SubmitChallenge.tsx │ │ │ │ │ │ ├── SubmitChallengeGraphQLApolloContainer.tsx │ │ │ │ │ │ ├── SubmitChallengeTypes.ts │ │ │ │ │ │ ├── SubmitChallengeViewComponent.tsx │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── WhitelistedDetail.tsx │ │ │ │ │ └── styledComponents.tsx │ │ │ │ ├── listinglist/ │ │ │ │ │ ├── EmptyRegistryTabContent.tsx │ │ │ │ │ ├── ListItemStyle.tsx │ │ │ │ │ ├── ListingList.tsx │ │ │ │ │ ├── ListingListItem.tsx │ │ │ │ │ ├── Listings.tsx │ │ │ │ │ ├── ListingsInProgress.tsx │ │ │ │ │ ├── ListingsInProgressContainer.tsx │ │ │ │ │ ├── RejectedListingListContainer.tsx │ │ │ │ │ ├── TabDescriptions.tsx │ │ │ │ │ ├── WhitelistedListingItem.tsx │ │ │ │ │ └── WhitelistedListingListContainer.tsx │ │ │ │ ├── newsroom/ │ │ │ │ │ ├── NewsroomDetail.tsx │ │ │ │ │ ├── NewsroomManagement.tsx │ │ │ │ │ └── NewsroomManagementV2.tsx │ │ │ │ ├── providers/ │ │ │ │ │ ├── AnalyticsProvider.tsx │ │ │ │ │ └── AppProvider.tsx │ │ │ │ └── utility/ │ │ │ │ ├── AsyncComponent.tsx │ │ │ │ ├── CompleteChallengeResultsHOC.tsx │ │ │ │ ├── CountdownTimer.tsx │ │ │ │ ├── ErrorLoadingData.tsx │ │ │ │ ├── ErrorNotFound.tsx │ │ │ │ ├── FormElements.tsx │ │ │ │ ├── HigherOrderComponents.tsx │ │ │ │ ├── ScrollToTop.tsx │ │ │ │ ├── TransactionStatusModalsHOC.tsx │ │ │ │ ├── ViewModules.tsx │ │ │ │ ├── WinningChallengeResultsHOC.tsx │ │ │ │ └── styledComponents.tsx │ │ │ ├── constants.ts │ │ │ ├── embeds/ │ │ │ │ ├── BoostLoader.tsx │ │ │ │ ├── EmbedsApp.tsx │ │ │ │ └── StoryBoostLoader.tsx │ │ │ ├── globals.d.ts │ │ │ ├── helpers/ │ │ │ │ ├── config.ts │ │ │ │ ├── contractAddresses.ts │ │ │ │ ├── government.ts │ │ │ │ ├── links.ts │ │ │ │ ├── listingEvents.ts │ │ │ │ ├── networkHelpers.ts │ │ │ │ ├── queryTransformations.ts │ │ │ │ ├── salt.ts │ │ │ │ ├── tokenController.ts │ │ │ │ ├── tokenEvents.ts │ │ │ │ ├── transforms.ts │ │ │ │ └── vote.ts │ │ │ ├── index.tsx │ │ │ ├── react-app-env.d.ts │ │ │ ├── redux/ │ │ │ │ ├── actionCreators/ │ │ │ │ │ ├── analytics.ts │ │ │ │ │ ├── challenges.ts │ │ │ │ │ ├── contractAddresses.ts │ │ │ │ │ ├── errors.ts │ │ │ │ │ ├── government.ts │ │ │ │ │ ├── network.ts │ │ │ │ │ ├── newsrooms.ts │ │ │ │ │ ├── ui.ts │ │ │ │ │ └── userAccount.ts │ │ │ │ ├── analytics.ts │ │ │ │ ├── reducers/ │ │ │ │ │ ├── challenges.ts │ │ │ │ │ ├── contractAddresses.ts │ │ │ │ │ ├── government.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── network.ts │ │ │ │ │ ├── newsrooms.ts │ │ │ │ │ ├── ui.ts │ │ │ │ │ └── userAccount.ts │ │ │ │ └── store.ts │ │ │ ├── registerServiceWorker.ts │ │ │ ├── registry/ │ │ │ │ ├── LazyRegistryApp.tsx │ │ │ │ ├── RegistryApp.tsx │ │ │ │ └── RegistryShell.tsx │ │ │ ├── selectors/ │ │ │ │ └── index.ts │ │ │ ├── stories/ │ │ │ │ └── StoriesApp.tsx │ │ │ └── typings.d.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.prod.json │ │ ├── tsconfig.test.json │ │ └── tslint.json │ ├── dev-utils/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── scripts/ │ │ │ ├── generate-from-files/ │ │ │ │ ├── bin.ts │ │ │ │ ├── index.ts │ │ │ │ └── utils.ts │ │ │ └── strip-artifacts.ts │ │ ├── src/ │ │ │ ├── index.ts │ │ │ ├── modules.d.ts │ │ │ └── test/ │ │ │ ├── bignumber-chai.ts │ │ │ ├── index.ts │ │ │ └── test.d.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── elements/ │ │ ├── .babelrc │ │ ├── .gitignore │ │ ├── .releaserc │ │ ├── .storybook/ │ │ │ ├── config.ts │ │ │ ├── preview-head.html │ │ │ ├── register-context.ts │ │ │ └── webpack.config.js │ │ ├── LICENSE │ │ ├── jest.config.js │ │ ├── package.json │ │ ├── public/ │ │ │ └── foo │ │ ├── src/ │ │ │ ├── __mocks__/ │ │ │ │ └── fileMock.js │ │ │ ├── __snapshots__/ │ │ │ │ └── index.stories.storyshot │ │ │ ├── __test__/ │ │ │ │ ├── setupTests.ts │ │ │ │ └── storyshot.test.ts │ │ │ ├── buttons/ │ │ │ │ ├── Button.tsx │ │ │ │ ├── CTAButton.tsx │ │ │ │ ├── CloseXButton.tsx │ │ │ │ ├── PaymentButton.tsx │ │ │ │ ├── ShareButton.tsx │ │ │ │ └── index.ts │ │ │ ├── colors/ │ │ │ │ └── index.ts │ │ │ ├── containers/ │ │ │ │ ├── Hero.tsx │ │ │ │ ├── Panel.tsx │ │ │ │ ├── index.ts │ │ │ │ └── mediaQueries.ts │ │ │ ├── icons/ │ │ │ │ ├── ApplicationInProgressIcon.tsx │ │ │ │ ├── ApprovedNewsroomsIcon.tsx │ │ │ │ ├── ArticleIndexIcon.tsx │ │ │ │ ├── ArticleIndexPanelIcon.tsx │ │ │ │ ├── ArticleSignIcon.tsx │ │ │ │ ├── ArticleSignPanelIcon.tsx │ │ │ │ ├── AvatarGenericIcon.tsx │ │ │ │ ├── BellIcon.tsx │ │ │ │ ├── BookreaderIcon.tsx │ │ │ │ ├── BrainIcon.tsx │ │ │ │ ├── CCAmexIcon.tsx │ │ │ │ ├── CCDiscoverIcon.tsx │ │ │ │ ├── CCMastercardIcon.tsx │ │ │ │ ├── CCSecurityCodeIcon.tsx │ │ │ │ ├── CCVisaIcon.tsx │ │ │ │ ├── ChallengeMarkIcon.tsx │ │ │ │ ├── Chevron.tsx │ │ │ │ ├── CircleLockIcon.tsx │ │ │ │ ├── CivilIcon.tsx │ │ │ │ ├── CivilTutorialIcon.tsx │ │ │ │ ├── ClipLoader.tsx │ │ │ │ ├── ClockIcon.tsx │ │ │ │ ├── CloseXIcon.tsx │ │ │ │ ├── CommitVoteSuccessIcon.tsx │ │ │ │ ├── CvlToken.tsx │ │ │ │ ├── DashboardNewsroomApplicationIcon.tsx │ │ │ │ ├── DisclosureArrowIcon.tsx │ │ │ │ ├── DropdownArrow.tsx │ │ │ │ ├── EmbedIcon.tsx │ │ │ │ ├── ErrorIcon.tsx │ │ │ │ ├── ExamIcon.tsx │ │ │ │ ├── ExchangeArrowsIcon.tsx │ │ │ │ ├── ExpandDownArrow.tsx │ │ │ │ ├── FacebookIcon.tsx │ │ │ │ ├── GrantSubmitIcon.tsx │ │ │ │ ├── GreenCheckMark.tsx │ │ │ │ ├── HamburgerIcon.tsx │ │ │ │ ├── HollowGrayNotGranted.tsx │ │ │ │ ├── HollowGreenCheck.tsx │ │ │ │ ├── HollowRedNoGood.tsx │ │ │ │ ├── Info.tsx │ │ │ │ ├── InstagramIcon.tsx │ │ │ │ ├── LinkIcon.tsx │ │ │ │ ├── LinkedInIcon.tsx │ │ │ │ ├── LockOpenIcon.tsx │ │ │ │ ├── MediumIcon.tsx │ │ │ │ ├── MetaMaskIcons.tsx │ │ │ │ ├── NetworkIcon.tsx │ │ │ │ ├── NorthEastArrow.tsx │ │ │ │ ├── OctopusErrorIcon.tsx │ │ │ │ ├── OpenInNewIcon.tsx │ │ │ │ ├── PhotoDragIcon.tsx │ │ │ │ ├── RegistryEmptyIcon.tsx │ │ │ │ ├── RejectedNewsroomsIcon.tsx │ │ │ │ ├── RequestAppealSuccessIcon.tsx │ │ │ │ ├── RevealVoteSuccessIcon.tsx │ │ │ │ ├── ReviewIcon.tsx │ │ │ │ ├── SecureLockIcon.tsx │ │ │ │ ├── ShareEmailIcon.tsx │ │ │ │ ├── ShareIcon.tsx │ │ │ │ ├── ShareTwitterIcon.tsx │ │ │ │ ├── SubmitChallengeSuccessIcon.tsx │ │ │ │ ├── TelegramIcon.tsx │ │ │ │ ├── TipIcon.tsx │ │ │ │ ├── TokenWalletIcon.tsx │ │ │ │ ├── TrendsIcon.tsx │ │ │ │ ├── TrustMarkIcon.tsx │ │ │ │ ├── TwitterIcon.tsx │ │ │ │ ├── VerifyIdentityIcon.tsx │ │ │ │ ├── WaitForApply.tsx │ │ │ │ ├── WarningIcon.tsx │ │ │ │ ├── ZoomInIcon.tsx │ │ │ │ ├── ZoomOutIcon.tsx │ │ │ │ ├── __snapshots__/ │ │ │ │ │ └── icon.stories.storyshot │ │ │ │ ├── icon.stories.tsx │ │ │ │ ├── index.ts │ │ │ │ └── logos/ │ │ │ │ ├── Burner.tsx │ │ │ │ ├── CivilLogo.tsx │ │ │ │ ├── Incognito.tsx │ │ │ │ ├── Metamask.tsx │ │ │ │ ├── OvalImage.ts │ │ │ │ ├── Paypal.tsx │ │ │ │ ├── Portis.tsx │ │ │ │ └── index.ts │ │ │ ├── images/ │ │ │ │ └── __snapshots__/ │ │ │ │ └── icon.stories.storyshot │ │ │ ├── index.stories.tsx │ │ │ ├── index.ts │ │ │ ├── inputs/ │ │ │ │ ├── Input.tsx │ │ │ │ ├── RadioInput.tsx │ │ │ │ └── index.ts │ │ │ ├── layouts/ │ │ │ │ └── index.ts │ │ │ ├── module.d.ts │ │ │ ├── share/ │ │ │ │ ├── SharePanel.tsx │ │ │ │ ├── ShareStory.tsx │ │ │ │ └── index.ts │ │ │ └── text/ │ │ │ ├── fonts.ts │ │ │ ├── headings.tsx │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── ethapi/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── abidecoder.ts │ │ │ ├── ethapi.ts │ │ │ ├── globals.d.ts │ │ │ ├── helpers.ts │ │ │ ├── index.ts │ │ │ └── infura.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── kirby/ │ │ ├── .gitignore │ │ ├── .releaserc │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ ├── KirbyApp.tsx │ │ │ ├── common/ │ │ │ │ ├── colors.ts │ │ │ │ ├── containers/ │ │ │ │ │ └── layouts.tsx │ │ │ │ ├── input/ │ │ │ │ │ └── WalletOptions.tsx │ │ │ │ └── text/ │ │ │ │ └── index.tsx │ │ │ ├── index.tsx │ │ │ ├── plugins/ │ │ │ │ ├── CivilID.ts │ │ │ │ └── common.ts │ │ │ ├── viewport/ │ │ │ │ └── Viewport.tsx │ │ │ └── views/ │ │ │ ├── SignatureConfirm.tsx │ │ │ ├── Web3Enable.tsx │ │ │ └── identity/ │ │ │ ├── Login.tsx │ │ │ └── Signup.tsx │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── newsroom-manager/ │ │ ├── package.json │ │ ├── src/ │ │ │ ├── ApplyToTCR.tsx │ │ │ ├── ApplyToTCRPlaceholder.tsx │ │ │ ├── CivilContext.tsx │ │ │ ├── CompleteYourProfile.tsx │ │ │ ├── CreateCharterPartOne.tsx │ │ │ ├── CreateCharterPartTwo.tsx │ │ │ ├── NameAndAddress.tsx │ │ │ ├── Newsroom.tsx │ │ │ ├── NewsroomUser.tsx │ │ │ ├── RosterMember.tsx │ │ │ ├── SignConstitution.tsx │ │ │ ├── TransactionButtonInner.tsx │ │ │ ├── Welcome.tsx │ │ │ ├── actionCreators.ts │ │ │ ├── contentViewer/ │ │ │ │ ├── ContentItem.tsx │ │ │ │ ├── ContentViewer.tsx │ │ │ │ ├── Revision.tsx │ │ │ │ ├── actions.ts │ │ │ │ ├── index.ts │ │ │ │ └── reducers.ts │ │ │ ├── index.ts │ │ │ ├── reducers.ts │ │ │ ├── styledComponents.tsx │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── newsroom-signup/ │ │ ├── package.json │ │ ├── src/ │ │ │ ├── ApplyToTCR/ │ │ │ │ ├── AboutApplicationButton.tsx │ │ │ │ ├── ApplyToTCR.tsx │ │ │ │ ├── ApplyToTCRForm.tsx │ │ │ │ ├── ApplyToTCRSuccess.tsx │ │ │ │ ├── ApplyToTCRWhitelisted.tsx │ │ │ │ ├── TransferToMultisig.tsx │ │ │ │ └── index.tsx │ │ │ ├── ApplyToTCRPlaceholder.tsx │ │ │ ├── AuthWrapper.tsx │ │ │ ├── DataWrapper.tsx │ │ │ ├── InfoModalButton.tsx │ │ │ ├── Newsroom.tsx │ │ │ ├── NewsroomManager/ │ │ │ │ ├── ManageContractMembers.tsx │ │ │ │ └── index.tsx │ │ │ ├── NewsroomProfile/ │ │ │ │ ├── AddRosterMembers.tsx │ │ │ │ ├── ApplicationSoFarPage.tsx │ │ │ │ ├── CharterQuestions.tsx │ │ │ │ ├── GrantApplication.tsx │ │ │ │ ├── LearnMoreButton.tsx │ │ │ │ ├── NewsroomBio.tsx │ │ │ │ ├── RosterMember.tsx │ │ │ │ ├── RosterMemberListItem.tsx │ │ │ │ ├── SignConstitution.tsx │ │ │ │ ├── WaitingAfterSkip.tsx │ │ │ │ ├── WaitingForGrant.tsx │ │ │ │ └── index.tsx │ │ │ ├── NewsroomUser.tsx │ │ │ ├── PurchaseTokens/ │ │ │ │ └── index.tsx │ │ │ ├── RepublishCharterNotice.tsx │ │ │ ├── SmartContract/ │ │ │ │ ├── AboutSmartContractsButton.tsx │ │ │ │ ├── AddMember.tsx │ │ │ │ ├── AddMembersToContract.tsx │ │ │ │ ├── CreateNewsroomContract.tsx │ │ │ │ ├── LetsGetStartedPage.tsx │ │ │ │ ├── UnderstandingEth.tsx │ │ │ │ └── index.tsx │ │ │ ├── TransactionButtonInner.tsx │ │ │ ├── TransactionStatusModalsHOC.tsx │ │ │ ├── Welcome.tsx │ │ │ ├── actionCreators.ts │ │ │ ├── analytics.ts │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ ├── mutations.ts │ │ │ ├── queries.ts │ │ │ ├── reducers.ts │ │ │ ├── styledComponents.tsx │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── tsconfig.json │ │ ├── tslint.json │ │ └── types.d.ts │ ├── sdk/ │ │ ├── .dockerignore │ │ ├── .prettierignore │ │ ├── .prettierrc.yaml │ │ ├── .releaserc │ │ ├── .storybook/ │ │ │ ├── config.tsx │ │ │ └── webpack.config.js │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── build.js │ │ ├── certs.js │ │ ├── config/ │ │ │ ├── env.js │ │ │ ├── jest/ │ │ │ │ ├── cssTransform.js │ │ │ │ └── fileTransform.js │ │ │ ├── paths.js │ │ │ ├── webpack.config.js │ │ │ └── webpackDevServer.config.js │ │ ├── docs/ │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ ├── make.bat │ │ │ └── source/ │ │ │ ├── civil_sdk_package.rst │ │ │ ├── conf.py │ │ │ ├── index.rst │ │ │ ├── install/ │ │ │ │ └── getting_started.rst │ │ │ ├── lockbox/ │ │ │ │ ├── index.rst │ │ │ │ └── intro.rst │ │ │ ├── registry/ │ │ │ │ ├── index.rst │ │ │ │ └── intro.rst │ │ │ └── requirements.txt │ │ ├── index.html │ │ ├── index.js │ │ ├── manifest.json │ │ ├── nginx.conf │ │ ├── package.json │ │ ├── public/ │ │ │ ├── boost-embed.html │ │ │ ├── index.html │ │ │ └── manifest.json │ │ ├── scripts/ │ │ │ ├── build.js │ │ │ ├── start.js │ │ │ └── test.js │ │ ├── server.js │ │ ├── site-maker.sh │ │ ├── src/ │ │ │ ├── constants.ts │ │ │ ├── examples/ │ │ │ │ └── registry.stories.tsx │ │ │ ├── iframe/ │ │ │ │ ├── index.tsx │ │ │ │ └── services/ │ │ │ │ ├── MessageHandler.test.ts │ │ │ │ ├── MessageHandler.ts │ │ │ │ ├── MessageHandlerTypes.ts │ │ │ │ ├── civil-node/ │ │ │ │ │ ├── CivilPersistence.test.ts │ │ │ │ │ ├── CivilPersistence.ts │ │ │ │ │ ├── LockboxService.ts │ │ │ │ │ └── Persistence.ts │ │ │ │ ├── communication/ │ │ │ │ │ ├── CivilWebsocket.ts │ │ │ │ │ ├── PrivateChannel.test.ts │ │ │ │ │ ├── PrivateChannel.ts │ │ │ │ │ ├── RealtimeCommunication.ts │ │ │ │ │ ├── ReceiveTypes.ts │ │ │ │ │ ├── SecureTypes.ts │ │ │ │ │ └── SendTypes.ts │ │ │ │ ├── crypto/ │ │ │ │ │ ├── crypto.test.ts │ │ │ │ │ └── crypto.ts │ │ │ │ ├── keys/ │ │ │ │ │ ├── Key.ts │ │ │ │ │ ├── KeyManager.test.ts │ │ │ │ │ ├── KeyManager.ts │ │ │ │ │ ├── KeyUtils.ts │ │ │ │ │ └── PersistentKey.ts │ │ │ │ └── messageTypes.ts │ │ │ ├── index.ts │ │ │ ├── react/ │ │ │ │ ├── CivilProvider.tsx │ │ │ │ ├── NewsroomWithdraw.tsx │ │ │ │ ├── StoryBoost/ │ │ │ │ │ ├── StoryBoost.tsx │ │ │ │ │ ├── embed.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── queries.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── boosts/ │ │ │ │ │ ├── Boost.stories.tsx │ │ │ │ │ ├── Boost.tsx │ │ │ │ │ ├── BoostCard.tsx │ │ │ │ │ ├── BoostCardListView.tsx │ │ │ │ │ ├── BoostCompleted.tsx │ │ │ │ │ ├── BoostEmbedIframe.tsx │ │ │ │ │ ├── BoostEmbedNoScroll.tsx │ │ │ │ │ ├── BoostForm.tsx │ │ │ │ │ ├── BoostImg.tsx │ │ │ │ │ ├── BoostModal.tsx │ │ │ │ │ ├── BoostNewsroom.tsx │ │ │ │ │ ├── BoostPayments.tsx │ │ │ │ │ ├── BoostPermissionsHOC.tsx │ │ │ │ │ ├── BoostProceeds.tsx │ │ │ │ │ ├── BoostProgress.tsx │ │ │ │ │ ├── BoostShare.tsx │ │ │ │ │ ├── BoostShareEmbed.tsx │ │ │ │ │ ├── BoostStyledComponents.tsx │ │ │ │ │ ├── BoostTextComponents.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── queries.ts │ │ │ │ │ └── types.ts │ │ │ │ ├── index.ts │ │ │ │ └── urlConstants.ts │ │ │ ├── react-app-env.d.ts │ │ │ ├── sdk/ │ │ │ │ ├── SDKMessage.ts │ │ │ │ ├── dmz/ │ │ │ │ │ └── DMZ.ts │ │ │ │ ├── index.ts │ │ │ │ ├── lockbox/ │ │ │ │ │ ├── Lockbox.ts │ │ │ │ │ └── LockboxMessage.ts │ │ │ │ ├── registry/ │ │ │ │ │ ├── Registry.ts │ │ │ │ │ └── RegistryMessage.ts │ │ │ │ └── telemetry/ │ │ │ │ └── Telemetry.ts │ │ │ ├── serviceWorker.ts │ │ │ ├── setupTests.ts │ │ │ ├── test-utils/ │ │ │ │ ├── MockWebsocketServer.ts │ │ │ │ └── helpers.ts │ │ │ └── types.d.ts │ │ ├── start.js │ │ ├── start.sh │ │ ├── test.js │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── tslint-rules/ │ │ ├── .releaserc │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ └── tslint.yaml │ ├── typescript-types/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ ├── src/ │ │ │ └── index.ts │ │ ├── tsconfig.json │ │ └── tslint.json │ ├── typescript-typings/ │ │ ├── .releaserc │ │ ├── LICENSE │ │ ├── README.md │ │ ├── package.json │ │ └── types/ │ │ ├── @ledgerhq/ │ │ │ ├── LICENSE │ │ │ └── index.d.ts │ │ ├── ethereumjs-abi/ │ │ │ └── index.d.ts │ │ ├── ethereumjs-util/ │ │ │ ├── LICENSE │ │ │ └── index.d.ts │ │ ├── ethjs-util/ │ │ │ └── index.d.ts │ │ ├── is-hex-prefixed/ │ │ │ └── index.d.ts │ │ ├── strip-hex-prefix/ │ │ │ └── index.d.ts │ │ ├── to-snake-case/ │ │ │ └── index.d.ts │ │ └── web3-provider-engine/ │ │ ├── LICENSE │ │ └── index.d.ts │ └── utils/ │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src/ │ │ ├── airswap.ts │ │ ├── apolloClient.ts │ │ ├── bip39.english.ts │ │ ├── browser.ts │ │ ├── civilConstants.ts │ │ ├── civilHelpers.ts │ │ ├── contracts.ts │ │ ├── coreHelpers/ │ │ │ ├── appealChallengeHelpers.ts │ │ │ ├── appealHelpers.ts │ │ │ ├── challengeHelpers.ts │ │ │ ├── index.ts │ │ │ ├── listingHelpers.ts │ │ │ ├── paramPropChallengeHelpers.ts │ │ │ ├── pollHelpers.ts │ │ │ └── userChallengeDataHelpers.ts │ │ ├── crypto.ts │ │ ├── email.ts │ │ ├── errors.ts │ │ ├── etherscan.ts │ │ ├── gql/ │ │ │ ├── queries.ts │ │ │ └── transforms.ts │ │ ├── handle.ts │ │ ├── index.ts │ │ ├── language.ts │ │ ├── localStorage.ts │ │ ├── rxjs.ts │ │ ├── salt.ts │ │ ├── stripe.ts │ │ ├── time.ts │ │ ├── types.d.ts │ │ ├── urlConstants.ts │ │ └── viewHelpers.tsx │ ├── test/ │ │ ├── language.ts │ │ └── salt.ts │ ├── tsconfig.json │ └── tslint.json └── tsconfig.json ================================================ FILE CONTENTS ================================================ ================================================ FILE: .circleci/config.yml ================================================ version: 2 # What is this - http://yaml.org/type/merge.html defaults: &defaults docker: - image: circleci/node:12.10 jobs: build: <<: *defaults resource_class: xlarge steps: - checkout - restore_cache: name: Restore yarn cache key: node-modules-{{ checksum "yarn.lock" }} - run: name: Install modules command: yarn --frozen-lockfile install - save_cache: name: Save yarn cache key: node-modules-{{ checksum "yarn.lock" }} paths: - node_modules - run: name: Building command: yarn build no_output_timeout: 30m - run: name: Copying boost loader script command: yarn copy:boost-loader - run: name: Ensuring prettified command: yarn prettier - run: name: Linting command: yarn lint - run: name: Starting Ganache command: yarn ganache:raw background: true - run: name: Running migrations command: yarn lerna run --scope=@joincivil/contracts migrate:ganache - run: name: Running tests (except contracts) command: | yarn test - add_ssh_keys: fingerprints: - "70:4a:4d:06:ec:1f:2a:fd:50:c6:a8:63:da:e9:0c:e6" - run: name: Releasing command: | yarn release pwd - persist_to_workspace: root: ./ paths: - ./packages/dapp/build - ./packages/dapp/devops coverage: <<: *defaults steps: - attach_workspace: at: ../ - run: name: Starting Ganache command: yarn ganache:raw background: true - run: name: Calculating coverage command: yarn coverage - run: name: Submitting coverage command: yarn coverage:submit # Docker steps # These steps have a different workspace roots and so will behave a bit differently # circleci/node has /users/circleci/project # civilmedia/gcloud-node has /root/project setup-gcp: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - run: name: Dump Google Cloud Credentials to file command: | echo ${GOOGLE_AUTH} | base64 -d > ${HOME}/gcp-key.json gcloud auth activate-service-account --key-file ${HOME}/gcp-key.json gcloud --quiet config set project ${GOOGLE_PROJECT_ID} gcloud --quiet config set compute/zone ${GOOGLE_COMPUTE_ZONE} gcloud --quiet container clusters get-credentials ${GOOGLE_CLUSTER_NAME} gcloud docker --authorize-only - persist_to_workspace: root: /root paths: - gcp-key.json - .config/gcloud - .docker - .dockercfg - .kubernetes_ns - .kube # Adds specific test images so we can both push specific branches via circleci, but # also start up an fresh test container with the last test image in k8s push-test-containers: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - checkout - attach_workspace: at: /root - setup_remote_docker - run: name: Build Container command: | cp -r /root/packages/dapp/build ./packages/dapp/build cp -r /root/packages/dapp/devops ./packages/dapp/devops TAG=`echo $CIRCLE_BRANCH | sed 's/\\//_/g'` docker build -f Dockerfile-dapp . \ --build-arg version=$CIRCLE_SHA1 \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:$TAG \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:$TAG-$CIRCLE_SHA1 \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:test \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:test-$CIRCLE_SHA1 - deploy: name: Push Containers to Registry command: | gcloud config list echo "pushing $GOOGLE_PROJECT_ID" docker push gcr.io/$GOOGLE_PROJECT_ID/dapp push-containers: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - checkout - attach_workspace: at: /root - setup_remote_docker - run: name: Build Container command: | cp -r /root/packages/dapp/build ./packages/dapp/build cp -r /root/packages/dapp/devops ./packages/dapp/devops TAG=`echo $CIRCLE_BRANCH | sed 's/\\//_/g'` docker build -f Dockerfile-dapp . \ --build-arg version=$CIRCLE_SHA1 \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:$TAG \ -t gcr.io/$GOOGLE_PROJECT_ID/dapp:$TAG-$CIRCLE_SHA1 - deploy: name: Push Containers to Registry command: | gcloud config list echo "pushing $GOOGLE_PROJECT_ID" docker push gcr.io/$GOOGLE_PROJECT_ID/dapp deploy-test: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - attach_workspace: at: /root - deploy: name: Update Kubernetes Deployment on TEST command: | TAG=`echo $CIRCLE_BRANCH | sed 's/\\//_/g'` kubectl set image deployment/dapp dapp=gcr.io/$GOOGLE_PROJECT_ID/dapp:$TAG-$CIRCLE_SHA1 --namespace test deploy-staging: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - attach_workspace: at: /root - deploy: name: Update Kubernetes Deployment on STAGING command: | kubectl set image deployment/dapp dapp=gcr.io/$GOOGLE_PROJECT_ID/dapp:master-$CIRCLE_SHA1 --namespace staging deploy-production: <<: *defaults docker: - image: civilmedia/gcloud-node:latest steps: - attach_workspace: at: /root - deploy: name: Update Kubernetes Deployment on PRODUCTION command: | kubectl set image deployment/dapp dapp=gcr.io/$GOOGLE_PROJECT_ID/dapp:production-$CIRCLE_SHA1 --namespace production workflows: version: 2 build-and-deploy: jobs: - build: context: gcp-common - setup-gcp: context: gcp-common requires: - build filters: branches: only: - master - production - /test.*/ - push-test-containers: context: gcp-common requires: - setup-gcp filters: branches: only: - /test.*/ - push-containers: context: gcp-common requires: - setup-gcp filters: branches: only: - master - production - deploy-test: context: gcp-common requires: - push-test-containers filters: branches: only: - /test.*/ - deploy-staging: context: gcp-common requires: - push-containers filters: branches: only: - master - deploy-production: context: gcp-common requires: - push-containers filters: branches: only: - production ================================================ FILE: .dockerignore ================================================ node_modules ================================================ FILE: .editorconfig ================================================ root = true [*] insert_final_newline = true indent_style = space indent_size = 2 end_of_line = lf [*.{mustache,handlebars}] insert_final_newline = false [*.{yaml,yml}] indent_size = 4 indent_style = space ================================================ FILE: .gitattributes ================================================ # Normalizes all line endings in the repository # as per https://git-scm.com/docs/gitattributes # # This is needed because Solium has a problem with mixed line endings # and returns false positives * text=auto # Automatically collapses storyshot diffs in GitHub: *.storyshot linguist-generated ================================================ FILE: .gitignore ================================================ # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # Bower dependency directory (https://bower.io/) bower_components # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules/ jspm_packages/ # Typescript v1 declaration files typings/ # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history # Output of 'npm pack' *.tgz # Yarn Integrity file .yarn-integrity # dotenv environment variables file .env packages/dapp/.env.local build/ # DS store *.DS_STORE # ide / intellij config .idea # package *package-lock.json coverage/ coverage.json ================================================ FILE: .prettierignore ================================================ node_modules/ build/ installed_contracts/ package.json generated/ doxity/ docs/asset-manifest.json /packages/dapp/src/components/docs/json/ coverage/ .0x-artifacts/ ================================================ FILE: .prettierrc.yaml ================================================ printWidth: 120 bracketSpacing: true semi: true singleQuote: false trailingComma: all useTabs: false ================================================ FILE: .releaserc ================================================ { "repositoryUrl": "git@github.com:joincivil/Civil.git", "branch": "master" } ================================================ FILE: .vscode/launch.json ================================================ { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "type": "node", "request": "launch", "name": "Launch Script", "program": "${file}", "outFiles": ["${workspaceFolder}/packages/*/build/**/*.{js,js.map}"], "sourceMaps": true, "smartStep": true } ] } ================================================ FILE: .vscode/settings.json ================================================ { "files.exclude": { "**/build/": true, "**/node_modules/": true }, "search.exclude": { "**/build/": true }, "typescript.tsdk": "node_modules/typescript/lib" } ================================================ FILE: Dockerfile-dapp ================================================ FROM nginx:1.12-alpine ADD ./packages/dapp/build /usr/share/nginx/html ADD ./packages/dapp/devops/nginx.conf /etc/nginx/conf.d/default.conf ADD ./packages/dapp/devops/start.sh /start.sh RUN chmod u+x /start.sh EXPOSE 3000 ENV ENVIRONMENT="{}" CMD /start.sh ================================================ FILE: README.md ================================================ ![Civil Logo](doc/civil_logo_white.png?raw=true) --- [Civil](https://joincivil.com/) is a decentralized and censorship resistant ecosystem for online Journalism. Read more in our whitepaper. [WIP Civil DApp](https://dapp.staging.cvl.pub/) - Read Documentation and Interact with Contracts and tools at our DApp, hosted for your convenience. This DApp and associated contracts are a Work In Progress and contracts are deployed on the Rinkeby testnet. If you would like some test CVL to try out the DApp, please ask in our Gitter room and we can send you some. This repository contains all of the open-source Civil tools and packages written in Typescript. We hope that those tools will be useful for creation of interesting applications on top of the ecosystem as well as be useful in any project in the Ethereum space. [![Coverage Status](https://coveralls.io/repos/github/joincivil/Civil/badge.svg)](https://coveralls.io/github/joincivil/Civil) [![CircleCI](https://img.shields.io/circleci/project/github/joincivil/Civil.svg)](https://circleci.com/gh/joincivil/Civil/tree/master) [![Gitter chat](https://badges.gitter.im/joincivil/Lobby.png)](https://gitter.im/joincivil/Lobby) [![Telegram chat](https://img.shields.io/badge/chat-telegram-blue.svg)](https://t.me/join_civil) Most of the packages require additional typings for external dependencies. You can include those by prepending @joincivil/typescript-typings package to your typeRoots config. ```json "typeRoots": ["node_modules/@joincivil/typescript-typings/types", "node_modules/@types"], ``` ### Published packages | Package | NPM | Description | | --------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | [`@joincivil/core`][core-url] | [![npm link](https://img.shields.io/badge/npm-core-blue.svg)](https://www.npmjs.com/package/@joincivil/core) | JS library for interacting with Civil ecosystem | | [`@joincivil/tslint-rules`](/packages/tslint-rules) | [![npm link](https://img.shields.io/badge/npm-tslint--rules-blue.svg)](https://www.npmjs.com/package/@joincivil/tslint-rules) | Linting rules for Civil's Typescript packages | | [`@joincivil/utils`](/packages/utils) | [![npm link](https://img.shields.io/badge/npm-utils-blue.svg)](https://www.npmjs.com/package/@joincivil/utils) | Utilities shared between Civil projects used during runtime | | [`@joincivil/typescript-types`](/packages/typescript-types) | [![npm link](https://img.shields.io/badge/npm-typescript--types-blue.svg)](https://www.npmjs.com/package/@joincivil/typescript-types) | Types used in multiple Civil packages | | [`@joincivil/typescript-typings`](/packages/typescript-typings) | [![npm link](https://img.shields.io/badge/npm-typescript--typings-blue.svg)](https://www.npmjs.com/package/@joincivil/typescript-typings) | Typescript type roots for external projects and internal modifications | | [`@joincivil/ethapi`](/packages/ethapi) | [![npm link](https://img.shields.io/badge/npm-ethapi-blue.svg)](https://www.npmjs.com/package/@joincivil/ethapi) | An abstraction of Ethereum communication | ### Private packages | Package | Description | | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- | | [`@joincivil/contracts`](/packages/contracts) | Smart-contracts needed for the Civil's protocol | | [`@joincivil/dapp`](/packages/dapp) | DApp for interacting with the Civil contracts | | [`@joincivil/dev-utils`](/packages/dev-utils) | Utilities needed for the proper working of the mono-repo packages, builds and tests | | [`@joincivil/debug-ui`](/packages/debug-ui) | WIP: Minimal website to monitor, observe and debug the protocol and all the utilities and packages of the ecosystem | ## Contributing Civil's ecosystem is free and open-source, we're all part of it and you're encouraged to be a part of it with us. Best place to start hacking would be to use the [`@joincivil/core`][core-url] and build some application on top of the protocol. If you're itching to delve deeper inside, [**help wanted**](https://github.com/joincivil/Civil/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and [**good first issue**](https://github.com/joincivil/Civil/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) labels are good places to get started and learn the architecture. ## Dev Setup ### Install dependencies This project is using [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/). They require `yarn >= 1.0` to work properly. Set up all dependencies: from the root directory: ```bash yarn install ``` ### Build Build all packages in the monorepo: ```bash yarn build ``` Turn on file-watch mode and rebuild most of the files on change: ```bash yarn watch ``` ### Lint Check all packages for linting errors: ```bash yarn lint ``` ### Testing Tests in Civil's ecosystem require the use of [Ganache](https://github.com/trufflesuite/ganache-cli), Ethereum's development test network, spin it in a seperate terminal: ```bash yarn ganache ``` Finally run all the tests in the main repository: ```bash yarn test ``` ### Easy Setup with front-end We've added a helper command to assist you if you want to develop using the front-end and a local ganache. Just 3 simple commands. First, however, you may want to add your own address (e.g. MetaMask account) to our config file so that you are distributed tokens/ETH properly and change the Appellate and GovernmentController addresses. This is especially useful if your MetaMask account is not the same as one of you ganache accounts (all ganache accounts are given tokens by default). Config file can be found at `packages/contracts/conf/config.json`. From the root directory: ```bash yarn ganache ``` Once that is running, in another terminal, from the root directory: ```bash yarn preparelocally ``` After that completes: ```bash cd packages/dapp yarn start ``` Now you have the dapp front-end running at `localhost:3000`. Make sure to select `localhost 8545` in metamask to interact with the dapp. ### Run commands in all packages Civil's monorepo is using [lerna](https://github.com/lerna/lerna) to easily manage the monorepo structure. Two helper yarn scripts are provided for your convenience. To run the supported lerna version: ```bash yarn lerna ``` To run scripts in all packages in the monorepo: ```bash yarn lerna:run ``` ### Cleaning the state To refresh the repository state as much as possible run: ```bash yarn clean && yarn lerna clean --yes && rm -r node_modules && yarn install ``` 🐙 was here. [core-url]: /packages/core ================================================ FILE: commitlint.config.js ================================================ module.exports = { extends: ["@commitlint/config-conventional", "@commitlint/config-lerna-scopes"] }; ================================================ FILE: lerna.json ================================================ { "lerna": "3.15.0", "packages": ["packages/*"], "npmClient": "yarn", "useWorkspaces": true, "version": "independent", "command": { "publish": { "conventionalCommits": true }, "version": { "message": "chore(release): release" } } } ================================================ FILE: package.json ================================================ { "name": "@joincivil/root", "private": true, "homepage": "https://civil.co", "workspaces": [ "packages/*" ], "scripts": { "build": "lerna run build --sort", "watch": "lerna run --parallel build:watch", "lint": "lerna run lint --parallel", "build:core": "lerna run --scope @joincivil/core build", "copy:boost-loader": "mkdir -p packages/dapp/build/loader/ && cp packages/sdk/build/static/js/boost.js* packages/dapp/build/loader/", "coverage": "lerna run coverage --parallel", "coverage:submit": "lcov-result-merger 'packages/*/coverage/lcov.info' | coveralls", "prettier": "prettier --config .prettierrc.yaml --write --list-different './**/*.{ts,tsx,json,md}'", "prettier:package": "[ $PACKAGE ] && prettier --config .prettierrc.yaml --write --list-different ./packages/$PACKAGE'/**/*.{ts,tsx,json,md}' || echo 'Specify a package name as environment variable to run prettier on just that package, e.g. `PACKAGE=dapp yarn prettier:package`'", "clean": "lerna run clean --parallel", "test": "CI=true lerna run test --stream --sort --ignore @joincivil/contracts", "test-contracts": "lerna run test --stream --sort", "lerna:run": "lerna run", "prepare": "lerna run prepare --no-sort", "ganache": "run-p ganache:raw 'lerna:run --scope @joincivil/contracts migrate:ganache'", "ganache:raw": "ganache-cli -p 8545 --networkId 50 -d -m \"${npm_package_config_mnemonic}\" --noVMErrorsOnRPCResponse", "migrate": "lerna run --scope @joincivil/contracts migrate:ganache", "serve:dapp": "cd ./packages/dapp && serve -s build", "publish:docs": "ncp ./packages/dapp/build/ ./docs/", "publish:artifacts-dev": "ncp ./packages/contracts/build/artifacts/CivilTCR.json ./packages/artifacts/v1/CivilTCR.json && ncp ./packages/contracts/build/artifacts/CivilPLCRVoting.json ./packages/artifacts/v1/CivilPLCRVoting.json && ncp ./packages/contracts/build/artifacts/CivilParameterizer.json ./packages/artifacts/v1/CivilParameterizer.json && ncp ./packages/contracts/build/artifacts/CVLToken.json ./packages/artifacts/v1/CVLToken.json && ncp ./packages/contracts/build/artifacts/EventStorage.json ./packages/artifacts/v1/EventStorage.json && ncp ./packages/contracts/build/artifacts/Government.json ./packages/artifacts/v1/Government.json && ncp ./packages/contracts/build/artifacts/MultiSigWallet.json ./packages/artifacts/v1/MultiSigWallet.json && ncp ./packages/contracts/build/artifacts/Newsroom.json ./packages/artifacts/v1/Newsroom.json && ncp ./packages/contracts/build/artifacts/NewsroomFactory.json ./packages/artifacts/v1/NewsroomFactory.json && ncp ./packages/contracts/build/artifacts/CivilTokenController.json ./packages/artifacts/v1/CivilTokenController.json && ncp ./packages/contracts/build/artifacts/CreateNewsroomInGroup.json ./packages/artifacts/v1/CreateNewsroomInGroup.json && ncp ./packages/contracts/build/artifacts/NoOpTokenController.json ./packages/artifacts/v1/NoOpTokenController.json", "preparelocally": "run-s migrate publish:artifacts-dev build:core", "commit": "commit", "release": "multi-semantic-release" }, "config": { "mnemonic": "notice tobacco baby curious trade other capable invite cable thunder file equal" }, "resolutions": { "ethers": "4.0.27", "**/ethers": "4.0.27" }, "license": "(Apache-2.0 OR LGPL-2.1-only)", "devDependencies": { "@commitlint/cli": "^7.5.2", "@commitlint/config-conventional": "^7.5.0", "@commitlint/config-lerna-scopes": "^8.1.0", "@commitlint/prompt-cli": "^8.1.0", "@semantic-release/npm": "^5.1.7", "coveralls": "^3.0.0", "ganache-cli": "^6.5.1", "husky": "^2.1.0", "lcov-result-merger": "^3.1.0", "lerna": "^3.15.0", "multi-semantic-release": "^1.1.0", "ncp": "^2.0.0", "npm-run-all": ">=4.1.5", "prettier": "1.18.2", "semantic-release": "^15.13.3" }, "husky": { "hooks": { "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" } } } ================================================ FILE: packages/artifacts/package.json ================================================ { "name": "@joincivil/artifacts", "version": "1.1.9", "description": "Civil Ethereum smart contract artifacts", "scripts": {}, "author": "The Civil Media Company", "bugs": { "url": "https://github.com/joincivil/Civil/issues" }, "publishConfig": { "access": "public" }, "homepage": "https://github.com/joincivil/Civil", "license": "LGPL-2.1" } ================================================ FILE: packages/artifacts/v1/ACL.json ================================================ { "contractName": "ACL", "bytecode": "0x608060405234801561001057600080fd5b5060008054600160a060020a03191633179055610355806100326000396000f30060806040526004361061006c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663217fe6c681146100715780632f54bf6e146100ec578063715018a61461010d5780638da5cb5b14610124578063f2fde38b14610155575b600080fd5b34801561007d57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100d8958335600160a060020a03169536956044949193909101919081908401838280828437509497506101769650505050505050565b604080519115158252519081900360200190f35b3480156100f857600080fd5b506100d8600160a060020a03600435166101fa565b34801561011957600080fd5b5061012261020e565b005b34801561013057600080fd5b5061013961027a565b60408051600160a060020a039092168252519081900360200190f35b34801561016157600080fd5b50610122600160a060020a0360043516610289565b60006001826040518082805190602001908083835b602083106101aa5780518252601f19909201916020918201910161018b565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b600054600160a060020a0316331461022557600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a031633146102a057600080fd5b6102a9816102ac565b50565b600160a060020a03811615156102c157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a72305820ccf2b858c6dafa2777144e5272cb0d25fb58b5b8254f5f61242d728f24a65bd50029", "deployedBytecode": "0x60806040526004361061006c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663217fe6c681146100715780632f54bf6e146100ec578063715018a61461010d5780638da5cb5b14610124578063f2fde38b14610155575b600080fd5b34801561007d57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100d8958335600160a060020a03169536956044949193909101919081908401838280828437509497506101769650505050505050565b604080519115158252519081900360200190f35b3480156100f857600080fd5b506100d8600160a060020a03600435166101fa565b34801561011957600080fd5b5061012261020e565b005b34801561013057600080fd5b5061013961027a565b60408051600160a060020a039092168252519081900360200190f35b34801561016157600080fd5b50610122600160a060020a0360043516610289565b60006001826040518082805190602001908083835b602083106101aa5780518252601f19909201916020918201910161018b565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b600054600160a060020a0316331461022557600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a031633146102a057600080fd5b6102a9816102ac565b50565b600160a060020a03811615156102c157600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a72305820ccf2b858c6dafa2777144e5272cb0d25fb58b5b8254f5f61242d728f24a65bd50029", "abi": [ { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "role", "type": "string" } ], "name": "hasRole", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" } ], "name": "isOwner", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/AddressRegistry.json ================================================ { "contractName": "AddressRegistry", "bytecode": "0x60806040523480156200001157600080fd5b5060405162002f3838038062002f38833981016040908152815160208301519183015160608401519193909101600160a060020a0384161515620000b657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f746f6b656e2061646472657373206973203000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156200012e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f766f74696e6720616464726573732069732030000000000000000000000000604482015290519081900360640190fd5b600160a060020a0382161515620001a657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f706172616d65746572697a6572206164647265737320697320300000000000604482015290519081900360640190fd5b60028054600160a060020a03808716600160a060020a0319928316179092556003805486841690831617905560048054928516929091169190911790558051620001f890600590602084019062000203565b5050505050620002a8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024657805160ff191683800117855562000276565b8280016001018555821562000276579182015b828111156200027657825182559160200191906001019062000259565b506200028492915062000288565b5090565b620002a591905b808211156200028457600081556001016200028f565b90565b612c8080620002b86000396000f3006080604052600436106101325763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301162b93811461013757806306fdde031461015a5780632ea9b696146101e45780633af32abf1461021957806347e7ef241461023a57806355246b9c1461025e5780635f02116f146102c757806361a9a8ca1461035557806365d96c82146103765780636eefcab9146103ca57806386bb8f37146103eb5780638f1d377614610406578063a5ba3b1e14610451578063a7aad3db14610475578063b42652e9146104ae578063bc4b010f146104cf578063c8187cf114610536578063dd4e7cfd1461054e578063e1e3f9151461056f578063f3fef3a3146105a0578063f96c8720146105c4578063fc0c546a14610619578063fce1ccca1461062e575b600080fd5b34801561014357600080fd5b50610158600160a060020a0360043516610643565b005b34801561016657600080fd5b5061016f610679565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101a9578181015183820152602001610191565b50505050905090810190601f1680156101d65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f057600080fd5b50610205600160a060020a0360043516610707565b604080519115158252519081900360200190f35b34801561022557600080fd5b50610205600160a060020a0360043516610843565b34801561024657600080fd5b50610158600160a060020a0360043516602435610869565b34801561026a57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610158948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a259650505050505050565b3480156102d357600080fd5b506040805160206004803580820135838102808601850190965280855261015895369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610eda9650505050505050565b34801561036157600080fd5b50610205600160a060020a0360043516610fae565b34801561038257600080fd5b50610397600160a060020a0360043516610fca565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103d657600080fd5b50610205600160a060020a0360043516611005565b3480156103f757600080fd5b50610158600435602435611050565b34801561041257600080fd5b5061041e600435611322565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561045d57600080fd5b50610205600435600160a060020a036024351661135e565b34801561048157600080fd5b5061049c600160a060020a036004351660243560443561138c565b60408051918252519081900360200190f35b3480156104ba57600080fd5b50610158600160a060020a036004351661145b565b3480156104db57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261049c958335600160a060020a031695369560449491939091019190819084018382808284375094975061164a9650505050505050565b34801561054257600080fd5b5061049c600435611f39565b34801561055a57600080fd5b50610205600160a060020a0360043516612165565b34801561057b57600080fd5b50610584612207565b60408051600160a060020a039092168252519081900360200190f35b3480156105ac57600080fd5b50610158600160a060020a0360043516602435612216565b3480156105d057600080fd5b5060408051602060048035808201358381028086018501909652808552610158953695939460249493850192918291850190849080828437509497506125bc9650505050505050565b34801561062557600080fd5b506105846125f4565b34801561063a57600080fd5b50610584612603565b61064c81612165565b1561065f5761065a81612612565b610676565b61066881610707565b156101325761065a81612696565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461072c83611005565b15156107a7576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561080e57600080fd5b505af1158015610822573d6000803e3d6000fd5b505050506040513d602081101561083857600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108e8576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d602081101561098e57600080fd5b505115156109d4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b6000610a3084610843565b15610a85576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b610a8e84610fae565b15610b09576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610b8357600080fd5b505af1158015610b97573d6000803e3d6000fd5b505050506040513d6020811015610bad57600080fd5b5051831015610c2c576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395610d1c9592169363693ec85e9360648084019491938390030190829087803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050506040513d6020811015610d0d57600080fd5b5051429063ffffffff6129f516565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610e13576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e98578181015183820152602001610e80565b50505050905090810190601f168015610ec55780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b8051825160009114610f5c576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610fa957610fa18382815181101515610f7a57fe5b906020019060200201518383815181101515610f9257fe5b90602001906020020151611050565b600101610f60565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015611049575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff16156110c5576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff1615151461113a576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b1580156111ae57600080fd5b505af11580156111c2573d6000803e3d6000fd5b505050506040513d60208110156111d857600080fd5b505191506111e733858561138c565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b15801561127557600080fd5b505af1158015611289573d6000803e3d6000fd5b505050506040513d602081101561129f57600080fd5b505115156112e5576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b15801561141457600080fd5b505af1158015611428573d6000803e3d6000fd5b505050506040513d602081101561143e57600080fd5b505190508282820281151561144f57fe5b04979650505050505050565b600160a060020a0380821660009081526001602081905260409091209081015490913361010090920416146114da576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6114e382610843565b151561155f576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003810154158061158d5750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611609576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b61161282612a02565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b1580156116e257600080fd5b505af11580156116f6573d6000803e3d6000fd5b505050506040513d602081101561170c57600080fd5b5051945061171989610fae565b806117285750600186015460ff165b15156117ca576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806117f85750600386015460009081526020819052604090206001015460a060020a900460ff165b1515611874576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b84866002015410156118c65761188989612a02565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611f2d565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050506040513d602081101561197757600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505050506040513d6020811015611a1d57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611a9957600080fd5b505af1158015611aad573d6000803e3d6000fd5b505050506040513d6020811015611ac357600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b158015611b2857600080fd5b505af1158015611b3c573d6000803e3d6000fd5b505050506040513d6020811015611b5257600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e484015292519397506064965090928392611c45928892611c39928c92611c2d92600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b158015611bf457600080fd5b505af1158015611c08573d6000803e3d6000fd5b505050506040513d6020811015611c1e57600080fd5b50518a9063ffffffff612be416565b9063ffffffff612bf616565b9063ffffffff612c1f16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b158015611d5e57600080fd5b505af1158015611d72573d6000803e3d6000fd5b505050506040513d6020811015611d8857600080fd5b50511515611dce576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b158015611e3557600080fd5b505af1158015611e49573d6000803e3d6000fd5b505050506040513d60a0811015611e5f57600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611eed578181015183820152602001611ed5565b50505050905090810190601f168015611f1a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611faa576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561201157600080fd5b505af1158015612025573d6000803e3d6000fd5b505050506040513d602081101561203b57600080fd5b50511515612093576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b1580156120fa57600080fd5b505af115801561210e573d6000803e3d6000fd5b505050506040513d602081101561212457600080fd5b505115156121475750600081815260208190526040902060029081015402610864565b50600090815260208190526040902080546002918201549091020390565b600160a060020a03811660009081526001602052604081206003015461218a83610fae565b80156121ad5750600160a060020a03831660009081526001602052604090205442115b80156121bf57506121bd83610843565b155b80156121f057508015806121f05750600081815260208190526040902060019081015460a060020a900460ff161515145b156121fe576001915061083d565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314612295576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115612317576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b600381015415806123455750600381015460009081526020819052604090206001015460a060020a900460ff165b1561249a57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156123c457600080fd5b505af11580156123d8573d6000803e3d6000fd5b505050506040513d60208110156123ee57600080fd5b50516002820154839003101561249a576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156124fb57600080fd5b505af115801561250f573d6000803e3d6000fd5b505050506040513d602081101561252557600080fd5b5051151561256b576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156125f0576125e882828151811015156125d957fe5b90602001906020020151610643565b6001016125bf565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561266d57604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a038116600090815260016020526040812060030154906126bc82611f39565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561275157600080fd5b505af1158015612765573d6000803e3d6000fd5b505050506040513d602081101561277b57600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156127f557600080fd5b505af1158015612809573d6000803e3d6000fd5b505050506040513d602081101561281f57600080fd5b5051156128a35761282f83612612565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610fa9565b6128ac83612a02565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b15801561291057600080fd5b505af1158015612924573d6000803e3d6000fd5b505050506040513d602081101561293a57600080fd5b50511515612992576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b8181018281101561138657fe5b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615612a6657604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2612a9b565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115612bde576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015612b5c57600080fd5b505af1158015612b70573d6000803e3d6000fd5b505050506040513d6020811015612b8657600080fd5b50511515612bde576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600082821115612bf057fe5b50900390565b6000821515612c0757506000611386565b50818102818382811515612c1757fe5b041461138657fe5b60008183811515612c2c57fe5b0493925050505600546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058208727268bdc490006160e8e6fcf5613b8c995495125aaa0531e39d67fd6a530ad0029", "deployedBytecode": "0x6080604052600436106101325763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301162b93811461013757806306fdde031461015a5780632ea9b696146101e45780633af32abf1461021957806347e7ef241461023a57806355246b9c1461025e5780635f02116f146102c757806361a9a8ca1461035557806365d96c82146103765780636eefcab9146103ca57806386bb8f37146103eb5780638f1d377614610406578063a5ba3b1e14610451578063a7aad3db14610475578063b42652e9146104ae578063bc4b010f146104cf578063c8187cf114610536578063dd4e7cfd1461054e578063e1e3f9151461056f578063f3fef3a3146105a0578063f96c8720146105c4578063fc0c546a14610619578063fce1ccca1461062e575b600080fd5b34801561014357600080fd5b50610158600160a060020a0360043516610643565b005b34801561016657600080fd5b5061016f610679565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101a9578181015183820152602001610191565b50505050905090810190601f1680156101d65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f057600080fd5b50610205600160a060020a0360043516610707565b604080519115158252519081900360200190f35b34801561022557600080fd5b50610205600160a060020a0360043516610843565b34801561024657600080fd5b50610158600160a060020a0360043516602435610869565b34801561026a57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610158948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a259650505050505050565b3480156102d357600080fd5b506040805160206004803580820135838102808601850190965280855261015895369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610eda9650505050505050565b34801561036157600080fd5b50610205600160a060020a0360043516610fae565b34801561038257600080fd5b50610397600160a060020a0360043516610fca565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103d657600080fd5b50610205600160a060020a0360043516611005565b3480156103f757600080fd5b50610158600435602435611050565b34801561041257600080fd5b5061041e600435611322565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561045d57600080fd5b50610205600435600160a060020a036024351661135e565b34801561048157600080fd5b5061049c600160a060020a036004351660243560443561138c565b60408051918252519081900360200190f35b3480156104ba57600080fd5b50610158600160a060020a036004351661145b565b3480156104db57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261049c958335600160a060020a031695369560449491939091019190819084018382808284375094975061164a9650505050505050565b34801561054257600080fd5b5061049c600435611f39565b34801561055a57600080fd5b50610205600160a060020a0360043516612165565b34801561057b57600080fd5b50610584612207565b60408051600160a060020a039092168252519081900360200190f35b3480156105ac57600080fd5b50610158600160a060020a0360043516602435612216565b3480156105d057600080fd5b5060408051602060048035808201358381028086018501909652808552610158953695939460249493850192918291850190849080828437509497506125bc9650505050505050565b34801561062557600080fd5b506105846125f4565b34801561063a57600080fd5b50610584612603565b61064c81612165565b1561065f5761065a81612612565b610676565b61066881610707565b156101325761065a81612696565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461072c83611005565b15156107a7576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561080e57600080fd5b505af1158015610822573d6000803e3d6000fd5b505050506040513d602081101561083857600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108e8576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d602081101561098e57600080fd5b505115156109d4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b6000610a3084610843565b15610a85576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b610a8e84610fae565b15610b09576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610b8357600080fd5b505af1158015610b97573d6000803e3d6000fd5b505050506040513d6020811015610bad57600080fd5b5051831015610c2c576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395610d1c9592169363693ec85e9360648084019491938390030190829087803b158015610ce357600080fd5b505af1158015610cf7573d6000803e3d6000fd5b505050506040513d6020811015610d0d57600080fd5b5051429063ffffffff6129f516565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015610da357600080fd5b505af1158015610db7573d6000803e3d6000fd5b505050506040513d6020811015610dcd57600080fd5b50511515610e13576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610e98578181015183820152602001610e80565b50505050905090810190601f168015610ec55780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b8051825160009114610f5c576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610fa957610fa18382815181101515610f7a57fe5b906020019060200201518383815181101515610f9257fe5b90602001906020020151611050565b600101610f60565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015611049575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff16156110c5576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff1615151461113a576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b1580156111ae57600080fd5b505af11580156111c2573d6000803e3d6000fd5b505050506040513d60208110156111d857600080fd5b505191506111e733858561138c565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b15801561127557600080fd5b505af1158015611289573d6000803e3d6000fd5b505050506040513d602081101561129f57600080fd5b505115156112e5576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b15801561141457600080fd5b505af1158015611428573d6000803e3d6000fd5b505050506040513d602081101561143e57600080fd5b505190508282820281151561144f57fe5b04979650505050505050565b600160a060020a0380821660009081526001602081905260409091209081015490913361010090920416146114da576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6114e382610843565b151561155f576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003810154158061158d5750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611609576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b61161282612a02565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b1580156116e257600080fd5b505af11580156116f6573d6000803e3d6000fd5b505050506040513d602081101561170c57600080fd5b5051945061171989610fae565b806117285750600186015460ff165b15156117ca576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806117f85750600386015460009081526020819052604090206001015460a060020a900460ff165b1515611874576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b84866002015410156118c65761188989612a02565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611f2d565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561194d57600080fd5b505af1158015611961573d6000803e3d6000fd5b505050506040513d602081101561197757600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156119f357600080fd5b505af1158015611a07573d6000803e3d6000fd5b505050506040513d6020811015611a1d57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611a9957600080fd5b505af1158015611aad573d6000803e3d6000fd5b505050506040513d6020811015611ac357600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b158015611b2857600080fd5b505af1158015611b3c573d6000803e3d6000fd5b505050506040513d6020811015611b5257600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e484015292519397506064965090928392611c45928892611c39928c92611c2d92600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b158015611bf457600080fd5b505af1158015611c08573d6000803e3d6000fd5b505050506040513d6020811015611c1e57600080fd5b50518a9063ffffffff612be416565b9063ffffffff612bf616565b9063ffffffff612c1f16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b158015611d5e57600080fd5b505af1158015611d72573d6000803e3d6000fd5b505050506040513d6020811015611d8857600080fd5b50511515611dce576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b158015611e3557600080fd5b505af1158015611e49573d6000803e3d6000fd5b505050506040513d60a0811015611e5f57600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611eed578181015183820152602001611ed5565b50505050905090810190601f168015611f1a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611faa576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561201157600080fd5b505af1158015612025573d6000803e3d6000fd5b505050506040513d602081101561203b57600080fd5b50511515612093576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b1580156120fa57600080fd5b505af115801561210e573d6000803e3d6000fd5b505050506040513d602081101561212457600080fd5b505115156121475750600081815260208190526040902060029081015402610864565b50600090815260208190526040902080546002918201549091020390565b600160a060020a03811660009081526001602052604081206003015461218a83610fae565b80156121ad5750600160a060020a03831660009081526001602052604090205442115b80156121bf57506121bd83610843565b155b80156121f057508015806121f05750600081815260208190526040902060019081015460a060020a900460ff161515145b156121fe576001915061083d565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314612295576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115612317576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b600381015415806123455750600381015460009081526020819052604090206001015460a060020a900460ff165b1561249a57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156123c457600080fd5b505af11580156123d8573d6000803e3d6000fd5b505050506040513d60208110156123ee57600080fd5b50516002820154839003101561249a576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156124fb57600080fd5b505af115801561250f573d6000803e3d6000fd5b505050506040513d602081101561252557600080fd5b5051151561256b576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612c35833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156125f0576125e882828151811015156125d957fe5b90602001906020020151610643565b6001016125bf565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561266d57604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a038116600090815260016020526040812060030154906126bc82611f39565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561275157600080fd5b505af1158015612765573d6000803e3d6000fd5b505050506040513d602081101561277b57600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156127f557600080fd5b505af1158015612809573d6000803e3d6000fd5b505050506040513d602081101561281f57600080fd5b5051156128a35761282f83612612565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610fa9565b6128ac83612a02565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b15801561291057600080fd5b505af1158015612924573d6000803e3d6000fd5b505050506040513d602081101561293a57600080fd5b50511515612992576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b8181018281101561138657fe5b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615612a6657604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2612a9b565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115612bde576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015612b5c57600080fd5b505af1158015612b70573d6000803e3d6000fd5b505050506040513d6020811015612b8657600080fd5b50511515612bde576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600082821115612bf057fe5b50900390565b6000821515612c0757506000611386565b50818102818382811515612c1757fe5b041461138657fe5b60008183811515612c2c57fe5b0493925050505600546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058208727268bdc490006160e8e6fcf5613b8c995495125aaa0531e39d67fd6a530ad0029", "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "listings", "outputs": [ { "name": "applicationExpiry", "type": "uint256" }, { "name": "whitelisted", "type": "bool" }, { "name": "owner", "type": "address" }, { "name": "unstakedDeposit", "type": "uint256" }, { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "totalTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "parameterizer", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_token", "type": "address" }, { "name": "_voting", "type": "address" }, { "name": "_parameterizer", "type": "address" }, { "name": "_name", "type": "string" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": true, "name": "applicant", "type": "address" } ], "name": "_Application", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_Challenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "added", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "withdrew", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Withdrawal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationWhitelisted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_TouchAndRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" }, { "name": "_data", "type": "string" } ], "name": "apply", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "deposit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "exit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_data", "type": "string" } ], "name": "challenge", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "updateStatus", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddresses", "type": "address[]" } ], "name": "updateStatuses", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "canBeWhitelisted", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "isWhitelisted", "outputs": [ { "name": "whitelisted", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appWasMade", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" } ], "name": "determineReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/AttributeStore.json ================================================ { "contractName": "AttributeStore", "bytecode": "0x610257610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600436106100625763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166350389f5c8114610067578063977aa031146100cc575b600080fd5b604080516020600460443581810135601f81018490048402850184019095528484526100ba9482359460248035953695946064949201919081908401838280828437509497506101309650505050505050565b60408051918252519081900360200190f35b8180156100d857600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261012e94823594602480359536959460649492019190819084018382808284375094975050933594506101ae9350505050565b005b6040518281528151600091829185918591602080830191908401908083835b6020831061016e5780518252601f19909201916020918201910161014f565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060009081529a90525090972054979650505050505050565b60405183815282516000918591859190602080830191908401908083835b602083106101eb5780518252601f1990920191602091820191016101cc565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060009081529a905250909720939093555050505050505600a165627a7a7230582079ab66d305fc0d9403e2a82ed5a7c4091142c9ec363996370b09386ef5b19a420029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100625763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166350389f5c8114610067578063977aa031146100cc575b600080fd5b604080516020600460443581810135601f81018490048402850184019095528484526100ba9482359460248035953695946064949201919081908401838280828437509497506101309650505050505050565b60408051918252519081900360200190f35b8180156100d857600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261012e94823594602480359536959460649492019190819084018382808284375094975050933594506101ae9350505050565b005b6040518281528151600091829185918591602080830191908401908083835b6020831061016e5780518252601f19909201916020918201910161014f565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060009081529a90525090972054979650505050505050565b60405183815282516000918591859190602080830191908401908083835b602083106101eb5780518252601f1990920191602091820191016101cc565b51815160209384036101000a6000190180199092169116179052604080519290940182900390912060009081529a905250909720939093555050505050505600a165627a7a7230582079ab66d305fc0d9403e2a82ed5a7c4091142c9ec363996370b09386ef5b19a420029", "abi": [ { "constant": true, "inputs": [ { "name": "self", "type": "AttributeStore.Data storage" }, { "name": "_UUID", "type": "bytes32" }, { "name": "_attrName", "type": "string" } ], "name": "getAttribute", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "AttributeStore.Data storage" }, { "name": "_UUID", "type": "bytes32" }, { "name": "_attrName", "type": "string" }, { "name": "_attrVal", "type": "uint256" } ], "name": "setAttribute", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x393e69e7ae7addcfd744b71d209b1f04800d89e5", "transactionHash": "0xcea1feb4c485e63783277ec35149e56f369d3c51da96f3a13825bc28bcbe5207" }, "4": { "events": {}, "links": {}, "address": "0x0584ee9107eebfc100994ad88c380fb8108fbc2d", "transactionHash": "0xcac7087ae3bd4989c4f046354760c689c8dde25f87878b91b39388285fdee4cb" } } } ================================================ FILE: packages/artifacts/v1/CVLToken.json ================================================ { "contractName": "CVLToken", "bytecode": "0x60806040523480156200001157600080fd5b50604051620011dc380380620011dc83398101604090815281516020808401519284015160608501516080860151948601805194969095929491019285918491869162000065916003919086019062000229565b5081516200007b90600490602085019062000229565b506005805460ff191660ff929092169190911761010060a860020a03191661010033021790555050600160a060020a03811615156200011b57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f636f6e74726f6c6c6572206e6f742070726f7669646564000000000000000000604482015290519081900360640190fd5b60068054600160a060020a031916600160a060020a0383161790556200014b338664010000000062000156810204565b5050505050620002ce565b600160a060020a03821615156200016c57600080fd5b60025462000189908264010000000062000d416200021582021704565b600255600160a060020a038216600090815260208190526040902054620001bf908264010000000062000d416200021582021704565b600160a060020a0383166000818152602081815260408083209490945583518581529351929391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a35050565b818101828110156200022357fe5b92915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200026c57805160ff19168380011785556200029c565b828001600101855582156200029c579182015b828111156200029c5782518255916020019190600101906200027f565b50620002aa929150620002ae565b5090565b620002cb91905b80821115620002aa5760008155600101620002b5565b90565b610efe80620002de6000396000f3006080604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610100578063095ea7b31461018a57806318160ddd146101c257806323b872dd146101e9578063313ce56714610213578063395093511461023e5780633cebb8231461026257806370a0823114610285578063715018a6146102a65780637f4ab1dd146102bb5780638da5cb5b146102d657806395d89b4114610307578063a457c2d71461031c578063a9059cbb14610340578063d4ce141514610364578063dd62ed3e1461038e578063f2fde38b146103b5578063f77c4791146103d6575b600080fd5b34801561010c57600080fd5b506101156103eb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014f578181015183820152602001610137565b50505050905090810190601f16801561017c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019657600080fd5b506101ae600160a060020a0360043516602435610481565b604080519115158252519081900360200190f35b3480156101ce57600080fd5b506101d76104ff565b60408051918252519081900360200190f35b3480156101f557600080fd5b506101ae600160a060020a0360043581169060243516604435610505565b34801561021f57600080fd5b5061022861061e565b6040805160ff9092168252519081900360200190f35b34801561024a57600080fd5b506101ae600160a060020a0360043516602435610627565b34801561026e57600080fd5b50610283600160a060020a03600435166106d7565b005b34801561029157600080fd5b506101d7600160a060020a03600435166107cd565b3480156102b257600080fd5b506102836107e8565b3480156102c757600080fd5b5061011560ff600435166108ab565b3480156102e257600080fd5b506102eb6109a1565b60408051600160a060020a039092168252519081900360200190f35b34801561031357600080fd5b506101156109b5565b34801561032857600080fd5b506101ae600160a060020a0360043516602435610a16565b34801561034c57600080fd5b506101ae600160a060020a0360043516602435610a61565b34801561037057600080fd5b50610228600160a060020a0360043581169060243516604435610b79565b34801561039a57600080fd5b506101d7600160a060020a0360043581169060243516610c27565b3480156103c157600080fd5b50610283600160a060020a0360043516610c52565b3480156103e257600080fd5b506102eb610cc5565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b6000600160a060020a038316151561049857600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600654604080517fd4ce1415000000000000000000000000000000000000000000000000000000008152600160a060020a0380871660048301528086166024830152604482018590529151600093879387938793919092169163d4ce141591606480830192602092919082900301818a87803b15801561058457600080fd5b505af1158015610598573d6000803e3d6000fd5b505050506040513d60208110156105ae57600080fd5b505160ff1615610608576040805160e560020a62461bcd02815260206004820152601960248201527f746f6b656e207472616e73666572207265737472696374656400000000000000604482015290519081900360640190fd5b610613878787610cd4565b979650505050505050565b60055460ff1690565b6000600160a060020a038316151561063e57600080fd5b336000908152600160209081526040808320600160a060020a0387168452909152902054610672908363ffffffff610d4116565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b6005546101009004600160a060020a0316331461073e576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038116151561079e576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74726f6c6c6572206e6f742070726f7669646564000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a031660009081526020819052604090205490565b6005546101009004600160a060020a0316331461084f576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600554604051610100909104600160a060020a0316907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a26005805474ffffffffffffffffffffffffffffffffffffffff0019169055565b600654604080517f7f4ab1dd00000000000000000000000000000000000000000000000000000000815260ff841660048201529051606092600160a060020a031691637f4ab1dd91602480830192600092919082900301818387803b15801561091357600080fd5b505af1158015610927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561095057600080fd5b81019080805164010000000081111561096857600080fd5b8201602081018481111561097b57600080fd5b815164010000000081118282018710171561099557600080fd5b50909695505050505050565b6005546101009004600160a060020a031681565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104775780601f1061044c57610100808354040283529160200191610477565b6000600160a060020a0383161515610a2d57600080fd5b336000908152600160209081526040808320600160a060020a0387168452909152902054610672908363ffffffff610d5416565b600654604080517fd4ce14150000000000000000000000000000000000000000000000000000000081523360048201819052600160a060020a038087166024840152604483018690529251600094919387938793919091169163d4ce14159160648082019260209290919082900301818a87803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b505050506040513d6020811015610b0b57600080fd5b505160ff1615610b65576040805160e560020a62461bcd02815260206004820152601960248201527f746f6b656e207472616e73666572207265737472696374656400000000000000604482015290519081900360640190fd5b610b6f8686610d66565b9695505050505050565b600654604080517fd4ce1415000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528581166024830152604482018590529151600093929092169163d4ce14159160648082019260209290919082900301818787803b158015610bf357600080fd5b505af1158015610c07573d6000803e3d6000fd5b505050506040513d6020811015610c1d57600080fd5b5051949350505050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6005546101009004600160a060020a03163314610cb9576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610cc281610d7c565b50565b600654600160a060020a031681565b600160a060020a0383166000908152600160209081526040808320338452909152812054610d08908363ffffffff610d5416565b600160a060020a0385166000908152600160209081526040808320338452909152902055610d37848484610e05565b5060019392505050565b81810182811015610d4e57fe5b92915050565b600082821115610d6057fe5b50900390565b6000610d73338484610e05565b50600192915050565b600160a060020a0381161515610d9157600080fd5b600554604051600160a060020a0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360058054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b600160a060020a0382161515610e1a57600080fd5b600160a060020a038316600090815260208190526040902054610e43908263ffffffff610d5416565b600160a060020a038085166000908152602081905260408082209390935590841681522054610e78908263ffffffff610d4116565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35050505600a165627a7a72305820dac04f05458cdeb4af0f3e06354cc2974db1073b65c7dde071a446ac4443cfc30029", "deployedBytecode": "0x6080604052600436106100fb5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde038114610100578063095ea7b31461018a57806318160ddd146101c257806323b872dd146101e9578063313ce56714610213578063395093511461023e5780633cebb8231461026257806370a0823114610285578063715018a6146102a65780637f4ab1dd146102bb5780638da5cb5b146102d657806395d89b4114610307578063a457c2d71461031c578063a9059cbb14610340578063d4ce141514610364578063dd62ed3e1461038e578063f2fde38b146103b5578063f77c4791146103d6575b600080fd5b34801561010c57600080fd5b506101156103eb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561014f578181015183820152602001610137565b50505050905090810190601f16801561017c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561019657600080fd5b506101ae600160a060020a0360043516602435610481565b604080519115158252519081900360200190f35b3480156101ce57600080fd5b506101d76104ff565b60408051918252519081900360200190f35b3480156101f557600080fd5b506101ae600160a060020a0360043581169060243516604435610505565b34801561021f57600080fd5b5061022861061e565b6040805160ff9092168252519081900360200190f35b34801561024a57600080fd5b506101ae600160a060020a0360043516602435610627565b34801561026e57600080fd5b50610283600160a060020a03600435166106d7565b005b34801561029157600080fd5b506101d7600160a060020a03600435166107cd565b3480156102b257600080fd5b506102836107e8565b3480156102c757600080fd5b5061011560ff600435166108ab565b3480156102e257600080fd5b506102eb6109a1565b60408051600160a060020a039092168252519081900360200190f35b34801561031357600080fd5b506101156109b5565b34801561032857600080fd5b506101ae600160a060020a0360043516602435610a16565b34801561034c57600080fd5b506101ae600160a060020a0360043516602435610a61565b34801561037057600080fd5b50610228600160a060020a0360043581169060243516604435610b79565b34801561039a57600080fd5b506101d7600160a060020a0360043581169060243516610c27565b3480156103c157600080fd5b50610283600160a060020a0360043516610c52565b3480156103e257600080fd5b506102eb610cc5565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104775780601f1061044c57610100808354040283529160200191610477565b820191906000526020600020905b81548152906001019060200180831161045a57829003601f168201915b5050505050905090565b6000600160a060020a038316151561049857600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600654604080517fd4ce1415000000000000000000000000000000000000000000000000000000008152600160a060020a0380871660048301528086166024830152604482018590529151600093879387938793919092169163d4ce141591606480830192602092919082900301818a87803b15801561058457600080fd5b505af1158015610598573d6000803e3d6000fd5b505050506040513d60208110156105ae57600080fd5b505160ff1615610608576040805160e560020a62461bcd02815260206004820152601960248201527f746f6b656e207472616e73666572207265737472696374656400000000000000604482015290519081900360640190fd5b610613878787610cd4565b979650505050505050565b60055460ff1690565b6000600160a060020a038316151561063e57600080fd5b336000908152600160209081526040808320600160a060020a0387168452909152902054610672908363ffffffff610d4116565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b6005546101009004600160a060020a0316331461073e576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038116151561079e576040805160e560020a62461bcd02815260206004820152601760248201527f636f6e74726f6c6c6572206e6f742070726f7669646564000000000000000000604482015290519081900360640190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a031660009081526020819052604090205490565b6005546101009004600160a060020a0316331461084f576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b600554604051610100909104600160a060020a0316907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a26005805474ffffffffffffffffffffffffffffffffffffffff0019169055565b600654604080517f7f4ab1dd00000000000000000000000000000000000000000000000000000000815260ff841660048201529051606092600160a060020a031691637f4ab1dd91602480830192600092919082900301818387803b15801561091357600080fd5b505af1158015610927573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561095057600080fd5b81019080805164010000000081111561096857600080fd5b8201602081018481111561097b57600080fd5b815164010000000081118282018710171561099557600080fd5b50909695505050505050565b6005546101009004600160a060020a031681565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156104775780601f1061044c57610100808354040283529160200191610477565b6000600160a060020a0383161515610a2d57600080fd5b336000908152600160209081526040808320600160a060020a0387168452909152902054610672908363ffffffff610d5416565b600654604080517fd4ce14150000000000000000000000000000000000000000000000000000000081523360048201819052600160a060020a038087166024840152604483018690529251600094919387938793919091169163d4ce14159160648082019260209290919082900301818a87803b158015610ae157600080fd5b505af1158015610af5573d6000803e3d6000fd5b505050506040513d6020811015610b0b57600080fd5b505160ff1615610b65576040805160e560020a62461bcd02815260206004820152601960248201527f746f6b656e207472616e73666572207265737472696374656400000000000000604482015290519081900360640190fd5b610b6f8686610d66565b9695505050505050565b600654604080517fd4ce1415000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528581166024830152604482018590529151600093929092169163d4ce14159160648082019260209290919082900301818787803b158015610bf357600080fd5b505af1158015610c07573d6000803e3d6000fd5b505050506040513d6020811015610c1d57600080fd5b5051949350505050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b6005546101009004600160a060020a03163314610cb9576040805160e560020a62461bcd02815260206004820152600960248201527f6e6f74206f776e65720000000000000000000000000000000000000000000000604482015290519081900360640190fd5b610cc281610d7c565b50565b600654600160a060020a031681565b600160a060020a0383166000908152600160209081526040808320338452909152812054610d08908363ffffffff610d5416565b600160a060020a0385166000908152600160209081526040808320338452909152902055610d37848484610e05565b5060019392505050565b81810182811015610d4e57fe5b92915050565b600082821115610d6057fe5b50900390565b6000610d73338484610e05565b50600192915050565b600160a060020a0381161515610d9157600080fd5b600554604051600160a060020a0380841692610100900416907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a360058054600160a060020a039092166101000274ffffffffffffffffffffffffffffffffffffffff0019909216919091179055565b600160a060020a0382161515610e1a57600080fd5b600160a060020a038316600090815260208190526040902054610e43908263ffffffff610d5416565b600160a060020a038085166000908152602081905260408082209390935590841681522054610e78908263ffffffff610d4116565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a35050505600a165627a7a72305820dac04f05458cdeb4af0f3e06354cc2974db1073b65c7dde071a446ac4443cfc30029", "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" }, { "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "controller", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_initialAmount", "type": "uint256" }, { "name": "_tokenName", "type": "string" }, { "name": "_decimalUnits", "type": "uint8" }, { "name": "_tokenSymbol", "type": "string" }, { "name": "_controller", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "constant": false, "inputs": [ { "name": "_controller", "type": "address" } ], "name": "changeController", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "success", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "detectTransferRestriction", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "restrictionCode", "type": "uint8" } ], "name": "messageForTransferRestriction", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": { "1": { "events": { "0xf8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c64820": { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0": { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" } }, "links": {}, "address": "0x01FA555c97D7958Fa6f771f3BbD5CCD508f81e22", "transactionHash": "0x2fec07865194447d25786ecf846adfa067de02db8750a5aaa7d256e2aa050504" }, "4": { "events": { "0xf8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c64820": { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0": { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef": { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925": { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" } }, "links": {}, "address": "0x3e39fa983abcd349d95aed608e798817397cf0d1", "transactionHash": "0x94724e5f073881e2af29d03e87af8d83c07408dbcba3bc08fcd3a9e516af28b3" } } } ================================================ FILE: packages/artifacts/v1/CivilPLCRVoting.json ================================================ { "contractName": "CivilPLCRVoting", "bytecode": "0x608060405234801561001057600080fd5b50604051604080611eb583398101604052805160209091015181600160a060020a038116151561003f57600080fd5b60058054600160a060020a031916600160a060020a03928316179055600080558116151561006c57600080fd5b60068054600160a060020a031916600160a060020a039290921691909117905550611e198061009c6000396000f3006080604052600436106101925763ffffffff60e060020a600035041663053e71a681146101975780632173a10f146101c15780632c052031146101d657806332ed3d60146101fd5780633b9302941461021b5780633ec36b991461023c57806340f41c1914610282578063427fa1d2146102b3578063441c77c0146102d457806349403183146103005780636148fed5146103185780636afa97a81461035b5780636b2d95d4146103825780636cbf9c5e146103a35780637f97e836146103c45780638090f92e146103e8578063819b02931461042057806388d21ff31461044a57806397508f36146104625780639760356014610477578063a1103f371461048f578063a25236fe146104b3578063a4439dc5146104cb578063aa7ca464146104e3578063b11d8bb814610507578063b43bd06914610525578063bb11ed7e1461054c578063d1382092146105a1578063d901402b146105c5578063d9548e53146105e9578063e7b1d43c14610601578063e8cfa3f014610619578063ee68483014610631578063fc0c546a14610649575b600080fd5b3480156101a357600080fd5b506101af60043561065e565b60408051918252519081900360200190f35b3480156101cd57600080fd5b506101af6106b3565b3480156101e257600080fd5b506101af600160a060020a03600435166024356044356106b8565b34801561020957600080fd5b506101af600435602435604435610881565b34801561022757600080fd5b506101af600160a060020a036004351661095d565b34801561024857600080fd5b50610280602460048035828101929082013591813580830192908201359160443580830192908201359160643591820191013561096f565b005b34801561028e57600080fd5b50610297610a0f565b60408051600160a060020a039092168252519081900360200190f35b3480156102bf57600080fd5b506101af600160a060020a0360043516610a1e565b3480156102e057600080fd5b506102ec600435610ad8565b604080519115158252519081900360200190f35b34801561030c57600080fd5b506102ec600435610b23565b34801561032457600080fd5b50610330600435610ba0565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561036757600080fd5b506101af600160a060020a0360043516602435604435610bce565b34801561038e57600080fd5b506101af600160a060020a0360043516610c85565b3480156103af57600080fd5b50610280600435602435604435606435610c99565b3480156103d057600080fd5b506102ec600160a060020a036004351660243561120b565b3480156103f457600080fd5b506102806024600480358281019290820135918135808301929082013591604435918201910135611250565b34801561042c57600080fd5b506102ec600435602435600160a060020a03604435166064356112cc565b34801561045657600080fd5b506102ec60043561130a565b34801561046e57600080fd5b506101af61131f565b34801561048357600080fd5b50610280600435611325565b34801561049b57600080fd5b506101af600160a060020a03600435166024356114c9565b3480156104bf57600080fd5b50610280600435611500565b3480156104d757600080fd5b506102ec60043561159a565b3480156104ef57600080fd5b506102ec600160a060020a03600435166024356115c8565b34801561051357600080fd5b5061028060043560243560443561160d565b34801561053157600080fd5b506101af600160a060020a0360043516602435604435611810565b34801561055857600080fd5b50604080516020600480358082013583810280860185019096528085526102809536959394602494938501929182918501908490808284375094975061189c9650505050505050565b3480156105ad57600080fd5b506101af600160a060020a03600435166024356118d4565b3480156105d157600080fd5b506101af600160a060020a03600435166024356119a6565b3480156105f557600080fd5b506102ec600435611a45565b34801561060d57600080fd5b50610280600435611a4a565b34801561062557600080fd5b506101af600435611b76565b34801561063d57600080fd5b506102ec600435611bca565b34801561065557600080fd5b50610297611bfc565b600061066982611bca565b151561067457600080fd5b61067d82610b23565b1561069a57506000818152600160205260409020600301546106ae565b506000818152600160205260409020600401545b919050565b600081565b60008060006106c686610a1e565b91506106d286836118d4565b90505b8115610874576106e586836118d4565b90508481116107b757838214156107af57600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561078057600080fd5b505af4158015610794573d6000803e3d6000fd5b505050506040513d60208110156107aa57600080fd5b505191505b819250610878565b600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561084157600080fd5b505af4158015610855573d6000803e3d6000fd5b505050506040513d602081101561086b57600080fd5b505191506106d5565b8192505b50509392505050565b600080546001018155808061089c428663ffffffff611c0b16565b91506108ae828563ffffffff611c0b16565b6040805160a08101825284815260208082018481528284018b8152600060608086018281526080870183815283548452600180885289852098518955955195880195909555925160028701559151600386015591516004909401939093555483518b8152918201879052818401859052925193945033937f404f1f1c229d9eb2a949e7584da6ffde9d059ef2169f487ca815434cce0640d0929181900390910190a35050600054949350505050565b60026020526000908152604090205481565b600087861461097d57600080fd5b87841461098957600080fd5b87821461099557600080fd5b5060005b87811015610a04576109fc8989838181106109b057fe5b9050602002013588888481811015156109c557fe5b602002919091013590508787858181106109db57fe5b9050602002013586868681811015156109f057fe5b90506020020135610c99565b600101610999565b505050505050505050565b600654600160a060020a031681565b600160a060020a038116600090815260036020908152604080832081517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________926330fe0a0a9260448082019391829003018186803b158015610aa657600080fd5b505af4158015610aba573d6000803e3d6000fd5b505050506040513d6020811015610ad057600080fd5b505192915050565b6000610ae38261130a565b1515610aee57600080fd5b60008281526001602081905260409091200154610b0a90611a45565b158015610b1d5750610b1b8261159a565b155b92915050565b6000610b2d611dbd565b610b3683611bca565b1515610b4157600080fd5b5050600090815260016020818152604092839020835160a0810185528154815292810154918301919091526002810154928201839052600381015460608301819052600490910154608090920182905290810190910260649091021190565b6001602081905260009182526040909120805491810154600282015460038301546004909301549192909185565b600080600080610bdd86611bca565b1515610be857600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff161515610c1c57600080fd5b610c2586610b23565b610c30576001610c33565b60005b60ff1692508285604051808381526020018281526020019250505060405180910390209150610c6287876119a6565b9050818114610c7057600080fd5b610c7a87876118d4565b979650505050505050565b6000610b1d82610c9484610a1e565b6118d4565b6000806000610ca78761159a565b1515610cb257600080fd5b33600090815260026020526040902054851115610cf55733600090815260026020526040902054610cea90869063ffffffff611c1816565b9250610cf583611500565b33600090815260026020526040902054851115610d1157600080fd5b861515610d1d57600080fd5b851515610d2957600080fd5b831580610ddf57503360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b158015610db257600080fd5b505af4158015610dc6573d6000803e3d6000fd5b505050506040513d6020811015610ddc57600080fd5b50515b1515610dea57600080fd5b3360009081526003602090815260409182902082517f07d29ac9000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610e6b57600080fd5b505af4158015610e7f573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b5051915086821415610f51573360009081526003602090815260409182902082517f07d29ac90000000000000000000000000000000000000000000000000000000081526004810191909152602481018a9052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610f2257600080fd5b505af4158015610f36573d6000803e3d6000fd5b505050506040513d6020811015610f4c57600080fd5b505191505b610f5d848333886112cc565b1515610f6857600080fd5b3360009081526003602052604080822081517f9735c51b000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604481018a905260648101859052905173__DLL___________________________________92639735c51b9260848082019391829003018186803b158015610ff357600080fd5b505af4158015611007573d6000803e3d6000fd5b5050505061101533886114c9565b604080517f977aa031000000000000000000000000000000000000000000000000000000008152600481810152602481018390526064810188905260806044820152600960848201527f6e756d546f6b656e73000000000000000000000000000000000000000000000060a4820152905191925073__AttributeStore________________________9163977aa0319160c480820192600092909190829003018186803b1580156110c557600080fd5b505af41580156110d9573d6000803e3d6000fd5b5050604080517f977aa03100000000000000000000000000000000000000000000000000000000815260048181015260248101859052606481018a905260806044820152600a60848201527f636f6d6d6974486173680000000000000000000000000000000000000000000060a4820152905173__AttributeStore________________________935063977aa031925060c4808301926000929190829003018186803b15801561118957600080fd5b505af415801561119d573d6000803e3d6000fd5b5050506000888152600160208181526040808420338086526005909101835293819020805460ff1916909317909255815189815291519293508a927fea7979e4280d7e6bffc1c7d83a1ac99f16d02ecc14465ce41016226783b663d79281900390910190a350505050505050565b60006112168261130a565b151561122157600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260059093019052205460ff1690565b600085841461125e57600080fd5b85821461126a57600080fd5b5060005b858110156112c3576112bb87878381811061128557fe5b90506020020135868684818110151561129a57fe5b9050602002013585858581811015156112af57fe5b9050602002013561160d565b60010161126e565b50505050505050565b60008060006112db85886118d4565b84101591506112ea85876118d4565b841115806112f6575085155b9050818015610c7a57509695505050505050565b60008115801590610b1d575050600054101590565b60005481565b6000818152600160208190526040909120015461134190611a45565b151561134c57600080fd5b3360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b1580156113cd57600080fd5b505af41580156113e1573d6000803e3d6000fd5b505050506040513d60208110156113f757600080fd5b5051151561140457600080fd5b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561148157600080fd5b505af4158015611495573d6000803e3d6000fd5b50506040513392508391507f402507661c8c8cb90e0a796450b8bdd28b6c516f05279c0cd29e84c344e1699a90600090a350565b604080516c01000000000000000000000000600160a060020a03851602815260148101839052905190819003603401902092915050565b61150981611c2a565b600654336000818152600260205260408082205481517f725248730000000000000000000000000000000000000000000000000000000081526004810194909452602484015251600160a060020a0390931692637252487392604480820193929182900301818387803b15801561157f57600080fd5b505af1158015611593573d6000803e3d6000fd5b5050505050565b60006115a58261130a565b15156115b057600080fd5b600082815260016020526040902054610b1b90611a45565b60006115d38261130a565b15156115de57600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260069093019052205460ff1690565b600061161884610ad8565b151561162357600080fd5b600084815260016020908152604080832033845260050190915290205460ff16151561164e57600080fd5b600084815260016020908152604080832033845260060190915290205460ff161561167857600080fd5b61168233856119a6565b60408051858152602081018590528151908190039091019020146116a557600080fd5b6116af33856118d4565b905082600114156116d65760008481526001602052604090206003018054820190556116ee565b60008481526001602052604090206004018054820190555b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561176b57600080fd5b505af415801561177f573d6000803e3d6000fd5b505050600085815260016020818152604080842033808652600682018452828620805460ff191686179055948a9052928252600383015460049093015481518781529283019390935281810192909252606081018690529051919250859187917f9b19aaec524fad29c0ced9b9973a15e3045d7c3be156d71394ab40f0d5f119ff919081900360800190a450505050565b60008060008061181f86611bca565b151561182a57600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff16151561185e57600080fd5b61186786610b23565b611872576000610c33565b6040805160018082526020820188905282519182900390920190209093509150610c6287876119a6565b60005b81518110156118d0576118c882828151811015156118b957fe5b90602001906020020151611325565b60010161189f565b5050565b600073__AttributeStore________________________6350389f5c60046118fc86866114c9565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600960648301527f6e756d546f6b656e73000000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561197357600080fd5b505af4158015611987573d6000803e3d6000fd5b505050506040513d602081101561199d57600080fd5b50519392505050565b600073__AttributeStore________________________6350389f5c60046119ce86866114c9565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600a60648301527f636f6d6d6974486173680000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561197357600080fd5b421190565b6000611a74611a5833610c85565b336000908152600260205260409020549063ffffffff611c1816565b905081811015611a8357600080fd5b3360008181526002602090815260408083208054879003905560055481517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810195909552602485018790529051600160a060020a039091169363a9059cbb9360448083019493928390030190829087803b158015611b0557600080fd5b505af1158015611b19573d6000803e3d6000fd5b505050506040513d6020811015611b2f57600080fd5b50511515611b3c57600080fd5b60408051838152905133917ffaeb7dbb9992397d26ea1944efd40c80b40f702faf69b46c67ad10aba68ccb79919081900360200190a25050565b6000611b8182611bca565b1515611b8c57600080fd5b611b9582610b23565b15611bb257506000818152600160205260409020600401546106ae565b506000818152600160205260409020600301546106ae565b6000611bd58261130a565b1515611be057600080fd5b60008281526001602081905260409091200154610b1d90611a45565b600554600160a060020a031681565b81810182811015610b1d57fe5b600082821115611c2457fe5b50900390565b600554604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518392600160a060020a0316916370a082319160248083019260209291908290030181600087803b158015611c8f57600080fd5b505af1158015611ca3573d6000803e3d6000fd5b505050506040513d6020811015611cb957600080fd5b50511015611cc657600080fd5b33600081815260026020908152604080832080548601905560055481517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690529051600160a060020a03909116936323b872dd9360648083019493928390030190829087803b158015611d4d57600080fd5b505af1158015611d61573d6000803e3d6000fd5b505050506040513d6020811015611d7757600080fd5b50511515611d8457600080fd5b60408051828152905133917ff7aaf024511d9982df8cd0d437c71c30106e6848cd1ba3d288d7a9c0e276aeda919081900360200190a250565b60a060405190810160405280600081526020016000815260200160008152602001600081526020016000815250905600a165627a7a72305820dfb0bd5ea70ad6f1df929d57bad9a8a3a61facd419e162e3168c26c446d299260029", "deployedBytecode": "0x6080604052600436106101925763ffffffff60e060020a600035041663053e71a681146101975780632173a10f146101c15780632c052031146101d657806332ed3d60146101fd5780633b9302941461021b5780633ec36b991461023c57806340f41c1914610282578063427fa1d2146102b3578063441c77c0146102d457806349403183146103005780636148fed5146103185780636afa97a81461035b5780636b2d95d4146103825780636cbf9c5e146103a35780637f97e836146103c45780638090f92e146103e8578063819b02931461042057806388d21ff31461044a57806397508f36146104625780639760356014610477578063a1103f371461048f578063a25236fe146104b3578063a4439dc5146104cb578063aa7ca464146104e3578063b11d8bb814610507578063b43bd06914610525578063bb11ed7e1461054c578063d1382092146105a1578063d901402b146105c5578063d9548e53146105e9578063e7b1d43c14610601578063e8cfa3f014610619578063ee68483014610631578063fc0c546a14610649575b600080fd5b3480156101a357600080fd5b506101af60043561065e565b60408051918252519081900360200190f35b3480156101cd57600080fd5b506101af6106b3565b3480156101e257600080fd5b506101af600160a060020a03600435166024356044356106b8565b34801561020957600080fd5b506101af600435602435604435610881565b34801561022757600080fd5b506101af600160a060020a036004351661095d565b34801561024857600080fd5b50610280602460048035828101929082013591813580830192908201359160443580830192908201359160643591820191013561096f565b005b34801561028e57600080fd5b50610297610a0f565b60408051600160a060020a039092168252519081900360200190f35b3480156102bf57600080fd5b506101af600160a060020a0360043516610a1e565b3480156102e057600080fd5b506102ec600435610ad8565b604080519115158252519081900360200190f35b34801561030c57600080fd5b506102ec600435610b23565b34801561032457600080fd5b50610330600435610ba0565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561036757600080fd5b506101af600160a060020a0360043516602435604435610bce565b34801561038e57600080fd5b506101af600160a060020a0360043516610c85565b3480156103af57600080fd5b50610280600435602435604435606435610c99565b3480156103d057600080fd5b506102ec600160a060020a036004351660243561120b565b3480156103f457600080fd5b506102806024600480358281019290820135918135808301929082013591604435918201910135611250565b34801561042c57600080fd5b506102ec600435602435600160a060020a03604435166064356112cc565b34801561045657600080fd5b506102ec60043561130a565b34801561046e57600080fd5b506101af61131f565b34801561048357600080fd5b50610280600435611325565b34801561049b57600080fd5b506101af600160a060020a03600435166024356114c9565b3480156104bf57600080fd5b50610280600435611500565b3480156104d757600080fd5b506102ec60043561159a565b3480156104ef57600080fd5b506102ec600160a060020a03600435166024356115c8565b34801561051357600080fd5b5061028060043560243560443561160d565b34801561053157600080fd5b506101af600160a060020a0360043516602435604435611810565b34801561055857600080fd5b50604080516020600480358082013583810280860185019096528085526102809536959394602494938501929182918501908490808284375094975061189c9650505050505050565b3480156105ad57600080fd5b506101af600160a060020a03600435166024356118d4565b3480156105d157600080fd5b506101af600160a060020a03600435166024356119a6565b3480156105f557600080fd5b506102ec600435611a45565b34801561060d57600080fd5b50610280600435611a4a565b34801561062557600080fd5b506101af600435611b76565b34801561063d57600080fd5b506102ec600435611bca565b34801561065557600080fd5b50610297611bfc565b600061066982611bca565b151561067457600080fd5b61067d82610b23565b1561069a57506000818152600160205260409020600301546106ae565b506000818152600160205260409020600401545b919050565b600081565b60008060006106c686610a1e565b91506106d286836118d4565b90505b8115610874576106e586836118d4565b90508481116107b757838214156107af57600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561078057600080fd5b505af4158015610794573d6000803e3d6000fd5b505050506040513d60208110156107aa57600080fd5b505191505b819250610878565b600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561084157600080fd5b505af4158015610855573d6000803e3d6000fd5b505050506040513d602081101561086b57600080fd5b505191506106d5565b8192505b50509392505050565b600080546001018155808061089c428663ffffffff611c0b16565b91506108ae828563ffffffff611c0b16565b6040805160a08101825284815260208082018481528284018b8152600060608086018281526080870183815283548452600180885289852098518955955195880195909555925160028701559151600386015591516004909401939093555483518b8152918201879052818401859052925193945033937f404f1f1c229d9eb2a949e7584da6ffde9d059ef2169f487ca815434cce0640d0929181900390910190a35050600054949350505050565b60026020526000908152604090205481565b600087861461097d57600080fd5b87841461098957600080fd5b87821461099557600080fd5b5060005b87811015610a04576109fc8989838181106109b057fe5b9050602002013588888481811015156109c557fe5b602002919091013590508787858181106109db57fe5b9050602002013586868681811015156109f057fe5b90506020020135610c99565b600101610999565b505050505050505050565b600654600160a060020a031681565b600160a060020a038116600090815260036020908152604080832081517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________926330fe0a0a9260448082019391829003018186803b158015610aa657600080fd5b505af4158015610aba573d6000803e3d6000fd5b505050506040513d6020811015610ad057600080fd5b505192915050565b6000610ae38261130a565b1515610aee57600080fd5b60008281526001602081905260409091200154610b0a90611a45565b158015610b1d5750610b1b8261159a565b155b92915050565b6000610b2d611dbd565b610b3683611bca565b1515610b4157600080fd5b5050600090815260016020818152604092839020835160a0810185528154815292810154918301919091526002810154928201839052600381015460608301819052600490910154608090920182905290810190910260649091021190565b6001602081905260009182526040909120805491810154600282015460038301546004909301549192909185565b600080600080610bdd86611bca565b1515610be857600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff161515610c1c57600080fd5b610c2586610b23565b610c30576001610c33565b60005b60ff1692508285604051808381526020018281526020019250505060405180910390209150610c6287876119a6565b9050818114610c7057600080fd5b610c7a87876118d4565b979650505050505050565b6000610b1d82610c9484610a1e565b6118d4565b6000806000610ca78761159a565b1515610cb257600080fd5b33600090815260026020526040902054851115610cf55733600090815260026020526040902054610cea90869063ffffffff611c1816565b9250610cf583611500565b33600090815260026020526040902054851115610d1157600080fd5b861515610d1d57600080fd5b851515610d2957600080fd5b831580610ddf57503360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b158015610db257600080fd5b505af4158015610dc6573d6000803e3d6000fd5b505050506040513d6020811015610ddc57600080fd5b50515b1515610dea57600080fd5b3360009081526003602090815260409182902082517f07d29ac9000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610e6b57600080fd5b505af4158015610e7f573d6000803e3d6000fd5b505050506040513d6020811015610e9557600080fd5b5051915086821415610f51573360009081526003602090815260409182902082517f07d29ac90000000000000000000000000000000000000000000000000000000081526004810191909152602481018a9052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610f2257600080fd5b505af4158015610f36573d6000803e3d6000fd5b505050506040513d6020811015610f4c57600080fd5b505191505b610f5d848333886112cc565b1515610f6857600080fd5b3360009081526003602052604080822081517f9735c51b000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604481018a905260648101859052905173__DLL___________________________________92639735c51b9260848082019391829003018186803b158015610ff357600080fd5b505af4158015611007573d6000803e3d6000fd5b5050505061101533886114c9565b604080517f977aa031000000000000000000000000000000000000000000000000000000008152600481810152602481018390526064810188905260806044820152600960848201527f6e756d546f6b656e73000000000000000000000000000000000000000000000060a4820152905191925073__AttributeStore________________________9163977aa0319160c480820192600092909190829003018186803b1580156110c557600080fd5b505af41580156110d9573d6000803e3d6000fd5b5050604080517f977aa03100000000000000000000000000000000000000000000000000000000815260048181015260248101859052606481018a905260806044820152600a60848201527f636f6d6d6974486173680000000000000000000000000000000000000000000060a4820152905173__AttributeStore________________________935063977aa031925060c4808301926000929190829003018186803b15801561118957600080fd5b505af415801561119d573d6000803e3d6000fd5b5050506000888152600160208181526040808420338086526005909101835293819020805460ff1916909317909255815189815291519293508a927fea7979e4280d7e6bffc1c7d83a1ac99f16d02ecc14465ce41016226783b663d79281900390910190a350505050505050565b60006112168261130a565b151561122157600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260059093019052205460ff1690565b600085841461125e57600080fd5b85821461126a57600080fd5b5060005b858110156112c3576112bb87878381811061128557fe5b90506020020135868684818110151561129a57fe5b9050602002013585858581811015156112af57fe5b9050602002013561160d565b60010161126e565b50505050505050565b60008060006112db85886118d4565b84101591506112ea85876118d4565b841115806112f6575085155b9050818015610c7a57509695505050505050565b60008115801590610b1d575050600054101590565b60005481565b6000818152600160208190526040909120015461134190611a45565b151561134c57600080fd5b3360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b1580156113cd57600080fd5b505af41580156113e1573d6000803e3d6000fd5b505050506040513d60208110156113f757600080fd5b5051151561140457600080fd5b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561148157600080fd5b505af4158015611495573d6000803e3d6000fd5b50506040513392508391507f402507661c8c8cb90e0a796450b8bdd28b6c516f05279c0cd29e84c344e1699a90600090a350565b604080516c01000000000000000000000000600160a060020a03851602815260148101839052905190819003603401902092915050565b61150981611c2a565b600654336000818152600260205260408082205481517f725248730000000000000000000000000000000000000000000000000000000081526004810194909452602484015251600160a060020a0390931692637252487392604480820193929182900301818387803b15801561157f57600080fd5b505af1158015611593573d6000803e3d6000fd5b5050505050565b60006115a58261130a565b15156115b057600080fd5b600082815260016020526040902054610b1b90611a45565b60006115d38261130a565b15156115de57600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260069093019052205460ff1690565b600061161884610ad8565b151561162357600080fd5b600084815260016020908152604080832033845260050190915290205460ff16151561164e57600080fd5b600084815260016020908152604080832033845260060190915290205460ff161561167857600080fd5b61168233856119a6565b60408051858152602081018590528151908190039091019020146116a557600080fd5b6116af33856118d4565b905082600114156116d65760008481526001602052604090206003018054820190556116ee565b60008481526001602052604090206004018054820190555b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561176b57600080fd5b505af415801561177f573d6000803e3d6000fd5b505050600085815260016020818152604080842033808652600682018452828620805460ff191686179055948a9052928252600383015460049093015481518781529283019390935281810192909252606081018690529051919250859187917f9b19aaec524fad29c0ced9b9973a15e3045d7c3be156d71394ab40f0d5f119ff919081900360800190a450505050565b60008060008061181f86611bca565b151561182a57600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff16151561185e57600080fd5b61186786610b23565b611872576000610c33565b6040805160018082526020820188905282519182900390920190209093509150610c6287876119a6565b60005b81518110156118d0576118c882828151811015156118b957fe5b90602001906020020151611325565b60010161189f565b5050565b600073__AttributeStore________________________6350389f5c60046118fc86866114c9565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600960648301527f6e756d546f6b656e73000000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561197357600080fd5b505af4158015611987573d6000803e3d6000fd5b505050506040513d602081101561199d57600080fd5b50519392505050565b600073__AttributeStore________________________6350389f5c60046119ce86866114c9565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600a60648301527f636f6d6d6974486173680000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561197357600080fd5b421190565b6000611a74611a5833610c85565b336000908152600260205260409020549063ffffffff611c1816565b905081811015611a8357600080fd5b3360008181526002602090815260408083208054879003905560055481517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810195909552602485018790529051600160a060020a039091169363a9059cbb9360448083019493928390030190829087803b158015611b0557600080fd5b505af1158015611b19573d6000803e3d6000fd5b505050506040513d6020811015611b2f57600080fd5b50511515611b3c57600080fd5b60408051838152905133917ffaeb7dbb9992397d26ea1944efd40c80b40f702faf69b46c67ad10aba68ccb79919081900360200190a25050565b6000611b8182611bca565b1515611b8c57600080fd5b611b9582610b23565b15611bb257506000818152600160205260409020600401546106ae565b506000818152600160205260409020600301546106ae565b6000611bd58261130a565b1515611be057600080fd5b60008281526001602081905260409091200154610b1d90611a45565b600554600160a060020a031681565b81810182811015610b1d57fe5b600082821115611c2457fe5b50900390565b600554604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518392600160a060020a0316916370a082319160248083019260209291908290030181600087803b158015611c8f57600080fd5b505af1158015611ca3573d6000803e3d6000fd5b505050506040513d6020811015611cb957600080fd5b50511015611cc657600080fd5b33600081815260026020908152604080832080548601905560055481517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690529051600160a060020a03909116936323b872dd9360648083019493928390030190829087803b158015611d4d57600080fd5b505af1158015611d61573d6000803e3d6000fd5b505050506040513d6020811015611d7757600080fd5b50511515611d8457600080fd5b60408051828152905133917ff7aaf024511d9982df8cd0d437c71c30106e6848cd1ba3d288d7a9c0e276aeda919081900360200190a250565b60a060405190810160405280600081526020016000815260200160008152602001600081526020016000815250905600a165627a7a72305820dfb0bd5ea70ad6f1df929d57bad9a8a3a61facd419e162e3168c26c446d299260029", "abi": [ { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "getTotalNumberOfTokensForWinningOption", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "INITIAL_POLL_NONCE", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_numTokens", "type": "uint256" }, { "name": "_pollID", "type": "uint256" } ], "name": "getInsertPointForNumTokens", "outputs": [ { "name": "prevNode", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_voteQuorum", "type": "uint256" }, { "name": "_commitDuration", "type": "uint256" }, { "name": "_revealDuration", "type": "uint256" } ], "name": "startPoll", "outputs": [ { "name": "pollID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "voteTokenBalance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" }, { "name": "_secretHashes", "type": "bytes32[]" }, { "name": "_numsTokens", "type": "uint256[]" }, { "name": "_prevPollIDs", "type": "uint256[]" } ], "name": "commitVotes", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "telemetry", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" } ], "name": "getLastNode", "outputs": [ { "name": "pollID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "revealPeriodActive", "outputs": [ { "name": "active", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "isPassed", "outputs": [ { "name": "passed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "pollMap", "outputs": [ { "name": "commitEndDate", "type": "uint256" }, { "name": "revealEndDate", "type": "uint256" }, { "name": "voteQuorum", "type": "uint256" }, { "name": "votesFor", "type": "uint256" }, { "name": "votesAgainst", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" } ], "name": "getLockedTokens", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" }, { "name": "_secretHash", "type": "bytes32" }, { "name": "_numTokens", "type": "uint256" }, { "name": "_prevPollID", "type": "uint256" } ], "name": "commitVote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "didCommit", "outputs": [ { "name": "committed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" }, { "name": "_voteOptions", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "revealVotes", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_prevID", "type": "uint256" }, { "name": "_nextID", "type": "uint256" }, { "name": "_voter", "type": "address" }, { "name": "_numTokens", "type": "uint256" } ], "name": "validPosition", "outputs": [ { "name": "valid", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "pollExists", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "pollNonce", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "rescueTokens", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_user", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "attrUUID", "outputs": [ { "name": "UUID", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "commitPeriodActive", "outputs": [ { "name": "active", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "didReveal", "outputs": [ { "name": "revealed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" }, { "name": "_voteOption", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "revealVote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "getNumPassingTokens", "outputs": [ { "name": "correctVotes", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" } ], "name": "rescueTokensInMultiplePolls", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "getNumTokens", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "getCommitHash", "outputs": [ { "name": "commitHash", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_terminationDate", "type": "uint256" } ], "name": "isExpired", "outputs": [ { "name": "expired", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_numTokens", "type": "uint256" } ], "name": "withdrawVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "pollEnded", "outputs": [ { "name": "ended", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "tokenAddr", "type": "address" }, { "name": "telemetryAddr", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VoteCommitted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": false, "name": "votesFor", "type": "uint256" }, { "indexed": false, "name": "votesAgainst", "type": "uint256" }, { "indexed": true, "name": "choice", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" }, { "indexed": false, "name": "salt", "type": "uint256" } ], "name": "_VoteRevealed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "voteQuorum", "type": "uint256" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": true, "name": "creator", "type": "address" } ], "name": "_PollCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VotingRightsGranted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VotingRightsWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_TokensRescued", "type": "event" }, { "constant": false, "inputs": [ { "name": "_numTokens", "type": "uint256" } ], "name": "requestVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "getNumLosingTokens", "outputs": [ { "name": "correctVotes", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "getTotalNumberOfTokensForLosingOption", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": { "1": { "events": {}, "links": { "DLL": "0x739f1745e415782861373c5ff1a6dc56d2d41451", "AttributeStore": "0x393e69e7ae7addcfd744b71d209b1f04800d89e5" }, "address": "0x55656b8a58df94c1e8b5142f8da973301452ea65", "transactionHash": "0x432e1660900510843f82adfbc0807d2426dc30cb0e8a7acce6c85c3cc72afe74" }, "4": { "events": {}, "links": { "DLL": "0x132f69eb9416cf555cc16e21fb0bbd21f38947c0", "AttributeStore": "0x0584ee9107eebfc100994ad88c380fb8108fbc2d" }, "address": "0x570bf68d286dd4225e2e77384c08dfebc4b01b5c", "transactionHash": "0x44e716278d983db08cc05db50f2572b24d105f1230d0a5fb7d79f32dd74b5c8a" } } } ================================================ FILE: packages/artifacts/v1/CivilParameterizer.json ================================================ { "contractName": "CivilParameterizer", "bytecode": "0x608060405262093a806005553480156200001857600080fd5b506040516200294e3803806200294e83398101604081815282516020808501518386015160038054600160a060020a03808716600160a060020a0319928316179092556004805492851692909116919091179055848601909452600a85527f6d696e4465706f736974000000000000000000000000000000000000000000009185019190915291909301805191929091849184918491620000e09183906000908110620000c157fe5b90602001906020020151620004f8640100000000026401000000009004565b6200012a6040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250826001815181101515620000c157fe5b620001746040805190810160405280600d81526020017f6170706c7953746167654c656e00000000000000000000000000000000000000815250826002815181101515620000c157fe5b620001be6040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250826003815181101515620000c157fe5b620002086040805190810160405280600e81526020017f636f6d6d697453746167654c656e000000000000000000000000000000000000815250826004815181101515620000c157fe5b620002526040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250826005815181101515620000c157fe5b6200029c6040805190810160405280600e81526020017f72657665616c53746167654c656e000000000000000000000000000000000000815250826006815181101515620000c157fe5b620002e66040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250826007815181101515620000c157fe5b620003306040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250826008815181101515620000c157fe5b6200037a6040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250826009815181101515620000c157fe5b620003c46040805190810160405280600a81526020017f766f746551756f72756d0000000000000000000000000000000000000000000081525082600a815181101515620000c157fe5b6200040e6040805190810160405280600b81526020017f70566f746551756f72756d00000000000000000000000000000000000000000081525082600b815181101515620000c157fe5b5050506200045b6040805190810160405280601281526020017f6368616c6c656e676541707065616c4c656e000000000000000000000000000081525082600c815181101515620000c157fe5b620004a56040805190810160405280601881526020017f6368616c6c656e676541707065616c436f6d6d69744c656e000000000000000081525082600d815181101515620000c157fe5b620004ef6040805190810160405280601881526020017f6368616c6c656e676541707065616c52657665616c4c656e000000000000000081525082600e815181101515620000c157fe5b50505062000570565b80600080846040518082805190602001908083835b602083106200052e5780518252601f1990920191602091820191016200050d565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b6123ce80620005806000396000f3006080604052600436106100fa5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100ff57806330490e911461012657806332ed5b1214610140578063353009901461020c57806350411552146102385780635f02116f14610250578063693ec85e146102de57806377609a41146103375780638240ae4b1461034f57806386bb8f37146103675780638f1d377614610382578063a5ba3b1e146103cd578063a7aad3db146103f1578063bade1c5414610418578063c51131fb14610473578063dc6ab5271461048b578063fc0c546a146104a3578063fce1ccca146104d4575b600080fd5b34801561010b57600080fd5b506101146104e9565b60408051918252519081900360200190f35b34801561013257600080fd5b5061013e6004356104ef565b005b34801561014c57600080fd5b506101586004356109ca565b604051808881526020018781526020018681526020018060200185600160a060020a0316600160a060020a03168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156101cb5781810151838201526020016101b3565b50505050905090810190601f1680156101f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561021857600080fd5b50610224600435610a96565b604080519115158252519081900360200190f35b34801561024457600080fd5b50610114600435610aaf565b34801561025c57600080fd5b506040805160206004803580820135838102808601850190965280855261013e95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610b819650505050505050565b3480156102ea57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610114943694929360249392840191908190840183828082843750949750610be49650505050505050565b34801561034357600080fd5b50610224600435610c5a565b34801561035b57600080fd5b50610114600435610e73565b34801561037357600080fd5b5061013e6004356024356113ab565b34801561038e57600080fd5b5061039a6004356115b7565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156103d957600080fd5b50610224600435600160a060020a03602435166115f4565b3480156103fd57600080fd5b50610114600160a060020a0360043516602435604435611624565b34801561042457600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011494369492936024939284019190819084018382808284375094975050933594506116fa9350505050565b34801561047f57600080fd5b50610224600435611bd0565b34801561049757600080fd5b50610114600435611cf3565b3480156104af57600080fd5b506104b8611d05565b60408051600160a060020a039092168252519081900360200190f35b3480156104e057600080fd5b506104b8611d14565b60055481565b60008181526002602081905260409091206004810154918101549091600160a060020a03169061051e84611bd0565b1561077857600383018054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526105c193909290918301828280156105b25780601f10610587576101008083540402835291602001916105b2565b820191906000526020600020905b81548152906001019060200180831161059557829003601f168201915b50505050508460060154611d23565b600683015460408051602081018390528181526003860180546002610100600183161502600019019091160492820183905287937f37f3986c71e1aa2c470cfc4a92af70820610c3065589d35ef1664ea27f3e73a5939192909181906060820190859080156106715780601f1061064657610100808354040283529160200191610671565b820191906000526020600020905b81548152906001019060200180831161065457829003601f168201915b5050935050505060405180910390a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b506004818101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005830181905560069092018290556003546040805160e060020a63a9059cbb028152600160a060020a0387811694820194909452602481018690529051929091169263a9059cbb926044808401936020939083900390910190829087803b15801561073c57600080fd5b505af1158015610750573d6000803e3d6000fd5b505050506040513d602081101561076657600080fd5b5051151561077357600080fd5b6107f4565b61078184610c5a565b1561078f5761077384611d99565b82600501544211156100fa5760405184907f29026cb2acebe6d0a4b6d593ccadf76e3fc6d0a02254e078b0c4a619608089d790600090a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b60646108346040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250610be4565b111561083c57fe5b606461087c6040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250610be4565b111561088457fe5b61096660055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b61095a61090c6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b61095a61094d6040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250610be4565b429063ffffffff6121e116565b9063ffffffff6121e116565b50600084815260026020819052604082208281556001810183905590810182905590610995600383018261223e565b5060048101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005820181905560069091015550505050565b60026020818152600092835260409283902080546001808301548386015460038501805489519481161561010002600019011697909704601f8101879004870284018701909852878352929690959294919291830182828015610a6e5780601f10610a4357610100808354040283529160200191610a6e565b820191906000526020600020905b815481529060010190602001808311610a5157829003601f168201915b50505050600483015460058401546006909401549293600160a060020a039091169290915087565b600081815260026020526040812060050154115b919050565b60048054604080517f053e71a600000000000000000000000000000000000000000000000000000000815292830184905251600092600160a060020a039092169163053e71a691602480830192602092919082900301818787803b158015610b1657600080fd5b505af1158015610b2a573d6000803e3d6000fd5b505050506040513d6020811015610b4057600080fd5b50511515610b635750600081815260016020526040902060029081015402610aaa565b50600090815260016020526040902080546002918201549091020390565b8051825160009114610b9257600080fd5b5060005b8251811015610bdf57610bd78382815181101515610bb057fe5b906020019060200201518383815181101515610bc857fe5b906020019060200201516113ab565b600101610b96565b505050565b6000806000836040518082805190602001908083835b60208310610c195780518252601f199092019160209182019101610bfa565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6000610c64612285565b610c6c6122cc565b600084815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015610d295780601f10610cfe57610100808354040283529160200191610d29565b820191906000526020600020905b815481529060010190602001808311610d0c57829003601f168201915b50505091835250506004820154600160a060020a039081166020808401919091526005840154604080850191909152600690940154606093840152848101805160009081526001808452868220875160a08101895281548152918101549586169482019490945260a060020a90940460ff1615159584019590955260028201549383019390935260030154608082015290519294509250108015610dcf57506040810151155b8015610e6b575060048054602080850151604080517fee6848300000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a039092169263ee68483092602480830193928290030181600087803b158015610e3e57600080fd5b505af1158015610e52573d6000803e3d6000fd5b505050506040513d6020811015610e6857600080fd5b50515b949350505050565b6000610e7d612285565b6000838152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f810186900486028201860190945283815286958695869593949360608601939291830182828015610f3c5780601f10610f1157610100808354040283529160200191610f3c565b820191906000526020600020905b815481529060010190602001808311610f1f57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040808301919091526006909201546060909101528101519095509350610f8287610a96565b8015610f9057506020850151155b1515610f9b57600080fd5b60045460408051808201909152600b81527f70566f746551756f72756d0000000000000000000000000000000000000000006020820152600160a060020a03909116906332ed3d6090610fed90610be4565b61102b6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b6110696040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b505050506040513d60208110156110f357600080fd5b50516040805160e08101909152601060a082019081527f7044697370656e736174696f6e5063740000000000000000000000000000000060c083015291945090819061116e9060649061116290899061115690849061115190610be4565b6121ee565b9063ffffffff61220016565b9063ffffffff61222916565b81523360208083018290526000604080850182905260608086018b905260809586018390528983526001808552828420885181558886015181830180548b87015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a911515919091021790559289015160028083019190915598909701516003978801558e8452968452818320909601899055935484517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018a9052935193909416936323b872dd936064808501949192918390030190829087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b505115156112c157600080fd5b60048054604080517f6148fed500000000000000000000000000000000000000000000000000000000815292830186905251600160a060020a0390911691636148fed59160248083019260a09291908290030181600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050506040513d60a081101561135057600080fd5b50805160209182015160408051878152938401839052838101829052519194509250339189917fe94e3086c4bfe84acba4437b85a80fca3721dfc419d1f7afe4fa4e470e670b489181900360600190a3509095945050505050565b6000828152600160209081526040808320338452600401909152812054819060ff16156113d757600080fd5b600084815260016020819052604090912081015460a060020a900460ff1615151461140157600080fd5b60048054604080517fb43bd0690000000000000000000000000000000000000000000000000000000081523393810193909352602483018790526044830186905251600160a060020a039091169163b43bd0699160648083019260209291908290030181600087803b15801561147657600080fd5b505af115801561148a573d6000803e3d6000fd5b505050506040513d60208110156114a057600080fd5b505191506114af338585611624565b6000858152600160208181526040808420600381018054899003905580548690038155338086526004909101835293819020805460ff191690931790925581518481529151939450919287927f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f59957928290030190a36003546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561157a57600080fd5b505af115801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b505115156115b157600080fd5b50505050565b60016020819052600091825260409091208054918101546002820154600390920154600160a060020a0382169260a060020a90920460ff16919085565b6000828152600160209081526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152600160209081526040808320600381015490546004805484517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038b811693820193909352602481018a9052604481018990529451939592948794929091169263b43bd0699260648084019382900301818787803b1580156116b357600080fd5b505af11580156116c7573d6000803e3d6000fd5b505050506040513d60208110156116dd57600080fd5b50519050828282028115156116ee57fe5b04979650505050505050565b600080600061173d6040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250610be4565b915084846040518083805190602001908083835b602083106117705780518252601f199092019160209182019101611751565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f64697370656e736174696f6e50637400000000000000000000000000000000008552905193849003600f0184208a5191965094508993925082918401908083835b602083106117ff5780518252601f1990920191602091820191016117e0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614806118cc5750604080517f7044697370656e736174696f6e5063740000000000000000000000000000000081529051908190036010018120865190918791819060208401908083835b602083106118995780518252601f19909201916020918201910161187a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b156118df5760648411156118df57600080fd5b6118e881610a96565b156118f257600080fd5b836118fc86610be4565b141561190757600080fd5b604080516101208101909152600e60e082019081527f704170706c7953746167654c656e00000000000000000000000000000000000061010083015281906119529061094d90610be4565b81526020016000815260200183815260200186815260200133600160a060020a031681526020016119c060055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b8152602090810186905260008381526002808352604091829020845181558484015160018201559184015190820155606083015180519192611a0a92600385019290910190612307565b5060808201516004828101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0393841617905560a0840151600584015560c090930151600690920191909155600354604080517f23b872dd000000000000000000000000000000000000000000000000000000008152339481019490945230602485015260448401869052519116916323b872dd9160648083019260209291908290030181600087803b158015611abf57600080fd5b505af1158015611ad3573d6000803e3d6000fd5b505050506040513d6020811015611ae957600080fd5b50511515611af657600080fd5b6000818152600260209081526040808320548151808401899052918201859052606082018690526080820181905260a0808352895190830152885133947fb25bdef16105f099e5c185f9c7fd969571e8e0caa3f7bd75409512fe0a41a60b948b948b9489948b949193839260c0840192918a0191908190849084905b83811015611b8a578181015183820152602001611b72565b50505050905090810190601f168015611bb75780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a2949350505050565b6000611bda612285565b600083815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015611c975780601f10611c6c57610100808354040283529160200191611c97565b820191906000526020600020905b815481529060010190602001808311611c7a57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040820152600690910154606090910152805190915042118015611cde57508060a0015142105b8015611cec57506020810151155b9392505050565b60006020819052908152604090205481565b600354600160a060020a031681565b600454600160a060020a031681565b80600080846040518082805190602001908083835b60208310611d575780518252601f199092019160209182019101611d38565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b611da1612285565b6000828152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f81018690048602820186019094528381528695919492936060860193919291830182828015611e5e5780601f10611e3357610100808354040283529160200191611e5e565b820191906000526020600020905b815481529060010190602001808311611e4157829003601f168201915b505050505081526020016004820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160058201548152602001600682015481525050925060016000846020015181526020019081526020016000209150611ed28360200151610aaf565b60048054602080870151604080517f053e71a60000000000000000000000000000000000000000000000000000000081529485019190915251939450600160a060020a039091169263053e71a69260248082019392918290030181600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b505050506040513d6020811015611f6857600080fd5b5051600383015560018201805474ff0000000000000000000000000000000000000000191660a060020a17905560048054602085810151604080517f494031830000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a0390921692634940318392602480830193928290030181600087803b158015611ffd57600080fd5b505af1158015612011573d6000803e3d6000fd5b505050506040513d602081101561202757600080fd5b50511561212e57428360a00151111561204c5761204c83606001518460c00151611d23565b6020808401518354600385015460408051928352938201528251919287927fc4497224aa78dd50c9b3e344aab02596201ca1e6dca4057a91a6c02f83f4f6c19281900390910190a360035460808401516040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156120f257600080fd5b505af1158015612106573d6000803e3d6000fd5b505050506040513d602081101561211c57600080fd5b5051151561212957600080fd5b6115b1565b6020808401518354600385015460408051928352938201528251919287927f362a12431f779a2baff4f77f75ba7960ae993a5c41b425df11f7fd0af2b9cbe69281900390910190a360035460208085015160009081526001808352604080832090910154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb9360448084019491938390030190829087803b15801561157a57600080fd5b8181018281101561161e57fe5b6000828211156121fa57fe5b50900390565b60008215156122115750600061161e565b5081810281838281151561222157fe5b041461161e57fe5b6000818381151561223657fe5b049392505050565b50805460018160011615610100020316600290046000825580601f106122645750612282565b601f0160209004906000526020600020908101906122829190612385565b50565b60e060405190810160405280600081526020016000815260200160008152602001606081526020016000600160a060020a0316815260200160008152602001600081525090565b60a060405190810160405280600081526020016000600160a060020a0316815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061234857805160ff1916838001178555612375565b82800160010185558215612375579182015b8281111561237557825182559160200191906001019061235a565b50612381929150612385565b5090565b61239f91905b80821115612381576000815560010161238b565b905600a165627a7a72305820ed840535900f894fb89ac1b708fbec598795cafcab5034977f4db1cc2ec92cea0029", "deployedBytecode": "0x6080604052600436106100fa5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100ff57806330490e911461012657806332ed5b1214610140578063353009901461020c57806350411552146102385780635f02116f14610250578063693ec85e146102de57806377609a41146103375780638240ae4b1461034f57806386bb8f37146103675780638f1d377614610382578063a5ba3b1e146103cd578063a7aad3db146103f1578063bade1c5414610418578063c51131fb14610473578063dc6ab5271461048b578063fc0c546a146104a3578063fce1ccca146104d4575b600080fd5b34801561010b57600080fd5b506101146104e9565b60408051918252519081900360200190f35b34801561013257600080fd5b5061013e6004356104ef565b005b34801561014c57600080fd5b506101586004356109ca565b604051808881526020018781526020018681526020018060200185600160a060020a0316600160a060020a03168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156101cb5781810151838201526020016101b3565b50505050905090810190601f1680156101f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561021857600080fd5b50610224600435610a96565b604080519115158252519081900360200190f35b34801561024457600080fd5b50610114600435610aaf565b34801561025c57600080fd5b506040805160206004803580820135838102808601850190965280855261013e95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610b819650505050505050565b3480156102ea57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610114943694929360249392840191908190840183828082843750949750610be49650505050505050565b34801561034357600080fd5b50610224600435610c5a565b34801561035b57600080fd5b50610114600435610e73565b34801561037357600080fd5b5061013e6004356024356113ab565b34801561038e57600080fd5b5061039a6004356115b7565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156103d957600080fd5b50610224600435600160a060020a03602435166115f4565b3480156103fd57600080fd5b50610114600160a060020a0360043516602435604435611624565b34801561042457600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011494369492936024939284019190819084018382808284375094975050933594506116fa9350505050565b34801561047f57600080fd5b50610224600435611bd0565b34801561049757600080fd5b50610114600435611cf3565b3480156104af57600080fd5b506104b8611d05565b60408051600160a060020a039092168252519081900360200190f35b3480156104e057600080fd5b506104b8611d14565b60055481565b60008181526002602081905260409091206004810154918101549091600160a060020a03169061051e84611bd0565b1561077857600383018054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526105c193909290918301828280156105b25780601f10610587576101008083540402835291602001916105b2565b820191906000526020600020905b81548152906001019060200180831161059557829003601f168201915b50505050508460060154611d23565b600683015460408051602081018390528181526003860180546002610100600183161502600019019091160492820183905287937f37f3986c71e1aa2c470cfc4a92af70820610c3065589d35ef1664ea27f3e73a5939192909181906060820190859080156106715780601f1061064657610100808354040283529160200191610671565b820191906000526020600020905b81548152906001019060200180831161065457829003601f168201915b5050935050505060405180910390a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b506004818101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005830181905560069092018290556003546040805160e060020a63a9059cbb028152600160a060020a0387811694820194909452602481018690529051929091169263a9059cbb926044808401936020939083900390910190829087803b15801561073c57600080fd5b505af1158015610750573d6000803e3d6000fd5b505050506040513d602081101561076657600080fd5b5051151561077357600080fd5b6107f4565b61078184610c5a565b1561078f5761077384611d99565b82600501544211156100fa5760405184907f29026cb2acebe6d0a4b6d593ccadf76e3fc6d0a02254e078b0c4a619608089d790600090a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b60646108346040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250610be4565b111561083c57fe5b606461087c6040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250610be4565b111561088457fe5b61096660055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b61095a61090c6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b61095a61094d6040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250610be4565b429063ffffffff6121e116565b9063ffffffff6121e116565b50600084815260026020819052604082208281556001810183905590810182905590610995600383018261223e565b5060048101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005820181905560069091015550505050565b60026020818152600092835260409283902080546001808301548386015460038501805489519481161561010002600019011697909704601f8101879004870284018701909852878352929690959294919291830182828015610a6e5780601f10610a4357610100808354040283529160200191610a6e565b820191906000526020600020905b815481529060010190602001808311610a5157829003601f168201915b50505050600483015460058401546006909401549293600160a060020a039091169290915087565b600081815260026020526040812060050154115b919050565b60048054604080517f053e71a600000000000000000000000000000000000000000000000000000000815292830184905251600092600160a060020a039092169163053e71a691602480830192602092919082900301818787803b158015610b1657600080fd5b505af1158015610b2a573d6000803e3d6000fd5b505050506040513d6020811015610b4057600080fd5b50511515610b635750600081815260016020526040902060029081015402610aaa565b50600090815260016020526040902080546002918201549091020390565b8051825160009114610b9257600080fd5b5060005b8251811015610bdf57610bd78382815181101515610bb057fe5b906020019060200201518383815181101515610bc857fe5b906020019060200201516113ab565b600101610b96565b505050565b6000806000836040518082805190602001908083835b60208310610c195780518252601f199092019160209182019101610bfa565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6000610c64612285565b610c6c6122cc565b600084815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015610d295780601f10610cfe57610100808354040283529160200191610d29565b820191906000526020600020905b815481529060010190602001808311610d0c57829003601f168201915b50505091835250506004820154600160a060020a039081166020808401919091526005840154604080850191909152600690940154606093840152848101805160009081526001808452868220875160a08101895281548152918101549586169482019490945260a060020a90940460ff1615159584019590955260028201549383019390935260030154608082015290519294509250108015610dcf57506040810151155b8015610e6b575060048054602080850151604080517fee6848300000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a039092169263ee68483092602480830193928290030181600087803b158015610e3e57600080fd5b505af1158015610e52573d6000803e3d6000fd5b505050506040513d6020811015610e6857600080fd5b50515b949350505050565b6000610e7d612285565b6000838152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f810186900486028201860190945283815286958695869593949360608601939291830182828015610f3c5780601f10610f1157610100808354040283529160200191610f3c565b820191906000526020600020905b815481529060010190602001808311610f1f57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040808301919091526006909201546060909101528101519095509350610f8287610a96565b8015610f9057506020850151155b1515610f9b57600080fd5b60045460408051808201909152600b81527f70566f746551756f72756d0000000000000000000000000000000000000000006020820152600160a060020a03909116906332ed3d6090610fed90610be4565b61102b6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b6110696040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b505050506040513d60208110156110f357600080fd5b50516040805160e08101909152601060a082019081527f7044697370656e736174696f6e5063740000000000000000000000000000000060c083015291945090819061116e9060649061116290899061115690849061115190610be4565b6121ee565b9063ffffffff61220016565b9063ffffffff61222916565b81523360208083018290526000604080850182905260608086018b905260809586018390528983526001808552828420885181558886015181830180548b87015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a911515919091021790559289015160028083019190915598909701516003978801558e8452968452818320909601899055935484517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018a9052935193909416936323b872dd936064808501949192918390030190829087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b505115156112c157600080fd5b60048054604080517f6148fed500000000000000000000000000000000000000000000000000000000815292830186905251600160a060020a0390911691636148fed59160248083019260a09291908290030181600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050506040513d60a081101561135057600080fd5b50805160209182015160408051878152938401839052838101829052519194509250339189917fe94e3086c4bfe84acba4437b85a80fca3721dfc419d1f7afe4fa4e470e670b489181900360600190a3509095945050505050565b6000828152600160209081526040808320338452600401909152812054819060ff16156113d757600080fd5b600084815260016020819052604090912081015460a060020a900460ff1615151461140157600080fd5b60048054604080517fb43bd0690000000000000000000000000000000000000000000000000000000081523393810193909352602483018790526044830186905251600160a060020a039091169163b43bd0699160648083019260209291908290030181600087803b15801561147657600080fd5b505af115801561148a573d6000803e3d6000fd5b505050506040513d60208110156114a057600080fd5b505191506114af338585611624565b6000858152600160208181526040808420600381018054899003905580548690038155338086526004909101835293819020805460ff191690931790925581518481529151939450919287927f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f59957928290030190a36003546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561157a57600080fd5b505af115801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b505115156115b157600080fd5b50505050565b60016020819052600091825260409091208054918101546002820154600390920154600160a060020a0382169260a060020a90920460ff16919085565b6000828152600160209081526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152600160209081526040808320600381015490546004805484517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038b811693820193909352602481018a9052604481018990529451939592948794929091169263b43bd0699260648084019382900301818787803b1580156116b357600080fd5b505af11580156116c7573d6000803e3d6000fd5b505050506040513d60208110156116dd57600080fd5b50519050828282028115156116ee57fe5b04979650505050505050565b600080600061173d6040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250610be4565b915084846040518083805190602001908083835b602083106117705780518252601f199092019160209182019101611751565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f64697370656e736174696f6e50637400000000000000000000000000000000008552905193849003600f0184208a5191965094508993925082918401908083835b602083106117ff5780518252601f1990920191602091820191016117e0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614806118cc5750604080517f7044697370656e736174696f6e5063740000000000000000000000000000000081529051908190036010018120865190918791819060208401908083835b602083106118995780518252601f19909201916020918201910161187a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b156118df5760648411156118df57600080fd5b6118e881610a96565b156118f257600080fd5b836118fc86610be4565b141561190757600080fd5b604080516101208101909152600e60e082019081527f704170706c7953746167654c656e00000000000000000000000000000000000061010083015281906119529061094d90610be4565b81526020016000815260200183815260200186815260200133600160a060020a031681526020016119c060055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b8152602090810186905260008381526002808352604091829020845181558484015160018201559184015190820155606083015180519192611a0a92600385019290910190612307565b5060808201516004828101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0393841617905560a0840151600584015560c090930151600690920191909155600354604080517f23b872dd000000000000000000000000000000000000000000000000000000008152339481019490945230602485015260448401869052519116916323b872dd9160648083019260209291908290030181600087803b158015611abf57600080fd5b505af1158015611ad3573d6000803e3d6000fd5b505050506040513d6020811015611ae957600080fd5b50511515611af657600080fd5b6000818152600260209081526040808320548151808401899052918201859052606082018690526080820181905260a0808352895190830152885133947fb25bdef16105f099e5c185f9c7fd969571e8e0caa3f7bd75409512fe0a41a60b948b948b9489948b949193839260c0840192918a0191908190849084905b83811015611b8a578181015183820152602001611b72565b50505050905090810190601f168015611bb75780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a2949350505050565b6000611bda612285565b600083815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015611c975780601f10611c6c57610100808354040283529160200191611c97565b820191906000526020600020905b815481529060010190602001808311611c7a57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040820152600690910154606090910152805190915042118015611cde57508060a0015142105b8015611cec57506020810151155b9392505050565b60006020819052908152604090205481565b600354600160a060020a031681565b600454600160a060020a031681565b80600080846040518082805190602001908083835b60208310611d575780518252601f199092019160209182019101611d38565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b611da1612285565b6000828152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f81018690048602820186019094528381528695919492936060860193919291830182828015611e5e5780601f10611e3357610100808354040283529160200191611e5e565b820191906000526020600020905b815481529060010190602001808311611e4157829003601f168201915b505050505081526020016004820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160058201548152602001600682015481525050925060016000846020015181526020019081526020016000209150611ed28360200151610aaf565b60048054602080870151604080517f053e71a60000000000000000000000000000000000000000000000000000000081529485019190915251939450600160a060020a039091169263053e71a69260248082019392918290030181600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b505050506040513d6020811015611f6857600080fd5b5051600383015560018201805474ff0000000000000000000000000000000000000000191660a060020a17905560048054602085810151604080517f494031830000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a0390921692634940318392602480830193928290030181600087803b158015611ffd57600080fd5b505af1158015612011573d6000803e3d6000fd5b505050506040513d602081101561202757600080fd5b50511561212e57428360a00151111561204c5761204c83606001518460c00151611d23565b6020808401518354600385015460408051928352938201528251919287927fc4497224aa78dd50c9b3e344aab02596201ca1e6dca4057a91a6c02f83f4f6c19281900390910190a360035460808401516040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156120f257600080fd5b505af1158015612106573d6000803e3d6000fd5b505050506040513d602081101561211c57600080fd5b5051151561212957600080fd5b6115b1565b6020808401518354600385015460408051928352938201528251919287927f362a12431f779a2baff4f77f75ba7960ae993a5c41b425df11f7fd0af2b9cbe69281900390910190a360035460208085015160009081526001808352604080832090910154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb9360448084019491938390030190829087803b15801561157a57600080fd5b8181018281101561161e57fe5b6000828211156121fa57fe5b50900390565b60008215156122115750600061161e565b5081810281838281151561222157fe5b041461161e57fe5b6000818381151561223657fe5b049392505050565b50805460018160011615610100020316600290046000825580601f106122645750612282565b601f0160209004906000526020600020908101906122829190612385565b50565b60e060405190810160405280600081526020016000815260200160008152602001606081526020016000600160a060020a0316815260200160008152602001600081525090565b60a060405190810160405280600081526020016000600160a060020a0316815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061234857805160ff1916838001178555612375565b82800160010185558215612375579182015b8281111561237557825182559160200191906001019061235a565b50612381929150612385565b5090565b61239f91905b80821115612381576000815560010161238b565b905600a165627a7a72305820ed840535900f894fb89ac1b708fbec598795cafcab5034977f4db1cc2ec92cea0029", "abi": [ { "constant": true, "inputs": [], "name": "PROCESSBY", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "processProposal", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "proposals", "outputs": [ { "name": "appExpiry", "type": "uint256" }, { "name": "challengeID", "type": "uint256" }, { "name": "deposit", "type": "uint256" }, { "name": "name", "type": "string" }, { "name": "owner", "type": "address" }, { "name": "processBy", "type": "uint256" }, { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "propExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" } ], "name": "challengeWinnerReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_name", "type": "string" } ], "name": "get", "outputs": [ { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "challengeReparameterization", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "winningTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_name", "type": "string" }, { "name": "_value", "type": "uint256" } ], "name": "proposeReparameterization", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "canBeSet", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "params", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "tokenAddr", "type": "address" }, { "name": "plcrAddr", "type": "address" }, { "name": "parameters", "type": "uint256[]" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" }, { "indexed": false, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": true, "name": "proposer", "type": "address" } ], "name": "_ReparameterizationProposal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_NewChallenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "_ProposalAccepted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" } ], "name": "_ProposalExpired", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x0b8170f7cec8564492ffea951be88b915a4e26d2", "transactionHash": "0x7414207569987e069e276668ade15c063449acb7e9414772eda5122c68ab06e4" }, "4": { "events": {}, "links": {}, "address": "0x4f4b97a4faebf2bd835a10c479e61faccef8755d", "transactionHash": "0x3fa875cd4e6a022cf8a5c465ed2158050bf7dddb347c0ed93e7eaa9556a29934" } } } ================================================ FILE: packages/artifacts/v1/CivilTCR.json ================================================ { "contractName": "CivilTCR", "bytecode": "0x60806040523480156200001157600080fd5b506040516080806200543d833981016040818152825160208085015183860151606090960151848601909452600885527f436976696c54435200000000000000000000000000000000000000000000000091850191909152909390929091908490849084908383838383838383600160a060020a0384161515620000f657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f746f6b656e2061646472657373206973203000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156200016e57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f766f74696e6720616464726573732069732030000000000000000000000000604482015290519081900360640190fd5b600160a060020a0382161515620001e657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f706172616d65746572697a6572206164647265737320697320300000000000604482015290519081900360640190fd5b60028054600160a060020a03808716600160a060020a03199283161790925560038054868416908316179055600480549285169290911691909117905580516200023890600590602084019062000418565b50505050600160a060020a038a1615159850620002bf97505050505050505057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f676f7674206164647265737320776173207a65726f0000000000000000000000604482015290519081900360640190fd5b80600160a060020a0316635793b9cf6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156200031757600080fd5b505af11580156200032c573d6000803e3d6000fd5b505050506040513d60208110156200034357600080fd5b5051600160a060020a03161515620003e257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f676f76742e676574476f7665726e6d656e74436f6e74726f6c6c65722061646460448201527f7265737320776173203000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60068054600160a060020a03948516600160a060020a031991821617909155600780549290941691161790915550620004bd9050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200045b57805160ff19168380011785556200048b565b828001600101855582156200048b579182015b828111156200048b5782518255916020019190600101906200046e565b50620004999291506200049d565b5090565b620004ba91905b80821115620004995760008155600101620004a4565b90565b614f7080620004cd6000396000f3006080604052600436106101875763ffffffff60e060020a60003504166301162b93811461018c57806306fdde03146101af5780630aac454314610239578063120c40c61461026e5780631e39d8d7146102e757806325ecef04146103185780632672f526146103395780632ea9b6961461034e5780633af32abf1461036f57806347e7ef241461039057806355246b9c146103b45780635b5d4e731461041d5780635f02116f1461043e57806361a9a8ca146104cc57806364c37318146104ed57806365d96c82146105055780636eefcab91461055957806386bb8f371461057a5780638f1d377614610595578063a5ba3b1e146105e0578063a7aad3db14610604578063acff86871461062b578063b42652e914610687578063bc4b010f146106a8578063c8187cf11461070f578063c931674b14610727578063dd4e7cfd14610754578063e1e3f91514610775578063f3fef3a31461078a578063f4c8cfc5146107ae578063f96c8720146107db578063fc0c546a14610830578063fce1ccca14610845575b600080fd5b34801561019857600080fd5b506101ad600160a060020a036004351661085a565b005b3480156101bb57600080fd5b506101c46108be565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101fe5781810151838201526020016101e6565b50505050905090810190601f16801561022b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561024557600080fd5b5061025a600160a060020a036004351661094c565b604080519115158252519081900360200190f35b34801561027a57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526102d5958335600160a060020a0316953695604494919390910191908190840183828082843750949750610aaf9650505050505050565b60408051918252519081900360200190f35b3480156102f357600080fd5b506102fc6111ce565b60408051600160a060020a039092168252519081900360200190f35b34801561032457600080fd5b5061025a600160a060020a03600435166111dd565b34801561034557600080fd5b506102fc6112d6565b34801561035a57600080fd5b5061025a600160a060020a03600435166112e5565b34801561037b57600080fd5b5061025a600160a060020a03600435166113c0565b34801561039c57600080fd5b506101ad600160a060020a03600435166024356113e2565b3480156103c057600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526101ad948235600160a060020a03169460248035953695946064949201919081908401838280828437509497506115889650505050505050565b34801561042957600080fd5b506101ad600160a060020a0360043516611598565b34801561044a57600080fd5b50604080516020600480358082013583810280860185019096528085526101ad95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061175d9650505050505050565b3480156104d857600080fd5b5061025a600160a060020a036004351661182c565b3480156104f957600080fd5b506102d5600435611848565b34801561051157600080fd5b50610526600160a060020a036004351661185a565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b34801561056557600080fd5b5061025a600160a060020a0360043516611895565b34801561058657600080fd5b506101ad6004356024356118e0565b3480156105a157600080fd5b506105ad600435611b59565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156105ec57600080fd5b5061025a600435600160a060020a0360243516611b95565b34801561061057600080fd5b506102d5600160a060020a0360043516602435604435611bc3565b34801561063757600080fd5b50610643600435611c06565b60408051600160a060020a0390981688526020880196909652868601949094529115156060860152608085015260a0840152151560c0830152519081900360e00190f35b34801561069357600080fd5b506101ad600160a060020a0360043516611c53565b3480156106b457600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526102d5958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e429650505050505050565b34801561071b57600080fd5b506102d5600435612098565b34801561073357600080fd5b506101ad60048035600160a060020a031690602480359081019101356123bd565b34801561076057600080fd5b5061025a600160a060020a03600435166126b5565b34801561078157600080fd5b506102fc612757565b34801561079657600080fd5b506101ad600160a060020a0360043516602435612766565b3480156107ba57600080fd5b506101ad60048035600160a060020a03169060248035908101910135612b0c565b3480156107e757600080fd5b50604080516020600480358082013583810280860185019096528085526101ad95369593946024949385019291829185019084908082843750949750612ff79650505050505050565b34801561083c57600080fd5b506102fc61302f565b34801561085157600080fd5b506102fc61303e565b610863816126b5565b15610876576108718161304d565b6108bb565b61087f816112e5565b1561088d5761087181613073565b610896816111dd565b156108a457610871816133d2565b6108ad8161094c565b15610187576108718161356e565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109445780601f1061091957610100808354040283529160200191610944565b820191906000526020600020905b81548152906001019060200180831161092757829003601f168201915b505050505081565b600160a060020a0381166000908152600160209081526040808320600301548084526009909252822061097e84611895565b15156109f9576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101541515610a0d5760009250610aa8565b6003546005820154604080517fee684830000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015610a7957600080fd5b505af1158015610a8d573d6000803e3d6000fd5b505050506040513d6020811015610aa357600080fd5b505192505b5050919050565b600160a060020a0382166000908152600160209081526040808320600380820154855260099093529083209182015490919083908190819060ff161515610b40576040805160e560020a62461bcd02815260206004820152601260248201527f41707065616c206e6f74206772616e7465640000000000000000000000000000604482015290519081900360640190fd5b600584015415610b9a576040805160e560020a62461bcd02815260206004820152601960248201527f41707065616c20616c7265616479206368616c6c656e67656400000000000000604482015290519081900360640190fd5b60048401544210610c1b576040805160e560020a62461bcd02815260206004820152602260248201527f41707065616c206e6f206c6f6e676572206f70656e20746f206368616c6c656e60448201527f6765000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003546007546040805160e160020a63349f642f028152602060048201819052601460248301527f61707065616c566f746550657263656e7461676500000000000000000000000060448301529151600160a060020a03948516946332ed3d6094169263693ec85e92606480820193918290030181600087803b158015610ca157600080fd5b505af1158015610cb5573d6000803e3d6000fd5b505050506040513d6020811015610ccb57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052601860248201527f6368616c6c656e676541707065616c436f6d6d69744c656e000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610d4757600080fd5b505af1158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052601860248201527f6368616c6c656e676541707065616c52657665616c4c656e000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d6020811015610e1757600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b158015610e6357600080fd5b505af1158015610e77573d6000803e3d6000fd5b505050506040513d6020811015610e8d57600080fd5b505160018501546007546040805160e160020a63349f642f028152602060048201819052602260248301527f61707065616c4368616c6c656e6765566f746544697370656e736174696f6e5060448301527f63740000000000000000000000000000000000000000000000000000000000006064838101919091529251959850919650610fa1948794610f95949093610f8993600160a060020a039092169263693ec85e9260848082019392918290030181600087803b158015610f5057600080fd5b505af1158015610f64573d6000803e3d6000fd5b505050506040513d6020811015610f7a57600080fd5b5051879063ffffffff61398016565b9063ffffffff61399216565b9063ffffffff6139bb16565b6040805160a081018252828152336020808301828152600084860181815260018c8101805460608901908152608089018581528e86528588528a862099518a5595519289018054945173ffffffffffffffffffffffffffffffffffffffff19909516600160a060020a039485161774ff0000000000000000000000000000000000000000191660a060020a95151595909502949094179093559151600280890191909155935160039097019690965560058c018b905591549154865160e060020a6323b872dd028152600481019590955230602486015260448501529451959650909216936323b872dd93606480840194938390030190829087803b1580156110a957600080fd5b505af11580156110bd573d6000803e3d6000fd5b505050506040513d60208110156110d357600080fd5b50511515611119576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b82856003015489600160a060020a03167fedfe36bf00610fb3b5474f1efd2de0d52ffb9a50b056ee37c33cea805fd441618a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611188578181015183820152602001611170565b50505050905090810190601f1680156111b55780820380516001836020036101000a031916815260200191505b509250505060405180910390a450909695505050505050565b600654600160a060020a031681565b600160a060020a0381166000908152600160209081526040808320600301548084526009909252822061120f84611895565b151561128a576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6002810154151561129e5760009250610aa8565b600381015460ff1615156112ba57428160020154109250610aa8565b4281600401541080156112cf57506005810154155b9250610aa8565b600754600160a060020a031681565b600160a060020a03811660009081526001602052604081206003015461130a83611895565b1515611385576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000818152600860205260409020544210156113a457600091506113ba565b6000818152600960205260409020600201541591505b50919050565b600160a060020a03166000908152600160208190526040909120015460ff1690565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611461576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b6002808201805484019055546040805160e060020a6323b872dd028152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b1580156114c757600080fd5b505af11580156114db573d6000803e3d6000fd5b505050506040513d60208110156114f157600080fd5b50511515611537576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b6115938383836139d0565b505050565b600760009054906101000a9004600160a060020a0316600160a060020a0316635793b9cf6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156115eb57600080fd5b505af11580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051600160a060020a0316331461169c576040805160e560020a62461bcd02815260206004820152602860248201527f73656e64657220776173206e6f742074686520476f7665726e6d656e7420436f60448201527f6e74726f6c6c6572000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03811615156116fc576040805160e560020a62461bcd02815260206004820152601b60248201527f4e657720476f7665726e6d656e74206164647265737320697320300000000000604482015290519081900360640190fd5b60078054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f016b4781993f669e6eac42012fead2d96f8381769b4efbb4ad686cca6031ea889181900360200190a150565b80518251600091146117df576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b82518110156115935761182483828151811015156117fd57fe5b90602001906020020151838381518110151561181557fe5b906020019060200201516118e0565b6001016117e3565b600160a060020a03166000908152600160205260408120541190565b60086020526000908152604090205481565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a03811660009081526001602052604081206003015481811180156118d9575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615611955576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff161515146119ca576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b6119d5338585613ab3565b91506119e2338585611bc3565b600085815260208190526040902060030154909150611a07908363ffffffff61398016565b6000858152602081905260409020600381019190915554611a2e908263ffffffff61398016565b6000858152602081815260408083209384553380845260049485018352818420805460ff19166001179055600254825160e060020a63a9059cbb02815295860191909152602485018690529051600160a060020a03919091169363a9059cbb9360448083019493928390030190829087803b158015611aac57600080fd5b505af1158015611ac0573d6000803e3d6000fd5b505050506040513d6020811015611ad657600080fd5b50511515611b1c576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b60008281526020819052604081206003810154815483611be4888888613ab3565b9050611bfa83610f95838563ffffffff61399216565b98975050505050505050565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154600160a060020a03909516959394929360ff92831693919290911687565b600160a060020a038082166000908152600160208190526040909120908101549091336101009092041614611cd2576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b611cdb826113c0565b1515611d57576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60038101541580611d855750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611e01576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b611e0a82613c0f565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b6000806000611e518585613df1565b91506000821115612090576007546040805160e160020a63349f642f028152602060048201819052601060248301527f7265717565737441707065616c4c656e000000000000000000000000000000006044830152915161206e93600160a060020a03169263693ec85e92606480820193918290030181600087803b158015611ed957600080fd5b505af1158015611eed573d6000803e3d6000fd5b505050506040513d6020811015611f0357600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e0000000000000000000000000000000000006044820152905161206293600160a060020a039093169263693ec85e92606480820193918290030181600087803b158015611f8457600080fd5b505af1158015611f98573d6000803e3d6000fd5b505050506040513d6020811015611fae57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561202a57600080fd5b505af115801561203e573d6000803e3d6000fd5b505050506040513d602081101561205457600080fd5b50519063ffffffff61469916565b9063ffffffff61469916565b9050612080428263ffffffff61469916565b6000838152600860205260409020555b509392505050565b600081815260208190526040812060010154819060a060020a900460ff161561210b576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561217257600080fd5b505af1158015612186573d6000803e3d6000fd5b505050506040513d602081101561219c57600080fd5b505115156121f4576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b60008381526009602052604090206003015460ff168015612227575060008381526009602052604090206006015460ff16155b905080156122e957600654604080517fe8cfa3f0000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163e8cfa3f0916024808201926020929091908290030181600087803b15801561229657600080fd5b505af11580156122aa573d6000803e3d6000fd5b505050506040513d60208110156122c057600080fd5b505115156122e45760008381526020819052604090206002908101540291506113ba565b61239e565b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b15801561235057600080fd5b505af1158015612364573d6000803e3d6000fd5b505050506040513d602081101561237a57600080fd5b5051151561239e5760008381526020819052604090206002908101540291506113ba565b5050600090815260208190526040902080546002918201549091020390565b600080600760009054906101000a9004600160a060020a0316600160a060020a03166356e1fb886040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561241357600080fd5b505af1158015612427573d6000803e3d6000fd5b505050506040513d602081101561243d57600080fd5b5051600160a060020a0316331461249e576040805160e560020a62461bcd02815260206004820152601c60248201527f73656e64657220776173206e6f742074686520417070656c6c61746500000000604482015290519081900360640190fd5b5050600160a060020a038316600090815260016020908152604080832060038101548452600990925290912060028101544210612525576040805160e560020a62461bcd02815260206004820152601d60248201527f4a756467652041707065616c207068617365206e6f7420616374697665000000604482015290519081900360640190fd5b600381015460ff1615612582576040805160e560020a62461bcd02815260206004820152601f60248201527f41707065616c2068617320616c7265616479206265656e206772616e74656400604482015290519081900360640190fd5b60038101805460ff19166001179055600480546040805160e160020a63349f642f0281526020938101849052601260248201527f6368616c6c656e676541707065616c4c656e00000000000000000000000000006044820152905161264993600160a060020a039093169263693ec85e92606480820193918290030181600087803b15801561261057600080fd5b505af1158015612624573d6000803e3d6000fd5b505050506040513d602081101561263a57600080fd5b5051429063ffffffff61469916565b600482015560038201546040805160208082528101869052600160a060020a038816917f85f61fe0f1b618d4efbf918ec1be0591560df9463fe15cbfb435c3537a1fc1029188918891908190810184848082843760405192018290039550909350505050a35050505050565b600160a060020a0381166000908152600160205260408120600301546126da8361182c565b80156126fd5750600160a060020a03831660009081526001602052604090205442115b801561270f575061270d836113c0565b155b801561274057508015806127405750600081815260208190526040902060019081015460a060020a900460ff161515145b1561274e57600191506113ba565b50600092915050565b600454600160a060020a031681565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146127e5576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115612867576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b600381015415806128955750600381015460009081526020819052604090206001015460a060020a900460ff165b156129ea57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561291457600080fd5b505af1158015612928573d6000803e3d6000fd5b505050506040513d602081101561293e57600080fd5b5051600282015483900310156129ea576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b158015612a4b57600080fd5b505af1158015612a5f573d6000803e3d6000fd5b505050506040513d6020811015612a7557600080fd5b50511515612abb576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b600160a060020a038084166000908152600160209081526040808320600380549082015483517fee684830000000000000000000000000000000000000000000000000000000008152600481019190915292519195859491169263ee684830926024808301939282900301818787803b158015612b8857600080fd5b505af1158015612b9c573d6000803e3d6000fd5b505050506040513d6020811015612bb257600080fd5b50511515612c30576040805160e560020a62461bcd02815260206004820152602860248201527f506f6c6c20666f72206c697374696e67206368616c6c656e676520686173206e60448201527f6f7420656e646564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60038301546000908152600860205260409020544210612c9a576040805160e560020a62461bcd02815260206004820152601c60248201527f526571756573742041707065616c207068617365206973206f76657200000000604482015290519081900360640190fd5b6003830154600090815260096020526040902054600160a060020a031615612d32576040805160e560020a62461bcd02815260206004820152602f60248201527f41707065616c20666f722074686973206368616c6c656e67652068617320616c60448201527f7265616479206265656e206d6164650000000000000000000000000000000000606482015290519081900360840190fd5b6007546040805160e160020a63349f642f028152602060048201819052600960248301527f61707065616c466565000000000000000000000000000000000000000000000060448301529151600160a060020a039093169263693ec85e926064808401939192918290030181600087803b158015612daf57600080fd5b505af1158015612dc3573d6000803e3d6000fd5b505050506040513d6020811015612dd957600080fd5b505160038401546000908152600960209081526040808320805473ffffffffffffffffffffffffffffffffffffffff19163317815560018101859055600754825160e160020a63349f642f02815260048101859052600e60248201527f6a7564676541707065616c4c656e00000000000000000000000000000000000060448201529251959750909550612e9a94600160a060020a03919091169363693ec85e93606480850194919392918390030190829087803b15801561261057600080fd5b600280830191909155546040805160e060020a6323b872dd028152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b158015612efe57600080fd5b505af1158015612f12573d6000803e3d6000fd5b505050506040513d6020811015612f2857600080fd5b50511515612f6e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b826003015486600160a060020a03167fdb6f1c08edff9a1f7e425164118b0473e04404404b2c2d38d6e96e41fcbc7fb1843389896040518085815260200184600160a060020a0316600160a060020a03168152602001806020018281038252848482818152602001925080828437604051920182900397509095505050505050a3505050505050565b60005b815181101561302b57613023828281518110151561301457fe5b9060200190602002015161085a565b600101612ffa565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b613056816146a6565b600160a060020a0316600090815260016020526040812060030155565b600160a060020a0381166000908152600160205260408120600301549061309982612098565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b505050506040513d602081101561315857600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156131d257600080fd5b505af11580156131e6573d6000803e3d6000fd5b505050506040513d60208110156131fc57600080fd5b5051156132805761320c8361304d565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3611593565b61328983613c0f565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b1580156132ed57600080fd5b505af1158015613301573d6000803e3d6000fd5b505050506040513d602081101561331757600080fd5b5051151561336f576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b600160a060020a03811660009081526001602090815260408083206003808201548552600990935290832091820154909290819060ff16156134ec576134178561472a565b600254835460018501546040805160e060020a63a9059cbb028152600160a060020a039384166004820152602481019290925251919092169163a9059cbb9160448083019260209291908290030181600087803b15801561347757600080fd5b505af115801561348b573d6000803e3d6000fd5b505050506040513d60208110156134a157600080fd5b505115156134e7576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b613567565b60038401546000908152602081905260409020600184015490925061351890600263ffffffff6139bb16565b825490915061352d908263ffffffff61469916565b8255600183015461355990613548908363ffffffff61398016565b60028401549063ffffffff61469916565b600283015561356785613073565b5050505050565b600160a060020a03811660009081526001602090815260408083206003810154808552600984528285206005810154808752948690529285209194909391906135b683612098565b60018301805474ff0000000000000000000000000000000000000000191660a060020a179055600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a039091169163053e71a6916024808201926020929091908290030181600087803b15801561364657600080fd5b505af115801561365a573d6000803e3d6000fd5b505050506040513d602081101561367057600080fd5b505160038084019190915554604080517f49403183000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a03909216916349403183916024808201926020929091908290030181600087803b1580156136e057600080fd5b505af11580156136f4573d6000803e3d6000fd5b505050506040513d602081101561370a57600080fd5b50511561384f5760068401805460ff1916600117905561372987613073565b60025460018301546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561378757600080fd5b505af115801561379b573d6000803e3d6000fd5b505050506040513d60208110156137b157600080fd5b505115156137f7576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b828588600160a060020a03167fc49556ab8bcbdd0403e98b6dac260ac86008640cda2a5a229c895353b87f2feb85600001548660030154604051808381526020018281526020019250505060405180910390a4613977565b6138588761472a565b60025484546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156138b357600080fd5b505af11580156138c7573d6000803e3d6000fd5b505050506040513d60208110156138dd57600080fd5b50511515613923576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b828588600160a060020a03167f8a7e8d1076fec4f93e4d57111b034ab3975009f601977350c4542e15d2e8b0f685600001548660030154604051808381526020018281526020019250505060405180910390a45b50505050505050565b60008282111561398c57fe5b50900390565b60008215156139a357506000611bbd565b508181028183828115156139b357fe5b0414611bbd57fe5b600081838115156139c857fe5b049392505050565b82600081905033600160a060020a031681600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613a1e57600080fd5b505af1158015613a32573d6000803e3d6000fd5b505050506040513d6020811015613a4857600080fd5b5051600160a060020a031614613aa8576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f74206f776e6572206f6620636f6e747261637400604482015290519081900360640190fd5b613567858585614a5d565b600082815260096020526040812060030154819060ff168015613ae8575060008481526009602052604090206006015460ff16155b90508015613b9957600654604080517f6afa97a8000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018890526044820187905291519190921691636afa97a89160648083019260209291908290030181600087803b158015613b6657600080fd5b505af1158015613b7a573d6000803e3d6000fd5b505050506040513d6020811015613b9057600080fd5b50519150612090565b600354604080517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015260248201889052604482018790529151919092169163b43bd0699160648083019260209291908290030181600087803b158015613b6657600080fd5b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615613c7357604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2613ca8565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115613deb576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015613d6957600080fd5b505af1158015613d7d573d6000803e3d6000fd5b505050506040513d6020811015613d9357600080fd5b50511515613deb576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b158015613e8957600080fd5b505af1158015613e9d573d6000803e3d6000fd5b505050506040513d6020811015613eb357600080fd5b50519450613ec08961182c565b80613ecf5750600186015460ff165b1515613f71576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b60038601541580613f9f5750600386015460009081526020819052604090206001015460a060020a900460ff165b151561401b576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b848660020154101561406d5761403089613c0f565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a26000965061468d565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b1580156140f457600080fd5b505af1158015614108573d6000803e3d6000fd5b505050506040513d602081101561411e57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561419a57600080fd5b505af11580156141ae573d6000803e3d6000fd5b505050506040513d60208110156141c457600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561424057600080fd5b505af1158015614254573d6000803e3d6000fd5b505050506040513d602081101561426a57600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b1580156142b657600080fd5b505af11580156142ca573d6000803e3d6000fd5b505050506040513d60208110156142e057600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e4840152925193975060649650909283926143bb928892610f95928c92610f8992600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b15801561438257600080fd5b505af1158015614396573d6000803e3d6000fd5b505050506040513d60208110156143ac57600080fd5b50518a9063ffffffff61398016565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c900390559454855160e060020a6323b872dd0281526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b1580156144be57600080fd5b505af11580156144d2573d6000803e3d6000fd5b505050506040513d60208110156144e857600080fd5b5051151561452e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b15801561459557600080fd5b505af11580156145a9573d6000803e3d6000fd5b505050506040513d60a08110156145bf57600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b8381101561464d578181015183820152602001614635565b50505050905090810190601f16801561467a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b81810182811015611bbd57fe5b600160a060020a0381166000908152600160208190526040909120015460ff16151561470157604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a0381166000908152600160209081526040808320600381015480855292849052908320909261475f83612098565b60018301805474ff0000000000000000000000000000000000000000191660a060020a179055600654604080517fe8cfa3f0000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a039091169163e8cfa3f0916024808201926020929091908290030181600087803b1580156147ef57600080fd5b505af1158015614803573d6000803e3d6000fd5b505050506040513d602081101561481957600080fd5b505160038084019190915554604080517f49403183000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a03909216916349403183916024808201926020929091908290030181600087803b15801561488957600080fd5b505af115801561489d573d6000803e3d6000fd5b505050506040513d60208110156148b357600080fd5b50511515614931576148c48561304d565b60028401546148d9908263ffffffff61469916565b60028501558154600383015460408051928352602083019190915280518592600160a060020a038916927f72506b3ce4d8f0cf8cf6ccb7cd5281af2b0d020121fb20abfa073eeb3f6d296e92918290030190a3613567565b61493a85613c0f565b60025460018301546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561499857600080fd5b505af11580156149ac573d6000803e3d6000fd5b505050506040513d60208110156149c257600080fd5b50511515614a08576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b8154600383015460408051928352602083019190915280518592600160a060020a038916927f446922bbfdaa528d4a969857cd0894d6bf8bbff52226624e752b3f1be7513b0a92918290030190a35050505050565b82803b60008111614ab8576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b6135678585856000614ac9846113c0565b15614b1e576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b614b278461182c565b15614ba2576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015614c1c57600080fd5b505af1158015614c30573d6000803e3d6000fd5b505050506040513d6020811015614c4657600080fd5b5051831015614cc5576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395614d7c9592169363693ec85e9360648084019491938390030190829087803b15801561261057600080fd5b815560028082018490555460018201546040805160e060020a6323b872dd028152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015614ded57600080fd5b505af1158015614e01573d6000803e3d6000fd5b505050506040513d6020811015614e1757600080fd5b50511515614e5d576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614ee2578181015183820152602001614eca565b50505050905090810190601f168015614f0f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a3505050505600546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058206bacf351822cd256e053c82d7193ba145a743ea3d6a46dc684273e25e65351cc0029", "deployedBytecode": "0x6080604052600436106101875763ffffffff60e060020a60003504166301162b93811461018c57806306fdde03146101af5780630aac454314610239578063120c40c61461026e5780631e39d8d7146102e757806325ecef04146103185780632672f526146103395780632ea9b6961461034e5780633af32abf1461036f57806347e7ef241461039057806355246b9c146103b45780635b5d4e731461041d5780635f02116f1461043e57806361a9a8ca146104cc57806364c37318146104ed57806365d96c82146105055780636eefcab91461055957806386bb8f371461057a5780638f1d377614610595578063a5ba3b1e146105e0578063a7aad3db14610604578063acff86871461062b578063b42652e914610687578063bc4b010f146106a8578063c8187cf11461070f578063c931674b14610727578063dd4e7cfd14610754578063e1e3f91514610775578063f3fef3a31461078a578063f4c8cfc5146107ae578063f96c8720146107db578063fc0c546a14610830578063fce1ccca14610845575b600080fd5b34801561019857600080fd5b506101ad600160a060020a036004351661085a565b005b3480156101bb57600080fd5b506101c46108be565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101fe5781810151838201526020016101e6565b50505050905090810190601f16801561022b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561024557600080fd5b5061025a600160a060020a036004351661094c565b604080519115158252519081900360200190f35b34801561027a57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526102d5958335600160a060020a0316953695604494919390910191908190840183828082843750949750610aaf9650505050505050565b60408051918252519081900360200190f35b3480156102f357600080fd5b506102fc6111ce565b60408051600160a060020a039092168252519081900360200190f35b34801561032457600080fd5b5061025a600160a060020a03600435166111dd565b34801561034557600080fd5b506102fc6112d6565b34801561035a57600080fd5b5061025a600160a060020a03600435166112e5565b34801561037b57600080fd5b5061025a600160a060020a03600435166113c0565b34801561039c57600080fd5b506101ad600160a060020a03600435166024356113e2565b3480156103c057600080fd5b50604080516020600460443581810135601f81018490048402850184019095528484526101ad948235600160a060020a03169460248035953695946064949201919081908401838280828437509497506115889650505050505050565b34801561042957600080fd5b506101ad600160a060020a0360043516611598565b34801561044a57600080fd5b50604080516020600480358082013583810280860185019096528085526101ad95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375094975061175d9650505050505050565b3480156104d857600080fd5b5061025a600160a060020a036004351661182c565b3480156104f957600080fd5b506102d5600435611848565b34801561051157600080fd5b50610526600160a060020a036004351661185a565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b34801561056557600080fd5b5061025a600160a060020a0360043516611895565b34801561058657600080fd5b506101ad6004356024356118e0565b3480156105a157600080fd5b506105ad600435611b59565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156105ec57600080fd5b5061025a600435600160a060020a0360243516611b95565b34801561061057600080fd5b506102d5600160a060020a0360043516602435604435611bc3565b34801561063757600080fd5b50610643600435611c06565b60408051600160a060020a0390981688526020880196909652868601949094529115156060860152608085015260a0840152151560c0830152519081900360e00190f35b34801561069357600080fd5b506101ad600160a060020a0360043516611c53565b3480156106b457600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526102d5958335600160a060020a0316953695604494919390910191908190840183828082843750949750611e429650505050505050565b34801561071b57600080fd5b506102d5600435612098565b34801561073357600080fd5b506101ad60048035600160a060020a031690602480359081019101356123bd565b34801561076057600080fd5b5061025a600160a060020a03600435166126b5565b34801561078157600080fd5b506102fc612757565b34801561079657600080fd5b506101ad600160a060020a0360043516602435612766565b3480156107ba57600080fd5b506101ad60048035600160a060020a03169060248035908101910135612b0c565b3480156107e757600080fd5b50604080516020600480358082013583810280860185019096528085526101ad95369593946024949385019291829185019084908082843750949750612ff79650505050505050565b34801561083c57600080fd5b506102fc61302f565b34801561085157600080fd5b506102fc61303e565b610863816126b5565b15610876576108718161304d565b6108bb565b61087f816112e5565b1561088d5761087181613073565b610896816111dd565b156108a457610871816133d2565b6108ad8161094c565b15610187576108718161356e565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156109445780601f1061091957610100808354040283529160200191610944565b820191906000526020600020905b81548152906001019060200180831161092757829003601f168201915b505050505081565b600160a060020a0381166000908152600160209081526040808320600301548084526009909252822061097e84611895565b15156109f9576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60058101541515610a0d5760009250610aa8565b6003546005820154604080517fee684830000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015610a7957600080fd5b505af1158015610a8d573d6000803e3d6000fd5b505050506040513d6020811015610aa357600080fd5b505192505b5050919050565b600160a060020a0382166000908152600160209081526040808320600380820154855260099093529083209182015490919083908190819060ff161515610b40576040805160e560020a62461bcd02815260206004820152601260248201527f41707065616c206e6f74206772616e7465640000000000000000000000000000604482015290519081900360640190fd5b600584015415610b9a576040805160e560020a62461bcd02815260206004820152601960248201527f41707065616c20616c7265616479206368616c6c656e67656400000000000000604482015290519081900360640190fd5b60048401544210610c1b576040805160e560020a62461bcd02815260206004820152602260248201527f41707065616c206e6f206c6f6e676572206f70656e20746f206368616c6c656e60448201527f6765000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6003546007546040805160e160020a63349f642f028152602060048201819052601460248301527f61707065616c566f746550657263656e7461676500000000000000000000000060448301529151600160a060020a03948516946332ed3d6094169263693ec85e92606480820193918290030181600087803b158015610ca157600080fd5b505af1158015610cb5573d6000803e3d6000fd5b505050506040513d6020811015610ccb57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052601860248201527f6368616c6c656e676541707065616c436f6d6d69744c656e000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610d4757600080fd5b505af1158015610d5b573d6000803e3d6000fd5b505050506040513d6020811015610d7157600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052601860248201527f6368616c6c656e676541707065616c52657665616c4c656e000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015610ded57600080fd5b505af1158015610e01573d6000803e3d6000fd5b505050506040513d6020811015610e1757600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b158015610e6357600080fd5b505af1158015610e77573d6000803e3d6000fd5b505050506040513d6020811015610e8d57600080fd5b505160018501546007546040805160e160020a63349f642f028152602060048201819052602260248301527f61707065616c4368616c6c656e6765566f746544697370656e736174696f6e5060448301527f63740000000000000000000000000000000000000000000000000000000000006064838101919091529251959850919650610fa1948794610f95949093610f8993600160a060020a039092169263693ec85e9260848082019392918290030181600087803b158015610f5057600080fd5b505af1158015610f64573d6000803e3d6000fd5b505050506040513d6020811015610f7a57600080fd5b5051879063ffffffff61398016565b9063ffffffff61399216565b9063ffffffff6139bb16565b6040805160a081018252828152336020808301828152600084860181815260018c8101805460608901908152608089018581528e86528588528a862099518a5595519289018054945173ffffffffffffffffffffffffffffffffffffffff19909516600160a060020a039485161774ff0000000000000000000000000000000000000000191660a060020a95151595909502949094179093559151600280890191909155935160039097019690965560058c018b905591549154865160e060020a6323b872dd028152600481019590955230602486015260448501529451959650909216936323b872dd93606480840194938390030190829087803b1580156110a957600080fd5b505af11580156110bd573d6000803e3d6000fd5b505050506040513d60208110156110d357600080fd5b50511515611119576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b82856003015489600160a060020a03167fedfe36bf00610fb3b5474f1efd2de0d52ffb9a50b056ee37c33cea805fd441618a6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611188578181015183820152602001611170565b50505050905090810190601f1680156111b55780820380516001836020036101000a031916815260200191505b509250505060405180910390a450909695505050505050565b600654600160a060020a031681565b600160a060020a0381166000908152600160209081526040808320600301548084526009909252822061120f84611895565b151561128a576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6002810154151561129e5760009250610aa8565b600381015460ff1615156112ba57428160020154109250610aa8565b4281600401541080156112cf57506005810154155b9250610aa8565b600754600160a060020a031681565b600160a060020a03811660009081526001602052604081206003015461130a83611895565b1515611385576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72206c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6000818152600860205260409020544210156113a457600091506113ba565b6000818152600960205260409020600201541591505b50919050565b600160a060020a03166000908152600160208190526040909120015460ff1690565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611461576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b6002808201805484019055546040805160e060020a6323b872dd028152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b1580156114c757600080fd5b505af11580156114db573d6000803e3d6000fd5b505050506040513d60208110156114f157600080fd5b50511515611537576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b6115938383836139d0565b505050565b600760009054906101000a9004600160a060020a0316600160a060020a0316635793b9cf6040518163ffffffff1660e060020a028152600401602060405180830381600087803b1580156115eb57600080fd5b505af11580156115ff573d6000803e3d6000fd5b505050506040513d602081101561161557600080fd5b5051600160a060020a0316331461169c576040805160e560020a62461bcd02815260206004820152602860248201527f73656e64657220776173206e6f742074686520476f7665726e6d656e7420436f60448201527f6e74726f6c6c6572000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a03811615156116fc576040805160e560020a62461bcd02815260206004820152601b60248201527f4e657720476f7665726e6d656e74206164647265737320697320300000000000604482015290519081900360640190fd5b60078054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f016b4781993f669e6eac42012fead2d96f8381769b4efbb4ad686cca6031ea889181900360200190a150565b80518251600091146117df576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b82518110156115935761182483828151811015156117fd57fe5b90602001906020020151838381518110151561181557fe5b906020019060200201516118e0565b6001016117e3565b600160a060020a03166000908152600160205260408120541190565b60086020526000908152604090205481565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a03811660009081526001602052604081206003015481811180156118d9575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615611955576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff161515146119ca576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b6119d5338585613ab3565b91506119e2338585611bc3565b600085815260208190526040902060030154909150611a07908363ffffffff61398016565b6000858152602081905260409020600381019190915554611a2e908263ffffffff61398016565b6000858152602081815260408083209384553380845260049485018352818420805460ff19166001179055600254825160e060020a63a9059cbb02815295860191909152602485018690529051600160a060020a03919091169363a9059cbb9360448083019493928390030190829087803b158015611aac57600080fd5b505af1158015611ac0573d6000803e3d6000fd5b505050506040513d6020811015611ad657600080fd5b50511515611b1c576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b60008281526020819052604081206003810154815483611be4888888613ab3565b9050611bfa83610f95838563ffffffff61399216565b98975050505050505050565b6009602052600090815260409020805460018201546002830154600384015460048501546005860154600690960154600160a060020a03909516959394929360ff92831693919290911687565b600160a060020a038082166000908152600160208190526040909120908101549091336101009092041614611cd2576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b611cdb826113c0565b1515611d57576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60038101541580611d855750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611e01576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b611e0a82613c0f565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b6000806000611e518585613df1565b91506000821115612090576007546040805160e160020a63349f642f028152602060048201819052601060248301527f7265717565737441707065616c4c656e000000000000000000000000000000006044830152915161206e93600160a060020a03169263693ec85e92606480820193918290030181600087803b158015611ed957600080fd5b505af1158015611eed573d6000803e3d6000fd5b505050506040513d6020811015611f0357600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e0000000000000000000000000000000000006044820152905161206293600160a060020a039093169263693ec85e92606480820193918290030181600087803b158015611f8457600080fd5b505af1158015611f98573d6000803e3d6000fd5b505050506040513d6020811015611fae57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561202a57600080fd5b505af115801561203e573d6000803e3d6000fd5b505050506040513d602081101561205457600080fd5b50519063ffffffff61469916565b9063ffffffff61469916565b9050612080428263ffffffff61469916565b6000838152600860205260409020555b509392505050565b600081815260208190526040812060010154819060a060020a900460ff161561210b576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561217257600080fd5b505af1158015612186573d6000803e3d6000fd5b505050506040513d602081101561219c57600080fd5b505115156121f4576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b60008381526009602052604090206003015460ff168015612227575060008381526009602052604090206006015460ff16155b905080156122e957600654604080517fe8cfa3f0000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163e8cfa3f0916024808201926020929091908290030181600087803b15801561229657600080fd5b505af11580156122aa573d6000803e3d6000fd5b505050506040513d60208110156122c057600080fd5b505115156122e45760008381526020819052604090206002908101540291506113ba565b61239e565b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b15801561235057600080fd5b505af1158015612364573d6000803e3d6000fd5b505050506040513d602081101561237a57600080fd5b5051151561239e5760008381526020819052604090206002908101540291506113ba565b5050600090815260208190526040902080546002918201549091020390565b600080600760009054906101000a9004600160a060020a0316600160a060020a03166356e1fb886040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561241357600080fd5b505af1158015612427573d6000803e3d6000fd5b505050506040513d602081101561243d57600080fd5b5051600160a060020a0316331461249e576040805160e560020a62461bcd02815260206004820152601c60248201527f73656e64657220776173206e6f742074686520417070656c6c61746500000000604482015290519081900360640190fd5b5050600160a060020a038316600090815260016020908152604080832060038101548452600990925290912060028101544210612525576040805160e560020a62461bcd02815260206004820152601d60248201527f4a756467652041707065616c207068617365206e6f7420616374697665000000604482015290519081900360640190fd5b600381015460ff1615612582576040805160e560020a62461bcd02815260206004820152601f60248201527f41707065616c2068617320616c7265616479206265656e206772616e74656400604482015290519081900360640190fd5b60038101805460ff19166001179055600480546040805160e160020a63349f642f0281526020938101849052601260248201527f6368616c6c656e676541707065616c4c656e00000000000000000000000000006044820152905161264993600160a060020a039093169263693ec85e92606480820193918290030181600087803b15801561261057600080fd5b505af1158015612624573d6000803e3d6000fd5b505050506040513d602081101561263a57600080fd5b5051429063ffffffff61469916565b600482015560038201546040805160208082528101869052600160a060020a038816917f85f61fe0f1b618d4efbf918ec1be0591560df9463fe15cbfb435c3537a1fc1029188918891908190810184848082843760405192018290039550909350505050a35050505050565b600160a060020a0381166000908152600160205260408120600301546126da8361182c565b80156126fd5750600160a060020a03831660009081526001602052604090205442115b801561270f575061270d836113c0565b155b801561274057508015806127405750600081815260208190526040902060019081015460a060020a900460ff161515145b1561274e57600191506113ba565b50600092915050565b600454600160a060020a031681565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146127e5576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115612867576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b600381015415806128955750600381015460009081526020819052604090206001015460a060020a900460ff165b156129ea57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561291457600080fd5b505af1158015612928573d6000803e3d6000fd5b505050506040513d602081101561293e57600080fd5b5051600282015483900310156129ea576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b158015612a4b57600080fd5b505af1158015612a5f573d6000803e3d6000fd5b505050506040513d6020811015612a7557600080fd5b50511515612abb576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b600160a060020a038084166000908152600160209081526040808320600380549082015483517fee684830000000000000000000000000000000000000000000000000000000008152600481019190915292519195859491169263ee684830926024808301939282900301818787803b158015612b8857600080fd5b505af1158015612b9c573d6000803e3d6000fd5b505050506040513d6020811015612bb257600080fd5b50511515612c30576040805160e560020a62461bcd02815260206004820152602860248201527f506f6c6c20666f72206c697374696e67206368616c6c656e676520686173206e60448201527f6f7420656e646564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60038301546000908152600860205260409020544210612c9a576040805160e560020a62461bcd02815260206004820152601c60248201527f526571756573742041707065616c207068617365206973206f76657200000000604482015290519081900360640190fd5b6003830154600090815260096020526040902054600160a060020a031615612d32576040805160e560020a62461bcd02815260206004820152602f60248201527f41707065616c20666f722074686973206368616c6c656e67652068617320616c60448201527f7265616479206265656e206d6164650000000000000000000000000000000000606482015290519081900360840190fd5b6007546040805160e160020a63349f642f028152602060048201819052600960248301527f61707065616c466565000000000000000000000000000000000000000000000060448301529151600160a060020a039093169263693ec85e926064808401939192918290030181600087803b158015612daf57600080fd5b505af1158015612dc3573d6000803e3d6000fd5b505050506040513d6020811015612dd957600080fd5b505160038401546000908152600960209081526040808320805473ffffffffffffffffffffffffffffffffffffffff19163317815560018101859055600754825160e160020a63349f642f02815260048101859052600e60248201527f6a7564676541707065616c4c656e00000000000000000000000000000000000060448201529251959750909550612e9a94600160a060020a03919091169363693ec85e93606480850194919392918390030190829087803b15801561261057600080fd5b600280830191909155546040805160e060020a6323b872dd028152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b158015612efe57600080fd5b505af1158015612f12573d6000803e3d6000fd5b505050506040513d6020811015612f2857600080fd5b50511515612f6e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b826003015486600160a060020a03167fdb6f1c08edff9a1f7e425164118b0473e04404404b2c2d38d6e96e41fcbc7fb1843389896040518085815260200184600160a060020a0316600160a060020a03168152602001806020018281038252848482818152602001925080828437604051920182900397509095505050505050a3505050505050565b60005b815181101561302b57613023828281518110151561301457fe5b9060200190602002015161085a565b600101612ffa565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b613056816146a6565b600160a060020a0316600090815260016020526040812060030155565b600160a060020a0381166000908152600160205260408120600301549061309982612098565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561312e57600080fd5b505af1158015613142573d6000803e3d6000fd5b505050506040513d602081101561315857600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156131d257600080fd5b505af11580156131e6573d6000803e3d6000fd5b505050506040513d60208110156131fc57600080fd5b5051156132805761320c8361304d565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3611593565b61328983613c0f565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b1580156132ed57600080fd5b505af1158015613301573d6000803e3d6000fd5b505050506040513d602081101561331757600080fd5b5051151561336f576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b600160a060020a03811660009081526001602090815260408083206003808201548552600990935290832091820154909290819060ff16156134ec576134178561472a565b600254835460018501546040805160e060020a63a9059cbb028152600160a060020a039384166004820152602481019290925251919092169163a9059cbb9160448083019260209291908290030181600087803b15801561347757600080fd5b505af115801561348b573d6000803e3d6000fd5b505050506040513d60208110156134a157600080fd5b505115156134e7576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b613567565b60038401546000908152602081905260409020600184015490925061351890600263ffffffff6139bb16565b825490915061352d908263ffffffff61469916565b8255600183015461355990613548908363ffffffff61398016565b60028401549063ffffffff61469916565b600283015561356785613073565b5050505050565b600160a060020a03811660009081526001602090815260408083206003810154808552600984528285206005810154808752948690529285209194909391906135b683612098565b60018301805474ff0000000000000000000000000000000000000000191660a060020a179055600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a039091169163053e71a6916024808201926020929091908290030181600087803b15801561364657600080fd5b505af115801561365a573d6000803e3d6000fd5b505050506040513d602081101561367057600080fd5b505160038084019190915554604080517f49403183000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a03909216916349403183916024808201926020929091908290030181600087803b1580156136e057600080fd5b505af11580156136f4573d6000803e3d6000fd5b505050506040513d602081101561370a57600080fd5b50511561384f5760068401805460ff1916600117905561372987613073565b60025460018301546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561378757600080fd5b505af115801561379b573d6000803e3d6000fd5b505050506040513d60208110156137b157600080fd5b505115156137f7576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b828588600160a060020a03167fc49556ab8bcbdd0403e98b6dac260ac86008640cda2a5a229c895353b87f2feb85600001548660030154604051808381526020018281526020019250505060405180910390a4613977565b6138588761472a565b60025484546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156138b357600080fd5b505af11580156138c7573d6000803e3d6000fd5b505050506040513d60208110156138dd57600080fd5b50511515613923576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b828588600160a060020a03167f8a7e8d1076fec4f93e4d57111b034ab3975009f601977350c4542e15d2e8b0f685600001548660030154604051808381526020018281526020019250505060405180910390a45b50505050505050565b60008282111561398c57fe5b50900390565b60008215156139a357506000611bbd565b508181028183828115156139b357fe5b0414611bbd57fe5b600081838115156139c857fe5b049392505050565b82600081905033600160a060020a031681600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613a1e57600080fd5b505af1158015613a32573d6000803e3d6000fd5b505050506040513d6020811015613a4857600080fd5b5051600160a060020a031614613aa8576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f74206f776e6572206f6620636f6e747261637400604482015290519081900360640190fd5b613567858585614a5d565b600082815260096020526040812060030154819060ff168015613ae8575060008481526009602052604090206006015460ff16155b90508015613b9957600654604080517f6afa97a8000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018890526044820187905291519190921691636afa97a89160648083019260209291908290030181600087803b158015613b6657600080fd5b505af1158015613b7a573d6000803e3d6000fd5b505050506040513d6020811015613b9057600080fd5b50519150612090565b600354604080517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015260248201889052604482018790529151919092169163b43bd0699160648083019260209291908290030181600087803b158015613b6657600080fd5b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615613c7357604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2613ca8565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115613deb576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015613d6957600080fd5b505af1158015613d7d573d6000803e3d6000fd5b505050506040513d6020811015613d9357600080fd5b50511515613deb576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b158015613e8957600080fd5b505af1158015613e9d573d6000803e3d6000fd5b505050506040513d6020811015613eb357600080fd5b50519450613ec08961182c565b80613ecf5750600186015460ff165b1515613f71576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b60038601541580613f9f5750600386015460009081526020819052604090206001015460a060020a900460ff165b151561401b576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b848660020154101561406d5761403089613c0f565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a26000965061468d565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b1580156140f457600080fd5b505af1158015614108573d6000803e3d6000fd5b505050506040513d602081101561411e57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561419a57600080fd5b505af11580156141ae573d6000803e3d6000fd5b505050506040513d60208110156141c457600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561424057600080fd5b505af1158015614254573d6000803e3d6000fd5b505050506040513d602081101561426a57600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b1580156142b657600080fd5b505af11580156142ca573d6000803e3d6000fd5b505050506040513d60208110156142e057600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e4840152925193975060649650909283926143bb928892610f95928c92610f8992600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b15801561438257600080fd5b505af1158015614396573d6000803e3d6000fd5b505050506040513d60208110156143ac57600080fd5b50518a9063ffffffff61398016565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c900390559454855160e060020a6323b872dd0281526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b1580156144be57600080fd5b505af11580156144d2573d6000803e3d6000fd5b505050506040513d60208110156144e857600080fd5b5051151561452e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b15801561459557600080fd5b505af11580156145a9573d6000803e3d6000fd5b505050506040513d60a08110156145bf57600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b8381101561464d578181015183820152602001614635565b50505050905090810190601f16801561467a5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b81810182811015611bbd57fe5b600160a060020a0381166000908152600160208190526040909120015460ff16151561470157604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a0381166000908152600160209081526040808320600381015480855292849052908320909261475f83612098565b60018301805474ff0000000000000000000000000000000000000000191660a060020a179055600654604080517fe8cfa3f0000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a039091169163e8cfa3f0916024808201926020929091908290030181600087803b1580156147ef57600080fd5b505af1158015614803573d6000803e3d6000fd5b505050506040513d602081101561481957600080fd5b505160038084019190915554604080517f49403183000000000000000000000000000000000000000000000000000000008152600481018690529051600160a060020a03909216916349403183916024808201926020929091908290030181600087803b15801561488957600080fd5b505af115801561489d573d6000803e3d6000fd5b505050506040513d60208110156148b357600080fd5b50511515614931576148c48561304d565b60028401546148d9908263ffffffff61469916565b60028501558154600383015460408051928352602083019190915280518592600160a060020a038916927f72506b3ce4d8f0cf8cf6ccb7cd5281af2b0d020121fb20abfa073eeb3f6d296e92918290030190a3613567565b61493a85613c0f565b60025460018301546040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561499857600080fd5b505af11580156149ac573d6000803e3d6000fd5b505050506040513d60208110156149c257600080fd5b50511515614a08576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b8154600383015460408051928352602083019190915280518592600160a060020a038916927f446922bbfdaa528d4a969857cd0894d6bf8bbff52226624e752b3f1be7513b0a92918290030190a35050505050565b82803b60008111614ab8576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b6135678585856000614ac9846113c0565b15614b1e576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b614b278461182c565b15614ba2576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015614c1c57600080fd5b505af1158015614c30573d6000803e3d6000fd5b505050506040513d6020811015614c4657600080fd5b5051831015614cc5576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395614d7c9592169363693ec85e9360648084019491938390030190829087803b15801561261057600080fd5b815560028082018490555460018201546040805160e060020a6323b872dd028152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015614ded57600080fd5b505af1158015614e01573d6000803e3d6000fd5b505050506040513d6020811015614e1757600080fd5b50511515614e5d576040805160e560020a62461bcd0281526020600482015260156024820152600080516020614f25833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614ee2578181015183820152602001614eca565b50505050905090810190601f168015614f0f5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a3505050505600546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058206bacf351822cd256e053c82d7193ba145a743ea3d6a46dc684273e25e65351cc0029", "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "civilVoting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "government", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "isWhitelisted", "outputs": [ { "name": "whitelisted", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "deposit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appWasMade", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challengeRequestAppealExpiries", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "listings", "outputs": [ { "name": "applicationExpiry", "type": "uint256" }, { "name": "whitelisted", "type": "bool" }, { "name": "owner", "type": "address" }, { "name": "unstakedDeposit", "type": "uint256" }, { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "totalTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "appeals", "outputs": [ { "name": "requester", "type": "address" }, { "name": "appealFeePaid", "type": "uint256" }, { "name": "appealPhaseExpiry", "type": "uint256" }, { "name": "appealGranted", "type": "bool" }, { "name": "appealOpenToChallengeExpiry", "type": "uint256" }, { "name": "appealChallengeID", "type": "uint256" }, { "name": "overturned", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "exit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "canBeWhitelisted", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "parameterizer", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddresses", "type": "address[]" } ], "name": "updateStatuses", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "token", "type": "address" }, { "name": "plcr", "type": "address" }, { "name": "param", "type": "address" }, { "name": "govt", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "appealFeePaid", "type": "uint256" }, { "indexed": false, "name": "requester", "type": "address" }, { "indexed": false, "name": "data", "type": "string" } ], "name": "_AppealRequested", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" } ], "name": "_AppealGranted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_FailedChallengeOverturned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_SuccessfulChallengeOverturned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": true, "name": "appealChallengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" } ], "name": "_GrantedAppealChallenged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": true, "name": "appealChallengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_GrantedAppealOverturned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": true, "name": "appealChallengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_GrantedAppealConfirmed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "newGovernment", "type": "address" } ], "name": "_GovernmentTransfered", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": true, "name": "applicant", "type": "address" } ], "name": "_Application", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_Challenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "added", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "withdrew", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Withdrawal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationWhitelisted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_TouchAndRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "amount", "type": "uint256" }, { "name": "data", "type": "string" } ], "name": "apply", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "data", "type": "string" } ], "name": "requestAppeal", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "data", "type": "string" } ], "name": "grantAppeal", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "newGovernment", "type": "address" } ], "name": "transferGovernment", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "updateStatus", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "data", "type": "string" } ], "name": "challenge", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "data", "type": "string" } ], "name": "challengeGrantedAppeal", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "challengeID", "type": "uint256" } ], "name": "determineReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "voter", "type": "address" }, { "name": "challengeID", "type": "uint256" }, { "name": "salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "canBeResolved", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appealCanBeResolved", "outputs": [ { "name": "canBeResolved", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appealChallengeCanBeResolved", "outputs": [ { "name": "canBeResolved", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0xbd5a95a66dd4e78bcb597198df222c4eddc14da7", "transactionHash": "0x7ed74c61ba31a254e5eaf7a179afaa8b129087d3d8e9119e56a39bfab1e4ef51" }, "4": { "events": {}, "links": {}, "address": "0xdad6d7ea1e43f8492a78bab8bb0d45a889ed6ac3", "transactionHash": "0xcf9e354de1162725950e287ecbf01ea52eb77551d9a818d4c4ea070e7d067225" } } } ================================================ FILE: packages/artifacts/v1/CivilTokenController.json ================================================ { "contractName": "CivilTokenController", "bytecode": "0x60806040523480156200001157600080fd5b5060008054600160a060020a03191633178155604080518082018252600781527f53554343455353000000000000000000000000000000000000000000000000006020820190815291517f6ef3054c0000000000000000000000000000000000000000000000000000000081526008600482018181526024830186905260606044840190815284516064850152845173__MessagesAndCodes______________________97636ef3054c97949690959094608490910191808383895b83811015620000e7578181015183820152602001620000cd565b50505050905090810190601f168015620001155780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b1580156200013557600080fd5b505af41580156200014a573d6000803e3d6000fd5b505050506040513d60208110156200016157600080fd5b5050604080518082018252601281527f4d5553545f42455f415f434956494c49414e00000000000000000000000000006020820190815291517f6ef3054c00000000000000000000000000000000000000000000000000000000815260086004820181815260016024840181905260606044850190815285516064860152855173__MessagesAndCodes______________________97636ef3054c979596939594936084019180838360005b83811015620002275781810151838201526020016200020d565b50505050905090810190601f168015620002555780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b1580156200027557600080fd5b505af41580156200028a573d6000803e3d6000fd5b505050506040513d6020811015620002a157600080fd5b5050604080518082018252601081527f4d5553545f42455f554e4c4f434b4544000000000000000000000000000000006020820190815291517f6ef3054c00000000000000000000000000000000000000000000000000000000815260086004820181815260026024840181905260606044850190815285516064860152855173__MessagesAndCodes______________________97636ef3054c979596939594936084019180838360005b83811015620003675781810151838201526020016200034d565b50505050905090810190601f168015620003955780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015620003b557600080fd5b505af4158015620003ca573d6000803e3d6000fd5b505050506040513d6020811015620003e157600080fd5b5050604080518082018252601081527f4d5553545f42455f5645524946494544000000000000000000000000000000006020820190815291517f6ef3054c00000000000000000000000000000000000000000000000000000000815260086004820181815260036024840181905260606044850190815285516064860152855173__MessagesAndCodes______________________97636ef3054c979596939594936084019180838360005b83811015620004a75781810151838201526020016200048d565b50505050905090810190601f168015620004d55780820380516001836020036101000a031916815260200191505b5094505050505060206040518083038186803b158015620004f557600080fd5b505af41580156200050a573d6000803e3d6000fd5b505050506040513d60208110156200052157600080fd5b505061143480620005336000396000f3006080604052600436106101d75763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e969a0581146101dc5780631299090a1461020757806314862ea51461022a578063166542b31461024b5780632d06177a146102805780633c421424146102a15780633f16b282146102c2578063439b650b146102e35780634b3d1485146102f8578063607c60bb14610319578063715018a61461033a578063725248731461034f57806373c601821461037357806378a21ddb146103945780637f4ab1dd1461041e57806381601496146104395780638bdeb4521461045a5780638da5cb5b1461047b5780639685cc57146104ac578063ab3d0c7a146104cd578063ac18de43146104ee578063ac1f38531461050f578063adbb916014610530578063bdcadb3b14610551578063c0e9794a14610566578063c56a3e881461057b578063ca3aaa9a14610590578063d4ce1415146105a5578063e7984d17146105cf578063e79a4fd4146105e4578063e99f29a414610605578063ee37c29f14610626578063ee56f4fa14610647578063f0fbca0614610668578063f198391814610689578063f281e7d11461069e578063f2fde38b146106bf578063fdff9b4d146106e0575b600080fd5b3480156101e857600080fd5b506101f1610701565b6040805160ff9092168252519081900360200190f35b34801561021357600080fd5b50610228600160a060020a0360043516610706565b005b34801561023657600080fd5b50610228600160a060020a03600435166107a0565b34801561025757600080fd5b5061026c600160a060020a0360043516610837565b604080519115158252519081900360200190f35b34801561028c57600080fd5b50610228600160a060020a036004351661084c565b3480156102ad57600080fd5b50610228600160a060020a036004351661088a565b3480156102ce57600080fd5b50610228600160a060020a0360043516610921565b3480156102ef57600080fd5b506101f16109bb565b34801561030457600080fd5b50610228600160a060020a03600435166109c0565b34801561032557600080fd5b50610228600160a060020a0360043516610a57565b34801561034657600080fd5b50610228610af1565b34801561035b57600080fd5b50610228600160a060020a0360043516602435610b5d565b34801561037f57600080fd5b50610228600160a060020a0360043516610b6a565b3480156103a057600080fd5b506103a9610c04565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103e35781810151838201526020016103cb565b50505050905090810190601f1680156104105780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561042a57600080fd5b506103a960ff60043516610c3b565b34801561044557600080fd5b5061026c600160a060020a0360043516610ce0565b34801561046657600080fd5b5061026c600160a060020a0360043516610cf5565b34801561048757600080fd5b50610490610d0a565b60408051600160a060020a039092168252519081900360200190f35b3480156104b857600080fd5b5061026c600160a060020a0360043516610d19565b3480156104d957600080fd5b50610228600160a060020a0360043516610d2e565b3480156104fa57600080fd5b50610228600160a060020a0360043516610dc5565b34801561051b57600080fd5b50610228600160a060020a0360043516610dfd565b34801561053c57600080fd5b50610228600160a060020a0360043516610e97565b34801561055d57600080fd5b506103a9610f2e565b34801561057257600080fd5b506101f1610f65565b34801561058757600080fd5b5061026c610f6a565b34801561059c57600080fd5b506101f1610f7a565b3480156105b157600080fd5b506101f1600160a060020a0360043581169060243516604435610f7f565b3480156105db57600080fd5b506103a961112c565b3480156105f057600080fd5b50610228600160a060020a0360043516611163565b34801561061157600080fd5b50610228600160a060020a03600435166111fa565b34801561063257600080fd5b50610228600160a060020a03600435166111fd565b34801561065357600080fd5b5061026c600160a060020a0360043516611297565b34801561067457600080fd5b5061026c600160a060020a03600435166112ac565b34801561069557600080fd5b506103a96112c1565b3480156106aa57600080fd5b5061026c600160a060020a03600435166112f8565b3480156106cb57600080fd5b50610228600160a060020a0360043516611316565b3480156106ec57600080fd5b5061026c600160a060020a0360043516611336565b600081565b61070f336112f8565b806107245750600054600160a060020a031633145b151561077c576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19166001179055565b6107a9336112f8565b806107be5750600054600160a060020a031633145b1515610816576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19169055565b60076020526000908152604090205460ff1681565b600054600160a060020a0316331461086357600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b610893336112f8565b806108a85750600054600160a060020a031633145b1515610900576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19169055565b61092a336112f8565b8061093f5750600054600160a060020a031633145b1515610997576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19166001179055565b600181565b6109c9336112f8565b806109de5750600054600160a060020a031633145b1515610a36576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19169055565b610a60336112f8565b80610a755750600054600160a060020a031633145b1515610acd576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19166001179055565b600054600160a060020a03163314610b0857600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b610b6682610921565b5050565b610b73336112f8565b80610b885750600054600160a060020a031633145b1515610be0576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19166001179055565b60408051808201909152601281527f4d5553545f42455f415f434956494c49414e0000000000000000000000000000602082015281565b60ff811660009081526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b600054600160a060020a031681565b60026020526000908152604090205460ff1681565b610d37336112f8565b80610d4c5750600054600160a060020a031633145b1515610da4576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19169055565b600054600160a060020a03163314610ddc57600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b610e06336112f8565b80610e1b5750600054600160a060020a031633145b1515610e73576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19166001179055565b610ea0336112f8565b80610eb55750600054600160a060020a031633145b1515610f0d576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19169055565b60408051808201909152601081527f4d5553545f42455f564552494649454400000000000000000000000000000000602082015281565b600381565b6000610f75336112f8565b905090565b600281565b600160a060020a03831660009081526002602052604081205460ff1680610fbe5750600160a060020a03841660009081526004602052604090205460ff165b15610fcb57506000611125565b600160a060020a03841660009081526006602052604090205460ff161561104057600160a060020a03831660009081526005602052604090205460ff168061102b5750600160a060020a03831660009081526002602052604090205460ff165b1561103857506000611125565b506003611125565b600160a060020a03841660009081526007602052604090205460ff16156110b557600160a060020a03831660009081526002602052604090205460ff16806110a05750600160a060020a03831660009081526003602052604090205460ff165b156110ad57506000611125565b506002611125565b600160a060020a03841660009081526003602052604090205460ff161561112157600160a060020a03831660009081526002602052604090205460ff16806110a05750600160a060020a03831660009081526007602052604090205460ff16156110ad57506000611125565b5060015b9392505050565b60408051808201909152600781527f5355434345535300000000000000000000000000000000000000000000000000602082015281565b61116c336112f8565b806111815750600054600160a060020a031633145b15156111d9576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19169055565b50565b611206336112f8565b8061121b5750600054600160a060020a031633145b1515611273576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19166001179055565b60036020526000908152604090205460ff1681565b60066020526000908152604090205460ff1681565b60408051808201909152601081527f4d5553545f42455f554e4c4f434b454400000000000000000000000000000000602082015281565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a0316331461132d57600080fd5b6111fa8161134b565b60016020526000908152604090205460ff1681565b600160a060020a038116151561136057600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905556006f726d207468697320616374696f6e00000000000000000000000000000000004f6e6c79206d616e6167657273206f72206f776e657273206d61792070657266a165627a7a72305820d72b701db11797950783bc2e00b52cb3d591869b6b0296d74de92ec7a7182b2c0029", "deployedBytecode": "0x6080604052600436106101d75763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e969a0581146101dc5780631299090a1461020757806314862ea51461022a578063166542b31461024b5780632d06177a146102805780633c421424146102a15780633f16b282146102c2578063439b650b146102e35780634b3d1485146102f8578063607c60bb14610319578063715018a61461033a578063725248731461034f57806373c601821461037357806378a21ddb146103945780637f4ab1dd1461041e57806381601496146104395780638bdeb4521461045a5780638da5cb5b1461047b5780639685cc57146104ac578063ab3d0c7a146104cd578063ac18de43146104ee578063ac1f38531461050f578063adbb916014610530578063bdcadb3b14610551578063c0e9794a14610566578063c56a3e881461057b578063ca3aaa9a14610590578063d4ce1415146105a5578063e7984d17146105cf578063e79a4fd4146105e4578063e99f29a414610605578063ee37c29f14610626578063ee56f4fa14610647578063f0fbca0614610668578063f198391814610689578063f281e7d11461069e578063f2fde38b146106bf578063fdff9b4d146106e0575b600080fd5b3480156101e857600080fd5b506101f1610701565b6040805160ff9092168252519081900360200190f35b34801561021357600080fd5b50610228600160a060020a0360043516610706565b005b34801561023657600080fd5b50610228600160a060020a03600435166107a0565b34801561025757600080fd5b5061026c600160a060020a0360043516610837565b604080519115158252519081900360200190f35b34801561028c57600080fd5b50610228600160a060020a036004351661084c565b3480156102ad57600080fd5b50610228600160a060020a036004351661088a565b3480156102ce57600080fd5b50610228600160a060020a0360043516610921565b3480156102ef57600080fd5b506101f16109bb565b34801561030457600080fd5b50610228600160a060020a03600435166109c0565b34801561032557600080fd5b50610228600160a060020a0360043516610a57565b34801561034657600080fd5b50610228610af1565b34801561035b57600080fd5b50610228600160a060020a0360043516602435610b5d565b34801561037f57600080fd5b50610228600160a060020a0360043516610b6a565b3480156103a057600080fd5b506103a9610c04565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103e35781810151838201526020016103cb565b50505050905090810190601f1680156104105780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561042a57600080fd5b506103a960ff60043516610c3b565b34801561044557600080fd5b5061026c600160a060020a0360043516610ce0565b34801561046657600080fd5b5061026c600160a060020a0360043516610cf5565b34801561048757600080fd5b50610490610d0a565b60408051600160a060020a039092168252519081900360200190f35b3480156104b857600080fd5b5061026c600160a060020a0360043516610d19565b3480156104d957600080fd5b50610228600160a060020a0360043516610d2e565b3480156104fa57600080fd5b50610228600160a060020a0360043516610dc5565b34801561051b57600080fd5b50610228600160a060020a0360043516610dfd565b34801561053c57600080fd5b50610228600160a060020a0360043516610e97565b34801561055d57600080fd5b506103a9610f2e565b34801561057257600080fd5b506101f1610f65565b34801561058757600080fd5b5061026c610f6a565b34801561059c57600080fd5b506101f1610f7a565b3480156105b157600080fd5b506101f1600160a060020a0360043581169060243516604435610f7f565b3480156105db57600080fd5b506103a961112c565b3480156105f057600080fd5b50610228600160a060020a0360043516611163565b34801561061157600080fd5b50610228600160a060020a03600435166111fa565b34801561063257600080fd5b50610228600160a060020a03600435166111fd565b34801561065357600080fd5b5061026c600160a060020a0360043516611297565b34801561067457600080fd5b5061026c600160a060020a03600435166112ac565b34801561069557600080fd5b506103a96112c1565b3480156106aa57600080fd5b5061026c600160a060020a03600435166112f8565b3480156106cb57600080fd5b50610228600160a060020a0360043516611316565b3480156106ec57600080fd5b5061026c600160a060020a0360043516611336565b600081565b61070f336112f8565b806107245750600054600160a060020a031633145b151561077c576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19166001179055565b6107a9336112f8565b806107be5750600054600160a060020a031633145b1515610816576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19169055565b60076020526000908152604090205460ff1681565b600054600160a060020a0316331461086357600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b610893336112f8565b806108a85750600054600160a060020a031633145b1515610900576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19169055565b61092a336112f8565b8061093f5750600054600160a060020a031633145b1515610997576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19166001179055565b600181565b6109c9336112f8565b806109de5750600054600160a060020a031633145b1515610a36576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19169055565b610a60336112f8565b80610a755750600054600160a060020a031633145b1515610acd576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19166001179055565b600054600160a060020a03163314610b0857600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b610b6682610921565b5050565b610b73336112f8565b80610b885750600054600160a060020a031633145b1515610be0576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19166001179055565b60408051808201909152601281527f4d5553545f42455f415f434956494c49414e0000000000000000000000000000602082015281565b60ff811660009081526008602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845260609392830182828015610cd45780601f10610ca957610100808354040283529160200191610cd4565b820191906000526020600020905b815481529060010190602001808311610cb757829003601f168201915b50505050509050919050565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b600054600160a060020a031681565b60026020526000908152604090205460ff1681565b610d37336112f8565b80610d4c5750600054600160a060020a031633145b1515610da4576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19169055565b600054600160a060020a03163314610ddc57600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b610e06336112f8565b80610e1b5750600054600160a060020a031633145b1515610e73576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19166001179055565b610ea0336112f8565b80610eb55750600054600160a060020a031633145b1515610f0d576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19169055565b60408051808201909152601081527f4d5553545f42455f564552494649454400000000000000000000000000000000602082015281565b600381565b6000610f75336112f8565b905090565b600281565b600160a060020a03831660009081526002602052604081205460ff1680610fbe5750600160a060020a03841660009081526004602052604090205460ff165b15610fcb57506000611125565b600160a060020a03841660009081526006602052604090205460ff161561104057600160a060020a03831660009081526005602052604090205460ff168061102b5750600160a060020a03831660009081526002602052604090205460ff165b1561103857506000611125565b506003611125565b600160a060020a03841660009081526007602052604090205460ff16156110b557600160a060020a03831660009081526002602052604090205460ff16806110a05750600160a060020a03831660009081526003602052604090205460ff165b156110ad57506000611125565b506002611125565b600160a060020a03841660009081526003602052604090205460ff161561112157600160a060020a03831660009081526002602052604090205460ff16806110a05750600160a060020a03831660009081526007602052604090205460ff16156110ad57506000611125565b5060015b9392505050565b60408051808201909152600781527f5355434345535300000000000000000000000000000000000000000000000000602082015281565b61116c336112f8565b806111815750600054600160a060020a031633145b15156111d9576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19169055565b50565b611206336112f8565b8061121b5750600054600160a060020a031633145b1515611273576040805160e560020a62461bcd02815260206004820152602f60248201526000805160206113e983398151915260448201526000805160206113c9833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19166001179055565b60036020526000908152604090205460ff1681565b60066020526000908152604090205460ff1681565b60408051808201909152601081527f4d5553545f42455f554e4c4f434b454400000000000000000000000000000000602082015281565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a0316331461132d57600080fd5b6111fa8161134b565b60016020526000908152604090205460ff1681565b600160a060020a038116151561136057600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905556006f726d207468697320616374696f6e00000000000000000000000000000000004f6e6c79206d616e6167657273206f72206f776e657273206d61792070657266a165627a7a72305820d72b701db11797950783bc2e00b52cb3d591869b6b0296d74de92ec7a7182b2c0029", "abi": [ { "constant": true, "inputs": [], "name": "SUCCESS_CODE", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToCivilians", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromUnlocked", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "newsroomMultisigList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "addManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromCore", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToUnlocked", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_A_CIVILIAN_CODE", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromVerified", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToNewsroomMultisigs", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToCore", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_A_CIVILIAN_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "verifiedList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "unlockedList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "coreList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromCivilians", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "removeManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToStorefront", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromStorefront", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_VERIFIED_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_VERIFIED_CODE", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "isManager", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_UNLOCKED_CODE", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "SUCCESS_MESSAGE", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromNewsroomMultisigs", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "checkProofOfUse", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToVerified", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "civilianList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "storefrontList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "MUST_BE_UNLOCKED_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "checkManagerStatus", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "managers", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": true, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "detectTransferRestriction", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "restrictionCode", "type": "uint8" } ], "name": "messageForTransferRestriction", "outputs": [ { "name": "message", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "user", "type": "address" }, { "name": "tokenAmount", "type": "uint256" } ], "name": "onRequestVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": { "MessagesAndCodes": "0x99Ed479b711f1Dec9377d8a1C63Bfa2D51486954" }, "address": "0x6d3dc15e04dd1d8968556d02cf209a4fb4ab8736", "transactionHash": "0x37a0f967335aad27ed10bb83d1df1065ef2b7e39e1057ff553b3d9808feb0ede" }, "4": { "events": {}, "links": { "MessagesAndCodes": "0x908d7ca8704592342a6b869687d81fa461e4d34f" }, "address": "0x6c343cfded474f9800e7b49287b210b608c2ea9b", "transactionHash": "0x71c5c36106d10fbe6e0b1200ff1f01001ead2cf806393b1bfa003531e6460aba" } } } ================================================ FILE: packages/artifacts/v1/ContractAddressRegistry.json ================================================ { "contractName": "ContractAddressRegistry", "bytecode": "0x60806040523480156200001157600080fd5b5060405162002fad38038062002fad83398101604090815281516020830151918301516060840151919390910183838383600160a060020a0384161515620000ba57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f746f6b656e2061646472657373206973203000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156200013257604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f766f74696e6720616464726573732069732030000000000000000000000000604482015290519081900360640190fd5b600160a060020a0382161515620001aa57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f706172616d65746572697a6572206164647265737320697320300000000000604482015290519081900360640190fd5b60028054600160a060020a03808716600160a060020a0319928316179092556003805486841690831617905560048054928516929091169190911790558051620001fc9060059060208401906200020b565b505050505050505050620002b0565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200024e57805160ff19168380011785556200027e565b828001600101855582156200027e579182015b828111156200027e57825182559160200191906001019062000261565b506200028c92915062000290565b5090565b620002ad91905b808211156200028c576000815560010162000297565b90565b612ced80620002c06000396000f3006080604052600436106101325763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301162b93811461013757806306fdde031461015a5780632ea9b696146101e45780633af32abf1461021957806347e7ef241461023a57806355246b9c1461025e5780635f02116f146102c757806361a9a8ca1461035557806365d96c82146103765780636eefcab9146103ca57806386bb8f37146103eb5780638f1d377614610406578063a5ba3b1e14610451578063a7aad3db14610475578063b42652e9146104ae578063bc4b010f146104cf578063c8187cf114610536578063dd4e7cfd1461054e578063e1e3f9151461056f578063f3fef3a3146105a0578063f96c8720146105c4578063fc0c546a14610619578063fce1ccca1461062e575b600080fd5b34801561014357600080fd5b50610158600160a060020a0360043516610643565b005b34801561016657600080fd5b5061016f610679565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101a9578181015183820152602001610191565b50505050905090810190601f1680156101d65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f057600080fd5b50610205600160a060020a0360043516610707565b604080519115158252519081900360200190f35b34801561022557600080fd5b50610205600160a060020a0360043516610843565b34801561024657600080fd5b50610158600160a060020a0360043516602435610869565b34801561026a57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610158948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a259650505050505050565b3480156102d357600080fd5b506040805160206004803580820135838102808601850190965280855261015895369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610a929650505050505050565b34801561036157600080fd5b50610205600160a060020a0360043516610b66565b34801561038257600080fd5b50610397600160a060020a0360043516610b82565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103d657600080fd5b50610205600160a060020a0360043516610bbd565b3480156103f757600080fd5b50610158600435602435610c08565b34801561041257600080fd5b5061041e600435610eda565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561045d57600080fd5b50610205600435600160a060020a0360243516610f16565b34801561048157600080fd5b5061049c600160a060020a0360043516602435604435610f44565b60408051918252519081900360200190f35b3480156104ba57600080fd5b50610158600160a060020a0360043516611013565b3480156104db57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261049c958335600160a060020a03169536956044949193909101919081908401838280828437509497506112029650505050505050565b34801561054257600080fd5b5061049c600435611af1565b34801561055a57600080fd5b50610205600160a060020a0360043516611d1d565b34801561057b57600080fd5b50610584611dbf565b60408051600160a060020a039092168252519081900360200190f35b3480156105ac57600080fd5b50610158600160a060020a0360043516602435611dce565b3480156105d057600080fd5b5060408051602060048035808201358381028086018501909652808552610158953695939460249493850192918291850190849080828437509497506121749650505050505050565b34801561062557600080fd5b506105846121ac565b34801561063a57600080fd5b506105846121bb565b61064c81611d1d565b1561065f5761065a816121ca565b610676565b61066881610707565b156101325761065a8161224e565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461072c83610bbd565b15156107a7576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561080e57600080fd5b505af1158015610822573d6000803e3d6000fd5b505050506040513d602081101561083857600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108e8576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d602081101561098e57600080fd5b505115156109d4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b82803b60008111610a80576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b610a8b8585856125ad565b5050505050565b8051825160009114610b14576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610b6157610b598382815181101515610b3257fe5b906020019060200201518383815181101515610b4a57fe5b90602001906020020151610c08565b600101610b18565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015610c01575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615610c7d576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff16151514610cf2576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b158015610d6657600080fd5b505af1158015610d7a573d6000803e3d6000fd5b505050506040513d6020811015610d9057600080fd5b50519150610d9f338585610f44565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b158015610e2d57600080fd5b505af1158015610e41573d6000803e3d6000fd5b505050506040513d6020811015610e5757600080fd5b50511515610e9d576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b158015610fcc57600080fd5b505af1158015610fe0573d6000803e3d6000fd5b505050506040513d6020811015610ff657600080fd5b505190508282820281151561100757fe5b04979650505050505050565b600160a060020a038082166000908152600160208190526040909120908101549091336101009092041614611092576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b61109b82610843565b1515611117576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600381015415806111455750600381015460009081526020819052604090206001015460a060020a900460ff165b15156111c1576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b6111ca82612a62565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b15801561129a57600080fd5b505af11580156112ae573d6000803e3d6000fd5b505050506040513d60208110156112c457600080fd5b505194506112d189610b66565b806112e05750600186015460ff165b1515611382576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806113b05750600386015460009081526020819052604090206001015460a060020a900460ff165b151561142c576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b848660020154101561147e5761144189612a62565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611ae5565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561150557600080fd5b505af1158015611519573d6000803e3d6000fd5b505050506040513d602081101561152f57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156115ab57600080fd5b505af11580156115bf573d6000803e3d6000fd5b505050506040513d60208110156115d557600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561165157600080fd5b505af1158015611665573d6000803e3d6000fd5b505050506040513d602081101561167b57600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b1580156116e057600080fd5b505af11580156116f4573d6000803e3d6000fd5b505050506040513d602081101561170a57600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e4840152925193975060649650909283926117fd9288926117f1928c926117e592600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b1580156117ac57600080fd5b505af11580156117c0573d6000803e3d6000fd5b505050506040513d60208110156117d657600080fd5b50518a9063ffffffff612c4416565b9063ffffffff612c5616565b9063ffffffff612c7f16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b15801561191657600080fd5b505af115801561192a573d6000803e3d6000fd5b505050506040513d602081101561194057600080fd5b50511515611986576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b1580156119ed57600080fd5b505af1158015611a01573d6000803e3d6000fd5b505050506040513d60a0811015611a1757600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611aa5578181015183820152602001611a8d565b50505050905090810190601f168015611ad25780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611b62576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015611bc957600080fd5b505af1158015611bdd573d6000803e3d6000fd5b505050506040513d6020811015611bf357600080fd5b50511515611c4b576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b158015611cb257600080fd5b505af1158015611cc6573d6000803e3d6000fd5b505050506040513d6020811015611cdc57600080fd5b50511515611cff5750600081815260208190526040902060029081015402610864565b50600090815260208190526040902080546002918201549091020390565b600160a060020a038116600090815260016020526040812060030154611d4283610b66565b8015611d655750600160a060020a03831660009081526001602052604090205442115b8015611d775750611d7583610843565b155b8015611da85750801580611da85750600081815260208190526040902060019081015460a060020a900460ff161515145b15611db6576001915061083d565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611e4d576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115611ecf576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b60038101541580611efd5750600381015460009081526020819052604090206001015460a060020a900460ff165b1561205257600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611f7c57600080fd5b505af1158015611f90573d6000803e3d6000fd5b505050506040513d6020811015611fa657600080fd5b505160028201548390031015612052576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156120b357600080fd5b505af11580156120c7573d6000803e3d6000fd5b505050506040513d60208110156120dd57600080fd5b50511515612123576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156121a8576121a0828281518110151561219157fe5b90602001906020020151610643565b600101612177565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561222557604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a0381166000908152600160205260408120600301549061227482611af1565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561230957600080fd5b505af115801561231d573d6000803e3d6000fd5b505050506040513d602081101561233357600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156123ad57600080fd5b505af11580156123c1573d6000803e3d6000fd5b505050506040513d60208110156123d757600080fd5b50511561245b576123e7836121ca565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610b61565b61246483612a62565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b1580156124c857600080fd5b505af11580156124dc573d6000803e3d6000fd5b505050506040513d60208110156124f257600080fd5b5051151561254a576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b60006125b884610843565b1561260d576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b61261684610b66565b15612691576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561270b57600080fd5b505af115801561271f573d6000803e3d6000fd5b505050506040513d602081101561273557600080fd5b50518310156127b4576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e000000000000000000000000000000000000006044830152915193956128a49592169363693ec85e9360648084019491938390030190829087803b15801561286b57600080fd5b505af115801561287f573d6000803e3d6000fd5b505050506040513d602081101561289557600080fd5b5051429063ffffffff612c9416565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b5051151561299b576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612a20578181015183820152602001612a08565b50505050905090810190601f168015612a4d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615612ac657604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2612afb565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115612c3e576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015612bbc57600080fd5b505af1158015612bd0573d6000803e3d6000fd5b505050506040513d6020811015612be657600080fd5b50511515612c3e576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600082821115612c5057fe5b50900390565b6000821515612c6757506000610f3e565b50818102818382811515612c7757fe5b0414610f3e57fe5b60008183811515612c8c57fe5b049392505050565b81810182811015610f3e57fe00546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a7230582009b5b072ae612c343edec7f7d8a7fbe1a0bf36c6024922a77b937617eb0e23960029", "deployedBytecode": "0x6080604052600436106101325763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166301162b93811461013757806306fdde031461015a5780632ea9b696146101e45780633af32abf1461021957806347e7ef241461023a57806355246b9c1461025e5780635f02116f146102c757806361a9a8ca1461035557806365d96c82146103765780636eefcab9146103ca57806386bb8f37146103eb5780638f1d377614610406578063a5ba3b1e14610451578063a7aad3db14610475578063b42652e9146104ae578063bc4b010f146104cf578063c8187cf114610536578063dd4e7cfd1461054e578063e1e3f9151461056f578063f3fef3a3146105a0578063f96c8720146105c4578063fc0c546a14610619578063fce1ccca1461062e575b600080fd5b34801561014357600080fd5b50610158600160a060020a0360043516610643565b005b34801561016657600080fd5b5061016f610679565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101a9578181015183820152602001610191565b50505050905090810190601f1680156101d65780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101f057600080fd5b50610205600160a060020a0360043516610707565b604080519115158252519081900360200190f35b34801561022557600080fd5b50610205600160a060020a0360043516610843565b34801561024657600080fd5b50610158600160a060020a0360043516602435610869565b34801561026a57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610158948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a259650505050505050565b3480156102d357600080fd5b506040805160206004803580820135838102808601850190965280855261015895369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610a929650505050505050565b34801561036157600080fd5b50610205600160a060020a0360043516610b66565b34801561038257600080fd5b50610397600160a060020a0360043516610b82565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103d657600080fd5b50610205600160a060020a0360043516610bbd565b3480156103f757600080fd5b50610158600435602435610c08565b34801561041257600080fd5b5061041e600435610eda565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561045d57600080fd5b50610205600435600160a060020a0360243516610f16565b34801561048157600080fd5b5061049c600160a060020a0360043516602435604435610f44565b60408051918252519081900360200190f35b3480156104ba57600080fd5b50610158600160a060020a0360043516611013565b3480156104db57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261049c958335600160a060020a03169536956044949193909101919081908401838280828437509497506112029650505050505050565b34801561054257600080fd5b5061049c600435611af1565b34801561055a57600080fd5b50610205600160a060020a0360043516611d1d565b34801561057b57600080fd5b50610584611dbf565b60408051600160a060020a039092168252519081900360200190f35b3480156105ac57600080fd5b50610158600160a060020a0360043516602435611dce565b3480156105d057600080fd5b5060408051602060048035808201358381028086018501909652808552610158953695939460249493850192918291850190849080828437509497506121749650505050505050565b34801561062557600080fd5b506105846121ac565b34801561063a57600080fd5b506105846121bb565b61064c81611d1d565b1561065f5761065a816121ca565b610676565b61066881610707565b156101325761065a8161224e565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ff5780601f106106d4576101008083540402835291602001916106ff565b820191906000526020600020905b8154815290600101906020018083116106e257829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461072c83610bbd565b15156107a7576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561080e57600080fd5b505af1158015610822573d6000803e3d6000fd5b505050506040513d602081101561083857600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108e8576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561096457600080fd5b505af1158015610978573d6000803e3d6000fd5b505050506040513d602081101561098e57600080fd5b505115156109d4576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b82803b60008111610a80576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b610a8b8585856125ad565b5050505050565b8051825160009114610b14576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610b6157610b598382815181101515610b3257fe5b906020019060200201518383815181101515610b4a57fe5b90602001906020020151610c08565b600101610b18565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015610c01575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615610c7d576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff16151514610cf2576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b158015610d6657600080fd5b505af1158015610d7a573d6000803e3d6000fd5b505050506040513d6020811015610d9057600080fd5b50519150610d9f338585610f44565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b158015610e2d57600080fd5b505af1158015610e41573d6000803e3d6000fd5b505050506040513d6020811015610e5757600080fd5b50511515610e9d576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b158015610fcc57600080fd5b505af1158015610fe0573d6000803e3d6000fd5b505050506040513d6020811015610ff657600080fd5b505190508282820281151561100757fe5b04979650505050505050565b600160a060020a038082166000908152600160208190526040909120908101549091336101009092041614611092576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b61109b82610843565b1515611117576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600381015415806111455750600381015460009081526020819052604090206001015460a060020a900460ff165b15156111c1576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b6111ca82612a62565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b15801561129a57600080fd5b505af11580156112ae573d6000803e3d6000fd5b505050506040513d60208110156112c457600080fd5b505194506112d189610b66565b806112e05750600186015460ff165b1515611382576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806113b05750600386015460009081526020819052604090206001015460a060020a900460ff165b151561142c576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b848660020154101561147e5761144189612a62565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611ae5565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561150557600080fd5b505af1158015611519573d6000803e3d6000fd5b505050506040513d602081101561152f57600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156115ab57600080fd5b505af11580156115bf573d6000803e3d6000fd5b505050506040513d60208110156115d557600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561165157600080fd5b505af1158015611665573d6000803e3d6000fd5b505050506040513d602081101561167b57600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b1580156116e057600080fd5b505af11580156116f4573d6000803e3d6000fd5b505050506040513d602081101561170a57600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e4840152925193975060649650909283926117fd9288926117f1928c926117e592600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b1580156117ac57600080fd5b505af11580156117c0573d6000803e3d6000fd5b505050506040513d60208110156117d657600080fd5b50518a9063ffffffff612c4416565b9063ffffffff612c5616565b9063ffffffff612c7f16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b15801561191657600080fd5b505af115801561192a573d6000803e3d6000fd5b505050506040513d602081101561194057600080fd5b50511515611986576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b1580156119ed57600080fd5b505af1158015611a01573d6000803e3d6000fd5b505050506040513d60a0811015611a1757600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611aa5578181015183820152602001611a8d565b50505050905090810190601f168015611ad25780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611b62576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015611bc957600080fd5b505af1158015611bdd573d6000803e3d6000fd5b505050506040513d6020811015611bf357600080fd5b50511515611c4b576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b158015611cb257600080fd5b505af1158015611cc6573d6000803e3d6000fd5b505050506040513d6020811015611cdc57600080fd5b50511515611cff5750600081815260208190526040902060029081015402610864565b50600090815260208190526040902080546002918201549091020390565b600160a060020a038116600090815260016020526040812060030154611d4283610b66565b8015611d655750600160a060020a03831660009081526001602052604090205442115b8015611d775750611d7583610843565b155b8015611da85750801580611da85750600081815260208190526040902060019081015460a060020a900460ff161515145b15611db6576001915061083d565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611e4d576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115611ecf576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b60038101541580611efd5750600381015460009081526020819052604090206001015460a060020a900460ff165b1561205257600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611f7c57600080fd5b505af1158015611f90573d6000803e3d6000fd5b505050506040513d6020811015611fa657600080fd5b505160028201548390031015612052576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156120b357600080fd5b505af11580156120c7573d6000803e3d6000fd5b505050506040513d60208110156120dd57600080fd5b50511515612123576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156121a8576121a0828281518110151561219157fe5b90602001906020020151610643565b600101612177565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561222557604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a0381166000908152600160205260408120600301549061227482611af1565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561230957600080fd5b505af115801561231d573d6000803e3d6000fd5b505050506040513d602081101561233357600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156123ad57600080fd5b505af11580156123c1573d6000803e3d6000fd5b505050506040513d60208110156123d757600080fd5b50511561245b576123e7836121ca565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610b61565b61246483612a62565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b1580156124c857600080fd5b505af11580156124dc573d6000803e3d6000fd5b505050506040513d60208110156124f257600080fd5b5051151561254a576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b60006125b884610843565b1561260d576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b61261684610b66565b15612691576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561270b57600080fd5b505af115801561271f573d6000803e3d6000fd5b505050506040513d602081101561273557600080fd5b50518310156127b4576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e000000000000000000000000000000000000006044830152915193956128a49592169363693ec85e9360648084019491938390030190829087803b15801561286b57600080fd5b505af115801561287f573d6000803e3d6000fd5b505050506040513d602081101561289557600080fd5b5051429063ffffffff612c9416565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b15801561292b57600080fd5b505af115801561293f573d6000803e3d6000fd5b505050506040513d602081101561295557600080fd5b5051151561299b576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612ca2833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612a20578181015183820152602001612a08565b50505050905090810190601f168015612a4d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b600160a060020a0381166000908152600160208190526040822090810154909190819060ff1615612ac657604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a2612afb565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff19169055928501839055600390940182905561010090920490921691811115612c3e576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b158015612bbc57600080fd5b505af1158015612bd0573d6000803e3d6000fd5b505050506040513d6020811015612be657600080fd5b50511515612c3e576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b600082821115612c5057fe5b50900390565b6000821515612c6757506000610f3e565b50818102818382811515612c7757fe5b0414610f3e57fe5b60008183811515612c8c57fe5b049392505050565b81810182811015610f3e57fe00546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a7230582009b5b072ae612c343edec7f7d8a7fbe1a0bf36c6024922a77b937617eb0e23960029", "abi": [ { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "updateStatus", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "isWhitelisted", "outputs": [ { "name": "whitelisted", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "deposit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appWasMade", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "listings", "outputs": [ { "name": "applicationExpiry", "type": "uint256" }, { "name": "whitelisted", "type": "bool" }, { "name": "owner", "type": "address" }, { "name": "unstakedDeposit", "type": "uint256" }, { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "totalTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "exit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_data", "type": "string" } ], "name": "challenge", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" } ], "name": "determineReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "canBeWhitelisted", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "parameterizer", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddresses", "type": "address[]" } ], "name": "updateStatuses", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_token", "type": "address" }, { "name": "_voting", "type": "address" }, { "name": "_parameterizer", "type": "address" }, { "name": "_name", "type": "string" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": true, "name": "applicant", "type": "address" } ], "name": "_Application", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_Challenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "added", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "withdrew", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Withdrawal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationWhitelisted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_TouchAndRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "amount", "type": "uint256" }, { "name": "data", "type": "string" } ], "name": "apply", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/CreateNewsroomInGroup.json ================================================ { "contractName": "CreateNewsroomInGroup", "bytecode": "0x608060405234801561001057600080fd5b5060405160408061056383398101604052805160209091015160008054600160a060020a03938416600160a060020a031991821617909155600180549390921692169190911790556104fc806100676000396000f3006080604052600436106100405763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166360bb9dab8114610045575b600080fd5b34801561005157600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011e94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020808901358a01803580830284810184018652818552999c8b359c909b909a95019850929650810194509092508291908501908490808284375094975050933594506101479350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60008083511115156101e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f696e697469616c4f776e657273206d7573742068617665206174206c6561737460448201527f206f6e65206d656d626572000000000000000000000000000000000000000000606482015290519081900360840190fd5b600080546040517f60bb9dab000000000000000000000000000000000000000000000000000000008152604481018790526084810185905260a060048201908152895160a4830152895173ffffffffffffffffffffffffffffffffffffffff909316936360bb9dab938b938b938b938b938b9383926024820192606483019260c4019160208c0191908190849084905b83811015610288578181015183820152602001610270565b50505050905090810190601f1680156102b55780820380516001836020036101000a031916815260200191505b5084810383528851815288516020918201918a019080838360005b838110156102e85781810151838201526020016102d0565b50505050905090810190601f1680156103155780820380516001836020036101000a031916815260200191505b508481038252865181528651602091820191808901910280838360005b8381101561034a578181015183820152602001610332565b5050505090500198505050505050505050602060405180830381600087803b15801561037557600080fd5b505af1158015610389573d6000803e3d6000fd5b505050506040513d602081101561039f57600080fd5b5051600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905192935073ffffffffffffffffffffffffffffffffffffffff9182169263607c60bb92851691638da5cb5b9160048083019260209291908290030181600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050506040513d602081101561044357600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff851602815273ffffffffffffffffffffffffffffffffffffffff909216600483015251602480830192600092919082900301818387803b1580156104af57600080fd5b505af11580156104c3573d6000803e3d6000fd5b50505050959450505050505600a165627a7a7230582020e80a80750a59f561c2e5f3958cab326c2079b79ceb08cb2cc80b234b7ed1360029", "deployedBytecode": "0x6080604052600436106100405763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166360bb9dab8114610045575b600080fd5b34801561005157600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011e94369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020808901358a01803580830284810184018652818552999c8b359c909b909a95019850929650810194509092508291908501908490808284375094975050933594506101479350505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b60008083511115156101e057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f696e697469616c4f776e657273206d7573742068617665206174206c6561737460448201527f206f6e65206d656d626572000000000000000000000000000000000000000000606482015290519081900360840190fd5b600080546040517f60bb9dab000000000000000000000000000000000000000000000000000000008152604481018790526084810185905260a060048201908152895160a4830152895173ffffffffffffffffffffffffffffffffffffffff909316936360bb9dab938b938b938b938b938b9383926024820192606483019260c4019160208c0191908190849084905b83811015610288578181015183820152602001610270565b50505050905090810190601f1680156102b55780820380516001836020036101000a031916815260200191505b5084810383528851815288516020918201918a019080838360005b838110156102e85781810151838201526020016102d0565b50505050905090810190601f1680156103155780820380516001836020036101000a031916815260200191505b508481038252865181528651602091820191808901910280838360005b8381101561034a578181015183820152602001610332565b5050505090500198505050505050505050602060405180830381600087803b15801561037557600080fd5b505af1158015610389573d6000803e3d6000fd5b505050506040513d602081101561039f57600080fd5b5051600154604080517f8da5cb5b000000000000000000000000000000000000000000000000000000008152905192935073ffffffffffffffffffffffffffffffffffffffff9182169263607c60bb92851691638da5cb5b9160048083019260209291908290030181600087803b15801561041957600080fd5b505af115801561042d573d6000803e3d6000fd5b505050506040513d602081101561044357600080fd5b5051604080517c010000000000000000000000000000000000000000000000000000000063ffffffff851602815273ffffffffffffffffffffffffffffffffffffffff909216600483015251602480830192600092919082900301818387803b1580156104af57600080fd5b505af11580156104c3573d6000803e3d6000fd5b50505050959450505050505600a165627a7a7230582020e80a80750a59f561c2e5f3958cab326c2079b79ceb08cb2cc80b234b7ed1360029", "abi": [ { "inputs": [ { "name": "_factory", "type": "address" }, { "name": "_controller", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "constant": false, "inputs": [ { "name": "name", "type": "string" }, { "name": "charterUri", "type": "string" }, { "name": "charterHash", "type": "bytes32" }, { "name": "initialOwners", "type": "address[]" }, { "name": "initialRequired", "type": "uint256" } ], "name": "create", "outputs": [ { "name": "newsroom", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x870188243e72210d2b9a276be411fd4f32c8eb40", "transactionHash": "0x2908b0b0a2abd60525c3eac018a7f5290c7ec453966e05a283f3d6a22a8e61c2" }, "4": { "events": {}, "links": {}, "address": "0x49d731e07c37f2e6eb9022a14b4198dbccc4452a", "transactionHash": "0x3bb3cba57c23fbbff8de793ef4bebc562495ef82ff99d906911d1914aa5f8c25" } } } ================================================ FILE: packages/artifacts/v1/DLL.json ================================================ { "contractName": "DLL", "bytecode": "0x610369610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600436106100a45763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166307d29ac981146100a957806330fe0a0a146100c9578063366a5ba2146100d75780636d900ed0146100f95780637c11cf64146101165780639735c51b14610121578063c426b00614610142578063ee4f1ac41461014d575b600080fd5b6100b7600435602435610158565b60408051918252519081900360200190f35b6100b760043560243561016b565b6100e5600435602435610181565b604080519115158252519081900360200190f35b81801561010557600080fd5b506101146004356024356101ff565b005b6100b7600435610261565b81801561012d57600080fd5b50610114600435602435604435606435610274565b6100e560043561031d565b6100b7600435610330565b6000908152602091909152604090205490565b6000908152602091909152604090206001015490565b600080600061018f8561031d565b80610198575083155b156101a657600092506101f7565b836101b086610330565b1480156101c45750836101c286610261565b145b915060006101d28686610158565b1480156101e8575060006101e6868661016b565b145b905081806101f4575080155b92505b505092915050565b60008061020c8484610181565b15156102175761025b565b6102218484610158565b915061022d848461016b565b6000838152602086905260408082206001908101849055838352818320869055868352908220828155015590505b50505050565b600061026e82600061016b565b92915050565b81151561028057600080fd5b61028a84836101ff565b82158061029c575061029c8484610181565b15156102a757600080fd5b8015806102b957506102b98482610181565b15156102c457600080fd5b806102cf8585610158565b146102d957600080fd5b826102e4858361016b565b146102ee57600080fd5b600082815260209490945260408085206001808201869055908390559385528085208390559084529092200155565b60008061032983610330565b1492915050565b600061026e8260006101585600a165627a7a72305820c3dc97a814bfbdde2012e6b0f81874a811b3bf4c31a4e7c101760b3a6e4c4bdf0029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100a45763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166307d29ac981146100a957806330fe0a0a146100c9578063366a5ba2146100d75780636d900ed0146100f95780637c11cf64146101165780639735c51b14610121578063c426b00614610142578063ee4f1ac41461014d575b600080fd5b6100b7600435602435610158565b60408051918252519081900360200190f35b6100b760043560243561016b565b6100e5600435602435610181565b604080519115158252519081900360200190f35b81801561010557600080fd5b506101146004356024356101ff565b005b6100b7600435610261565b81801561012d57600080fd5b50610114600435602435604435606435610274565b6100e560043561031d565b6100b7600435610330565b6000908152602091909152604090205490565b6000908152602091909152604090206001015490565b600080600061018f8561031d565b80610198575083155b156101a657600092506101f7565b836101b086610330565b1480156101c45750836101c286610261565b145b915060006101d28686610158565b1480156101e8575060006101e6868661016b565b145b905081806101f4575080155b92505b505092915050565b60008061020c8484610181565b15156102175761025b565b6102218484610158565b915061022d848461016b565b6000838152602086905260408082206001908101849055838352818320869055868352908220828155015590505b50505050565b600061026e82600061016b565b92915050565b81151561028057600080fd5b61028a84836101ff565b82158061029c575061029c8484610181565b15156102a757600080fd5b8015806102b957506102b98482610181565b15156102c457600080fd5b806102cf8585610158565b146102d957600080fd5b826102e4858361016b565b146102ee57600080fd5b600082815260209490945260408085206001808201869055908390559385528085208390559084529092200155565b60008061032983610330565b1492915050565b600061026e8260006101585600a165627a7a72305820c3dc97a814bfbdde2012e6b0f81874a811b3bf4c31a4e7c101760b3a6e4c4bdf0029", "abi": [ { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" } ], "name": "isEmpty", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" }, { "name": "_curr", "type": "uint256" } ], "name": "contains", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" }, { "name": "_curr", "type": "uint256" } ], "name": "getNext", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" }, { "name": "_curr", "type": "uint256" } ], "name": "getPrev", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" } ], "name": "getStart", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "self", "type": "DLL.Data storage" } ], "name": "getEnd", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "DLL.Data storage" }, { "name": "_prev", "type": "uint256" }, { "name": "_curr", "type": "uint256" }, { "name": "_next", "type": "uint256" } ], "name": "insert", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "DLL.Data storage" }, { "name": "_curr", "type": "uint256" } ], "name": "remove", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x739f1745e415782861373c5ff1a6dc56d2d41451", "transactionHash": "0x3df1e3ecf9e6df6c8e4a96431cf90e855940819003e8278765923f017e9311c3" }, "4": { "events": {}, "links": {}, "address": "0x132f69eb9416cf555cc16e21fb0bbd21f38947c0", "transactionHash": "0x5dc8e17f9ba17cb2a54c1aafd69d8ff58e27e40945ba2951758120a77683fe9d" } } } ================================================ FILE: packages/artifacts/v1/DummyACL.json ================================================ { "contractName": "DummyACL", "bytecode": "0x608060405234801561001057600080fd5b5060008054600160a060020a031916331790556107c8806100326000396000f30060806040526004361061008d5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631bfe03088114610092578063217fe6c6146100fb5780632f54bf6e146101765780633ad554d014610197578063715018a6146102215780637d72aa65146102365780638da5cb5b1461029d578063f2fde38b146102ce575b600080fd5b34801561009e57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100f9958335600160a060020a03169536956044949193909101919081908401838280828437509497506102ef9650505050505050565b005b34801561010757600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610162958335600160a060020a03169536956044949193909101919081908401838280828437509497506103569650505050505050565b604080519115158252519081900360200190f35b34801561018257600080fd5b50610162600160a060020a03600435166103da565b3480156101a357600080fd5b506101ac6103ee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101e65781810151838201526020016101ce565b50505050905090810190601f1680156102135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561022d57600080fd5b506100f9610425565b34801561024257600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100f9958335600160a060020a03169536956044949193909101919081908401838280828437509497506104919650505050505050565b3480156102a957600080fd5b506102b26104f3565b60408051600160a060020a039092168252519081900360200190f35b3480156102da57600080fd5b506100f9600160a060020a0360043516610502565b60408051808201909152600881527f74657374726f6c65000000000000000000000000000000000000000000000000602082015261032c336103da565b8061033c575061033c3382610356565b151561034757600080fd5b6103518383610525565b505050565b60006001826040518082805190602001908083835b6020831061038a5780518252601f19909201916020918201910161036b565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60408051808201909152600881527f74657374726f6c65000000000000000000000000000000000000000000000000602082015281565b600054600160a060020a0316331461043c57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60408051808201909152600881527f74657374726f6c6500000000000000000000000000000000000000000000000060208201526104ce336103da565b806104de57506104de3382610356565b15156104e957600080fd5b610351838361063f565b600054600160a060020a031681565b600054600160a060020a0316331461051957600080fd5b6105228161071f565b50565b6001816040518082805190602001908083835b602083106105575780518252601f199092019160209182019101610538565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b838110156106015781810151838201526020016105e9565b50505050905090810190601f16801561062e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b600180826040518082805190602001908083835b602083106106725780518252601f199092019160209182019101610653565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed96508995509384938401929086019190819084908490838110156106015781810151838201526020016105e9565b600160a060020a038116151561073457600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a723058201421ccdf0c904fb3153c11d645e2964674a679dbfc554483108975e2707d2cd20029", "deployedBytecode": "0x60806040526004361061008d5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631bfe03088114610092578063217fe6c6146100fb5780632f54bf6e146101765780633ad554d014610197578063715018a6146102215780637d72aa65146102365780638da5cb5b1461029d578063f2fde38b146102ce575b600080fd5b34801561009e57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100f9958335600160a060020a03169536956044949193909101919081908401838280828437509497506102ef9650505050505050565b005b34801561010757600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610162958335600160a060020a03169536956044949193909101919081908401838280828437509497506103569650505050505050565b604080519115158252519081900360200190f35b34801561018257600080fd5b50610162600160a060020a03600435166103da565b3480156101a357600080fd5b506101ac6103ee565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101e65781810151838201526020016101ce565b50505050905090810190601f1680156102135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561022d57600080fd5b506100f9610425565b34801561024257600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100f9958335600160a060020a03169536956044949193909101919081908401838280828437509497506104919650505050505050565b3480156102a957600080fd5b506102b26104f3565b60408051600160a060020a039092168252519081900360200190f35b3480156102da57600080fd5b506100f9600160a060020a0360043516610502565b60408051808201909152600881527f74657374726f6c65000000000000000000000000000000000000000000000000602082015261032c336103da565b8061033c575061033c3382610356565b151561034757600080fd5b6103518383610525565b505050565b60006001826040518082805190602001908083835b6020831061038a5780518252601f19909201916020918201910161036b565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60408051808201909152600881527f74657374726f6c65000000000000000000000000000000000000000000000000602082015281565b600054600160a060020a0316331461043c57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b60408051808201909152600881527f74657374726f6c6500000000000000000000000000000000000000000000000060208201526104ce336103da565b806104de57506104de3382610356565b15156104e957600080fd5b610351838361063f565b600054600160a060020a031681565b600054600160a060020a0316331461051957600080fd5b6105228161071f565b50565b6001816040518082805190602001908083835b602083106105575780518252601f199092019160209182019101610538565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b838110156106015781810151838201526020016105e9565b50505050905090810190601f16801561062e5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b600180826040518082805190602001908083835b602083106106725780518252601f199092019160209182019101610653565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed96508995509384938401929086019190819084908490838110156106015781810151838201526020016105e9565b600160a060020a038116151561073457600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a723058201421ccdf0c904fb3153c11d645e2964674a679dbfc554483108975e2707d2cd20029", "abi": [ { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "role", "type": "string" } ], "name": "hasRole", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" } ], "name": "isOwner", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "TEST_ROLE", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": false, "inputs": [ { "name": "who", "type": "address" }, { "name": "what", "type": "string" } ], "name": "addRole", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "who", "type": "address" }, { "name": "what", "type": "string" } ], "name": "removeRole", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/DummyTokenTelemetry.json ================================================ { "contractName": "DummyTokenTelemetry", "bytecode": "0x608060405234801561001057600080fd5b5060a38061001f6000396000f300608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416637252487381146043575b600080fd5b348015604e57600080fd5b50607173ffffffffffffffffffffffffffffffffffffffff600435166024356073565b005b50505600a165627a7a7230582089d5d5be2c07c845a1d0213c3930ca84eb4ed8af463b6d8fced6c457ad012ae40029", "deployedBytecode": "0x608060405260043610603e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416637252487381146043575b600080fd5b348015604e57600080fd5b50607173ffffffffffffffffffffffffffffffffffffffff600435166024356073565b005b50505600a165627a7a7230582089d5d5be2c07c845a1d0213c3930ca84eb4ed8af463b6d8fced6c457ad012ae40029", "abi": [ { "constant": false, "inputs": [ { "name": "user", "type": "address" }, { "name": "tokenAmount", "type": "uint256" } ], "name": "onRequestVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/ECRecovery.json ================================================ { "contractName": "ECRecovery", "bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a723058207908cba412f3804a638418afca8c553575433d1929b9fbfed8c7d69eed359dc60029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fd00a165627a7a723058207908cba412f3804a638418afca8c553575433d1929b9fbfed8c7d69eed359dc60029", "abi": [], "networks": { "1": { "events": {}, "links": {}, "address": "0x944712803bc20ac97464a5130f624f125d1fa4c2", "transactionHash": "0xbf6d7c02c5a9d008b5b7c5dbfa76dc08bb0d5f16dd492ffb10bd98115e4aab2a" }, "4": { "events": {}, "links": {}, "address": "0xb01f514594b731da26ba9cac6977c3f5395b2891", "transactionHash": "0x13aa22f9b40fa8381bf283db30bd75499c77e43c61c5dfd3dd443941cc7b84a1" } } } ================================================ FILE: packages/artifacts/v1/ERC1404.json ================================================ { "contractName": "ERC1404", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "constant": true, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "detectTransferRestriction", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "restrictionCode", "type": "uint8" } ], "name": "messageForTransferRestriction", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/ERC20.json ================================================ { "contractName": "ERC20", "bytecode": "0x608060405234801561001057600080fd5b50610535806100206000396000f30060806040526004361061008d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663095ea7b3811461009257806318160ddd146100ca57806323b872dd146100f1578063395093511461011b57806370a082311461013f578063a457c2d714610160578063a9059cbb14610184578063dd62ed3e146101a8575b600080fd5b34801561009e57600080fd5b506100b6600160a060020a03600435166024356101cf565b604080519115158252519081900360200190f35b3480156100d657600080fd5b506100df61024d565b60408051918252519081900360200190f35b3480156100fd57600080fd5b506100b6600160a060020a0360043581169060243516604435610253565b34801561012757600080fd5b506100b6600160a060020a03600435166024356102c0565b34801561014b57600080fd5b506100df600160a060020a0360043516610370565b34801561016c57600080fd5b506100b6600160a060020a036004351660243561038b565b34801561019057600080fd5b506100b6600160a060020a03600435166024356103d6565b3480156101b457600080fd5b506100df600160a060020a03600435811690602435166103ec565b6000600160a060020a03831615156101e657600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600160a060020a0383166000908152600160209081526040808320338452909152812054610287908363ffffffff61041716565b600160a060020a03851660009081526001602090815260408083203384529091529020556102b6848484610429565b5060019392505050565b6000600160a060020a03831615156102d757600080fd5b336000908152600160209081526040808320600160a060020a038716845290915290205461030b908363ffffffff6104f616565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a031660009081526020819052604090205490565b6000600160a060020a03831615156103a257600080fd5b336000908152600160209081526040808320600160a060020a038716845290915290205461030b908363ffffffff61041716565b60006103e3338484610429565b50600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b60008282111561042357fe5b50900390565b600160a060020a038216151561043e57600080fd5b600160a060020a038316600090815260208190526040902054610467908263ffffffff61041716565b600160a060020a03808516600090815260208190526040808220939093559084168152205461049c908263ffffffff6104f616565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b8181018281101561050357fe5b929150505600a165627a7a7230582037c6c2ff5a4e8f47ff5a68e8e7186424f545994cc301b2c864d2ed93e7f7fdcf0029", "deployedBytecode": "0x60806040526004361061008d5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663095ea7b3811461009257806318160ddd146100ca57806323b872dd146100f1578063395093511461011b57806370a082311461013f578063a457c2d714610160578063a9059cbb14610184578063dd62ed3e146101a8575b600080fd5b34801561009e57600080fd5b506100b6600160a060020a03600435166024356101cf565b604080519115158252519081900360200190f35b3480156100d657600080fd5b506100df61024d565b60408051918252519081900360200190f35b3480156100fd57600080fd5b506100b6600160a060020a0360043581169060243516604435610253565b34801561012757600080fd5b506100b6600160a060020a03600435166024356102c0565b34801561014b57600080fd5b506100df600160a060020a0360043516610370565b34801561016c57600080fd5b506100b6600160a060020a036004351660243561038b565b34801561019057600080fd5b506100b6600160a060020a03600435166024356103d6565b3480156101b457600080fd5b506100df600160a060020a03600435811690602435166103ec565b6000600160a060020a03831615156101e657600080fd5b336000818152600160209081526040808320600160a060020a03881680855290835292819020869055805186815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a350600192915050565b60025490565b600160a060020a0383166000908152600160209081526040808320338452909152812054610287908363ffffffff61041716565b600160a060020a03851660009081526001602090815260408083203384529091529020556102b6848484610429565b5060019392505050565b6000600160a060020a03831615156102d757600080fd5b336000908152600160209081526040808320600160a060020a038716845290915290205461030b908363ffffffff6104f616565b336000818152600160209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a031660009081526020819052604090205490565b6000600160a060020a03831615156103a257600080fd5b336000908152600160209081526040808320600160a060020a038716845290915290205461030b908363ffffffff61041716565b60006103e3338484610429565b50600192915050565b600160a060020a03918216600090815260016020908152604080832093909416825291909152205490565b60008282111561042357fe5b50900390565b600160a060020a038216151561043e57600080fd5b600160a060020a038316600090815260208190526040902054610467908263ffffffff61041716565b600160a060020a03808516600090815260208190526040808220939093559084168152205461049c908263ffffffff6104f616565b600160a060020a038084166000818152602081815260409182902094909455805185815290519193928716927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef92918290030190a3505050565b8181018281101561050357fe5b929150505600a165627a7a7230582037c6c2ff5a4e8f47ff5a68e8e7186424f545994cc301b2c864d2ed93e7f7fdcf0029", "abi": [ { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" }, { "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/ERC20Detailed.json ================================================ { "contractName": "ERC20Detailed", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "who", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" }, { "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "name", "type": "string" }, { "name": "symbol", "type": "string" }, { "name": "decimals", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "symbol", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "decimals", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/EventStorage.json ================================================ { "contractName": "EventStorage", "bytecode": "0x608060405234801561001057600080fd5b506101bc806100206000396000f3006080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663131a06808114610045575b600080fd5b34801561005157600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261009e9436949293602493928401919081908401838280828437509497506100a09650505050505050565b005b806040518082805190602001908083835b602083106100d05780518252601f1990920191602091820191016100b1565b51815160209384036101000a60001901801990921691161790526040805192909401829003822081835287518383015287519096507f2162a3c4a129c520b65f2837a045d97d2119710c87276c5ca08ed28155daa13a95508794929350839283019185019080838360005b8381101561015357818101518382015260200161013b565b50505050905090810190601f1680156101805780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505600a165627a7a72305820d317eab53c4c69e58b5e68e4360454842082a7998c37d283f042ae7a62c414c80029", "deployedBytecode": "0x6080604052600436106100405763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663131a06808114610045575b600080fd5b34801561005157600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261009e9436949293602493928401919081908401838280828437509497506100a09650505050505050565b005b806040518082805190602001908083835b602083106100d05780518252601f1990920191602091820191016100b1565b51815160209384036101000a60001901801990921691161790526040805192909401829003822081835287518383015287519096507f2162a3c4a129c520b65f2837a045d97d2119710c87276c5ca08ed28155daa13a95508794929350839283019185019080838360005b8381101561015357818101518382015260200161013b565b50505050905090810190601f1680156101805780820380516001836020036101000a031916815260200191505b509250505060405180910390a2505600a165627a7a72305820d317eab53c4c69e58b5e68e4360454842082a7998c37d283f042ae7a62c414c80029", "abi": [ { "anonymous": false, "inputs": [ { "indexed": true, "name": "dataHash", "type": "bytes32" }, { "indexed": false, "name": "data", "type": "string" } ], "name": "StringStored", "type": "event" }, { "constant": false, "inputs": [ { "name": "data", "type": "string" } ], "name": "store", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0xe649d7dbefa1111f0614d418ff06e895313cba6a", "transactionHash": "0xfe7934cadf19f7ea6ba329b04dc63e2268e1295a59a18569bfb4686b706e4914" }, "4": { "events": {}, "links": {}, "address": "0x7e858704d81a72d908a81ce4fedbb5be3fc99d53", "transactionHash": "0xd4266421e9bc775eca7fabe2f38431ea1414b94cacd06109e2f7e80b2a217ce7" } } } ================================================ FILE: packages/artifacts/v1/Factory.json ================================================ { "contractName": "Factory", "bytecode": "0x608060405234801561001057600080fd5b506101e4806100206000396000f3006080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811461005b57806357183c821461009d5780638f838478146100f7575b600080fd5b34801561006757600080fd5b5061008973ffffffffffffffffffffffffffffffffffffffff60043516610137565b604080519115158252519081900360200190f35b3480156100a957600080fd5b506100ce73ffffffffffffffffffffffffffffffffffffffff6004351660243561014c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561010357600080fd5b5061012573ffffffffffffffffffffffffffffffffffffffff60043516610190565b60408051918252519081900360200190f35b60006020819052908152604090205460ff1681565b60016020528160005260406000208181548110151561016757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260016020526040902054905600a165627a7a723058205a2875f8d6cc23a6354fba88ca79d49079e026f47111ab476da3aad2b58dca190029", "deployedBytecode": "0x6080604052600436106100565763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811461005b57806357183c821461009d5780638f838478146100f7575b600080fd5b34801561006757600080fd5b5061008973ffffffffffffffffffffffffffffffffffffffff60043516610137565b604080519115158252519081900360200190f35b3480156100a957600080fd5b506100ce73ffffffffffffffffffffffffffffffffffffffff6004351660243561014c565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561010357600080fd5b5061012573ffffffffffffffffffffffffffffffffffffffff60043516610190565b60408051918252519081900360200190f35b60006020819052908152604090205460ff1681565b60016020528160005260406000208181548110151561016757fe5b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff169150829050565b73ffffffffffffffffffffffffffffffffffffffff16600090815260016020526040902054905600a165627a7a723058205a2875f8d6cc23a6354fba88ca79d49079e026f47111ab476da3aad2b58dca190029", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "isInstantiation", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" }, { "name": "", "type": "uint256" } ], "name": "instantiations", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "instantiation", "type": "address" } ], "name": "ContractInstantiation", "type": "event" }, { "constant": true, "inputs": [ { "name": "creator", "type": "address" } ], "name": "getInstantiationCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/Government.json ================================================ { "contractName": "Government", "bytecode": "0x608060405262093a806007553480156200001857600080fd5b5060405162001c6638038062001c6683398101604090815281516020830151918301516060840151608085015160a086015160c087015160e08801516101008901516101208a01516101408b01516101608c01516101808d01519a9c999a98999798969795969495939492939192909101600160a060020a038d1615156200010157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f617070656c6c6174654164647220616464726573732069732030000000000000604482015290519081900360640190fd5b600160a060020a038c1615156200017957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f676f7665726e6d656e74436f6e74726f6c6c6572416464722069732030000000604482015290519081900360640190fd5b8c6000806101000a815481600160a060020a030219169083600160a060020a031602179055508b600160006101000a815481600160a060020a030219169083600160a060020a031602179055508a600660006101000a815481600160a060020a030219169083600160a060020a031602179055506200023d6040805190810160405280601081526020017f7265717565737441707065616c4c656e000000000000000000000000000000008152508a6200044f640100000000026401000000009004565b60408051808201909152600e81527f6a7564676541707065616c4c656e00000000000000000000000000000000000060208201526200028690896401000000006200044f810204565b60408051808201909152600981527f61707065616c46656500000000000000000000000000000000000000000000006020820152620002cf908b6401000000006200044f810204565b60408051808201909152601481527f61707065616c566f746550657263656e7461676500000000000000000000000060208201526200031890886401000000006200044f810204565b6200038f606060405190810160405280602281526020017f61707065616c4368616c6c656e6765566f746544697370656e736174696f6e5081526020017f6374000000000000000000000000000000000000000000000000000000000000815250876200044f640100000000026401000000009004565b60408051808201909152601381527f676f767450436f6d6d697453746167654c656e000000000000000000000000006020820152620003d890856401000000006200044f810204565b60408051808201909152601381527f676f76745052657665616c53746167654c656e0000000000000000000000000060208201526200042190846401000000006200044f810204565b600282905580516200043b90600390602084019062000575565b50505050505050505050505050506200061a565b8060046000846040518082805190602001908083835b60208310620004865780518252601f19909201916020918201910162000465565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055507f0e92bd4b74871caaf73a4a51ca5ad4f01e5c5215e940a2f2a1f4c755b955066c82826040518080602001838152602001828103825284818151815260200191508051906020019080838360005b83811015620005355781810151838201526020016200051b565b50505050905090810190601f168015620005635780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620005b857805160ff1916838001178555620005e8565b82800160010185558215620005e8579182015b82811115620005e8578251825591602001919060010190620005cb565b50620005f6929150620005fa565b5090565b6200061791905b80821115620005f6576000815560010162000601565b90565b61163c806200062a6000396000f3006080604052600436106100ef5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100f457806330490e911461011b57806332ed5b121461013557806335300990146101da578063551224251461020657806356e1fb88146102275780635793b9cf14610258578063693ec85e1461026d5780638ca7f51c146102c6578063b0924d6e14610350578063bade1c54146103ae578063c7d93fd414610409578063d5fd9e661461041e578063dc6ab52714610433578063f2a2129b1461044b578063fce1ccca14610460578063ffa1bdf014610475575b600080fd5b34801561010057600080fd5b5061010961048d565b60408051918252519081900360200190f35b34801561012757600080fd5b50610133600435610493565b005b34801561014157600080fd5b5061014d6004356104ad565b6040518085815260200180602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561019c578181015183820152602001610184565b50505050905090810190601f1680156101c95780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156101e657600080fd5b506101f2600435610560565b604080519115158252519081900360200190f35b34801561021257600080fd5b50610133600160a060020a0360043516610576565b34801561023357600080fd5b5061023c6106e5565b60408051600160a060020a039092168252519081900360200190f35b34801561026457600080fd5b5061023c6106f5565b34801561027957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101099436949293602493928401919081908401838280828437509497506107049650505050505050565b3480156102d257600080fd5b506102db61077b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103155781810151838201526020016102fd565b50505050905090810190601f1680156103425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561035c57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101339583359536956044949193909101919081908401838280828437509497506108099650505050505050565b3480156103ba57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610109943694929360249392840191908190840183828082843750949750509335945061092b9350505050565b34801561041557600080fd5b50610109610ffd565b34801561042a57600080fd5b5061023c611003565b34801561043f57600080fd5b50610109600435611012565b34801561045757600080fd5b5061023c611024565b34801561046c57600080fd5b5061023c611033565b34801561048157600080fd5b506101f2600435611042565b60075481565b61049c81611042565b156100ef576104aa816111c6565b50565b6005602090815260009182526040918290208054600180830180548651600293821615610100026000190190911692909204601f81018690048602830186019096528582529194929390929083018282801561054a5780601f1061051f5761010080835404028352916020019161054a565b820191906000526020600020905b81548152906001019060200180831161052d57829003601f168201915b5050505050908060020154908060030154905084565b6000908152600560205260408120600201541190565b600154600160a060020a031633146105fe576040805160e560020a62461bcd02815260206004820152602360248201527f53656e646572206973206e6f7420476f7665726e6d656e7420436f6e74726f6c60448201527f6c65720000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0381161515610684576040805160e560020a62461bcd02815260206004820152602260248201527f6e6577417070656c6c6174652061646472657373206d757374206e6f7420626560448201527f2030000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f759a9d1715f38685bd08c7fb25060b7b6795cddf54214336e02a0533c5c7b89e9181900360200190a150565b600054600160a060020a03165b90565b600154600160a060020a031690565b600060046000836040518082805190602001908083835b6020831061073a5780518252601f19909201916020918201910161071b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108015780601f106107d657610100808354040283529160200191610801565b820191906000526020600020905b8154815290600101906020018083116107e457829003601f168201915b505050505081565b600054600160a060020a0316331461086b576040805160e560020a62461bcd02815260206004820152601760248201527f53656e646572206973206e6f7420417070656c6c617465000000000000000000604482015290519081900360640190fd5b6002829055805161088390600390602084019061150f565b5060408051838152602080820183815284519383019390935283517f2f6679e95449d4806445cd50a14e77e4b83ea193ae84e30f8a3247436442c25593869386939092606084019185019080838360005b838110156108ec5781810151838201526020016108d4565b50505050905090810190601f1680156109195780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050565b6000805481908190600160a060020a03163314610992576040805160e560020a62461bcd02815260206004820152601760248201527f53656e646572206973206e6f7420417070656c6c617465000000000000000000604482015290519081900360640190fd5b84846040518083805190602001908083835b602083106109c35780518252601f1990920191602091820191016109a4565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f61707065616c566f746550657263656e74616765000000000000000000000000855290519384900360140184208a5191975094508993925082918401908083835b60208310610a525780518252601f199092019160209182019101610a33565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161480610b485750604080517f61707065616c4368616c6c656e6765566f746544697370656e736174696f6e5081527f637400000000000000000000000000000000000000000000000000000000000060208083019190915291519081900360220181208751909288929182918401908083835b60208310610b155780518252601f199092019160209182019101610af6565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b15610bcc576064841115610bcc576040805160e560020a62461bcd02815260206004820152603760248201527f50657263656e7461676520706172616d6574657273206d757374206265206c6560448201527f7373207468616e206f7220657175616c20746f20313030000000000000000000606482015290519081900360840190fd5b610bd582610560565b15610c50576040805160e560020a62461bcd02815260206004820152602a60248201527f50726f706f736564207265706172616d65746572697a6174696f6e20616c726560448201527f6164792065786973747300000000000000000000000000000000000000000000606482015290519081900360840190fd5b83610c5a86610704565b1415610cd6576040805160e560020a62461bcd02815260206004820152603c60248201527f50726f706f736564207265706172616d65746572697a6174696f6e20776f756c60448201527f64206e6f74206368616e676520706172616d657465722076616c756500000000606482015290519081900360840190fd5b60065460408051808201909152601481527f61707065616c566f746550657263656e746167650000000000000000000000006020820152600160a060020a03909116906332ed3d6090610d2890610704565b610d666040805190810160405280601381526020017f676f767450436f6d6d697453746167654c656e00000000000000000000000000815250610704565b610da46040805190810160405280601381526020017f676f76745052657665616c53746167654c656e00000000000000000000000000815250610704565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b158015610e0457600080fd5b505af1158015610e18573d6000803e3d6000fd5b505050506040513d6020811015610e2e57600080fd5b505160408051608081018252828152602081810189905260075483518085018552601381527f676f76745052657665616c53746167654c656e0000000000000000000000000092810192909252939450909291830191610eef91610ee390610e9590610704565b610ee3610ed66040805190810160405280601381526020017f676f767450436f6d6d697453746167654c656e00000000000000000000000000815250610704565b429063ffffffff61141b16565b9063ffffffff61141b16565b8152602090810186905260008481526005825260409020825181558282015180519192610f249260018501929091019061150f565b5060408201518160020155606082015181600301559050507f74adf299a4c734e1ae114977ab264221c2f4a914c02243561aaa9158735d32248585848460405180806020018581526020018460001916600019168152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015610fb8578181015183820152602001610fa0565b50505050905090810190601f168015610fe55780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b60025481565b600054600160a060020a031681565b60046020526000908152604090205481565b600154600160a060020a031681565b600654600160a060020a031681565b600061104c61158d565b600083815260056020908152604091829020825160808101845281548152600180830180548651600260001994831615610100029490940190911692909204601f81018690048602830186019096528582529194929385810193919291908301828280156110fb5780601f106110d0576101008083540402835291602001916110fb565b820191906000526020600020905b8154815290600101906020018083116110de57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050600081600001511180156111bf57506006548151604080517fee684830000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561119257600080fd5b505af11580156111a6573d6000803e3d6000fd5b505050506040513d60208110156111bc57600080fd5b50515b9392505050565b6000818152600560209081526040808320600654815483517f49403183000000000000000000000000000000000000000000000000000000008152600481019190915292519194600160a060020a03909116936349403183936024808201949293918390030190829087803b15801561123e57600080fd5b505af1158015611252573d6000803e3d6000fd5b505050506040513d602081101561126857600080fd5b5051156113aa57428160020154111561136757611325816001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113165780601f106112eb57610100808354040283529160200191611316565b820191906000526020600020905b8154815290600101906020018083116112f957829003601f168201915b5050505050826003015461142e565b805460408051848152602081019290925280517fe040346a7ca6935dfd5ccdb81e13933d6af35a399b27c7c61d2888b4960336479281900390910190a16113a5565b805460408051848152602081019290925280517f0571dcf79f562f7040389aac4b84570b60ed77c3a1f6d9f10f2e3dc86d647e8f9281900390910190a15b6113e8565b805460408051848152602081019290925280517fcbc6fb3892c732a14043baca80213f571ebc1a385c676b25d9907fe8e7a2e37b9281900390910190a15b60008281526005602052604081208181559061140760018301826115b6565b506000600282018190556003909101555050565b8181018281101561142857fe5b92915050565b8060046000846040518082805190602001908083835b602083106114635780518252601f199092019160209182019101611444565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055507f0e92bd4b74871caaf73a4a51ca5ad4f01e5c5215e940a2f2a1f4c755b955066c8282604051808060200183815260200182810382528481815181526020019150805190602001908083836000838110156108ec5781810151838201526020016108d4565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061155057805160ff191683800117855561157d565b8280016001018555821561157d579182015b8281111561157d578251825591602001919060010190611562565b506115899291506115f6565b5090565b608060405190810160405280600081526020016060815260200160008152602001600081525090565b50805460018160011615610100020316600290046000825580601f106115dc57506104aa565b601f0160209004906000526020600020908101906104aa91905b6106f291905b8082111561158957600081556001016115fc5600a165627a7a7230582035fa71b840b4110f8e60e666f6fd5a19b10da33825fdc2453d3c4cf448e963170029", "deployedBytecode": "0x6080604052600436106100ef5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100f457806330490e911461011b57806332ed5b121461013557806335300990146101da578063551224251461020657806356e1fb88146102275780635793b9cf14610258578063693ec85e1461026d5780638ca7f51c146102c6578063b0924d6e14610350578063bade1c54146103ae578063c7d93fd414610409578063d5fd9e661461041e578063dc6ab52714610433578063f2a2129b1461044b578063fce1ccca14610460578063ffa1bdf014610475575b600080fd5b34801561010057600080fd5b5061010961048d565b60408051918252519081900360200190f35b34801561012757600080fd5b50610133600435610493565b005b34801561014157600080fd5b5061014d6004356104ad565b6040518085815260200180602001848152602001838152602001828103825285818151815260200191508051906020019080838360005b8381101561019c578181015183820152602001610184565b50505050905090810190601f1680156101c95780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b3480156101e657600080fd5b506101f2600435610560565b604080519115158252519081900360200190f35b34801561021257600080fd5b50610133600160a060020a0360043516610576565b34801561023357600080fd5b5061023c6106e5565b60408051600160a060020a039092168252519081900360200190f35b34801561026457600080fd5b5061023c6106f5565b34801561027957600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526101099436949293602493928401919081908401838280828437509497506107049650505050505050565b3480156102d257600080fd5b506102db61077b565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103155781810151838201526020016102fd565b50505050905090810190601f1680156103425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561035c57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526101339583359536956044949193909101919081908401838280828437509497506108099650505050505050565b3480156103ba57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610109943694929360249392840191908190840183828082843750949750509335945061092b9350505050565b34801561041557600080fd5b50610109610ffd565b34801561042a57600080fd5b5061023c611003565b34801561043f57600080fd5b50610109600435611012565b34801561045757600080fd5b5061023c611024565b34801561046c57600080fd5b5061023c611033565b34801561048157600080fd5b506101f2600435611042565b60075481565b61049c81611042565b156100ef576104aa816111c6565b50565b6005602090815260009182526040918290208054600180830180548651600293821615610100026000190190911692909204601f81018690048602830186019096528582529194929390929083018282801561054a5780601f1061051f5761010080835404028352916020019161054a565b820191906000526020600020905b81548152906001019060200180831161052d57829003601f168201915b5050505050908060020154908060030154905084565b6000908152600560205260408120600201541190565b600154600160a060020a031633146105fe576040805160e560020a62461bcd02815260206004820152602360248201527f53656e646572206973206e6f7420476f7665726e6d656e7420436f6e74726f6c60448201527f6c65720000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0381161515610684576040805160e560020a62461bcd02815260206004820152602260248201527f6e6577417070656c6c6174652061646472657373206d757374206e6f7420626560448201527f2030000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008054600160a060020a03831673ffffffffffffffffffffffffffffffffffffffff19909116811790915560408051918252517f759a9d1715f38685bd08c7fb25060b7b6795cddf54214336e02a0533c5c7b89e9181900360200190a150565b600054600160a060020a03165b90565b600154600160a060020a031690565b600060046000836040518082805190602001908083835b6020831061073a5780518252601f19909201916020918201910161071b565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6003805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156108015780601f106107d657610100808354040283529160200191610801565b820191906000526020600020905b8154815290600101906020018083116107e457829003601f168201915b505050505081565b600054600160a060020a0316331461086b576040805160e560020a62461bcd02815260206004820152601760248201527f53656e646572206973206e6f7420417070656c6c617465000000000000000000604482015290519081900360640190fd5b6002829055805161088390600390602084019061150f565b5060408051838152602080820183815284519383019390935283517f2f6679e95449d4806445cd50a14e77e4b83ea193ae84e30f8a3247436442c25593869386939092606084019185019080838360005b838110156108ec5781810151838201526020016108d4565b50505050905090810190601f1680156109195780820380516001836020036101000a031916815260200191505b50935050505060405180910390a15050565b6000805481908190600160a060020a03163314610992576040805160e560020a62461bcd02815260206004820152601760248201527f53656e646572206973206e6f7420417070656c6c617465000000000000000000604482015290519081900360640190fd5b84846040518083805190602001908083835b602083106109c35780518252601f1990920191602091820191016109a4565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f61707065616c566f746550657263656e74616765000000000000000000000000855290519384900360140184208a5191975094508993925082918401908083835b60208310610a525780518252601f199092019160209182019101610a33565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020600019161480610b485750604080517f61707065616c4368616c6c656e6765566f746544697370656e736174696f6e5081527f637400000000000000000000000000000000000000000000000000000000000060208083019190915291519081900360220181208751909288929182918401908083835b60208310610b155780518252601f199092019160209182019101610af6565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b15610bcc576064841115610bcc576040805160e560020a62461bcd02815260206004820152603760248201527f50657263656e7461676520706172616d6574657273206d757374206265206c6560448201527f7373207468616e206f7220657175616c20746f20313030000000000000000000606482015290519081900360840190fd5b610bd582610560565b15610c50576040805160e560020a62461bcd02815260206004820152602a60248201527f50726f706f736564207265706172616d65746572697a6174696f6e20616c726560448201527f6164792065786973747300000000000000000000000000000000000000000000606482015290519081900360840190fd5b83610c5a86610704565b1415610cd6576040805160e560020a62461bcd02815260206004820152603c60248201527f50726f706f736564207265706172616d65746572697a6174696f6e20776f756c60448201527f64206e6f74206368616e676520706172616d657465722076616c756500000000606482015290519081900360840190fd5b60065460408051808201909152601481527f61707065616c566f746550657263656e746167650000000000000000000000006020820152600160a060020a03909116906332ed3d6090610d2890610704565b610d666040805190810160405280601381526020017f676f767450436f6d6d697453746167654c656e00000000000000000000000000815250610704565b610da46040805190810160405280601381526020017f676f76745052657665616c53746167654c656e00000000000000000000000000815250610704565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b158015610e0457600080fd5b505af1158015610e18573d6000803e3d6000fd5b505050506040513d6020811015610e2e57600080fd5b505160408051608081018252828152602081810189905260075483518085018552601381527f676f76745052657665616c53746167654c656e0000000000000000000000000092810192909252939450909291830191610eef91610ee390610e9590610704565b610ee3610ed66040805190810160405280601381526020017f676f767450436f6d6d697453746167654c656e00000000000000000000000000815250610704565b429063ffffffff61141b16565b9063ffffffff61141b16565b8152602090810186905260008481526005825260409020825181558282015180519192610f249260018501929091019061150f565b5060408201518160020155606082015181600301559050507f74adf299a4c734e1ae114977ab264221c2f4a914c02243561aaa9158735d32248585848460405180806020018581526020018460001916600019168152602001838152602001828103825286818151815260200191508051906020019080838360005b83811015610fb8578181015183820152602001610fa0565b50505050905090810190601f168015610fe55780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a1509392505050565b60025481565b600054600160a060020a031681565b60046020526000908152604090205481565b600154600160a060020a031681565b600654600160a060020a031681565b600061104c61158d565b600083815260056020908152604091829020825160808101845281548152600180830180548651600260001994831615610100029490940190911692909204601f81018690048602830186019096528582529194929385810193919291908301828280156110fb5780601f106110d0576101008083540402835291602001916110fb565b820191906000526020600020905b8154815290600101906020018083116110de57829003601f168201915b50505050508152602001600282015481526020016003820154815250509050600081600001511180156111bf57506006548151604080517fee684830000000000000000000000000000000000000000000000000000000008152600481019290925251600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b15801561119257600080fd5b505af11580156111a6573d6000803e3d6000fd5b505050506040513d60208110156111bc57600080fd5b50515b9392505050565b6000818152600560209081526040808320600654815483517f49403183000000000000000000000000000000000000000000000000000000008152600481019190915292519194600160a060020a03909116936349403183936024808201949293918390030190829087803b15801561123e57600080fd5b505af1158015611252573d6000803e3d6000fd5b505050506040513d602081101561126857600080fd5b5051156113aa57428160020154111561136757611325816001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113165780601f106112eb57610100808354040283529160200191611316565b820191906000526020600020905b8154815290600101906020018083116112f957829003601f168201915b5050505050826003015461142e565b805460408051848152602081019290925280517fe040346a7ca6935dfd5ccdb81e13933d6af35a399b27c7c61d2888b4960336479281900390910190a16113a5565b805460408051848152602081019290925280517f0571dcf79f562f7040389aac4b84570b60ed77c3a1f6d9f10f2e3dc86d647e8f9281900390910190a15b6113e8565b805460408051848152602081019290925280517fcbc6fb3892c732a14043baca80213f571ebc1a385c676b25d9907fe8e7a2e37b9281900390910190a15b60008281526005602052604081208181559061140760018301826115b6565b506000600282018190556003909101555050565b8181018281101561142857fe5b92915050565b8060046000846040518082805190602001908083835b602083106114635780518252601f199092019160209182019101611444565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916600019168152602001908152602001600020819055507f0e92bd4b74871caaf73a4a51ca5ad4f01e5c5215e940a2f2a1f4c755b955066c8282604051808060200183815260200182810382528481815181526020019150805190602001908083836000838110156108ec5781810151838201526020016108d4565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061155057805160ff191683800117855561157d565b8280016001018555821561157d579182015b8281111561157d578251825591602001919060010190611562565b506115899291506115f6565b5090565b608060405190810160405280600081526020016060815260200160008152602001600081525090565b50805460018160011615610100020316600290046000825580601f106115dc57506104aa565b601f0160209004906000526020600020908101906104aa91905b6106f291905b8082111561158957600081556001016115fc5600a165627a7a7230582035fa71b840b4110f8e60e666f6fd5a19b10da33825fdc2453d3c4cf448e963170029", "abi": [ { "constant": true, "inputs": [], "name": "PROCESSBY", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "proposals", "outputs": [ { "name": "pollID", "type": "uint256" }, { "name": "name", "type": "string" }, { "name": "processBy", "type": "uint256" }, { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "constitutionURI", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "constitutionHash", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "appellate", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "params", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "governmentController", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "appellateAddr", "type": "address" }, { "name": "governmentControllerAddr", "type": "address" }, { "name": "plcrAddr", "type": "address" }, { "name": "appealFeeAmount", "type": "uint256" }, { "name": "requestAppealLength", "type": "uint256" }, { "name": "judgeAppealLength", "type": "uint256" }, { "name": "appealSupermajorityPercentage", "type": "uint256" }, { "name": "appealChallengeVoteDispensationPct", "type": "uint256" }, { "name": "pDeposit", "type": "uint256" }, { "name": "pCommitStageLength", "type": "uint256" }, { "name": "pRevealStageLength", "type": "uint256" }, { "name": "constHash", "type": "bytes32" }, { "name": "constURI", "type": "string" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "newAppellate", "type": "address" } ], "name": "_AppellateSet", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "_ParameterSet", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" }, { "indexed": false, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "pollID", "type": "uint256" } ], "name": "_GovtReparameterizationProposal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "propId", "type": "bytes32" }, { "indexed": false, "name": "pollID", "type": "uint256" } ], "name": "_ProposalPassed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "propId", "type": "bytes32" }, { "indexed": false, "name": "pollID", "type": "uint256" } ], "name": "_ProposalExpired", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "propId", "type": "bytes32" }, { "indexed": false, "name": "pollID", "type": "uint256" } ], "name": "_ProposalFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "proposedHash", "type": "bytes32" }, { "indexed": false, "name": "proposedURI", "type": "string" } ], "name": "_NewConstSet", "type": "event" }, { "constant": true, "inputs": [], "name": "getAppellate", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getGovernmentController", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "name", "type": "string" } ], "name": "get", "outputs": [ { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_name", "type": "string" }, { "name": "_value", "type": "uint256" } ], "name": "proposeReparameterization", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newConstHash", "type": "bytes32" }, { "name": "_newConstURI", "type": "string" } ], "name": "setNewConstitution", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "processProposal", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "propExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "propCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "newAppellate", "type": "address" } ], "name": "setAppellate", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0xc625fc42ab6d07746b953ae98b4ec22622e1b9a9", "transactionHash": "0xce40a08667372af7663cc1453e2f730b1ea978f6d98a9fb30f9bf8703eedeab1" }, "4": { "events": {}, "links": {}, "address": "0x4dc4168bfbe5b8bb2a4ccad35fe15e2417c022e8", "transactionHash": "0x20d26446303aaa71241e0f755687210bba1756d104cd063dc2d1a08a3d1ce7ad" } } } ================================================ FILE: packages/artifacts/v1/IERC20.json ================================================ { "contractName": "IERC20", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "anonymous": false, "inputs": [ { "indexed": true, "name": "from", "type": "address" }, { "indexed": true, "name": "to", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" }, { "indexed": true, "name": "spender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "constant": true, "inputs": [], "name": "totalSupply", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "who", "type": "address" } ], "name": "balanceOf", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "owner", "type": "address" }, { "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "spender", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "approve", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/IGovernment.json ================================================ { "contractName": "IGovernment", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "constant": true, "inputs": [], "name": "getAppellate", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getGovernmentController", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "name", "type": "string" } ], "name": "get", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/IMultiSigWalletFactory.json ================================================ { "contractName": "IMultiSigWalletFactory", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "constant": false, "inputs": [ { "name": "_owners", "type": "address[]" }, { "name": "_required", "type": "uint256" } ], "name": "create", "outputs": [ { "name": "wallet", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/Managed.json ================================================ { "contractName": "Managed", "bytecode": "0x608060405260008054600160a060020a031916331790556103a8806100256000396000f30060806040526004361061008d5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d06177a8114610092578063715018a6146100b55780638da5cb5b146100ca578063ac18de43146100fb578063c56a3e881461011c578063f281e7d114610145578063f2fde38b14610166578063fdff9b4d14610187575b600080fd5b34801561009e57600080fd5b506100b3600160a060020a03600435166101a8565b005b3480156100c157600080fd5b506100b36101e6565b3480156100d657600080fd5b506100df610252565b60408051600160a060020a039092168252519081900360200190f35b34801561010757600080fd5b506100b3600160a060020a0360043516610261565b34801561012857600080fd5b50610131610299565b604080519115158252519081900360200190f35b34801561015157600080fd5b50610131600160a060020a03600435166102a9565b34801561017257600080fd5b506100b3600160a060020a03600435166102c7565b34801561019357600080fd5b50610131600160a060020a03600435166102ea565b600054600160a060020a031633146101bf57600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b600054600160a060020a031633146101fd57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a0316331461027857600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b60006102a4336102a9565b905090565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a031633146102de57600080fd5b6102e7816102ff565b50565b60016020526000908152604090205460ff1681565b600160a060020a038116151561031457600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a72305820857ede70e317fc03c266a267a7047d1df819bc8bacb0177900580c4f2c5fd3050029", "deployedBytecode": "0x60806040526004361061008d5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632d06177a8114610092578063715018a6146100b55780638da5cb5b146100ca578063ac18de43146100fb578063c56a3e881461011c578063f281e7d114610145578063f2fde38b14610166578063fdff9b4d14610187575b600080fd5b34801561009e57600080fd5b506100b3600160a060020a03600435166101a8565b005b3480156100c157600080fd5b506100b36101e6565b3480156100d657600080fd5b506100df610252565b60408051600160a060020a039092168252519081900360200190f35b34801561010757600080fd5b506100b3600160a060020a0360043516610261565b34801561012857600080fd5b50610131610299565b604080519115158252519081900360200190f35b34801561015157600080fd5b50610131600160a060020a03600435166102a9565b34801561017257600080fd5b506100b3600160a060020a03600435166102c7565b34801561019357600080fd5b50610131600160a060020a03600435166102ea565b600054600160a060020a031633146101bf57600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b600054600160a060020a031633146101fd57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a0316331461027857600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b60006102a4336102a9565b905090565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a031633146102de57600080fd5b6102e7816102ff565b50565b60016020526000908152604090205460ff1681565b600160a060020a038116151561031457600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a72305820857ede70e317fc03c266a267a7047d1df819bc8bacb0177900580c4f2c5fd3050029", "abi": [ { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "managers", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": true, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "checkManagerStatus", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "isManager", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "addManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "removeManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/ManagedWhitelist.json ================================================ { "contractName": "ManagedWhitelist", "bytecode": "0x608060405260008054600160a060020a03191633179055610ed0806100256000396000f30060806040526004361061015e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631299090a811461016357806314862ea514610186578063166542b3146101a75780632d06177a146101dc5780633c421424146101fd5780633f16b2821461021e5780634b3d14851461023f578063607c60bb14610260578063715018a61461028157806373c601821461029657806381601496146102b75780638bdeb452146102d85780638da5cb5b146102f95780639685cc571461032a578063ab3d0c7a1461034b578063ac18de431461036c578063ac1f38531461038d578063adbb9160146103ae578063c56a3e88146103cf578063e79a4fd4146103e4578063e99f29a414610405578063ee37c29f14610426578063ee56f4fa14610447578063f0fbca0614610468578063f281e7d114610489578063f2fde38b146104aa578063fdff9b4d146104cb575b600080fd5b34801561016f57600080fd5b50610184600160a060020a03600435166104ec565b005b34801561019257600080fd5b50610184600160a060020a0360043516610586565b3480156101b357600080fd5b506101c8600160a060020a036004351661061d565b604080519115158252519081900360200190f35b3480156101e857600080fd5b50610184600160a060020a0360043516610632565b34801561020957600080fd5b50610184600160a060020a0360043516610670565b34801561022a57600080fd5b50610184600160a060020a0360043516610707565b34801561024b57600080fd5b50610184600160a060020a03600435166107a1565b34801561026c57600080fd5b50610184600160a060020a0360043516610838565b34801561028d57600080fd5b506101846108d2565b3480156102a257600080fd5b50610184600160a060020a036004351661093e565b3480156102c357600080fd5b506101c8600160a060020a03600435166109d8565b3480156102e457600080fd5b506101c8600160a060020a03600435166109ed565b34801561030557600080fd5b5061030e610a02565b60408051600160a060020a039092168252519081900360200190f35b34801561033657600080fd5b506101c8600160a060020a0360043516610a11565b34801561035757600080fd5b50610184600160a060020a0360043516610a26565b34801561037857600080fd5b50610184600160a060020a0360043516610abd565b34801561039957600080fd5b50610184600160a060020a0360043516610af5565b3480156103ba57600080fd5b50610184600160a060020a0360043516610b8f565b3480156103db57600080fd5b506101c8610c26565b3480156103f057600080fd5b50610184600160a060020a0360043516610c36565b34801561041157600080fd5b50610184600160a060020a0360043516610ccd565b34801561043257600080fd5b50610184600160a060020a0360043516610cd0565b34801561045357600080fd5b506101c8600160a060020a0360043516610d6a565b34801561047457600080fd5b506101c8600160a060020a0360043516610d7f565b34801561049557600080fd5b506101c8600160a060020a0360043516610d94565b3480156104b657600080fd5b50610184600160a060020a0360043516610db2565b3480156104d757600080fd5b506101c8600160a060020a0360043516610dd2565b6104f533610d94565b8061050a5750600054600160a060020a031633145b1515610562576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19166001179055565b61058f33610d94565b806105a45750600054600160a060020a031633145b15156105fc576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19169055565b60076020526000908152604090205460ff1681565b600054600160a060020a0316331461064957600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b61067933610d94565b8061068e5750600054600160a060020a031633145b15156106e6576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19169055565b61071033610d94565b806107255750600054600160a060020a031633145b151561077d576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19166001179055565b6107aa33610d94565b806107bf5750600054600160a060020a031633145b1515610817576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19169055565b61084133610d94565b806108565750600054600160a060020a031633145b15156108ae576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19166001179055565b600054600160a060020a031633146108e957600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b61094733610d94565b8061095c5750600054600160a060020a031633145b15156109b4576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19166001179055565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b600054600160a060020a031681565b60026020526000908152604090205460ff1681565b610a2f33610d94565b80610a445750600054600160a060020a031633145b1515610a9c576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19169055565b600054600160a060020a03163314610ad457600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b610afe33610d94565b80610b135750600054600160a060020a031633145b1515610b6b576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19166001179055565b610b9833610d94565b80610bad5750600054600160a060020a031633145b1515610c05576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19169055565b6000610c3133610d94565b905090565b610c3f33610d94565b80610c545750600054600160a060020a031633145b1515610cac576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19169055565b50565b610cd933610d94565b80610cee5750600054600160a060020a031633145b1515610d46576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19166001179055565b60036020526000908152604090205460ff1681565b60066020526000908152604090205460ff1681565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a03163314610dc957600080fd5b610ccd81610de7565b60016020526000908152604090205460ff1681565b600160a060020a0381161515610dfc57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905556006f726d207468697320616374696f6e00000000000000000000000000000000004f6e6c79206d616e6167657273206f72206f776e657273206d61792070657266a165627a7a7230582018948cf633264309374c866bb9a843c540d638fc0fdf4c0058040d0caaead7110029", "deployedBytecode": "0x60806040526004361061015e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631299090a811461016357806314862ea514610186578063166542b3146101a75780632d06177a146101dc5780633c421424146101fd5780633f16b2821461021e5780634b3d14851461023f578063607c60bb14610260578063715018a61461028157806373c601821461029657806381601496146102b75780638bdeb452146102d85780638da5cb5b146102f95780639685cc571461032a578063ab3d0c7a1461034b578063ac18de431461036c578063ac1f38531461038d578063adbb9160146103ae578063c56a3e88146103cf578063e79a4fd4146103e4578063e99f29a414610405578063ee37c29f14610426578063ee56f4fa14610447578063f0fbca0614610468578063f281e7d114610489578063f2fde38b146104aa578063fdff9b4d146104cb575b600080fd5b34801561016f57600080fd5b50610184600160a060020a03600435166104ec565b005b34801561019257600080fd5b50610184600160a060020a0360043516610586565b3480156101b357600080fd5b506101c8600160a060020a036004351661061d565b604080519115158252519081900360200190f35b3480156101e857600080fd5b50610184600160a060020a0360043516610632565b34801561020957600080fd5b50610184600160a060020a0360043516610670565b34801561022a57600080fd5b50610184600160a060020a0360043516610707565b34801561024b57600080fd5b50610184600160a060020a03600435166107a1565b34801561026c57600080fd5b50610184600160a060020a0360043516610838565b34801561028d57600080fd5b506101846108d2565b3480156102a257600080fd5b50610184600160a060020a036004351661093e565b3480156102c357600080fd5b506101c8600160a060020a03600435166109d8565b3480156102e457600080fd5b506101c8600160a060020a03600435166109ed565b34801561030557600080fd5b5061030e610a02565b60408051600160a060020a039092168252519081900360200190f35b34801561033657600080fd5b506101c8600160a060020a0360043516610a11565b34801561035757600080fd5b50610184600160a060020a0360043516610a26565b34801561037857600080fd5b50610184600160a060020a0360043516610abd565b34801561039957600080fd5b50610184600160a060020a0360043516610af5565b3480156103ba57600080fd5b50610184600160a060020a0360043516610b8f565b3480156103db57600080fd5b506101c8610c26565b3480156103f057600080fd5b50610184600160a060020a0360043516610c36565b34801561041157600080fd5b50610184600160a060020a0360043516610ccd565b34801561043257600080fd5b50610184600160a060020a0360043516610cd0565b34801561045357600080fd5b506101c8600160a060020a0360043516610d6a565b34801561047457600080fd5b506101c8600160a060020a0360043516610d7f565b34801561049557600080fd5b506101c8600160a060020a0360043516610d94565b3480156104b657600080fd5b50610184600160a060020a0360043516610db2565b3480156104d757600080fd5b506101c8600160a060020a0360043516610dd2565b6104f533610d94565b8061050a5750600054600160a060020a031633145b1515610562576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19166001179055565b61058f33610d94565b806105a45750600054600160a060020a031633145b15156105fc576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19169055565b60076020526000908152604090205460ff1681565b600054600160a060020a0316331461064957600080fd5b600160a060020a03166000908152600160208190526040909120805460ff19169091179055565b61067933610d94565b8061068e5750600054600160a060020a031633145b15156106e6576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19169055565b61071033610d94565b806107255750600054600160a060020a031633145b151561077d576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600460205260409020805460ff19166001179055565b6107aa33610d94565b806107bf5750600054600160a060020a031633145b1515610817576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19169055565b61084133610d94565b806108565750600054600160a060020a031633145b15156108ae576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19166001179055565b600054600160a060020a031633146108e957600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b61094733610d94565b8061095c5750600054600160a060020a031633145b15156109b4576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600260205260409020805460ff19166001179055565b60056020526000908152604090205460ff1681565b60046020526000908152604090205460ff1681565b600054600160a060020a031681565b60026020526000908152604090205460ff1681565b610a2f33610d94565b80610a445750600054600160a060020a031633145b1515610a9c576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600360205260409020805460ff19169055565b600054600160a060020a03163314610ad457600080fd5b600160a060020a03166000908152600160205260409020805460ff19169055565b610afe33610d94565b80610b135750600054600160a060020a031633145b1515610b6b576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19166001179055565b610b9833610d94565b80610bad5750600054600160a060020a031633145b1515610c05576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600660205260409020805460ff19169055565b6000610c3133610d94565b905090565b610c3f33610d94565b80610c545750600054600160a060020a031633145b1515610cac576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600760205260409020805460ff19169055565b50565b610cd933610d94565b80610cee5750600054600160a060020a031633145b1515610d46576040805160e560020a62461bcd02815260206004820152602f6024820152600080516020610e858339815191526044820152600080516020610e65833981519152606482015290519081900360840190fd5b600160a060020a03166000908152600560205260409020805460ff19166001179055565b60036020526000908152604090205460ff1681565b60066020526000908152604090205460ff1681565b600160a060020a031660009081526001602052604090205460ff1690565b600054600160a060020a03163314610dc957600080fd5b610ccd81610de7565b60016020526000908152604090205460ff1681565b600160a060020a0381161515610dfc57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905556006f726d207468697320616374696f6e00000000000000000000000000000000004f6e6c79206d616e6167657273206f72206f776e657273206d61792070657266a165627a7a7230582018948cf633264309374c866bb9a843c540d638fc0fdf4c0058040d0caaead7110029", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "newsroomMultisigList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "addManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "verifiedList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "unlockedList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "coreList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "removeManager", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "isManager", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "civilianList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "storefrontList", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "managerAddress", "type": "address" } ], "name": "checkManagerStatus", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "managers", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToCore", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromCore", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToCivilians", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromCivilians", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToUnlocked", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromUnlocked", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToVerified", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromVerified", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToStorefront", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromStorefront", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "addToNewsroomMultisigs", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "removeFromNewsroomMultisigs", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "operator", "type": "address" } ], "name": "checkProofOfUse", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/MessagesAndCodes.json ================================================ { "contractName": "MessagesAndCodes", "bytecode": "0x610a88610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600436106100995763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636ef3054c811461009e57806379bb4acc14610117578063832a10ef14610194578063d7118140146101f7578063d87d728914610215578063ef0067941461021d578063f7feed761461027b575b600080fd5b8180156100aa57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610101948235946024803560ff16953695946064949201919081908401838280828437509497506102839650505050505050565b6040805160ff9092168252519081900360200190f35b61011f610456565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610159578181015183820152602001610141565b50505050905090810190601f1680156101865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8180156101a057600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610101948235946024803560ff169536959460649492019190819084018382808284375094975061047b9650505050505050565b81801561020357600080fd5b5061010160043560ff602435166105de565b61011f6107cc565b81801561022957600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261010195833595369560449491939091019190819084018382808284375094975061082c9650505050505050565b61011f6108d9565b600061028e82610939565b60408051808201909152601e8152600080516020610a3d8339815191526020820152901561033d5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156103025781810151838201526020016102ea565b50505050905090810190601f16801561032f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610348848461093e565b60408051606081018252602b81527f476976656e20636f646520697320616c726561647920706f696e74696e67207460208201527f6f2061206d6573736167650000000000000000000000000000000000000000009181019190915290156103f55760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b5060ff8316600090815260208581526040909120835161041792850190610968565b505050600191820180549283018155600090815260209081902090830401805460ff808416601f9095166101000a948502940219169290921790915590565b60408051808201909152601e8152600080516020610a3d833981519152602082015281565b600061048682610939565b60408051808201909152601e8152600080516020610a3d833981519152602082015290156104f95760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50610504848461093e565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f65737361676500000000000000000000000000000000000000000000000000008152509015156105b35760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b5060ff831660009081526020858152604090912083516105d592850190610968565b50919392505050565b60008060006105ed858561093e565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f657373616765000000000000000000000000000000000000000000000000000081525090151561069c5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50600091505b8360ff16856001018360ff168154811015156106ba57fe5b60009182526020918290209181049091015460ff601f9092166101000a900416146106ea576001909101906106a2565b50805b60018501546000190160ff8216101561078257846001018160010160ff1681548110151561071757fe5b90600052602060002090602091828204019190069054906101000a900460ff16856001018260ff1681548110151561074b57fe5b90600052602060002090602091828204019190066101000a81548160ff021916908360ff16021790555080806001019150506106ed565b600185018054906107979060001983016109e6565b50604080516020818101808452600080845260ff891681529189905292902090516107c29290610968565b5092949350505050565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f657373616765000000000000000000000000000000000000000000000000000081525081565b600061083782610939565b60408051808201909152601e8152600080516020610a3d833981519152602082015290156108aa5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50600090505b6108ba838261093e565b156108c7576001016108b0565b6108d2838284610283565b5092915050565b606060405190810160405280602b81526020017f476976656e20636f646520697320616c726561647920706f696e74696e67207481526020017f6f2061206d65737361676500000000000000000000000000000000000000000081525081565b511590565b60ff1660009081526020919091526040812054600260001961010060018416150201909116041190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109a957805160ff19168380011785556109d6565b828001600101855582156109d6579182015b828111156109d65782518255916020019190600101906109bb565b506109e2929150610a1f565b5090565b815481835581811115610a1a57601f016020900481601f01602090048360005260206000209182019101610a1a9190610a1f565b505050565b610a3991905b808211156109e25760008155600101610a25565b9056004d6573736167652063616e6e6f7420626520656d70747920737472696e670000a165627a7a723058203316a332657354bcd1343d28645cfb43554d085b9143092d97b1e09a98365c9e0029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600436106100995763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416636ef3054c811461009e57806379bb4acc14610117578063832a10ef14610194578063d7118140146101f7578063d87d728914610215578063ef0067941461021d578063f7feed761461027b575b600080fd5b8180156100aa57600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610101948235946024803560ff16953695946064949201919081908401838280828437509497506102839650505050505050565b6040805160ff9092168252519081900360200190f35b61011f610456565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610159578181015183820152602001610141565b50505050905090810190601f1680156101865780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8180156101a057600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610101948235946024803560ff169536959460649492019190819084018382808284375094975061047b9650505050505050565b81801561020357600080fd5b5061010160043560ff602435166105de565b61011f6107cc565b81801561022957600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261010195833595369560449491939091019190819084018382808284375094975061082c9650505050505050565b61011f6108d9565b600061028e82610939565b60408051808201909152601e8152600080516020610a3d8339815191526020820152901561033d5760405160e560020a62461bcd0281526004018080602001828103825283818151815260200191508051906020019080838360005b838110156103025781810151838201526020016102ea565b50505050905090810190601f16801561032f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50610348848461093e565b60408051606081018252602b81527f476976656e20636f646520697320616c726561647920706f696e74696e67207460208201527f6f2061206d6573736167650000000000000000000000000000000000000000009181019190915290156103f55760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b5060ff8316600090815260208581526040909120835161041792850190610968565b505050600191820180549283018155600090815260209081902090830401805460ff808416601f9095166101000a948502940219169290921790915590565b60408051808201909152601e8152600080516020610a3d833981519152602082015281565b600061048682610939565b60408051808201909152601e8152600080516020610a3d833981519152602082015290156104f95760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50610504848461093e565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f65737361676500000000000000000000000000000000000000000000000000008152509015156105b35760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b5060ff831660009081526020858152604090912083516105d592850190610968565b50919392505050565b60008060006105ed858561093e565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f657373616765000000000000000000000000000000000000000000000000000081525090151561069c5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50600091505b8360ff16856001018360ff168154811015156106ba57fe5b60009182526020918290209181049091015460ff601f9092166101000a900416146106ea576001909101906106a2565b50805b60018501546000190160ff8216101561078257846001018160010160ff1681548110151561071757fe5b90600052602060002090602091828204019190069054906101000a900460ff16856001018260ff1681548110151561074b57fe5b90600052602060002090602091828204019190066101000a81548160ff021916908360ff16021790555080806001019150506106ed565b600185018054906107979060001983016109e6565b50604080516020818101808452600080845260ff891681529189905292902090516107c29290610968565b5092949350505050565b606060405190810160405280602681526020017f476976656e20636f646520646f6573206e6f7420706f696e7420746f2061206d81526020017f657373616765000000000000000000000000000000000000000000000000000081525081565b600061083782610939565b60408051808201909152601e8152600080516020610a3d833981519152602082015290156108aa5760405160e560020a62461bcd028152600401808060200182810382528381815181526020019150805190602001908083836000838110156103025781810151838201526020016102ea565b50600090505b6108ba838261093e565b156108c7576001016108b0565b6108d2838284610283565b5092915050565b606060405190810160405280602b81526020017f476976656e20636f646520697320616c726561647920706f696e74696e67207481526020017f6f2061206d65737361676500000000000000000000000000000000000000000081525081565b511590565b60ff1660009081526020919091526040812054600260001961010060018416150201909116041190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106109a957805160ff19168380011785556109d6565b828001600101855582156109d6579182015b828111156109d65782518255916020019190600101906109bb565b506109e2929150610a1f565b5090565b815481835581811115610a1a57601f016020900481601f01602090048360005260206000209182019101610a1a9190610a1f565b505050565b610a3991905b808211156109e25760008155600101610a25565b9056004d6573736167652063616e6e6f7420626520656d70747920737472696e670000a165627a7a723058203316a332657354bcd1343d28645cfb43554d085b9143092d97b1e09a98365c9e0029", "abi": [ { "constant": true, "inputs": [], "name": "EMPTY_MESSAGE_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "CODE_UNASSIGNED_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "CODE_RESERVED_ERROR", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "MessagesAndCodes.Data storage" }, { "name": "_code", "type": "uint8" }, { "name": "_message", "type": "string" } ], "name": "addMessage", "outputs": [ { "name": "code", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "MessagesAndCodes.Data storage" }, { "name": "_message", "type": "string" } ], "name": "autoAddMessage", "outputs": [ { "name": "code", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "MessagesAndCodes.Data storage" }, { "name": "_code", "type": "uint8" } ], "name": "removeMessage", "outputs": [ { "name": "code", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "self", "type": "MessagesAndCodes.Data storage" }, { "name": "_code", "type": "uint8" }, { "name": "_message", "type": "string" } ], "name": "updateMessage", "outputs": [ { "name": "code", "type": "uint8" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x99Ed479b711f1Dec9377d8a1C63Bfa2D51486954", "transactionHash": "0xe85b40dbc84b9be09b08dda29965050057754e3b003115fc353dbe342c4e0e51" }, "4": { "events": {}, "links": {}, "address": "0x908d7ca8704592342a6b869687d81fa461e4d34f", "transactionHash": "0xae78712dfb6415c599eb5075bac1ce99537e27583d3ec450d18a317a5a7c9fce" } } } ================================================ FILE: packages/artifacts/v1/Migrations.json ================================================ { "contractName": "Migrations", "bytecode": "0x608060405234801561001057600080fd5b5060008054600160a060020a0319163317905561023c806100326000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630900f0108114610066578063445df0ac146100965780638da5cb5b146100bd578063fdacd576146100fb575b600080fd5b34801561007257600080fd5b5061009473ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100a257600080fd5b506100ab6101c5565b60408051918252519081900360200190f35b3480156100c957600080fd5b506100d26101cb565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561010757600080fd5b506100946004356101e7565b6000805473ffffffffffffffffffffffffffffffffffffffff163314156101c1578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101a857600080fd5b505af11580156101bc573d6000803e3d6000fd5b505050505b5050565b60015481565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1633141561020d5760018190555b505600a165627a7a7230582074fe09b9d2bb05f0f5174691f1b13ebeff6ec4d39bc8c0ebc32b1680ffa298080029", "deployedBytecode": "0x6080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630900f0108114610066578063445df0ac146100965780638da5cb5b146100bd578063fdacd576146100fb575b600080fd5b34801561007257600080fd5b5061009473ffffffffffffffffffffffffffffffffffffffff60043516610113565b005b3480156100a257600080fd5b506100ab6101c5565b60408051918252519081900360200190f35b3480156100c957600080fd5b506100d26101cb565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b34801561010757600080fd5b506100946004356101e7565b6000805473ffffffffffffffffffffffffffffffffffffffff163314156101c1578190508073ffffffffffffffffffffffffffffffffffffffff1663fdacd5766001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050600060405180830381600087803b1580156101a857600080fd5b505af11580156101bc573d6000803e3d6000fd5b505050505b5050565b60015481565b60005473ffffffffffffffffffffffffffffffffffffffff1681565b60005473ffffffffffffffffffffffffffffffffffffffff1633141561020d5760018190555b505600a165627a7a7230582074fe09b9d2bb05f0f5174691f1b13ebeff6ec4d39bc8c0ebc32b1680ffa298080029", "abi": [ { "constant": true, "inputs": [], "name": "last_completed_migration", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "constant": false, "inputs": [ { "name": "completed", "type": "uint256" } ], "name": "setCompleted", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "newAddress", "type": "address" } ], "name": "upgrade", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x4c65b5d73c193dba847def751339324c0693b122", "transactionHash": "0x05b626d4689485a69bfeb8a2f41080a952a018e33bf867680a5d35d814a72122" }, "4": { "events": {}, "links": {}, "address": "0x7bf363c45e455c8032a2a6753647aa08c4806973", "transactionHash": "0x4872f9337d4be8f164b0a44a0c154fda72c042618d609e2698598c7d4e5364c3" } } } ================================================ FILE: packages/artifacts/v1/MultiSigWallet.json ================================================ { "contractName": "MultiSigWallet", "bytecode": "0x60806040523480156200001157600080fd5b50604051620016a6380380620016a68339810160405280516020820151910180519091906000908260328211156200004857600080fd5b818111156200005657600080fd5b8015156200006357600080fd5b8115156200007057600080fd5b600092505b845183101562000149576002600086858151811015156200009257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff16158015620000e957508451600090869085908110620000d357fe5b90602001906020020151600160a060020a031614155b1515620000f557600080fd5b60016002600087868151811015156200010a57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000075565b84516200015e90600390602088019062000170565b50505060049190915550620002049050565b828054828255906000526020600020908101928215620001c8579160200282015b82811115620001c85782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019062000191565b50620001d6929150620001da565b5090565b6200020191905b80821115620001d6578054600160a060020a0319168155600101620001e1565b90565b61149280620002146000396000f30060806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019257806320ea8d86146101b35780632f54bf6e146101cb5780633411c81c1461020057806354741525146102245780637065cb4814610255578063784547a7146102765780638b51d13f1461028e5780639ace38c2146102a6578063a0e67e2b14610361578063a8abe69a146103c6578063b5dc40c3146103eb578063b77bf60014610403578063ba51a6df14610418578063c01a8c8414610430578063c642747414610448578063d74f8edd146104b1578063dc8452cd146104c6578063e20056e6146104db578063ee22610b14610502575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561051a565b60408051600160a060020a039092168252519081900360200190f35b34801561019e57600080fd5b5061015c600160a060020a0360043516610542565b3480156101bf57600080fd5b5061015c6004356106b9565b3480156101d757600080fd5b506101ec600160a060020a0360043516610773565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600435600160a060020a0360243516610788565b34801561023057600080fd5b50610243600435151560243515156107a8565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015c600160a060020a0360043516610814565b34801561028257600080fd5b506101ec60043561093a565b34801561029a57600080fd5b506102436004356109be565b3480156102b257600080fd5b506102be600435610a2d565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561032357818101518382015260200161030b565b50505050905090810190601f1680156103505780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561036d57600080fd5b50610376610aeb565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103b257818101518382015260200161039a565b505050509050019250505060405180910390f35b3480156103d257600080fd5b5061037660043560243560443515156064351515610b4e565b3480156103f757600080fd5b50610376600435610c87565b34801561040f57600080fd5b50610243610e00565b34801561042457600080fd5b5061015c600435610e06565b34801561043c57600080fd5b5061015c600435610e86565b34801561045457600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610243948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610f519650505050505050565b3480156104bd57600080fd5b50610243610f70565b3480156104d257600080fd5b50610243610f75565b3480156104e757600080fd5b5061015c600160a060020a0360043581169060243516610f7b565b34801561050e57600080fd5b5061015c600435611105565b600380548290811061052857fe5b600091825260209091200154600160a060020a0316905081565b600033301461055057600080fd5b600160a060020a038216600090815260026020526040902054829060ff16151561057957600080fd5b600160a060020a0383166000908152600260205260408120805460ff1916905591505b600354600019018210156106545782600160a060020a03166003838154811015156105c357fe5b600091825260209091200154600160a060020a03161415610649576003805460001981019081106105f057fe5b60009182526020909120015460038054600160a060020a03909216918490811061061657fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550610654565b60019091019061059c565b60038054600019019061066790826113a5565b5060035460045411156106805760035461068090610e06565b604051600160a060020a038416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156106d757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561070357600080fd5b600084815260208190526040902060030154849060ff161561072457600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561080d578380156107d5575060008181526020819052604090206003015460ff16155b806107f957508280156107f9575060008181526020819052604090206003015460ff165b15610805576001820191505b6001016107ac565b5092915050565b33301461082057600080fd5b600160a060020a038116600090815260026020526040902054819060ff161561084857600080fd5b81600160a060020a038116151561085e57600080fd5b600354600454600190910190603282111561087857600080fd5b8181111561088557600080fd5b80151561089157600080fd5b81151561089d57600080fd5b600160a060020a038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b6003548110156109b7576000848152600160205260408120600380549192918490811061096857fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561099c576001820191505b6004548214156109af57600192506109b7565b60010161093f565b5050919050565b6000805b600354811015610a2757600083815260016020526040812060038054919291849081106109eb57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610a1f576001820191505b6001016109c2565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f8101889004880284018801909652858352600160a060020a0390931695909491929190830182828015610ad85780601f10610aad57610100808354040283529160200191610ad8565b820191906000526020600020905b815481529060010190602001808311610abb57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b4357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b25575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610b80578160200160208202803883390190505b50925060009150600090505b600554811015610c0757858015610bb5575060008181526020819052604090206003015460ff16155b80610bd95750848015610bd9575060008181526020819052604090206003015460ff165b15610bff57808383815181101515610bed57fe5b60209081029091010152600191909101905b600101610b8c565b878703604051908082528060200260200182016040528015610c33578160200160208202803883390190505b5093508790505b86811015610c7c578281815181101515610c5057fe5b9060200190602002015184898303815181101515610c6a57fe5b60209081029091010152600101610c3a565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610cbc578160200160208202803883390190505b50925060009150600090505b600354811015610d795760008581526001602052604081206003805491929184908110610cf157fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610d71576003805482908110610d2c57fe5b6000918252602090912001548351600160a060020a0390911690849084908110610d5257fe5b600160a060020a03909216602092830290910190910152600191909101905b600101610cc8565b81604051908082528060200260200182016040528015610da3578160200160208202803883390190505b509350600090505b81811015610df8578281815181101515610dc157fe5b906020019060200201518482815181101515610dd957fe5b600160a060020a03909216602092830290910190910152600101610dab565b505050919050565b60055481565b333014610e1257600080fd5b600354816032821115610e2457600080fd5b81811115610e3157600080fd5b801515610e3d57600080fd5b811515610e4957600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff161515610ea457600080fd5b6000828152602081905260409020548290600160a060020a03161515610ec957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff1615610ef457600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610f4a85611105565b5050505050565b6000610f5e8484846112b5565b9050610f6981610e86565b9392505050565b603281565b60045481565b6000333014610f8957600080fd5b600160a060020a038316600090815260026020526040902054839060ff161515610fb257600080fd5b600160a060020a038316600090815260026020526040902054839060ff1615610fda57600080fd5b600092505b60035483101561106b5784600160a060020a031660038481548110151561100257fe5b600091825260209091200154600160a060020a03161415611060578360038481548110151561102d57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555061106b565b600190920191610fdf565b600160a060020a03808616600081815260026020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b3360008181526002602052604081205490919060ff16151561112657600080fd5b60008381526001602090815260408083203380855292529091205484919060ff16151561115257600080fd5b600085815260208190526040902060030154859060ff161561117357600080fd5b61117c8661093a565b156112ad576000868152602081905260409081902060038101805460ff19166001908117909155815481830154935160028085018054959b50600160a060020a039093169594929391928392859260001991831615610100029190910190911604801561122a5780601f106111ff5761010080835404028352916020019161122a565b820191906000526020600020905b81548152906001019060200180831161120d57829003601f168201915b505091505060006040518083038185875af192505050156112755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26112ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038501805460ff191690555b505050505050565b600083600160a060020a03811615156112cd57600080fd5b60055460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152808452959095208451815473ffffffffffffffffffffffffffffffffffffffff19169416939093178355516001830155925180519496509193909261134d9260028501929101906113ce565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156113c9576000838152602090206113c991810190830161144c565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061140f57805160ff191683800117855561143c565b8280016001018555821561143c579182015b8281111561143c578251825591602001919060010190611421565b5061144892915061144c565b5090565b610b4b91905b8082111561144857600081556001016114525600a165627a7a72305820e8ee551a5d8acd2ae22a24eec7633688fd4bbc740b3aa2cd8d47d9d6cb6847390029", "deployedBytecode": "0x60806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019257806320ea8d86146101b35780632f54bf6e146101cb5780633411c81c1461020057806354741525146102245780637065cb4814610255578063784547a7146102765780638b51d13f1461028e5780639ace38c2146102a6578063a0e67e2b14610361578063a8abe69a146103c6578063b5dc40c3146103eb578063b77bf60014610403578063ba51a6df14610418578063c01a8c8414610430578063c642747414610448578063d74f8edd146104b1578063dc8452cd146104c6578063e20056e6146104db578063ee22610b14610502575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561051a565b60408051600160a060020a039092168252519081900360200190f35b34801561019e57600080fd5b5061015c600160a060020a0360043516610542565b3480156101bf57600080fd5b5061015c6004356106b9565b3480156101d757600080fd5b506101ec600160a060020a0360043516610773565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600435600160a060020a0360243516610788565b34801561023057600080fd5b50610243600435151560243515156107a8565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015c600160a060020a0360043516610814565b34801561028257600080fd5b506101ec60043561093a565b34801561029a57600080fd5b506102436004356109be565b3480156102b257600080fd5b506102be600435610a2d565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561032357818101518382015260200161030b565b50505050905090810190601f1680156103505780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561036d57600080fd5b50610376610aeb565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103b257818101518382015260200161039a565b505050509050019250505060405180910390f35b3480156103d257600080fd5b5061037660043560243560443515156064351515610b4e565b3480156103f757600080fd5b50610376600435610c87565b34801561040f57600080fd5b50610243610e00565b34801561042457600080fd5b5061015c600435610e06565b34801561043c57600080fd5b5061015c600435610e86565b34801561045457600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610243948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610f519650505050505050565b3480156104bd57600080fd5b50610243610f70565b3480156104d257600080fd5b50610243610f75565b3480156104e757600080fd5b5061015c600160a060020a0360043581169060243516610f7b565b34801561050e57600080fd5b5061015c600435611105565b600380548290811061052857fe5b600091825260209091200154600160a060020a0316905081565b600033301461055057600080fd5b600160a060020a038216600090815260026020526040902054829060ff16151561057957600080fd5b600160a060020a0383166000908152600260205260408120805460ff1916905591505b600354600019018210156106545782600160a060020a03166003838154811015156105c357fe5b600091825260209091200154600160a060020a03161415610649576003805460001981019081106105f057fe5b60009182526020909120015460038054600160a060020a03909216918490811061061657fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550610654565b60019091019061059c565b60038054600019019061066790826113a5565b5060035460045411156106805760035461068090610e06565b604051600160a060020a038416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156106d757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561070357600080fd5b600084815260208190526040902060030154849060ff161561072457600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561080d578380156107d5575060008181526020819052604090206003015460ff16155b806107f957508280156107f9575060008181526020819052604090206003015460ff165b15610805576001820191505b6001016107ac565b5092915050565b33301461082057600080fd5b600160a060020a038116600090815260026020526040902054819060ff161561084857600080fd5b81600160a060020a038116151561085e57600080fd5b600354600454600190910190603282111561087857600080fd5b8181111561088557600080fd5b80151561089157600080fd5b81151561089d57600080fd5b600160a060020a038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b6003548110156109b7576000848152600160205260408120600380549192918490811061096857fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561099c576001820191505b6004548214156109af57600192506109b7565b60010161093f565b5050919050565b6000805b600354811015610a2757600083815260016020526040812060038054919291849081106109eb57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610a1f576001820191505b6001016109c2565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f8101889004880284018801909652858352600160a060020a0390931695909491929190830182828015610ad85780601f10610aad57610100808354040283529160200191610ad8565b820191906000526020600020905b815481529060010190602001808311610abb57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b4357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b25575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610b80578160200160208202803883390190505b50925060009150600090505b600554811015610c0757858015610bb5575060008181526020819052604090206003015460ff16155b80610bd95750848015610bd9575060008181526020819052604090206003015460ff165b15610bff57808383815181101515610bed57fe5b60209081029091010152600191909101905b600101610b8c565b878703604051908082528060200260200182016040528015610c33578160200160208202803883390190505b5093508790505b86811015610c7c578281815181101515610c5057fe5b9060200190602002015184898303815181101515610c6a57fe5b60209081029091010152600101610c3a565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610cbc578160200160208202803883390190505b50925060009150600090505b600354811015610d795760008581526001602052604081206003805491929184908110610cf157fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610d71576003805482908110610d2c57fe5b6000918252602090912001548351600160a060020a0390911690849084908110610d5257fe5b600160a060020a03909216602092830290910190910152600191909101905b600101610cc8565b81604051908082528060200260200182016040528015610da3578160200160208202803883390190505b509350600090505b81811015610df8578281815181101515610dc157fe5b906020019060200201518482815181101515610dd957fe5b600160a060020a03909216602092830290910190910152600101610dab565b505050919050565b60055481565b333014610e1257600080fd5b600354816032821115610e2457600080fd5b81811115610e3157600080fd5b801515610e3d57600080fd5b811515610e4957600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff161515610ea457600080fd5b6000828152602081905260409020548290600160a060020a03161515610ec957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff1615610ef457600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610f4a85611105565b5050505050565b6000610f5e8484846112b5565b9050610f6981610e86565b9392505050565b603281565b60045481565b6000333014610f8957600080fd5b600160a060020a038316600090815260026020526040902054839060ff161515610fb257600080fd5b600160a060020a038316600090815260026020526040902054839060ff1615610fda57600080fd5b600092505b60035483101561106b5784600160a060020a031660038481548110151561100257fe5b600091825260209091200154600160a060020a03161415611060578360038481548110151561102d57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555061106b565b600190920191610fdf565b600160a060020a03808616600081815260026020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b3360008181526002602052604081205490919060ff16151561112657600080fd5b60008381526001602090815260408083203380855292529091205484919060ff16151561115257600080fd5b600085815260208190526040902060030154859060ff161561117357600080fd5b61117c8661093a565b156112ad576000868152602081905260409081902060038101805460ff19166001908117909155815481830154935160028085018054959b50600160a060020a039093169594929391928392859260001991831615610100029190910190911604801561122a5780601f106111ff5761010080835404028352916020019161122a565b820191906000526020600020905b81548152906001019060200180831161120d57829003601f168201915b505091505060006040518083038185875af192505050156112755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26112ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038501805460ff191690555b505050505050565b600083600160a060020a03811615156112cd57600080fd5b60055460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152808452959095208451815473ffffffffffffffffffffffffffffffffffffffff19169416939093178355516001830155925180519496509193909261134d9260028501929101906113ce565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156113c9576000838152602090206113c991810190830161144c565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061140f57805160ff191683800117855561143c565b8280016001018555821561143c579182015b8281111561143c578251825591602001919060010190611421565b5061144892915061144c565b5090565b610b4b91905b8082111561144857600081556001016114525600a165627a7a72305820e8ee551a5d8acd2ae22a24eec7633688fd4bbc740b3aa2cd8d47d9d6cb6847390029", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "owners", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "isOwner", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" }, { "name": "", "type": "address" } ], "name": "confirmations", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "transactions", "outputs": [ { "name": "destination", "type": "address" }, { "name": "value", "type": "uint256" }, { "name": "data", "type": "bytes" }, { "name": "executed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "transactionCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "MAX_OWNER_COUNT", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "required", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "initialOwners", "type": "address[]" }, { "name": "initialRequired", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "payable": true, "stateMutability": "payable", "type": "fallback" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "sender", "type": "address" }, { "indexed": true, "name": "transactionId", "type": "uint256" } ], "name": "Confirmation", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "sender", "type": "address" }, { "indexed": true, "name": "transactionId", "type": "uint256" } ], "name": "Revocation", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "transactionId", "type": "uint256" } ], "name": "Submission", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "transactionId", "type": "uint256" } ], "name": "Execution", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "transactionId", "type": "uint256" } ], "name": "ExecutionFailure", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "sender", "type": "address" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" } ], "name": "OwnerAddition", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "owner", "type": "address" } ], "name": "OwnerRemoval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "required", "type": "uint256" } ], "name": "RequirementChange", "type": "event" }, { "constant": false, "inputs": [ { "name": "owner", "type": "address" } ], "name": "addOwner", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "owner", "type": "address" } ], "name": "removeOwner", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "owner", "type": "address" }, { "name": "newOwner", "type": "address" } ], "name": "replaceOwner", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "newRequired", "type": "uint256" } ], "name": "changeRequirement", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "destination", "type": "address" }, { "name": "value", "type": "uint256" }, { "name": "data", "type": "bytes" } ], "name": "submitTransaction", "outputs": [ { "name": "transactionId", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "confirmTransaction", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "revokeConfirmation", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "executeTransaction", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "isConfirmed", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "getConfirmationCount", "outputs": [ { "name": "count", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "pending", "type": "bool" }, { "name": "executed", "type": "bool" } ], "name": "getTransactionCount", "outputs": [ { "name": "count", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "getOwners", "outputs": [ { "name": "", "type": "address[]" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "transactionId", "type": "uint256" } ], "name": "getConfirmations", "outputs": [ { "name": "_confirmations", "type": "address[]" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "from", "type": "uint256" }, { "name": "to", "type": "uint256" }, { "name": "pending", "type": "bool" }, { "name": "executed", "type": "bool" } ], "name": "getTransactionIds", "outputs": [ { "name": "_transactionIds", "type": "uint256[]" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/MultiSigWalletFactory.json ================================================ { "contractName": "MultiSigWalletFactory", "bytecode": "0x608060405234801561001057600080fd5b506119cb806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811461006657806357183c821461009b5780638f838478146100db578063f8f738081461010e575b600080fd5b34801561007257600080fd5b50610087600160a060020a0360043516610165565b604080519115158252519081900360200190f35b3480156100a757600080fd5b506100bf600160a060020a036004351660243561017a565b60408051600160a060020a039092168252519081900360200190f35b3480156100e757600080fd5b506100fc600160a060020a03600435166101b1565b60408051918252519081900360200190f35b34801561011a57600080fd5b50604080516020600480358082013583810280860185019096528085526100bf9536959394602494938501929182918501908490808284375094975050933594506101cc9350505050565b60006020819052908152604090205460ff1681565b60016020528160005260406000208181548110151561019557fe5b600091825260209091200154600160a060020a03169150829050565b600160a060020a031660009081526001602052604090205490565b600082826101d86102e9565b60208082018390526040808352845190830152835182916060830191868201910280838360005b838110156102175781810151838201526020016101ff565b505050509050019350505050604051809103906000f08015801561023f573d6000803e3d6000fd5b50905061024b81610251565b92915050565b600160a060020a038116600081815260208181526040808320805460ff19166001908117909155338085528184528285208054928301815585529383902001805473ffffffffffffffffffffffffffffffffffffffff19168517905580519283529082019290925281517f4fb057ad4a26ed17a57957fa69c306f11987596069b89521c511fc9a894e6161929181900390910190a150565b6040516116a6806102fa83390190560060806040523480156200001157600080fd5b50604051620016a6380380620016a68339810160405280516020820151910180519091906000908260328211156200004857600080fd5b818111156200005657600080fd5b8015156200006357600080fd5b8115156200007057600080fd5b600092505b845183101562000149576002600086858151811015156200009257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff16158015620000e957508451600090869085908110620000d357fe5b90602001906020020151600160a060020a031614155b1515620000f557600080fd5b60016002600087868151811015156200010a57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000075565b84516200015e90600390602088019062000170565b50505060049190915550620002049050565b828054828255906000526020600020908101928215620001c8579160200282015b82811115620001c85782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019062000191565b50620001d6929150620001da565b5090565b6200020191905b80821115620001d6578054600160a060020a0319168155600101620001e1565b90565b61149280620002146000396000f30060806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019257806320ea8d86146101b35780632f54bf6e146101cb5780633411c81c1461020057806354741525146102245780637065cb4814610255578063784547a7146102765780638b51d13f1461028e5780639ace38c2146102a6578063a0e67e2b14610361578063a8abe69a146103c6578063b5dc40c3146103eb578063b77bf60014610403578063ba51a6df14610418578063c01a8c8414610430578063c642747414610448578063d74f8edd146104b1578063dc8452cd146104c6578063e20056e6146104db578063ee22610b14610502575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561051a565b60408051600160a060020a039092168252519081900360200190f35b34801561019e57600080fd5b5061015c600160a060020a0360043516610542565b3480156101bf57600080fd5b5061015c6004356106b9565b3480156101d757600080fd5b506101ec600160a060020a0360043516610773565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600435600160a060020a0360243516610788565b34801561023057600080fd5b50610243600435151560243515156107a8565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015c600160a060020a0360043516610814565b34801561028257600080fd5b506101ec60043561093a565b34801561029a57600080fd5b506102436004356109be565b3480156102b257600080fd5b506102be600435610a2d565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561032357818101518382015260200161030b565b50505050905090810190601f1680156103505780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561036d57600080fd5b50610376610aeb565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103b257818101518382015260200161039a565b505050509050019250505060405180910390f35b3480156103d257600080fd5b5061037660043560243560443515156064351515610b4e565b3480156103f757600080fd5b50610376600435610c87565b34801561040f57600080fd5b50610243610e00565b34801561042457600080fd5b5061015c600435610e06565b34801561043c57600080fd5b5061015c600435610e86565b34801561045457600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610243948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610f519650505050505050565b3480156104bd57600080fd5b50610243610f70565b3480156104d257600080fd5b50610243610f75565b3480156104e757600080fd5b5061015c600160a060020a0360043581169060243516610f7b565b34801561050e57600080fd5b5061015c600435611105565b600380548290811061052857fe5b600091825260209091200154600160a060020a0316905081565b600033301461055057600080fd5b600160a060020a038216600090815260026020526040902054829060ff16151561057957600080fd5b600160a060020a0383166000908152600260205260408120805460ff1916905591505b600354600019018210156106545782600160a060020a03166003838154811015156105c357fe5b600091825260209091200154600160a060020a03161415610649576003805460001981019081106105f057fe5b60009182526020909120015460038054600160a060020a03909216918490811061061657fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550610654565b60019091019061059c565b60038054600019019061066790826113a5565b5060035460045411156106805760035461068090610e06565b604051600160a060020a038416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156106d757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561070357600080fd5b600084815260208190526040902060030154849060ff161561072457600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561080d578380156107d5575060008181526020819052604090206003015460ff16155b806107f957508280156107f9575060008181526020819052604090206003015460ff165b15610805576001820191505b6001016107ac565b5092915050565b33301461082057600080fd5b600160a060020a038116600090815260026020526040902054819060ff161561084857600080fd5b81600160a060020a038116151561085e57600080fd5b600354600454600190910190603282111561087857600080fd5b8181111561088557600080fd5b80151561089157600080fd5b81151561089d57600080fd5b600160a060020a038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b6003548110156109b7576000848152600160205260408120600380549192918490811061096857fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561099c576001820191505b6004548214156109af57600192506109b7565b60010161093f565b5050919050565b6000805b600354811015610a2757600083815260016020526040812060038054919291849081106109eb57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610a1f576001820191505b6001016109c2565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f8101889004880284018801909652858352600160a060020a0390931695909491929190830182828015610ad85780601f10610aad57610100808354040283529160200191610ad8565b820191906000526020600020905b815481529060010190602001808311610abb57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b4357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b25575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610b80578160200160208202803883390190505b50925060009150600090505b600554811015610c0757858015610bb5575060008181526020819052604090206003015460ff16155b80610bd95750848015610bd9575060008181526020819052604090206003015460ff165b15610bff57808383815181101515610bed57fe5b60209081029091010152600191909101905b600101610b8c565b878703604051908082528060200260200182016040528015610c33578160200160208202803883390190505b5093508790505b86811015610c7c578281815181101515610c5057fe5b9060200190602002015184898303815181101515610c6a57fe5b60209081029091010152600101610c3a565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610cbc578160200160208202803883390190505b50925060009150600090505b600354811015610d795760008581526001602052604081206003805491929184908110610cf157fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610d71576003805482908110610d2c57fe5b6000918252602090912001548351600160a060020a0390911690849084908110610d5257fe5b600160a060020a03909216602092830290910190910152600191909101905b600101610cc8565b81604051908082528060200260200182016040528015610da3578160200160208202803883390190505b509350600090505b81811015610df8578281815181101515610dc157fe5b906020019060200201518482815181101515610dd957fe5b600160a060020a03909216602092830290910190910152600101610dab565b505050919050565b60055481565b333014610e1257600080fd5b600354816032821115610e2457600080fd5b81811115610e3157600080fd5b801515610e3d57600080fd5b811515610e4957600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff161515610ea457600080fd5b6000828152602081905260409020548290600160a060020a03161515610ec957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff1615610ef457600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610f4a85611105565b5050505050565b6000610f5e8484846112b5565b9050610f6981610e86565b9392505050565b603281565b60045481565b6000333014610f8957600080fd5b600160a060020a038316600090815260026020526040902054839060ff161515610fb257600080fd5b600160a060020a038316600090815260026020526040902054839060ff1615610fda57600080fd5b600092505b60035483101561106b5784600160a060020a031660038481548110151561100257fe5b600091825260209091200154600160a060020a03161415611060578360038481548110151561102d57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555061106b565b600190920191610fdf565b600160a060020a03808616600081815260026020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b3360008181526002602052604081205490919060ff16151561112657600080fd5b60008381526001602090815260408083203380855292529091205484919060ff16151561115257600080fd5b600085815260208190526040902060030154859060ff161561117357600080fd5b61117c8661093a565b156112ad576000868152602081905260409081902060038101805460ff19166001908117909155815481830154935160028085018054959b50600160a060020a039093169594929391928392859260001991831615610100029190910190911604801561122a5780601f106111ff5761010080835404028352916020019161122a565b820191906000526020600020905b81548152906001019060200180831161120d57829003601f168201915b505091505060006040518083038185875af192505050156112755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26112ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038501805460ff191690555b505050505050565b600083600160a060020a03811615156112cd57600080fd5b60055460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152808452959095208451815473ffffffffffffffffffffffffffffffffffffffff19169416939093178355516001830155925180519496509193909261134d9260028501929101906113ce565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156113c9576000838152602090206113c991810190830161144c565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061140f57805160ff191683800117855561143c565b8280016001018555821561143c579182015b8281111561143c578251825591602001919060010190611421565b5061144892915061144c565b5090565b610b4b91905b8082111561144857600081556001016114525600a165627a7a72305820e8ee551a5d8acd2ae22a24eec7633688fd4bbc740b3aa2cd8d47d9d6cb6847390029a165627a7a72305820bfca035a444402a0fed02cb97f121f6142c3990834b45fe9d91cf63c9408a1800029", "deployedBytecode": "0x6080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811461006657806357183c821461009b5780638f838478146100db578063f8f738081461010e575b600080fd5b34801561007257600080fd5b50610087600160a060020a0360043516610165565b604080519115158252519081900360200190f35b3480156100a757600080fd5b506100bf600160a060020a036004351660243561017a565b60408051600160a060020a039092168252519081900360200190f35b3480156100e757600080fd5b506100fc600160a060020a03600435166101b1565b60408051918252519081900360200190f35b34801561011a57600080fd5b50604080516020600480358082013583810280860185019096528085526100bf9536959394602494938501929182918501908490808284375094975050933594506101cc9350505050565b60006020819052908152604090205460ff1681565b60016020528160005260406000208181548110151561019557fe5b600091825260209091200154600160a060020a03169150829050565b600160a060020a031660009081526001602052604090205490565b600082826101d86102e9565b60208082018390526040808352845190830152835182916060830191868201910280838360005b838110156102175781810151838201526020016101ff565b505050509050019350505050604051809103906000f08015801561023f573d6000803e3d6000fd5b50905061024b81610251565b92915050565b600160a060020a038116600081815260208181526040808320805460ff19166001908117909155338085528184528285208054928301815585529383902001805473ffffffffffffffffffffffffffffffffffffffff19168517905580519283529082019290925281517f4fb057ad4a26ed17a57957fa69c306f11987596069b89521c511fc9a894e6161929181900390910190a150565b6040516116a6806102fa83390190560060806040523480156200001157600080fd5b50604051620016a6380380620016a68339810160405280516020820151910180519091906000908260328211156200004857600080fd5b818111156200005657600080fd5b8015156200006357600080fd5b8115156200007057600080fd5b600092505b845183101562000149576002600086858151811015156200009257fe5b6020908102909101810151600160a060020a031682528101919091526040016000205460ff16158015620000e957508451600090869085908110620000d357fe5b90602001906020020151600160a060020a031614155b1515620000f557600080fd5b60016002600087868151811015156200010a57fe5b602090810291909101810151600160a060020a03168252810191909152604001600020805460ff19169115159190911790556001929092019162000075565b84516200015e90600390602088019062000170565b50505060049190915550620002049050565b828054828255906000526020600020908101928215620001c8579160200282015b82811115620001c85782518254600160a060020a031916600160a060020a0390911617825560209092019160019091019062000191565b50620001d6929150620001da565b5090565b6200020191905b80821115620001d6578054600160a060020a0319168155600101620001e1565b90565b61149280620002146000396000f30060806040526004361061011c5763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663025e7c27811461015e578063173825d91461019257806320ea8d86146101b35780632f54bf6e146101cb5780633411c81c1461020057806354741525146102245780637065cb4814610255578063784547a7146102765780638b51d13f1461028e5780639ace38c2146102a6578063a0e67e2b14610361578063a8abe69a146103c6578063b5dc40c3146103eb578063b77bf60014610403578063ba51a6df14610418578063c01a8c8414610430578063c642747414610448578063d74f8edd146104b1578063dc8452cd146104c6578063e20056e6146104db578063ee22610b14610502575b600034111561015c5760408051348152905133917fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c919081900360200190a25b005b34801561016a57600080fd5b5061017660043561051a565b60408051600160a060020a039092168252519081900360200190f35b34801561019e57600080fd5b5061015c600160a060020a0360043516610542565b3480156101bf57600080fd5b5061015c6004356106b9565b3480156101d757600080fd5b506101ec600160a060020a0360043516610773565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600435600160a060020a0360243516610788565b34801561023057600080fd5b50610243600435151560243515156107a8565b60408051918252519081900360200190f35b34801561026157600080fd5b5061015c600160a060020a0360043516610814565b34801561028257600080fd5b506101ec60043561093a565b34801561029a57600080fd5b506102436004356109be565b3480156102b257600080fd5b506102be600435610a2d565b6040518085600160a060020a0316600160a060020a031681526020018481526020018060200183151515158152602001828103825284818151815260200191508051906020019080838360005b8381101561032357818101518382015260200161030b565b50505050905090810190601f1680156103505780820380516001836020036101000a031916815260200191505b509550505050505060405180910390f35b34801561036d57600080fd5b50610376610aeb565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156103b257818101518382015260200161039a565b505050509050019250505060405180910390f35b3480156103d257600080fd5b5061037660043560243560443515156064351515610b4e565b3480156103f757600080fd5b50610376600435610c87565b34801561040f57600080fd5b50610243610e00565b34801561042457600080fd5b5061015c600435610e06565b34801561043c57600080fd5b5061015c600435610e86565b34801561045457600080fd5b50604080516020600460443581810135601f8101849004840285018401909552848452610243948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610f519650505050505050565b3480156104bd57600080fd5b50610243610f70565b3480156104d257600080fd5b50610243610f75565b3480156104e757600080fd5b5061015c600160a060020a0360043581169060243516610f7b565b34801561050e57600080fd5b5061015c600435611105565b600380548290811061052857fe5b600091825260209091200154600160a060020a0316905081565b600033301461055057600080fd5b600160a060020a038216600090815260026020526040902054829060ff16151561057957600080fd5b600160a060020a0383166000908152600260205260408120805460ff1916905591505b600354600019018210156106545782600160a060020a03166003838154811015156105c357fe5b600091825260209091200154600160a060020a03161415610649576003805460001981019081106105f057fe5b60009182526020909120015460038054600160a060020a03909216918490811061061657fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a03160217905550610654565b60019091019061059c565b60038054600019019061066790826113a5565b5060035460045411156106805760035461068090610e06565b604051600160a060020a038416907f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9090600090a2505050565b3360008181526002602052604090205460ff1615156106d757600080fd5b60008281526001602090815260408083203380855292529091205483919060ff16151561070357600080fd5b600084815260208190526040902060030154849060ff161561072457600080fd5b6000858152600160209081526040808320338085529252808320805460ff191690555187927ff6a317157440607f36269043eb55f1287a5a19ba2216afeab88cd46cbcfb88e991a35050505050565b60026020526000908152604090205460ff1681565b600160209081526000928352604080842090915290825290205460ff1681565b6000805b60055481101561080d578380156107d5575060008181526020819052604090206003015460ff16155b806107f957508280156107f9575060008181526020819052604090206003015460ff165b15610805576001820191505b6001016107ac565b5092915050565b33301461082057600080fd5b600160a060020a038116600090815260026020526040902054819060ff161561084857600080fd5b81600160a060020a038116151561085e57600080fd5b600354600454600190910190603282111561087857600080fd5b8181111561088557600080fd5b80151561089157600080fd5b81151561089d57600080fd5b600160a060020a038516600081815260026020526040808220805460ff1916600190811790915560038054918201815583527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b01805473ffffffffffffffffffffffffffffffffffffffff191684179055517ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d9190a25050505050565b600080805b6003548110156109b7576000848152600160205260408120600380549192918490811061096857fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff161561099c576001820191505b6004548214156109af57600192506109b7565b60010161093f565b5050919050565b6000805b600354811015610a2757600083815260016020526040812060038054919291849081106109eb57fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610a1f576001820191505b6001016109c2565b50919050565b6000602081815291815260409081902080546001808301546002808501805487516101009582161595909502600019011691909104601f8101889004880284018801909652858352600160a060020a0390931695909491929190830182828015610ad85780601f10610aad57610100808354040283529160200191610ad8565b820191906000526020600020905b815481529060010190602001808311610abb57829003601f168201915b5050506003909301549192505060ff1684565b60606003805480602002602001604051908101604052809291908181526020018280548015610b4357602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311610b25575b505050505090505b90565b606080600080600554604051908082528060200260200182016040528015610b80578160200160208202803883390190505b50925060009150600090505b600554811015610c0757858015610bb5575060008181526020819052604090206003015460ff16155b80610bd95750848015610bd9575060008181526020819052604090206003015460ff165b15610bff57808383815181101515610bed57fe5b60209081029091010152600191909101905b600101610b8c565b878703604051908082528060200260200182016040528015610c33578160200160208202803883390190505b5093508790505b86811015610c7c578281815181101515610c5057fe5b9060200190602002015184898303815181101515610c6a57fe5b60209081029091010152600101610c3a565b505050949350505050565b606080600080600380549050604051908082528060200260200182016040528015610cbc578160200160208202803883390190505b50925060009150600090505b600354811015610d795760008581526001602052604081206003805491929184908110610cf157fe5b6000918252602080832090910154600160a060020a0316835282019290925260400190205460ff1615610d71576003805482908110610d2c57fe5b6000918252602090912001548351600160a060020a0390911690849084908110610d5257fe5b600160a060020a03909216602092830290910190910152600191909101905b600101610cc8565b81604051908082528060200260200182016040528015610da3578160200160208202803883390190505b509350600090505b81811015610df8578281815181101515610dc157fe5b906020019060200201518482815181101515610dd957fe5b600160a060020a03909216602092830290910190910152600101610dab565b505050919050565b60055481565b333014610e1257600080fd5b600354816032821115610e2457600080fd5b81811115610e3157600080fd5b801515610e3d57600080fd5b811515610e4957600080fd5b60048390556040805184815290517fa3f1ee9126a074d9326c682f561767f710e927faa811f7a99829d49dc421797a9181900360200190a1505050565b3360008181526002602052604090205460ff161515610ea457600080fd5b6000828152602081905260409020548290600160a060020a03161515610ec957600080fd5b60008381526001602090815260408083203380855292529091205484919060ff1615610ef457600080fd5b6000858152600160208181526040808420338086529252808420805460ff1916909317909255905187927f4a504a94899432a9846e1aa406dceb1bcfd538bb839071d49d1e5e23f5be30ef91a3610f4a85611105565b5050505050565b6000610f5e8484846112b5565b9050610f6981610e86565b9392505050565b603281565b60045481565b6000333014610f8957600080fd5b600160a060020a038316600090815260026020526040902054839060ff161515610fb257600080fd5b600160a060020a038316600090815260026020526040902054839060ff1615610fda57600080fd5b600092505b60035483101561106b5784600160a060020a031660038481548110151561100257fe5b600091825260209091200154600160a060020a03161415611060578360038481548110151561102d57fe5b9060005260206000200160006101000a815481600160a060020a030219169083600160a060020a0316021790555061106b565b600190920191610fdf565b600160a060020a03808616600081815260026020526040808220805460ff1990811690915593881682528082208054909416600117909355915190917f8001553a916ef2f495d26a907cc54d96ed840d7bda71e73194bf5a9df7a76b9091a2604051600160a060020a038516907ff39e6e1eb0edcf53c221607b54b00cd28f3196fed0a24994dc308b8f611b682d90600090a25050505050565b3360008181526002602052604081205490919060ff16151561112657600080fd5b60008381526001602090815260408083203380855292529091205484919060ff16151561115257600080fd5b600085815260208190526040902060030154859060ff161561117357600080fd5b61117c8661093a565b156112ad576000868152602081905260409081902060038101805460ff19166001908117909155815481830154935160028085018054959b50600160a060020a039093169594929391928392859260001991831615610100029190910190911604801561122a5780601f106111ff5761010080835404028352916020019161122a565b820191906000526020600020905b81548152906001019060200180831161120d57829003601f168201915b505091505060006040518083038185875af192505050156112755760405186907f33e13ecb54c3076d8e8bb8c2881800a4d972b792045ffae98fdf46df365fed7590600090a26112ad565b60405186907f526441bb6c1aba3c9a4a6ca1d6545da9c2333c8c48343ef398eb858d72b7923690600090a260038501805460ff191690555b505050505050565b600083600160a060020a03811615156112cd57600080fd5b60055460408051608081018252600160a060020a0388811682526020808301898152838501898152600060608601819052878152808452959095208451815473ffffffffffffffffffffffffffffffffffffffff19169416939093178355516001830155925180519496509193909261134d9260028501929101906113ce565b50606091909101516003909101805460ff191691151591909117905560058054600101905560405182907fc0ba8fe4b176c1714197d43b9cc6bcf797a4a7461c5fe8d0ef6e184ae7601e5190600090a2509392505050565b8154818355818111156113c9576000838152602090206113c991810190830161144c565b505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061140f57805160ff191683800117855561143c565b8280016001018555821561143c579182015b8281111561143c578251825591602001919060010190611421565b5061144892915061144c565b5090565b610b4b91905b8082111561144857600081556001016114525600a165627a7a72305820e8ee551a5d8acd2ae22a24eec7633688fd4bbc740b3aa2cd8d47d9d6cb6847390029a165627a7a72305820bfca035a444402a0fed02cb97f121f6142c3990834b45fe9d91cf63c9408a1800029", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "isInstantiation", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" }, { "name": "", "type": "uint256" } ], "name": "instantiations", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "creator", "type": "address" } ], "name": "getInstantiationCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "instantiation", "type": "address" } ], "name": "ContractInstantiation", "type": "event" }, { "constant": false, "inputs": [ { "name": "_owners", "type": "address[]" }, { "name": "_required", "type": "uint256" } ], "name": "create", "outputs": [ { "name": "wallet", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x15f91c1936d854e74d6793efffe9f0b1a81098c5", "transactionHash": "0x52050d5dd130629109516b2c518d040f5e185fe4f2d56aee77af3e9493ffaff4" }, "4": { "events": {}, "links": {}, "address": "0x8c0938fe37e91a143fe25812c116241c9e49e14c", "transactionHash": "0x0216a9ba0b3bc6eebbc0afcc2a996515f57ed986740a1db763f075ffa3c2fb87" } } } ================================================ FILE: packages/artifacts/v1/Newsroom.json ================================================ { "contractName": "Newsroom", "bytecode": "0x60806040523480156200001157600080fd5b506040516200232738038062002327833981016040908152815160208301519183015160008054600160a060020a0319163317905590830192919091019062000063836401000000006200009b810204565b620000918282600060206040519081016040528060008152506200018c640100000000026401000000009004565b50505050620009f2565b600054600160a060020a03163314620000b357600080fd5b8051600010620000c257600080fd5b8051620000d79060059060208401906200094d565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc939092918291820190849080156200017b5780601f106200014f576101008083540402835291602001916200017b565b820191906000526020600020905b8154815290600101906020018083116200015d57829003601f168201915b50509250505060405180910390a150565b6000806040805190810160405280600681526020017f656469746f720000000000000000000000000000000000000000000000000000815250620001df336200034a640100000000026401000000009004565b80620001fb5750620001fb33826401000000006200035e810204565b15156200020757600080fd5b60048054600181019091559150600160a060020a0385161580156200022b57508351155b806200024b5750600160a060020a038516158015906200024b5750835115155b15156200025757600080fd5b60008281526002602052604090206001018054600160a060020a031916600160a060020a0387161790556200029882888887640100000000620003e4810204565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b8381101562000305578181015183820152602001620002eb565b50505050905090810190601f168015620003335780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a0390811691161490565b60006001826040518082805190602001908083835b60208310620003945780518252601f19909201916020918201910162000373565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600080600060045487101515620003fa57600080fd5b861515620004225762000416336401000000006200034a810204565b15156200042257600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936200049293928501929101906200094d565b506040820151600282015560608201518051620004ba9160038401916020909101906200094d565b50505050600182015482546200050691600160a060020a0316908990859085908110620004e357fe5b9060005260206000209060040201620005fd640100000000026401000000009004565b156200054b576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b83811015620005b85781810151838201526020016200059e565b50505050905090810190601f168015620005e65780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b60008080600160a060020a03861615806200062d5750600384015460026000196101006001841615020190911604155b156200066057600384015460026000196101006001841615020190911604156200065657600080fd5b60009250620007bc565b8354604080516c0100000000000000000000000030028152601481019290925251908190036034019020620006a39064010000000062001671620007c582021704565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a1693620007629390929091830182828015620007455780601f10620007195761010080835404028352916020019162000745565b820191906000526020600020905b8154815290600101906020018083116200072757829003601f168201915b5088949350506401000000006200171b6200087182021704915050565b600160a060020a0316146200077657600080fd5b506000818152600360205260409020805460ff1615806200079a5750848160010154145b1515620007a657600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106200083f5780518252601f1990920191602091820191016200081e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b600080600080845160411415156200088d576000935062000944565b50505060208201516040830151606084015160001a601b60ff82161015620008b357601b015b8060ff16601b14158015620008cc57508060ff16601c14155b15620008dc576000935062000944565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af115801562000937573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200099057805160ff1916838001178555620009c0565b82800160010185558215620009c0579182015b82811115620009c0578251825591602001919060010190620009a3565b50620009ce929150620009d2565b5090565b620009ef91905b80821115620009ce5760008155600101620009d9565b90565b6119258062000a026000396000f3006080604052600436106101065763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461010b5780630b7ad54c146101955780631bfe0308146102aa578063217fe6c6146102d95780632f54bf6e146103545780635614bdc8146103755780636192e3e81461039f57806365462d96146103ba578063715018a6146103ef5780637d72aa651461040457806384a1176c146104315780638da5cb5b146104de578063a54d19881461050f578063c47f00271461052a578063cc45969614610583578063e45e1c7d14610598578063e5975bdc146105cc578063efc97390146105ed578063f2fde38b14610605575b600080fd5b34801561011757600080fd5b50610120610626565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015a578181015183820152602001610142565b50505050905090810190601f1680156101875780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101a157600080fd5b506101ad6004356106b4565b60408051868152908101849052600160a060020a038316606082015260a060208083018281528751928401929092528651608084019160c08501919089019080838360005b8381101561020a5781810151838201526020016101f2565b50505050905090810190601f1680156102375780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561026a578181015183820152602001610252565b50505050905090810190601f1680156102975780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b3480156102b657600080fd5b506102d760048035600160a060020a031690602480359081019101356106ed565b005b3480156102e557600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610340958335600160a060020a03169536956044949193909101919081908401838280828437509497506107719650505050505050565b604080519115158252519081900360200190f35b34801561036057600080fd5b50610340600160a060020a03600435166107f5565b34801561038157600080fd5b5061038d600435610809565b60408051918252519081900360200190f35b3480156103ab57600080fd5b506101ad60043560243561081b565b3480156103c657600080fd5b506102d760048035906024803591600160a060020a0360443516916064359081019101356109b6565b3480156103fb57600080fd5b506102d7610b2b565b34801561041057600080fd5b506102d760048035600160a060020a03169060248035908101910135610b97565b34801561043d57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261038d94369492936024939284019190819084018382808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a89359a8a830135600160a060020a03169a91999098506060909101965091945090810192508190840183828082843750949750610c159650505050505050565b3480156104ea57600080fd5b506104f3610d9c565b60408051600160a060020a039092168252519081900360200190f35b34801561051b57600080fd5b50610340600435602435610dab565b34801561053657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d7943694929360249392840191908190840183828082843750949750610e059650505050505050565b34801561058f57600080fd5b5061038d610eee565b3480156105a457600080fd5b506102d760048035906024803580820192908101359160443591606435918201910135610ef4565b3480156105d857600080fd5b506102d7600160a060020a0360043516610fac565b3480156105f957600080fd5b5061034060043561101f565b34801561061157600080fd5b506102d7600160a060020a0360043516611043565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ac5780601f10610681576101008083540402835291602001916106ac565b820191906000526020600020905b81548152906001019060200180831161068f57829003601f168201915b505050505081565b6000818152600260205260408120546060908290819083906106db9087906000190161081b565b939a9299509097509550909350915050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610716336107f5565b8061072657506107263382610771565b151561073157600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611066945050505050565b50505050565b60006001826040518082805190602001908083835b602083106107a55780518252601f199092019160209182019101610786565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60009081526002602052604090205490565b600082815260026020526040812080546060918391829184918390881061084157600080fd5b815482908990811061084f57fe5b600091825260209182902060049190910201805460028083015460018781015481860180546040805161010095831615959095026000190190911695909504601f810189900489028401890190955284835295975093959193600160a060020a031692600388019286919083018282801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050845460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959950869450925084019050828280156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505090509650965096509650965050509295509295909350565b60008060408051908101604052806006815260200160d160020a6532b234ba37b9028152506109e4336107f5565b806109f457506109f43382610771565b15156109ff57600080fd5b6004548810610a0d57600080fd5b60008881526002602052604090206001810154909350600160a060020a03161580610a4757506001830154600160a060020a038781169116145b1515610a5257600080fd5b82548710610a5f57600080fd5b871515610a7a57610a6f336107f5565b1515610a7a57600080fd5b60018301805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388161790558254839088908110610ab257fe5b600091825260209091206004909102019150610ad26003830186866117f0565b50610ade868984611180565b1515610ae957600080fd5b85600160a060020a031687897f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6160405160405180910390a45050505050505050565b600054600160a060020a03163314610b4257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610bc0336107f5565b80610bd05750610bd03382610771565b1515610bdb57600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611323945050505050565b60008060408051908101604052806006815260200160d160020a6532b234ba37b902815250610c43336107f5565b80610c535750610c533382610771565b1515610c5e57600080fd5b60048054600181019091559150600160a060020a038516158015610c8157508351155b80610c9f5750600160a060020a03851615801590610c9f5750835115155b1515610caa57600080fd5b6000828152600260205260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038716179055610ced82888887611403565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d58578181015183820152602001610d40565b50505050905090810190601f168015610d855780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a031681565b600082815260026020526040812080548310610dc657600080fd5b8083815481101515610dd457fe5b6000918252602090912060036004909202010154600260001961010060018416150201909116041515949350505050565b600054600160a060020a03163314610e1c57600080fd5b8051600010610e2a57600080fd5b8051610e3d90600590602084019061186e565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc93909291829182019084908015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50509250505060405180910390a150565b60045481565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610f1d336107f5565b80610f2d5750610f2d3382610771565b1515610f3857600080fd5b610fa28787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a81528c955093508a92508991508190840183828082843750611403945050505050565b5050505050505050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610fd5336107f5565b80610fe55750610fe53382610771565b1515610ff057600080fd5b61101b8260408051908101604052806006815260200160d160020a6532b234ba37b902815250611323565b5050565b60008181526002602052604081205461103d90839060001901610dab565b92915050565b600054600160a060020a0316331461105a57600080fd5b611063816115f4565b50565b6001816040518082805190602001908083835b602083106110985780518252601f199092019160209182019101611079565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b8381101561114257818101518382015260200161112a565b50505050905090810190601f16801561116f5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b60008080600160a060020a03861615806111af5750600384015460026000196101006001841615020190911604155b156111df57600384015460026000196101006001841615020190911604156111d657600080fd5b6000925061131a565b8354604080516c010000000000000000000000003002815260148101929092525190819003603401902061121290611671565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a16936112c393909290918301828280156112af5780601f10611284576101008083540402835291602001916112af565b820191906000526020600020905b81548152906001019060200180831161129257829003601f168201915b50889493505063ffffffff61171b16915050565b600160a060020a0316146112d657600080fd5b506000818152600360205260409020805460ff1615806112f95750848160010154145b151561130457600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b600180826040518082805190602001908083835b602083106113565780518252601f199092019160209182019101611337565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed965089955093849384019290860191908190849084908381101561114257818101518382015260200161112a565b60008060006004548710151561141857600080fd5b86151561143357611428336107f5565b151561143357600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936114a1939285019291019061186e565b5060408201516002820155606082015180516114c791600384019160209091019061186e565b505050506001820154825461150191600160a060020a03169089908590859081106114ee57fe5b9060005260206000209060040201611180565b15611545576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b838110156115b0578181015183820152602001611598565b50505050905090810190601f1680156115dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b600160a060020a038116151561160957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106116e95780518252601f1990920191602091820191016116ca565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000806000808451604114151561173557600093506117e7565b50505060208201516040830151606084015160001a601b60ff8216101561175a57601b015b8060ff16601b1415801561177257508060ff16601c14155b1561178057600093506117e7565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156117da573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118315782800160ff1982351617855561185e565b8280016001018555821561185e579182015b8281111561185e578235825591602001919060010190611843565b5061186a9291506118dc565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118af57805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e5782518255916020019190600101906118c1565b6118f691905b8082111561186a57600081556001016118e2565b905600a165627a7a72305820bbb8f14f037c6a58da466d96dc1aa6aa3e562c829066ed2d14b761e1b2a6b1f20029", "deployedBytecode": "0x6080604052600436106101065763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461010b5780630b7ad54c146101955780631bfe0308146102aa578063217fe6c6146102d95780632f54bf6e146103545780635614bdc8146103755780636192e3e81461039f57806365462d96146103ba578063715018a6146103ef5780637d72aa651461040457806384a1176c146104315780638da5cb5b146104de578063a54d19881461050f578063c47f00271461052a578063cc45969614610583578063e45e1c7d14610598578063e5975bdc146105cc578063efc97390146105ed578063f2fde38b14610605575b600080fd5b34801561011757600080fd5b50610120610626565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015a578181015183820152602001610142565b50505050905090810190601f1680156101875780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101a157600080fd5b506101ad6004356106b4565b60408051868152908101849052600160a060020a038316606082015260a060208083018281528751928401929092528651608084019160c08501919089019080838360005b8381101561020a5781810151838201526020016101f2565b50505050905090810190601f1680156102375780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561026a578181015183820152602001610252565b50505050905090810190601f1680156102975780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b3480156102b657600080fd5b506102d760048035600160a060020a031690602480359081019101356106ed565b005b3480156102e557600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610340958335600160a060020a03169536956044949193909101919081908401838280828437509497506107719650505050505050565b604080519115158252519081900360200190f35b34801561036057600080fd5b50610340600160a060020a03600435166107f5565b34801561038157600080fd5b5061038d600435610809565b60408051918252519081900360200190f35b3480156103ab57600080fd5b506101ad60043560243561081b565b3480156103c657600080fd5b506102d760048035906024803591600160a060020a0360443516916064359081019101356109b6565b3480156103fb57600080fd5b506102d7610b2b565b34801561041057600080fd5b506102d760048035600160a060020a03169060248035908101910135610b97565b34801561043d57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261038d94369492936024939284019190819084018382808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a89359a8a830135600160a060020a03169a91999098506060909101965091945090810192508190840183828082843750949750610c159650505050505050565b3480156104ea57600080fd5b506104f3610d9c565b60408051600160a060020a039092168252519081900360200190f35b34801561051b57600080fd5b50610340600435602435610dab565b34801561053657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d7943694929360249392840191908190840183828082843750949750610e059650505050505050565b34801561058f57600080fd5b5061038d610eee565b3480156105a457600080fd5b506102d760048035906024803580820192908101359160443591606435918201910135610ef4565b3480156105d857600080fd5b506102d7600160a060020a0360043516610fac565b3480156105f957600080fd5b5061034060043561101f565b34801561061157600080fd5b506102d7600160a060020a0360043516611043565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ac5780601f10610681576101008083540402835291602001916106ac565b820191906000526020600020905b81548152906001019060200180831161068f57829003601f168201915b505050505081565b6000818152600260205260408120546060908290819083906106db9087906000190161081b565b939a9299509097509550909350915050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610716336107f5565b8061072657506107263382610771565b151561073157600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611066945050505050565b50505050565b60006001826040518082805190602001908083835b602083106107a55780518252601f199092019160209182019101610786565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60009081526002602052604090205490565b600082815260026020526040812080546060918391829184918390881061084157600080fd5b815482908990811061084f57fe5b600091825260209182902060049190910201805460028083015460018781015481860180546040805161010095831615959095026000190190911695909504601f810189900489028401890190955284835295975093959193600160a060020a031692600388019286919083018282801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050845460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959950869450925084019050828280156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505090509650965096509650965050509295509295909350565b60008060408051908101604052806006815260200160d160020a6532b234ba37b9028152506109e4336107f5565b806109f457506109f43382610771565b15156109ff57600080fd5b6004548810610a0d57600080fd5b60008881526002602052604090206001810154909350600160a060020a03161580610a4757506001830154600160a060020a038781169116145b1515610a5257600080fd5b82548710610a5f57600080fd5b871515610a7a57610a6f336107f5565b1515610a7a57600080fd5b60018301805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388161790558254839088908110610ab257fe5b600091825260209091206004909102019150610ad26003830186866117f0565b50610ade868984611180565b1515610ae957600080fd5b85600160a060020a031687897f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6160405160405180910390a45050505050505050565b600054600160a060020a03163314610b4257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610bc0336107f5565b80610bd05750610bd03382610771565b1515610bdb57600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611323945050505050565b60008060408051908101604052806006815260200160d160020a6532b234ba37b902815250610c43336107f5565b80610c535750610c533382610771565b1515610c5e57600080fd5b60048054600181019091559150600160a060020a038516158015610c8157508351155b80610c9f5750600160a060020a03851615801590610c9f5750835115155b1515610caa57600080fd5b6000828152600260205260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038716179055610ced82888887611403565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d58578181015183820152602001610d40565b50505050905090810190601f168015610d855780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a031681565b600082815260026020526040812080548310610dc657600080fd5b8083815481101515610dd457fe5b6000918252602090912060036004909202010154600260001961010060018416150201909116041515949350505050565b600054600160a060020a03163314610e1c57600080fd5b8051600010610e2a57600080fd5b8051610e3d90600590602084019061186e565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc93909291829182019084908015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50509250505060405180910390a150565b60045481565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610f1d336107f5565b80610f2d5750610f2d3382610771565b1515610f3857600080fd5b610fa28787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a81528c955093508a92508991508190840183828082843750611403945050505050565b5050505050505050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610fd5336107f5565b80610fe55750610fe53382610771565b1515610ff057600080fd5b61101b8260408051908101604052806006815260200160d160020a6532b234ba37b902815250611323565b5050565b60008181526002602052604081205461103d90839060001901610dab565b92915050565b600054600160a060020a0316331461105a57600080fd5b611063816115f4565b50565b6001816040518082805190602001908083835b602083106110985780518252601f199092019160209182019101611079565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b8381101561114257818101518382015260200161112a565b50505050905090810190601f16801561116f5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b60008080600160a060020a03861615806111af5750600384015460026000196101006001841615020190911604155b156111df57600384015460026000196101006001841615020190911604156111d657600080fd5b6000925061131a565b8354604080516c010000000000000000000000003002815260148101929092525190819003603401902061121290611671565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a16936112c393909290918301828280156112af5780601f10611284576101008083540402835291602001916112af565b820191906000526020600020905b81548152906001019060200180831161129257829003601f168201915b50889493505063ffffffff61171b16915050565b600160a060020a0316146112d657600080fd5b506000818152600360205260409020805460ff1615806112f95750848160010154145b151561130457600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b600180826040518082805190602001908083835b602083106113565780518252601f199092019160209182019101611337565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed965089955093849384019290860191908190849084908381101561114257818101518382015260200161112a565b60008060006004548710151561141857600080fd5b86151561143357611428336107f5565b151561143357600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936114a1939285019291019061186e565b5060408201516002820155606082015180516114c791600384019160209091019061186e565b505050506001820154825461150191600160a060020a03169089908590859081106114ee57fe5b9060005260206000209060040201611180565b15611545576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b838110156115b0578181015183820152602001611598565b50505050905090810190601f1680156115dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b600160a060020a038116151561160957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106116e95780518252601f1990920191602091820191016116ca565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000806000808451604114151561173557600093506117e7565b50505060208201516040830151606084015160001a601b60ff8216101561175a57601b015b8060ff16601b1415801561177257508060ff16601c14155b1561178057600093506117e7565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156117da573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118315782800160ff1982351617855561185e565b8280016001018555821561185e579182015b8281111561185e578235825591602001919060010190611843565b5061186a9291506118dc565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118af57805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e5782518255916020019190600101906118c1565b6118f691905b8082111561186a57600081556001016118e2565b905600a165627a7a72305820bbb8f14f037c6a58da466d96dc1aa6aa3e562c829066ed2d14b761e1b2a6b1f20029", "abi": [ { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" }, { "name": "role", "type": "string" } ], "name": "hasRole", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "user", "type": "address" } ], "name": "isOwner", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "contentCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "name": "newsroomName", "type": "string" }, { "name": "charterUri", "type": "string" }, { "name": "charterHash", "type": "bytes32" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "editor", "type": "address" }, { "indexed": true, "name": "contentId", "type": "uint256" }, { "indexed": false, "name": "uri", "type": "string" } ], "name": "ContentPublished", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "contentId", "type": "uint256" }, { "indexed": true, "name": "revisionId", "type": "uint256" }, { "indexed": true, "name": "author", "type": "address" } ], "name": "RevisionSigned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "editor", "type": "address" }, { "indexed": true, "name": "contentId", "type": "uint256" }, { "indexed": true, "name": "revisionId", "type": "uint256" }, { "indexed": false, "name": "uri", "type": "string" } ], "name": "RevisionUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "newName", "type": "string" } ], "name": "NameChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "granter", "type": "address" }, { "indexed": true, "name": "grantee", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": true, "inputs": [ { "name": "contentId", "type": "uint256" } ], "name": "getContent", "outputs": [ { "name": "contentHash", "type": "bytes32" }, { "name": "uri", "type": "string" }, { "name": "timestamp", "type": "uint256" }, { "name": "author", "type": "address" }, { "name": "signature", "type": "bytes" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "contentId", "type": "uint256" }, { "name": "revisionId", "type": "uint256" } ], "name": "getRevision", "outputs": [ { "name": "contentHash", "type": "bytes32" }, { "name": "uri", "type": "string" }, { "name": "timestamp", "type": "uint256" }, { "name": "author", "type": "address" }, { "name": "signature", "type": "bytes" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "contentId", "type": "uint256" } ], "name": "revisionCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "contentId", "type": "uint256" } ], "name": "isContentSigned", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "contentId", "type": "uint256" }, { "name": "revisionId", "type": "uint256" } ], "name": "isRevisionSigned", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "newName", "type": "string" } ], "name": "setName", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "who", "type": "address" }, { "name": "role", "type": "string" } ], "name": "addRole", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "who", "type": "address" } ], "name": "addEditor", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "who", "type": "address" }, { "name": "role", "type": "string" } ], "name": "removeRole", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "contentUri", "type": "string" }, { "name": "contentHash", "type": "bytes32" }, { "name": "author", "type": "address" }, { "name": "signature", "type": "bytes" } ], "name": "publishContent", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "contentId", "type": "uint256" }, { "name": "contentUri", "type": "string" }, { "name": "contentHash", "type": "bytes32" }, { "name": "signature", "type": "bytes" } ], "name": "updateRevision", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "contentId", "type": "uint256" }, { "name": "revisionId", "type": "uint256" }, { "name": "author", "type": "address" }, { "name": "signature", "type": "bytes" } ], "name": "signRevision", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/NewsroomFactory.json ================================================ { "contractName": "NewsroomFactory", "bytecode": "0x608060405234801561001057600080fd5b50604051602080612a6f833981016040525160028054600160a060020a031916600160a060020a03909216919091179055612a1f806100506000396000f3006080604052600436106200007e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811462000083578063421b58d614620000bb57806357183c8214620000ef57806360bb9dab14620001165780638f83847814620001f25780639ec94e991462000228575b600080fd5b3480156200009057600080fd5b50620000a7600160a060020a03600435166200024c565b604080519115158252519081900360200190f35b348015620000c857600080fd5b50620000d362000261565b60408051600160a060020a039092168252519081900360200190f35b348015620000fc57600080fd5b50620000d3600160a060020a036004351660243562000270565b3480156200012357600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452620000d394369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020808901358a01803580830284810184018652818552999c8b359c909b909a9501985092965081019450909250829190850190849080828437509497505093359450620002a89350505050565b348015620001ff57600080fd5b5062000216600160a060020a0360043516620005ed565b60408051918252519081900360200190f35b3480156200023557600080fd5b50620000d3600160a060020a036004351662000608565b60006020819052908152604090205460ff1681565b600254600160a060020a031681565b6001602052816000526040600020818154811015156200028c57fe5b600091825260209091200154600160a060020a03169150829050565b600254604080517ff8f7380800000000000000000000000000000000000000000000000000000000815260248101849052600481019182528451604482015284516000938493600160a060020a039091169263f8f7380892889288929091829160640190602080870191028083838c5b838110156200033257818101518382015260200162000318565b505050509050019350505050602060405180830381600087803b1580156200035957600080fd5b505af11580156200036e573d6000803e3d6000fd5b505050506040513d60208110156200038557600080fd5b5051905086868662000396620006bb565b60408101829052606080825284519082015283518190602080830191608084019188019080838360005b83811015620003da578181015183820152602001620003c0565b50505050905090810190601f168015620004085780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b838110156200043d57818101518382015260200162000423565b50505050905090810190601f1680156200046b5780820380516001836020036101000a031916815260200191505b5095505050505050604051809103906000f08015801562000490573d6000803e3d6000fd5b50604080517fe5975bdc0000000000000000000000000000000000000000000000000000000081523360048201529051919350600160a060020a0384169163e5975bdc9160248082019260009290919082900301818387803b158015620004f657600080fd5b505af11580156200050b573d6000803e3d6000fd5b5050505081600160a060020a031663f2fde38b826040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156200058457600080fd5b505af115801562000599573d6000803e3d6000fd5b50505050600160a060020a038181166000908152600360205260409020805473ffffffffffffffffffffffffffffffffffffffff1916918416919091179055620005e38262000623565b5095945050505050565b600160a060020a031660009081526001602052604090205490565b600360205260009081526040902054600160a060020a031681565b600160a060020a038116600081815260208181526040808320805460ff19166001908117909155338085528184528285208054928301815585529383902001805473ffffffffffffffffffffffffffffffffffffffff19168517905580519283529082019290925281517f4fb057ad4a26ed17a57957fa69c306f11987596069b89521c511fc9a894e6161929181900390910190a150565b60405161232780620006cd83390190560060806040523480156200001157600080fd5b506040516200232738038062002327833981016040908152815160208301519183015160008054600160a060020a0319163317905590830192919091019062000063836401000000006200009b810204565b620000918282600060206040519081016040528060008152506200018c640100000000026401000000009004565b50505050620009f2565b600054600160a060020a03163314620000b357600080fd5b8051600010620000c257600080fd5b8051620000d79060059060208401906200094d565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc939092918291820190849080156200017b5780601f106200014f576101008083540402835291602001916200017b565b820191906000526020600020905b8154815290600101906020018083116200015d57829003601f168201915b50509250505060405180910390a150565b6000806040805190810160405280600681526020017f656469746f720000000000000000000000000000000000000000000000000000815250620001df336200034a640100000000026401000000009004565b80620001fb5750620001fb33826401000000006200035e810204565b15156200020757600080fd5b60048054600181019091559150600160a060020a0385161580156200022b57508351155b806200024b5750600160a060020a038516158015906200024b5750835115155b15156200025757600080fd5b60008281526002602052604090206001018054600160a060020a031916600160a060020a0387161790556200029882888887640100000000620003e4810204565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b8381101562000305578181015183820152602001620002eb565b50505050905090810190601f168015620003335780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a0390811691161490565b60006001826040518082805190602001908083835b60208310620003945780518252601f19909201916020918201910162000373565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600080600060045487101515620003fa57600080fd5b861515620004225762000416336401000000006200034a810204565b15156200042257600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936200049293928501929101906200094d565b506040820151600282015560608201518051620004ba9160038401916020909101906200094d565b50505050600182015482546200050691600160a060020a0316908990859085908110620004e357fe5b9060005260206000209060040201620005fd640100000000026401000000009004565b156200054b576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b83811015620005b85781810151838201526020016200059e565b50505050905090810190601f168015620005e65780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b60008080600160a060020a03861615806200062d5750600384015460026000196101006001841615020190911604155b156200066057600384015460026000196101006001841615020190911604156200065657600080fd5b60009250620007bc565b8354604080516c0100000000000000000000000030028152601481019290925251908190036034019020620006a39064010000000062001671620007c582021704565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a1693620007629390929091830182828015620007455780601f10620007195761010080835404028352916020019162000745565b820191906000526020600020905b8154815290600101906020018083116200072757829003601f168201915b5088949350506401000000006200171b6200087182021704915050565b600160a060020a0316146200077657600080fd5b506000818152600360205260409020805460ff1615806200079a5750848160010154145b1515620007a657600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106200083f5780518252601f1990920191602091820191016200081e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b600080600080845160411415156200088d576000935062000944565b50505060208201516040830151606084015160001a601b60ff82161015620008b357601b015b8060ff16601b14158015620008cc57508060ff16601c14155b15620008dc576000935062000944565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af115801562000937573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200099057805160ff1916838001178555620009c0565b82800160010185558215620009c0579182015b82811115620009c0578251825591602001919060010190620009a3565b50620009ce929150620009d2565b5090565b620009ef91905b80821115620009ce5760008155600101620009d9565b90565b6119258062000a026000396000f3006080604052600436106101065763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461010b5780630b7ad54c146101955780631bfe0308146102aa578063217fe6c6146102d95780632f54bf6e146103545780635614bdc8146103755780636192e3e81461039f57806365462d96146103ba578063715018a6146103ef5780637d72aa651461040457806384a1176c146104315780638da5cb5b146104de578063a54d19881461050f578063c47f00271461052a578063cc45969614610583578063e45e1c7d14610598578063e5975bdc146105cc578063efc97390146105ed578063f2fde38b14610605575b600080fd5b34801561011757600080fd5b50610120610626565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015a578181015183820152602001610142565b50505050905090810190601f1680156101875780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101a157600080fd5b506101ad6004356106b4565b60408051868152908101849052600160a060020a038316606082015260a060208083018281528751928401929092528651608084019160c08501919089019080838360005b8381101561020a5781810151838201526020016101f2565b50505050905090810190601f1680156102375780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561026a578181015183820152602001610252565b50505050905090810190601f1680156102975780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b3480156102b657600080fd5b506102d760048035600160a060020a031690602480359081019101356106ed565b005b3480156102e557600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610340958335600160a060020a03169536956044949193909101919081908401838280828437509497506107719650505050505050565b604080519115158252519081900360200190f35b34801561036057600080fd5b50610340600160a060020a03600435166107f5565b34801561038157600080fd5b5061038d600435610809565b60408051918252519081900360200190f35b3480156103ab57600080fd5b506101ad60043560243561081b565b3480156103c657600080fd5b506102d760048035906024803591600160a060020a0360443516916064359081019101356109b6565b3480156103fb57600080fd5b506102d7610b2b565b34801561041057600080fd5b506102d760048035600160a060020a03169060248035908101910135610b97565b34801561043d57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261038d94369492936024939284019190819084018382808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a89359a8a830135600160a060020a03169a91999098506060909101965091945090810192508190840183828082843750949750610c159650505050505050565b3480156104ea57600080fd5b506104f3610d9c565b60408051600160a060020a039092168252519081900360200190f35b34801561051b57600080fd5b50610340600435602435610dab565b34801561053657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d7943694929360249392840191908190840183828082843750949750610e059650505050505050565b34801561058f57600080fd5b5061038d610eee565b3480156105a457600080fd5b506102d760048035906024803580820192908101359160443591606435918201910135610ef4565b3480156105d857600080fd5b506102d7600160a060020a0360043516610fac565b3480156105f957600080fd5b5061034060043561101f565b34801561061157600080fd5b506102d7600160a060020a0360043516611043565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ac5780601f10610681576101008083540402835291602001916106ac565b820191906000526020600020905b81548152906001019060200180831161068f57829003601f168201915b505050505081565b6000818152600260205260408120546060908290819083906106db9087906000190161081b565b939a9299509097509550909350915050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610716336107f5565b8061072657506107263382610771565b151561073157600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611066945050505050565b50505050565b60006001826040518082805190602001908083835b602083106107a55780518252601f199092019160209182019101610786565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60009081526002602052604090205490565b600082815260026020526040812080546060918391829184918390881061084157600080fd5b815482908990811061084f57fe5b600091825260209182902060049190910201805460028083015460018781015481860180546040805161010095831615959095026000190190911695909504601f810189900489028401890190955284835295975093959193600160a060020a031692600388019286919083018282801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050845460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959950869450925084019050828280156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505090509650965096509650965050509295509295909350565b60008060408051908101604052806006815260200160d160020a6532b234ba37b9028152506109e4336107f5565b806109f457506109f43382610771565b15156109ff57600080fd5b6004548810610a0d57600080fd5b60008881526002602052604090206001810154909350600160a060020a03161580610a4757506001830154600160a060020a038781169116145b1515610a5257600080fd5b82548710610a5f57600080fd5b871515610a7a57610a6f336107f5565b1515610a7a57600080fd5b60018301805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388161790558254839088908110610ab257fe5b600091825260209091206004909102019150610ad26003830186866117f0565b50610ade868984611180565b1515610ae957600080fd5b85600160a060020a031687897f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6160405160405180910390a45050505050505050565b600054600160a060020a03163314610b4257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610bc0336107f5565b80610bd05750610bd03382610771565b1515610bdb57600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611323945050505050565b60008060408051908101604052806006815260200160d160020a6532b234ba37b902815250610c43336107f5565b80610c535750610c533382610771565b1515610c5e57600080fd5b60048054600181019091559150600160a060020a038516158015610c8157508351155b80610c9f5750600160a060020a03851615801590610c9f5750835115155b1515610caa57600080fd5b6000828152600260205260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038716179055610ced82888887611403565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d58578181015183820152602001610d40565b50505050905090810190601f168015610d855780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a031681565b600082815260026020526040812080548310610dc657600080fd5b8083815481101515610dd457fe5b6000918252602090912060036004909202010154600260001961010060018416150201909116041515949350505050565b600054600160a060020a03163314610e1c57600080fd5b8051600010610e2a57600080fd5b8051610e3d90600590602084019061186e565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc93909291829182019084908015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50509250505060405180910390a150565b60045481565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610f1d336107f5565b80610f2d5750610f2d3382610771565b1515610f3857600080fd5b610fa28787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a81528c955093508a92508991508190840183828082843750611403945050505050565b5050505050505050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610fd5336107f5565b80610fe55750610fe53382610771565b1515610ff057600080fd5b61101b8260408051908101604052806006815260200160d160020a6532b234ba37b902815250611323565b5050565b60008181526002602052604081205461103d90839060001901610dab565b92915050565b600054600160a060020a0316331461105a57600080fd5b611063816115f4565b50565b6001816040518082805190602001908083835b602083106110985780518252601f199092019160209182019101611079565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b8381101561114257818101518382015260200161112a565b50505050905090810190601f16801561116f5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b60008080600160a060020a03861615806111af5750600384015460026000196101006001841615020190911604155b156111df57600384015460026000196101006001841615020190911604156111d657600080fd5b6000925061131a565b8354604080516c010000000000000000000000003002815260148101929092525190819003603401902061121290611671565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a16936112c393909290918301828280156112af5780601f10611284576101008083540402835291602001916112af565b820191906000526020600020905b81548152906001019060200180831161129257829003601f168201915b50889493505063ffffffff61171b16915050565b600160a060020a0316146112d657600080fd5b506000818152600360205260409020805460ff1615806112f95750848160010154145b151561130457600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b600180826040518082805190602001908083835b602083106113565780518252601f199092019160209182019101611337565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed965089955093849384019290860191908190849084908381101561114257818101518382015260200161112a565b60008060006004548710151561141857600080fd5b86151561143357611428336107f5565b151561143357600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936114a1939285019291019061186e565b5060408201516002820155606082015180516114c791600384019160209091019061186e565b505050506001820154825461150191600160a060020a03169089908590859081106114ee57fe5b9060005260206000209060040201611180565b15611545576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b838110156115b0578181015183820152602001611598565b50505050905090810190601f1680156115dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b600160a060020a038116151561160957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106116e95780518252601f1990920191602091820191016116ca565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000806000808451604114151561173557600093506117e7565b50505060208201516040830151606084015160001a601b60ff8216101561175a57601b015b8060ff16601b1415801561177257508060ff16601c14155b1561178057600093506117e7565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156117da573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118315782800160ff1982351617855561185e565b8280016001018555821561185e579182015b8281111561185e578235825591602001919060010190611843565b5061186a9291506118dc565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118af57805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e5782518255916020019190600101906118c1565b6118f691905b8082111561186a57600081556001016118e2565b905600a165627a7a72305820bbb8f14f037c6a58da466d96dc1aa6aa3e562c829066ed2d14b761e1b2a6b1f20029a165627a7a7230582061abee9df0f5aab95e391427cf7f772ee5fa9ba914d17d428b32b983c8fdc3ca0029", "deployedBytecode": "0x6080604052600436106200007e5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416632f4f3316811462000083578063421b58d614620000bb57806357183c8214620000ef57806360bb9dab14620001165780638f83847814620001f25780639ec94e991462000228575b600080fd5b3480156200009057600080fd5b50620000a7600160a060020a03600435166200024c565b604080519115158252519081900360200190f35b348015620000c857600080fd5b50620000d362000261565b60408051600160a060020a039092168252519081900360200190f35b348015620000fc57600080fd5b50620000d3600160a060020a036004351660243562000270565b3480156200012357600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452620000d394369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020808901358a01803580830284810184018652818552999c8b359c909b909a9501985092965081019450909250829190850190849080828437509497505093359450620002a89350505050565b348015620001ff57600080fd5b5062000216600160a060020a0360043516620005ed565b60408051918252519081900360200190f35b3480156200023557600080fd5b50620000d3600160a060020a036004351662000608565b60006020819052908152604090205460ff1681565b600254600160a060020a031681565b6001602052816000526040600020818154811015156200028c57fe5b600091825260209091200154600160a060020a03169150829050565b600254604080517ff8f7380800000000000000000000000000000000000000000000000000000000815260248101849052600481019182528451604482015284516000938493600160a060020a039091169263f8f7380892889288929091829160640190602080870191028083838c5b838110156200033257818101518382015260200162000318565b505050509050019350505050602060405180830381600087803b1580156200035957600080fd5b505af11580156200036e573d6000803e3d6000fd5b505050506040513d60208110156200038557600080fd5b5051905086868662000396620006bb565b60408101829052606080825284519082015283518190602080830191608084019188019080838360005b83811015620003da578181015183820152602001620003c0565b50505050905090810190601f168015620004085780820380516001836020036101000a031916815260200191505b50838103825285518152855160209182019187019080838360005b838110156200043d57818101518382015260200162000423565b50505050905090810190601f1680156200046b5780820380516001836020036101000a031916815260200191505b5095505050505050604051809103906000f08015801562000490573d6000803e3d6000fd5b50604080517fe5975bdc0000000000000000000000000000000000000000000000000000000081523360048201529051919350600160a060020a0384169163e5975bdc9160248082019260009290919082900301818387803b158015620004f657600080fd5b505af11580156200050b573d6000803e3d6000fd5b5050505081600160a060020a031663f2fde38b826040518263ffffffff167c01000000000000000000000000000000000000000000000000000000000281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156200058457600080fd5b505af115801562000599573d6000803e3d6000fd5b50505050600160a060020a038181166000908152600360205260409020805473ffffffffffffffffffffffffffffffffffffffff1916918416919091179055620005e38262000623565b5095945050505050565b600160a060020a031660009081526001602052604090205490565b600360205260009081526040902054600160a060020a031681565b600160a060020a038116600081815260208181526040808320805460ff19166001908117909155338085528184528285208054928301815585529383902001805473ffffffffffffffffffffffffffffffffffffffff19168517905580519283529082019290925281517f4fb057ad4a26ed17a57957fa69c306f11987596069b89521c511fc9a894e6161929181900390910190a150565b60405161232780620006cd83390190560060806040523480156200001157600080fd5b506040516200232738038062002327833981016040908152815160208301519183015160008054600160a060020a0319163317905590830192919091019062000063836401000000006200009b810204565b620000918282600060206040519081016040528060008152506200018c640100000000026401000000009004565b50505050620009f2565b600054600160a060020a03163314620000b357600080fd5b8051600010620000c257600080fd5b8051620000d79060059060208401906200094d565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc939092918291820190849080156200017b5780601f106200014f576101008083540402835291602001916200017b565b820191906000526020600020905b8154815290600101906020018083116200015d57829003601f168201915b50509250505060405180910390a150565b6000806040805190810160405280600681526020017f656469746f720000000000000000000000000000000000000000000000000000815250620001df336200034a640100000000026401000000009004565b80620001fb5750620001fb33826401000000006200035e810204565b15156200020757600080fd5b60048054600181019091559150600160a060020a0385161580156200022b57508351155b806200024b5750600160a060020a038516158015906200024b5750835115155b15156200025757600080fd5b60008281526002602052604090206001018054600160a060020a031916600160a060020a0387161790556200029882888887640100000000620003e4810204565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b8381101562000305578181015183820152602001620002eb565b50505050905090810190601f168015620003335780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a0390811691161490565b60006001826040518082805190602001908083835b60208310620003945780518252601f19909201916020918201910162000373565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600080600060045487101515620003fa57600080fd5b861515620004225762000416336401000000006200034a810204565b15156200042257600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936200049293928501929101906200094d565b506040820151600282015560608201518051620004ba9160038401916020909101906200094d565b50505050600182015482546200050691600160a060020a0316908990859085908110620004e357fe5b9060005260206000209060040201620005fd640100000000026401000000009004565b156200054b576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b83811015620005b85781810151838201526020016200059e565b50505050905090810190601f168015620005e65780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b60008080600160a060020a03861615806200062d5750600384015460026000196101006001841615020190911604155b156200066057600384015460026000196101006001841615020190911604156200065657600080fd5b60009250620007bc565b8354604080516c0100000000000000000000000030028152601481019290925251908190036034019020620006a39064010000000062001671620007c582021704565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a1693620007629390929091830182828015620007455780601f10620007195761010080835404028352916020019162000745565b820191906000526020600020905b8154815290600101906020018083116200072757829003601f168201915b5088949350506401000000006200171b6200087182021704915050565b600160a060020a0316146200077657600080fd5b506000818152600360205260409020805460ff1615806200079a5750848160010154145b1515620007a657600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106200083f5780518252601f1990920191602091820191016200081e565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b600080600080845160411415156200088d576000935062000944565b50505060208201516040830151606084015160001a601b60ff82161015620008b357601b015b8060ff16601b14158015620008cc57508060ff16601c14155b15620008dc576000935062000944565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af115801562000937573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200099057805160ff1916838001178555620009c0565b82800160010185558215620009c0579182015b82811115620009c0578251825591602001919060010190620009a3565b50620009ce929150620009d2565b5090565b620009ef91905b80821115620009ce5760008155600101620009d9565b90565b6119258062000a026000396000f3006080604052600436106101065763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461010b5780630b7ad54c146101955780631bfe0308146102aa578063217fe6c6146102d95780632f54bf6e146103545780635614bdc8146103755780636192e3e81461039f57806365462d96146103ba578063715018a6146103ef5780637d72aa651461040457806384a1176c146104315780638da5cb5b146104de578063a54d19881461050f578063c47f00271461052a578063cc45969614610583578063e45e1c7d14610598578063e5975bdc146105cc578063efc97390146105ed578063f2fde38b14610605575b600080fd5b34801561011757600080fd5b50610120610626565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561015a578181015183820152602001610142565b50505050905090810190601f1680156101875780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101a157600080fd5b506101ad6004356106b4565b60408051868152908101849052600160a060020a038316606082015260a060208083018281528751928401929092528651608084019160c08501919089019080838360005b8381101561020a5781810151838201526020016101f2565b50505050905090810190601f1680156102375780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561026a578181015183820152602001610252565b50505050905090810190601f1680156102975780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b3480156102b657600080fd5b506102d760048035600160a060020a031690602480359081019101356106ed565b005b3480156102e557600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610340958335600160a060020a03169536956044949193909101919081908401838280828437509497506107719650505050505050565b604080519115158252519081900360200190f35b34801561036057600080fd5b50610340600160a060020a03600435166107f5565b34801561038157600080fd5b5061038d600435610809565b60408051918252519081900360200190f35b3480156103ab57600080fd5b506101ad60043560243561081b565b3480156103c657600080fd5b506102d760048035906024803591600160a060020a0360443516916064359081019101356109b6565b3480156103fb57600080fd5b506102d7610b2b565b34801561041057600080fd5b506102d760048035600160a060020a03169060248035908101910135610b97565b34801561043d57600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261038d94369492936024939284019190819084018382808284375050604080516020888301358a018035601f8101839004830284018301909452838352979a89359a8a830135600160a060020a03169a91999098506060909101965091945090810192508190840183828082843750949750610c159650505050505050565b3480156104ea57600080fd5b506104f3610d9c565b60408051600160a060020a039092168252519081900360200190f35b34801561051b57600080fd5b50610340600435602435610dab565b34801561053657600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526102d7943694929360249392840191908190840183828082843750949750610e059650505050505050565b34801561058f57600080fd5b5061038d610eee565b3480156105a457600080fd5b506102d760048035906024803580820192908101359160443591606435918201910135610ef4565b3480156105d857600080fd5b506102d7600160a060020a0360043516610fac565b3480156105f957600080fd5b5061034060043561101f565b34801561061157600080fd5b506102d7600160a060020a0360043516611043565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106ac5780601f10610681576101008083540402835291602001916106ac565b820191906000526020600020905b81548152906001019060200180831161068f57829003601f168201915b505050505081565b6000818152600260205260408120546060908290819083906106db9087906000190161081b565b939a9299509097509550909350915050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610716336107f5565b8061072657506107263382610771565b151561073157600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611066945050505050565b50505050565b60006001826040518082805190602001908083835b602083106107a55780518252601f199092019160209182019101610786565b51815160209384036101000a600019018019909216911617905292019485525060408051948590038201909420600160a060020a0397909716600090815296905250509092205460ff1692915050565b600054600160a060020a0390811691161490565b60009081526002602052604090205490565b600082815260026020526040812080546060918391829184918390881061084157600080fd5b815482908990811061084f57fe5b600091825260209182902060049190910201805460028083015460018781015481860180546040805161010095831615959095026000190190911695909504601f810189900489028401890190955284835295975093959193600160a060020a031692600388019286919083018282801561090b5780601f106108e05761010080835404028352916020019161090b565b820191906000526020600020905b8154815290600101906020018083116108ee57829003601f168201915b5050845460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959950869450925084019050828280156109995780601f1061096e57610100808354040283529160200191610999565b820191906000526020600020905b81548152906001019060200180831161097c57829003601f168201915b505050505090509650965096509650965050509295509295909350565b60008060408051908101604052806006815260200160d160020a6532b234ba37b9028152506109e4336107f5565b806109f457506109f43382610771565b15156109ff57600080fd5b6004548810610a0d57600080fd5b60008881526002602052604090206001810154909350600160a060020a03161580610a4757506001830154600160a060020a038781169116145b1515610a5257600080fd5b82548710610a5f57600080fd5b871515610a7a57610a6f336107f5565b1515610a7a57600080fd5b60018301805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388161790558254839088908110610ab257fe5b600091825260209091206004909102019150610ad26003830186866117f0565b50610ade868984611180565b1515610ae957600080fd5b85600160a060020a031687897f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6160405160405180910390a45050505050505050565b600054600160a060020a03163314610b4257600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610bc0336107f5565b80610bd05750610bd03382610771565b1515610bdb57600080fd5b61076b8484848080601f01602080910402602001604051908101604052809392919081815260200183838082843750611323945050505050565b60008060408051908101604052806006815260200160d160020a6532b234ba37b902815250610c43336107f5565b80610c535750610c533382610771565b1515610c5e57600080fd5b60048054600181019091559150600160a060020a038516158015610c8157508351155b80610c9f5750600160a060020a03851615801590610c9f5750835115155b1515610caa57600080fd5b6000828152600260205260409020600101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038716179055610ced82888887611403565b508133600160a060020a03167f1ede735f9b446d8014022fed176848ac3894c54942bef9ff452f7ae42b50d5ae896040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d58578181015183820152602001610d40565b50505050905090810190601f168015610d855780820380516001836020036101000a031916815260200191505b509250505060405180910390a35095945050505050565b600054600160a060020a031681565b600082815260026020526040812080548310610dc657600080fd5b8083815481101515610dd457fe5b6000918252602090912060036004909202010154600260001961010060018416150201909116041515949350505050565b600054600160a060020a03163314610e1c57600080fd5b8051600010610e2a57600080fd5b8051610e3d90600590602084019061186e565b5060408051602080825260058054600260001961010060018416150201909116049183018290527f4737457377f528cc8afd815f73ecb8b05df80d047dbffc41c17750a4033592bc93909291829182019084908015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b50509250505060405180910390a150565b60045481565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610f1d336107f5565b80610f2d5750610f2d3382610771565b1515610f3857600080fd5b610fa28787878080601f0160208091040260200160405190810160405280939291908181526020018383808284375050604080516020601f8c018190048102820181019092528a81528c955093508a92508991508190840183828082843750611403945050505050565b5050505050505050565b604080518082019091526006815260d160020a6532b234ba37b9026020820152610fd5336107f5565b80610fe55750610fe53382610771565b1515610ff057600080fd5b61101b8260408051908101604052806006815260200160d160020a6532b234ba37b902815250611323565b5050565b60008181526002602052604081205461103d90839060001901610dab565b92915050565b600054600160a060020a0316331461105a57600080fd5b611063816115f4565b50565b6001816040518082805190602001908083835b602083106110985780518252601f199092019160209182019101611079565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0388166000818152918452828220805460ff19169055838752875187850152875190963396507f6a52fb0cb0e75e6a6721483d2e539b38273ec6fe95b648a41e1a901594aeccb895508894909384939084019291860191908190849084905b8381101561114257818101518382015260200161112a565b50505050905090810190601f16801561116f5780820380516001836020036101000a031916815260200191505b509250505060405180910390a35050565b60008080600160a060020a03861615806111af5750600384015460026000196101006001841615020190911604155b156111df57600384015460026000196101006001841615020190911604156111d657600080fd5b6000925061131a565b8354604080516c010000000000000000000000003002815260148101929092525190819003603401902061121290611671565b600385018054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152939550600160a060020a038a16936112c393909290918301828280156112af5780601f10611284576101008083540402835291602001916112af565b820191906000526020600020905b81548152906001019060200180831161129257829003601f168201915b50889493505063ffffffff61171b16915050565b600160a060020a0316146112d657600080fd5b506000818152600360205260409020805460ff1615806112f95750848160010154145b151561130457600080fd5b805460ff19166001908117825581810186905592505b50509392505050565b600180826040518082805190602001908083835b602083106113565780518252601f199092019160209182019101611337565b51815160209384036101000a6000190180199092169116179052920194855250604080519485900382018520600160a060020a0389166000818152918452828220805460ff191698151598909817909755828652875186840152875133967fa40c1dc2b34f6b51c3ea614b688f243e50047ed9fa3ea19010303d70dac781ed965089955093849384019290860191908190849084908381101561114257818101518382015260200161112a565b60008060006004548710151561141857600080fd5b86151561143357611428336107f5565b151561143357600080fd5b50506000858152600260209081526040808320805482516080810184528881528085018a815242948201949094526060810188905260018083018085558488529686902082516004850290910190815594518051949793969395929492936114a1939285019291019061186e565b5060408201516002820155606082015180516114c791600384019160209091019061186e565b505050506001820154825461150191600160a060020a03169089908590859081106114ee57fe5b9060005260206000209060040201611180565b15611545576001820154604051600160a060020a0390911690829089907f605611fc50d3effbe4af88e82f5daebfcffe0fb8f3b34ed32f1a746290ccbc6190600090a45b808733600160a060020a03167f18b6b5c485f8822a270464dd544d0715597dc8f1a007ee2b0252b62b8b9fb390896040518080602001828103825283818151815260200191508051906020019080838360005b838110156115b0578181015183820152602001611598565b50505050905090810190601f1680156115dd5780820380516001836020036101000a031916815260200191505b509250505060405180910390a45050949350505050565b600160a060020a038116151561160957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b604080517f19457468657265756d205369676e6564204d6573736167653a0a333200000000602080830191909152603c80830185905283518084039091018152605c909201928390528151600093918291908401908083835b602083106116e95780518252601f1990920191602091820191016116ca565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095945050505050565b6000806000808451604114151561173557600093506117e7565b50505060208201516040830151606084015160001a601b60ff8216101561175a57601b015b8060ff16601b1415801561177257508060ff16601c14155b1561178057600093506117e7565b60408051600080825260208083018085528a905260ff8516838501526060830187905260808301869052925160019360a0808501949193601f19840193928390039091019190865af11580156117da573d6000803e3d6000fd5b5050506020604051035193505b50505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118315782800160ff1982351617855561185e565b8280016001018555821561185e579182015b8281111561185e578235825591602001919060010190611843565b5061186a9291506118dc565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106118af57805160ff191683800117855561185e565b8280016001018555821561185e579182015b8281111561185e5782518255916020019190600101906118c1565b6118f691905b8082111561186a57600081556001016118e2565b905600a165627a7a72305820bbb8f14f037c6a58da466d96dc1aa6aa3e562c829066ed2d14b761e1b2a6b1f20029a165627a7a7230582061abee9df0f5aab95e391427cf7f772ee5fa9ba914d17d428b32b983c8fdc3ca0029", "abi": [ { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "isInstantiation", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "multisigFactory", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" }, { "name": "", "type": "uint256" } ], "name": "instantiations", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "creator", "type": "address" } ], "name": "getInstantiationCount", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "multisigNewsrooms", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "multisigFactoryAddr", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "sender", "type": "address" }, { "indexed": false, "name": "instantiation", "type": "address" } ], "name": "ContractInstantiation", "type": "event" }, { "constant": false, "inputs": [ { "name": "name", "type": "string" }, { "name": "charterUri", "type": "string" }, { "name": "charterHash", "type": "bytes32" }, { "name": "initialOwners", "type": "address[]" }, { "name": "initialRequired", "type": "uint256" } ], "name": "create", "outputs": [ { "name": "newsroom", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x3e39fa983abcd349d95aed608e798817397cf0d1", "transactionHash": "0x4ed89d96fddd5ed862f7652f6d4bedf115e627d9accab6332753425aecee4b22" }, "4": { "events": {}, "links": {}, "address": "0x0437bb69da983a508ce77b5f16dc86a96163318b", "transactionHash": "0xdcdcb9108039bed24946a9e7177ffe96bfa879b0181968dfdca620d005838fde" } } } ================================================ FILE: packages/artifacts/v1/NoOpTokenController.json ================================================ { "contractName": "NoOpTokenController", "bytecode": "0x608060405234801561001057600080fd5b50610216806100206000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e969a0581146100665780637f4ab1dd14610091578063d4ce141514610121578063e7984d1714610158575b600080fd5b34801561007257600080fd5b5061007b61016d565b6040805160ff9092168252519081900360200190f35b34801561009d57600080fd5b506100ac60ff60043516610172565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100e65781810151838201526020016100ce565b50505050905090810190601f1680156101135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561012d57600080fd5b5061007b73ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356101aa565b34801561016457600080fd5b506100ac6101b3565b600081565b5060408051808201909152600781527f5355434345535300000000000000000000000000000000000000000000000000602082015290565b60009392505050565b60408051808201909152600781527f53554343455353000000000000000000000000000000000000000000000000006020820152815600a165627a7a72305820d56090aba1d725400a587dae6987101030e942980bb3be930c720c7e7bc9cc0d0029", "deployedBytecode": "0x6080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630e969a0581146100665780637f4ab1dd14610091578063d4ce141514610121578063e7984d1714610158575b600080fd5b34801561007257600080fd5b5061007b61016d565b6040805160ff9092168252519081900360200190f35b34801561009d57600080fd5b506100ac60ff60043516610172565b6040805160208082528351818301528351919283929083019185019080838360005b838110156100e65781810151838201526020016100ce565b50505050905090810190601f1680156101135780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561012d57600080fd5b5061007b73ffffffffffffffffffffffffffffffffffffffff600435811690602435166044356101aa565b34801561016457600080fd5b506100ac6101b3565b600081565b5060408051808201909152600781527f5355434345535300000000000000000000000000000000000000000000000000602082015290565b60009392505050565b60408051808201909152600781527f53554343455353000000000000000000000000000000000000000000000000006020820152815600a165627a7a72305820d56090aba1d725400a587dae6987101030e942980bb3be930c720c7e7bc9cc0d0029", "abi": [ { "constant": true, "inputs": [], "name": "SUCCESS_CODE", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "SUCCESS_MESSAGE", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "from", "type": "address" }, { "name": "to", "type": "address" }, { "name": "value", "type": "uint256" } ], "name": "detectTransferRestriction", "outputs": [ { "name": "", "type": "uint8" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "restrictionCode", "type": "uint8" } ], "name": "messageForTransferRestriction", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0xd3661aa186d83692b29855d396a3a44bc8fd5836", "transactionHash": "0x92972c8f1f8aa0c268d0532865a9a00e4cb56cf723e3a18168c396ee324b172d" }, "4": { "events": {}, "links": {}, "address": "0x15f91c1936d854e74d6793efffe9f0b1a81098c5", "transactionHash": "0xa3b31e9ba2be964ebee3e95ccd266c4cf275b95ceb9ebd273504796a58bf5a2f" } } } ================================================ FILE: packages/artifacts/v1/Ownable.json ================================================ { "contractName": "Ownable", "bytecode": "0x608060405234801561001057600080fd5b5060008054600160a060020a0319163317905561020b806100326000396000f3006080604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663715018a6811461005b5780638da5cb5b14610072578063f2fde38b146100a3575b600080fd5b34801561006757600080fd5b506100706100c4565b005b34801561007e57600080fd5b50610087610130565b60408051600160a060020a039092168252519081900360200190f35b3480156100af57600080fd5b50610070600160a060020a036004351661013f565b600054600160a060020a031633146100db57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a0316331461015657600080fd5b61015f81610162565b50565b600160a060020a038116151561017757600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582095d8eb5308d7c5c389b6182abeb94e0ac7500ada8771a228e93aec273d2905030029", "deployedBytecode": "0x6080604052600436106100565763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663715018a6811461005b5780638da5cb5b14610072578063f2fde38b146100a3575b600080fd5b34801561006757600080fd5b506100706100c4565b005b34801561007e57600080fd5b50610087610130565b60408051600160a060020a039092168252519081900360200190f35b3480156100af57600080fd5b50610070600160a060020a036004351661013f565b600054600160a060020a031633146100db57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a0316331461015657600080fd5b61015f81610162565b50565b600160a060020a038116151561017757600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a7230582095d8eb5308d7c5c389b6182abeb94e0ac7500ada8771a228e93aec273d2905030029", "abi": [ { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/PLCRVoting.json ================================================ { "contractName": "PLCRVoting", "bytecode": "0x608060405234801561001057600080fd5b50604051602080611c7e8339810160405251600160a060020a038116151561003757600080fd5b60058054600160a060020a03909216600160a060020a031990921691909117905560008055611c138061006b6000396000f3006080604052600436106101715763ffffffff60e060020a600035041663053e71a681146101765780632173a10f146101a05780632c052031146101b557806332ed3d60146101dc5780633b930294146101fa5780633ec36b991461021b578063427fa1d214610261578063441c77c01461028257806349403183146102ae5780636148fed5146102c65780636b2d95d4146103095780636cbf9c5e1461032a5780637f97e8361461034b5780638090f92e1461036f578063819b0293146103a757806388d21ff3146103d157806397508f36146103e957806397603560146103fe578063a1103f3714610416578063a25236fe1461043a578063a4439dc514610452578063aa7ca4641461046a578063b11d8bb81461048e578063b43bd069146104ac578063bb11ed7e146104d3578063d138209214610528578063d901402b1461054c578063d9548e5314610570578063e7b1d43c14610588578063ee684830146105a0578063fc0c546a146105b8575b600080fd5b34801561018257600080fd5b5061018e6004356105e9565b60408051918252519081900360200190f35b3480156101ac57600080fd5b5061018e61063e565b3480156101c157600080fd5b5061018e600160a060020a0360043516602435604435610643565b3480156101e857600080fd5b5061018e60043560243560443561080c565b34801561020657600080fd5b5061018e600160a060020a03600435166108e8565b34801561022757600080fd5b5061025f60246004803582810192908201359181358083019290820135916044358083019290820135916064359182019101356108fa565b005b34801561026d57600080fd5b5061018e600160a060020a036004351661099a565b34801561028e57600080fd5b5061029a600435610a54565b604080519115158252519081900360200190f35b3480156102ba57600080fd5b5061029a600435610a9f565b3480156102d257600080fd5b506102de600435610b1c565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561031557600080fd5b5061018e600160a060020a0360043516610b4a565b34801561033657600080fd5b5061025f600435602435604435606435610b5e565b34801561035757600080fd5b5061029a600160a060020a03600435166024356110d0565b34801561037b57600080fd5b5061025f6024600480358281019290820135918135808301929082013591604435918201910135611115565b3480156103b357600080fd5b5061029a600435602435600160a060020a0360443516606435611191565b3480156103dd57600080fd5b5061029a6004356111d2565b3480156103f557600080fd5b5061018e6111e7565b34801561040a57600080fd5b5061025f6004356111ed565b34801561042257600080fd5b5061018e600160a060020a0360043516602435611391565b34801561044657600080fd5b5061025f6004356113c8565b34801561045e57600080fd5b5061029a60043561155b565b34801561047657600080fd5b5061029a600160a060020a0360043516602435611589565b34801561049a57600080fd5b5061025f6004356024356044356115ce565b3480156104b857600080fd5b5061018e600160a060020a03600435166024356044356117d1565b3480156104df57600080fd5b506040805160206004803580820135838102808601850190965280855261025f9536959394602494938501929182918501908490808284375094975061187d9650505050505050565b34801561053457600080fd5b5061018e600160a060020a03600435166024356118b5565b34801561055857600080fd5b5061018e600160a060020a0360043516602435611987565b34801561057c57600080fd5b5061029a600435611a26565b34801561059457600080fd5b5061025f600435611a2b565b3480156105ac57600080fd5b5061029a600435611b57565b3480156105c457600080fd5b506105cd611b89565b60408051600160a060020a039092168252519081900360200190f35b60006105f482611b57565b15156105ff57600080fd5b61060882610a9f565b156106255750600081815260016020526040902060030154610639565b506000818152600160205260409020600401545b919050565b600081565b60008060006106518661099a565b915061065d86836118b5565b90505b81156107ff5761067086836118b5565b9050848111610742578382141561073a57600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561070b57600080fd5b505af415801561071f573d6000803e3d6000fd5b505050506040513d602081101561073557600080fd5b505191505b819250610803565b600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b1580156107cc57600080fd5b505af41580156107e0573d6000803e3d6000fd5b505050506040513d60208110156107f657600080fd5b50519150610660565b8192505b50509392505050565b6000805460010181558080610827428663ffffffff611b9816565b9150610839828563ffffffff611b9816565b6040805160a08101825284815260208082018481528284018b8152600060608086018281526080870183815283548452600180885289852098518955955195880195909555925160028701559151600386015591516004909401939093555483518b8152918201879052818401859052925193945033937f404f1f1c229d9eb2a949e7584da6ffde9d059ef2169f487ca815434cce0640d0929181900390910190a35050600054949350505050565b60026020526000908152604090205481565b600087861461090857600080fd5b87841461091457600080fd5b87821461092057600080fd5b5060005b8781101561098f5761098789898381811061093b57fe5b90506020020135888884818110151561095057fe5b6020029190910135905087878581811061096657fe5b90506020020135868686818110151561097b57fe5b90506020020135610b5e565b600101610924565b505050505050505050565b600160a060020a038116600090815260036020908152604080832081517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________926330fe0a0a9260448082019391829003018186803b158015610a2257600080fd5b505af4158015610a36573d6000803e3d6000fd5b505050506040513d6020811015610a4c57600080fd5b505192915050565b6000610a5f826111d2565b1515610a6a57600080fd5b60008281526001602081905260409091200154610a8690611a26565b158015610a995750610a978261155b565b155b92915050565b6000610aa9611bb7565b610ab283611b57565b1515610abd57600080fd5b5050600090815260016020818152604092839020835160a0810185528154815292810154918301919091526002810154928201839052600381015460608301819052600490910154608090920182905290810190910260649091021190565b6001602081905260009182526040909120805491810154600282015460038301546004909301549192909185565b6000610a9982610b598461099a565b6118b5565b6000806000610b6c8761155b565b1515610b7757600080fd5b33600090815260026020526040902054851115610bba5733600090815260026020526040902054610baf90869063ffffffff611ba516565b9250610bba836113c8565b33600090815260026020526040902054851115610bd657600080fd5b861515610be257600080fd5b851515610bee57600080fd5b831580610ca457503360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b158015610c7757600080fd5b505af4158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b50515b1515610caf57600080fd5b3360009081526003602090815260409182902082517f07d29ac9000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610d3057600080fd5b505af4158015610d44573d6000803e3d6000fd5b505050506040513d6020811015610d5a57600080fd5b5051915086821415610e16573360009081526003602090815260409182902082517f07d29ac90000000000000000000000000000000000000000000000000000000081526004810191909152602481018a9052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610de757600080fd5b505af4158015610dfb573d6000803e3d6000fd5b505050506040513d6020811015610e1157600080fd5b505191505b610e2284833388611191565b1515610e2d57600080fd5b3360009081526003602052604080822081517f9735c51b000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604481018a905260648101859052905173__DLL___________________________________92639735c51b9260848082019391829003018186803b158015610eb857600080fd5b505af4158015610ecc573d6000803e3d6000fd5b50505050610eda3388611391565b604080517f977aa031000000000000000000000000000000000000000000000000000000008152600481810152602481018390526064810188905260806044820152600960848201527f6e756d546f6b656e73000000000000000000000000000000000000000000000060a4820152905191925073__AttributeStore________________________9163977aa0319160c480820192600092909190829003018186803b158015610f8a57600080fd5b505af4158015610f9e573d6000803e3d6000fd5b5050604080517f977aa03100000000000000000000000000000000000000000000000000000000815260048181015260248101859052606481018a905260806044820152600a60848201527f636f6d6d6974486173680000000000000000000000000000000000000000000060a4820152905173__AttributeStore________________________935063977aa031925060c4808301926000929190829003018186803b15801561104e57600080fd5b505af4158015611062573d6000803e3d6000fd5b5050506000888152600160208181526040808420338086526005909101835293819020805460ff1916909317909255815189815291519293508a927fea7979e4280d7e6bffc1c7d83a1ac99f16d02ecc14465ce41016226783b663d79281900390910190a350505050505050565b60006110db826111d2565b15156110e657600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260059093019052205460ff1690565b600085841461112357600080fd5b85821461112f57600080fd5b5060005b858110156111885761118087878381811061114a57fe5b90506020020135868684818110151561115f57fe5b90506020020135858585818110151561117457fe5b905060200201356115ce565b600101611133565b50505050505050565b60008060006111a085886118b5565b84101591506111af85876118b5565b841115806111bb575085155b90508180156111c75750805b979650505050505050565b60008115801590610a99575050600054101590565b60005481565b6000818152600160208190526040909120015461120990611a26565b151561121457600080fd5b3360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b15801561129557600080fd5b505af41580156112a9573d6000803e3d6000fd5b505050506040513d60208110156112bf57600080fd5b505115156112cc57600080fd5b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561134957600080fd5b505af415801561135d573d6000803e3d6000fd5b50506040513392508391507f402507661c8c8cb90e0a796450b8bdd28b6c516f05279c0cd29e84c344e1699a90600090a350565b604080516c01000000000000000000000000600160a060020a03851602815260148101839052905190819003603401902092915050565b600554604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518392600160a060020a0316916370a082319160248083019260209291908290030181600087803b15801561142d57600080fd5b505af1158015611441573d6000803e3d6000fd5b505050506040513d602081101561145757600080fd5b5051101561146457600080fd5b33600081815260026020908152604080832080548601905560055481517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690529051600160a060020a03909116936323b872dd9360648083019493928390030190829087803b1580156114eb57600080fd5b505af11580156114ff573d6000803e3d6000fd5b505050506040513d602081101561151557600080fd5b5051151561152257600080fd5b60408051828152905133917ff7aaf024511d9982df8cd0d437c71c30106e6848cd1ba3d288d7a9c0e276aeda919081900360200190a250565b6000611566826111d2565b151561157157600080fd5b600082815260016020526040902054610a9790611a26565b6000611594826111d2565b151561159f57600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260069093019052205460ff1690565b60006115d984610a54565b15156115e457600080fd5b600084815260016020908152604080832033845260050190915290205460ff16151561160f57600080fd5b600084815260016020908152604080832033845260060190915290205460ff161561163957600080fd5b6116433385611987565b604080518581526020810185905281519081900390910190201461166657600080fd5b61167033856118b5565b905082600114156116975760008481526001602052604090206003018054820190556116af565b60008481526001602052604090206004018054820190555b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561172c57600080fd5b505af4158015611740573d6000803e3d6000fd5b505050600085815260016020818152604080842033808652600682018452828620805460ff191686179055948a9052928252600383015460049093015481518781529283019390935281810192909252606081018690529051919250859187917f9b19aaec524fad29c0ced9b9973a15e3045d7c3be156d71394ab40f0d5f119ff919081900360800190a450505050565b6000806000806117e086611b57565b15156117eb57600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff16151561181f57600080fd5b61182886610a9f565b611833576000611836565b60015b60ff16925082856040518083815260200182815260200192505050604051809103902091506118658787611987565b905081811461187357600080fd5b6111c787876118b5565b60005b81518110156118b1576118a9828281518110151561189a57fe5b906020019060200201516111ed565b600101611880565b5050565b600073__AttributeStore________________________6350389f5c60046118dd8686611391565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600960648301527f6e756d546f6b656e73000000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561195457600080fd5b505af4158015611968573d6000803e3d6000fd5b505050506040513d602081101561197e57600080fd5b50519392505050565b600073__AttributeStore________________________6350389f5c60046119af8686611391565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600a60648301527f636f6d6d6974486173680000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561195457600080fd5b421190565b6000611a55611a3933610b4a565b336000908152600260205260409020549063ffffffff611ba516565b905081811015611a6457600080fd5b3360008181526002602090815260408083208054879003905560055481517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810195909552602485018790529051600160a060020a039091169363a9059cbb9360448083019493928390030190829087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b505050506040513d6020811015611b1057600080fd5b50511515611b1d57600080fd5b60408051838152905133917ffaeb7dbb9992397d26ea1944efd40c80b40f702faf69b46c67ad10aba68ccb79919081900360200190a25050565b6000611b62826111d2565b1515611b6d57600080fd5b60008281526001602081905260409091200154610a9990611a26565b600554600160a060020a031681565b81810182811015610a9957fe5b600082821115611bb157fe5b50900390565b60a060405190810160405280600081526020016000815260200160008152602001600081526020016000815250905600a165627a7a72305820ff005710c1354d39fc831ef485711030c736a039e71777dc40e17e4d4a7a08dc0029", "deployedBytecode": "0x6080604052600436106101715763ffffffff60e060020a600035041663053e71a681146101765780632173a10f146101a05780632c052031146101b557806332ed3d60146101dc5780633b930294146101fa5780633ec36b991461021b578063427fa1d214610261578063441c77c01461028257806349403183146102ae5780636148fed5146102c65780636b2d95d4146103095780636cbf9c5e1461032a5780637f97e8361461034b5780638090f92e1461036f578063819b0293146103a757806388d21ff3146103d157806397508f36146103e957806397603560146103fe578063a1103f3714610416578063a25236fe1461043a578063a4439dc514610452578063aa7ca4641461046a578063b11d8bb81461048e578063b43bd069146104ac578063bb11ed7e146104d3578063d138209214610528578063d901402b1461054c578063d9548e5314610570578063e7b1d43c14610588578063ee684830146105a0578063fc0c546a146105b8575b600080fd5b34801561018257600080fd5b5061018e6004356105e9565b60408051918252519081900360200190f35b3480156101ac57600080fd5b5061018e61063e565b3480156101c157600080fd5b5061018e600160a060020a0360043516602435604435610643565b3480156101e857600080fd5b5061018e60043560243560443561080c565b34801561020657600080fd5b5061018e600160a060020a03600435166108e8565b34801561022757600080fd5b5061025f60246004803582810192908201359181358083019290820135916044358083019290820135916064359182019101356108fa565b005b34801561026d57600080fd5b5061018e600160a060020a036004351661099a565b34801561028e57600080fd5b5061029a600435610a54565b604080519115158252519081900360200190f35b3480156102ba57600080fd5b5061029a600435610a9f565b3480156102d257600080fd5b506102de600435610b1c565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b34801561031557600080fd5b5061018e600160a060020a0360043516610b4a565b34801561033657600080fd5b5061025f600435602435604435606435610b5e565b34801561035757600080fd5b5061029a600160a060020a03600435166024356110d0565b34801561037b57600080fd5b5061025f6024600480358281019290820135918135808301929082013591604435918201910135611115565b3480156103b357600080fd5b5061029a600435602435600160a060020a0360443516606435611191565b3480156103dd57600080fd5b5061029a6004356111d2565b3480156103f557600080fd5b5061018e6111e7565b34801561040a57600080fd5b5061025f6004356111ed565b34801561042257600080fd5b5061018e600160a060020a0360043516602435611391565b34801561044657600080fd5b5061025f6004356113c8565b34801561045e57600080fd5b5061029a60043561155b565b34801561047657600080fd5b5061029a600160a060020a0360043516602435611589565b34801561049a57600080fd5b5061025f6004356024356044356115ce565b3480156104b857600080fd5b5061018e600160a060020a03600435166024356044356117d1565b3480156104df57600080fd5b506040805160206004803580820135838102808601850190965280855261025f9536959394602494938501929182918501908490808284375094975061187d9650505050505050565b34801561053457600080fd5b5061018e600160a060020a03600435166024356118b5565b34801561055857600080fd5b5061018e600160a060020a0360043516602435611987565b34801561057c57600080fd5b5061029a600435611a26565b34801561059457600080fd5b5061025f600435611a2b565b3480156105ac57600080fd5b5061029a600435611b57565b3480156105c457600080fd5b506105cd611b89565b60408051600160a060020a039092168252519081900360200190f35b60006105f482611b57565b15156105ff57600080fd5b61060882610a9f565b156106255750600081815260016020526040902060030154610639565b506000818152600160205260409020600401545b919050565b600081565b60008060006106518661099a565b915061065d86836118b5565b90505b81156107ff5761067086836118b5565b9050848111610742578382141561073a57600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b15801561070b57600080fd5b505af415801561071f573d6000803e3d6000fd5b505050506040513d602081101561073557600080fd5b505191505b819250610803565b600160a060020a03861660009081526003602090815260409182902082517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101859052915173__DLL___________________________________926330fe0a0a926044808301939192829003018186803b1580156107cc57600080fd5b505af41580156107e0573d6000803e3d6000fd5b505050506040513d60208110156107f657600080fd5b50519150610660565b8192505b50509392505050565b6000805460010181558080610827428663ffffffff611b9816565b9150610839828563ffffffff611b9816565b6040805160a08101825284815260208082018481528284018b8152600060608086018281526080870183815283548452600180885289852098518955955195880195909555925160028701559151600386015591516004909401939093555483518b8152918201879052818401859052925193945033937f404f1f1c229d9eb2a949e7584da6ffde9d059ef2169f487ca815434cce0640d0929181900390910190a35050600054949350505050565b60026020526000908152604090205481565b600087861461090857600080fd5b87841461091457600080fd5b87821461092057600080fd5b5060005b8781101561098f5761098789898381811061093b57fe5b90506020020135888884818110151561095057fe5b6020029190910135905087878581811061096657fe5b90506020020135868686818110151561097b57fe5b90506020020135610b5e565b600101610924565b505050505050505050565b600160a060020a038116600090815260036020908152604080832081517f30fe0a0a000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________926330fe0a0a9260448082019391829003018186803b158015610a2257600080fd5b505af4158015610a36573d6000803e3d6000fd5b505050506040513d6020811015610a4c57600080fd5b505192915050565b6000610a5f826111d2565b1515610a6a57600080fd5b60008281526001602081905260409091200154610a8690611a26565b158015610a995750610a978261155b565b155b92915050565b6000610aa9611bb7565b610ab283611b57565b1515610abd57600080fd5b5050600090815260016020818152604092839020835160a0810185528154815292810154918301919091526002810154928201839052600381015460608301819052600490910154608090920182905290810190910260649091021190565b6001602081905260009182526040909120805491810154600282015460038301546004909301549192909185565b6000610a9982610b598461099a565b6118b5565b6000806000610b6c8761155b565b1515610b7757600080fd5b33600090815260026020526040902054851115610bba5733600090815260026020526040902054610baf90869063ffffffff611ba516565b9250610bba836113c8565b33600090815260026020526040902054851115610bd657600080fd5b861515610be257600080fd5b851515610bee57600080fd5b831580610ca457503360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b158015610c7757600080fd5b505af4158015610c8b573d6000803e3d6000fd5b505050506040513d6020811015610ca157600080fd5b50515b1515610caf57600080fd5b3360009081526003602090815260409182902082517f07d29ac9000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610d3057600080fd5b505af4158015610d44573d6000803e3d6000fd5b505050506040513d6020811015610d5a57600080fd5b5051915086821415610e16573360009081526003602090815260409182902082517f07d29ac90000000000000000000000000000000000000000000000000000000081526004810191909152602481018a9052915173__DLL___________________________________926307d29ac9926044808301939192829003018186803b158015610de757600080fd5b505af4158015610dfb573d6000803e3d6000fd5b505050506040513d6020811015610e1157600080fd5b505191505b610e2284833388611191565b1515610e2d57600080fd5b3360009081526003602052604080822081517f9735c51b000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052604481018a905260648101859052905173__DLL___________________________________92639735c51b9260848082019391829003018186803b158015610eb857600080fd5b505af4158015610ecc573d6000803e3d6000fd5b50505050610eda3388611391565b604080517f977aa031000000000000000000000000000000000000000000000000000000008152600481810152602481018390526064810188905260806044820152600960848201527f6e756d546f6b656e73000000000000000000000000000000000000000000000060a4820152905191925073__AttributeStore________________________9163977aa0319160c480820192600092909190829003018186803b158015610f8a57600080fd5b505af4158015610f9e573d6000803e3d6000fd5b5050604080517f977aa03100000000000000000000000000000000000000000000000000000000815260048181015260248101859052606481018a905260806044820152600a60848201527f636f6d6d6974486173680000000000000000000000000000000000000000000060a4820152905173__AttributeStore________________________935063977aa031925060c4808301926000929190829003018186803b15801561104e57600080fd5b505af4158015611062573d6000803e3d6000fd5b5050506000888152600160208181526040808420338086526005909101835293819020805460ff1916909317909255815189815291519293508a927fea7979e4280d7e6bffc1c7d83a1ac99f16d02ecc14465ce41016226783b663d79281900390910190a350505050505050565b60006110db826111d2565b15156110e657600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260059093019052205460ff1690565b600085841461112357600080fd5b85821461112f57600080fd5b5060005b858110156111885761118087878381811061114a57fe5b90506020020135868684818110151561115f57fe5b90506020020135858585818110151561117457fe5b905060200201356115ce565b600101611133565b50505050505050565b60008060006111a085886118b5565b84101591506111af85876118b5565b841115806111bb575085155b90508180156111c75750805b979650505050505050565b60008115801590610a99575050600054101590565b60005481565b6000818152600160208190526040909120015461120990611a26565b151561121457600080fd5b3360009081526003602090815260409182902082517f366a5ba2000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052915173__DLL___________________________________9263366a5ba2926044808301939192829003018186803b15801561129557600080fd5b505af41580156112a9573d6000803e3d6000fd5b505050506040513d60208110156112bf57600080fd5b505115156112cc57600080fd5b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101849052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561134957600080fd5b505af415801561135d573d6000803e3d6000fd5b50506040513392508391507f402507661c8c8cb90e0a796450b8bdd28b6c516f05279c0cd29e84c344e1699a90600090a350565b604080516c01000000000000000000000000600160a060020a03851602815260148101839052905190819003603401902092915050565b600554604080517f70a0823100000000000000000000000000000000000000000000000000000000815233600482015290518392600160a060020a0316916370a082319160248083019260209291908290030181600087803b15801561142d57600080fd5b505af1158015611441573d6000803e3d6000fd5b505050506040513d602081101561145757600080fd5b5051101561146457600080fd5b33600081815260026020908152604080832080548601905560055481517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810195909552306024860152604485018690529051600160a060020a03909116936323b872dd9360648083019493928390030190829087803b1580156114eb57600080fd5b505af11580156114ff573d6000803e3d6000fd5b505050506040513d602081101561151557600080fd5b5051151561152257600080fd5b60408051828152905133917ff7aaf024511d9982df8cd0d437c71c30106e6848cd1ba3d288d7a9c0e276aeda919081900360200190a250565b6000611566826111d2565b151561157157600080fd5b600082815260016020526040902054610a9790611a26565b6000611594826111d2565b151561159f57600080fd5b506000908152600160209081526040808320600160a060020a0394909416835260069093019052205460ff1690565b60006115d984610a54565b15156115e457600080fd5b600084815260016020908152604080832033845260050190915290205460ff16151561160f57600080fd5b600084815260016020908152604080832033845260060190915290205460ff161561163957600080fd5b6116433385611987565b604080518581526020810185905281519081900390910190201461166657600080fd5b61167033856118b5565b905082600114156116975760008481526001602052604090206003018054820190556116af565b60008481526001602052604090206004018054820190555b3360009081526003602052604080822081517f6d900ed0000000000000000000000000000000000000000000000000000000008152600481019190915260248101879052905173__DLL___________________________________92636d900ed09260448082019391829003018186803b15801561172c57600080fd5b505af4158015611740573d6000803e3d6000fd5b505050600085815260016020818152604080842033808652600682018452828620805460ff191686179055948a9052928252600383015460049093015481518781529283019390935281810192909252606081018690529051919250859187917f9b19aaec524fad29c0ced9b9973a15e3045d7c3be156d71394ab40f0d5f119ff919081900360800190a450505050565b6000806000806117e086611b57565b15156117eb57600080fd5b6000868152600160209081526040808320600160a060020a038b16845260060190915290205460ff16151561181f57600080fd5b61182886610a9f565b611833576000611836565b60015b60ff16925082856040518083815260200182815260200192505050604051809103902091506118658787611987565b905081811461187357600080fd5b6111c787876118b5565b60005b81518110156118b1576118a9828281518110151561189a57fe5b906020019060200201516111ed565b600101611880565b5050565b600073__AttributeStore________________________6350389f5c60046118dd8686611391565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600960648301527f6e756d546f6b656e73000000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561195457600080fd5b505af4158015611968573d6000803e3d6000fd5b505050506040513d602081101561197e57600080fd5b50519392505050565b600073__AttributeStore________________________6350389f5c60046119af8686611391565b6040805160e060020a63ffffffff86160281526004810193909352602483019190915260606044830152600a60648301527f636f6d6d6974486173680000000000000000000000000000000000000000000060848301525160a4808301926020929190829003018186803b15801561195457600080fd5b421190565b6000611a55611a3933610b4a565b336000908152600260205260409020549063ffffffff611ba516565b905081811015611a6457600080fd5b3360008181526002602090815260408083208054879003905560055481517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810195909552602485018790529051600160a060020a039091169363a9059cbb9360448083019493928390030190829087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b505050506040513d6020811015611b1057600080fd5b50511515611b1d57600080fd5b60408051838152905133917ffaeb7dbb9992397d26ea1944efd40c80b40f702faf69b46c67ad10aba68ccb79919081900360200190a25050565b6000611b62826111d2565b1515611b6d57600080fd5b60008281526001602081905260409091200154610a9990611a26565b600554600160a060020a031681565b81810182811015610a9957fe5b600082821115611bb157fe5b50900390565b60a060405190810160405280600081526020016000815260200160008152602001600081526020016000815250905600a165627a7a72305820ff005710c1354d39fc831ef485711030c736a039e71777dc40e17e4d4a7a08dc0029", "abi": [ { "constant": true, "inputs": [], "name": "INITIAL_POLL_NONCE", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "voteTokenBalance", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "pollMap", "outputs": [ { "name": "commitEndDate", "type": "uint256" }, { "name": "revealEndDate", "type": "uint256" }, { "name": "voteQuorum", "type": "uint256" }, { "name": "votesFor", "type": "uint256" }, { "name": "votesAgainst", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "pollNonce", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_token", "type": "address" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VoteCommitted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": false, "name": "votesFor", "type": "uint256" }, { "indexed": false, "name": "votesAgainst", "type": "uint256" }, { "indexed": true, "name": "choice", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" }, { "indexed": false, "name": "salt", "type": "uint256" } ], "name": "_VoteRevealed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "voteQuorum", "type": "uint256" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": true, "name": "creator", "type": "address" } ], "name": "_PollCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VotingRightsGranted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "numTokens", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_VotingRightsWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "pollID", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_TokensRescued", "type": "event" }, { "constant": false, "inputs": [ { "name": "_numTokens", "type": "uint256" } ], "name": "requestVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_numTokens", "type": "uint256" } ], "name": "withdrawVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "rescueTokens", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" } ], "name": "rescueTokensInMultiplePolls", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" }, { "name": "_secretHash", "type": "bytes32" }, { "name": "_numTokens", "type": "uint256" }, { "name": "_prevPollID", "type": "uint256" } ], "name": "commitVote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" }, { "name": "_secretHashes", "type": "bytes32[]" }, { "name": "_numsTokens", "type": "uint256[]" }, { "name": "_prevPollIDs", "type": "uint256[]" } ], "name": "commitVotes", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_prevID", "type": "uint256" }, { "name": "_nextID", "type": "uint256" }, { "name": "_voter", "type": "address" }, { "name": "_numTokens", "type": "uint256" } ], "name": "validPosition", "outputs": [ { "name": "valid", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollID", "type": "uint256" }, { "name": "_voteOption", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "revealVote", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_pollIDs", "type": "uint256[]" }, { "name": "_voteOptions", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "revealVotes", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "getNumPassingTokens", "outputs": [ { "name": "correctVotes", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_voteQuorum", "type": "uint256" }, { "name": "_commitDuration", "type": "uint256" }, { "name": "_revealDuration", "type": "uint256" } ], "name": "startPoll", "outputs": [ { "name": "pollID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "isPassed", "outputs": [ { "name": "passed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "getTotalNumberOfTokensForWinningOption", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "pollEnded", "outputs": [ { "name": "ended", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "commitPeriodActive", "outputs": [ { "name": "active", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "revealPeriodActive", "outputs": [ { "name": "active", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "didCommit", "outputs": [ { "name": "committed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "didReveal", "outputs": [ { "name": "revealed", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_pollID", "type": "uint256" } ], "name": "pollExists", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "getCommitHash", "outputs": [ { "name": "commitHash", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "getNumTokens", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" } ], "name": "getLastNode", "outputs": [ { "name": "pollID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" } ], "name": "getLockedTokens", "outputs": [ { "name": "numTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_numTokens", "type": "uint256" }, { "name": "_pollID", "type": "uint256" } ], "name": "getInsertPointForNumTokens", "outputs": [ { "name": "prevNode", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_terminationDate", "type": "uint256" } ], "name": "isExpired", "outputs": [ { "name": "expired", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_user", "type": "address" }, { "name": "_pollID", "type": "uint256" } ], "name": "attrUUID", "outputs": [ { "name": "UUID", "type": "bytes32" } ], "payable": false, "stateMutability": "pure", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/Parameterizer.json ================================================ { "contractName": "Parameterizer", "bytecode": "0x608060405262093a806005553480156200001857600080fd5b50604051620028683803806200286883398101604081815282516020808501518386015160038054600160a060020a03808716600160a060020a0319928316179092556004805492851692909116919091179055848601909452600a85527f6d696e4465706f736974000000000000000000000000000000000000000000009185019190915291909301805191929091620000db919083906000908110620000bc57fe5b9060200190602002015162000412640100000000026401000000009004565b620001256040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250826001815181101515620000bc57fe5b6200016f6040805190810160405280600d81526020017f6170706c7953746167654c656e00000000000000000000000000000000000000815250826002815181101515620000bc57fe5b620001b96040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250826003815181101515620000bc57fe5b620002036040805190810160405280600e81526020017f636f6d6d697453746167654c656e000000000000000000000000000000000000815250826004815181101515620000bc57fe5b6200024d6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250826005815181101515620000bc57fe5b620002976040805190810160405280600e81526020017f72657665616c53746167654c656e000000000000000000000000000000000000815250826006815181101515620000bc57fe5b620002e16040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250826007815181101515620000bc57fe5b6200032b6040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250826008815181101515620000bc57fe5b620003756040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250826009815181101515620000bc57fe5b620003bf6040805190810160405280600a81526020017f766f746551756f72756d0000000000000000000000000000000000000000000081525082600a815181101515620000bc57fe5b620004096040805190810160405280600b81526020017f70566f746551756f72756d00000000000000000000000000000000000000000081525082600b815181101515620000bc57fe5b5050506200048a565b80600080846040518082805190602001908083835b60208310620004485780518252601f19909201916020918201910162000427565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b6123ce806200049a6000396000f3006080604052600436106100fa5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100ff57806330490e911461012657806332ed5b1214610140578063353009901461020c57806350411552146102385780635f02116f14610250578063693ec85e146102de57806377609a41146103375780638240ae4b1461034f57806386bb8f37146103675780638f1d377614610382578063a5ba3b1e146103cd578063a7aad3db146103f1578063bade1c5414610418578063c51131fb14610473578063dc6ab5271461048b578063fc0c546a146104a3578063fce1ccca146104d4575b600080fd5b34801561010b57600080fd5b506101146104e9565b60408051918252519081900360200190f35b34801561013257600080fd5b5061013e6004356104ef565b005b34801561014c57600080fd5b506101586004356109ca565b604051808881526020018781526020018681526020018060200185600160a060020a0316600160a060020a03168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156101cb5781810151838201526020016101b3565b50505050905090810190601f1680156101f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561021857600080fd5b50610224600435610a96565b604080519115158252519081900360200190f35b34801561024457600080fd5b50610114600435610aaf565b34801561025c57600080fd5b506040805160206004803580820135838102808601850190965280855261013e95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610b819650505050505050565b3480156102ea57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610114943694929360249392840191908190840183828082843750949750610be49650505050505050565b34801561034357600080fd5b50610224600435610c5a565b34801561035b57600080fd5b50610114600435610e73565b34801561037357600080fd5b5061013e6004356024356113ab565b34801561038e57600080fd5b5061039a6004356115b7565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156103d957600080fd5b50610224600435600160a060020a03602435166115f4565b3480156103fd57600080fd5b50610114600160a060020a0360043516602435604435611624565b34801561042457600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011494369492936024939284019190819084018382808284375094975050933594506116fa9350505050565b34801561047f57600080fd5b50610224600435611bd0565b34801561049757600080fd5b50610114600435611cf3565b3480156104af57600080fd5b506104b8611d05565b60408051600160a060020a039092168252519081900360200190f35b3480156104e057600080fd5b506104b8611d14565b60055481565b60008181526002602081905260409091206004810154918101549091600160a060020a03169061051e84611bd0565b1561077857600383018054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526105c193909290918301828280156105b25780601f10610587576101008083540402835291602001916105b2565b820191906000526020600020905b81548152906001019060200180831161059557829003601f168201915b50505050508460060154611d23565b600683015460408051602081018390528181526003860180546002610100600183161502600019019091160492820183905287937f37f3986c71e1aa2c470cfc4a92af70820610c3065589d35ef1664ea27f3e73a5939192909181906060820190859080156106715780601f1061064657610100808354040283529160200191610671565b820191906000526020600020905b81548152906001019060200180831161065457829003601f168201915b5050935050505060405180910390a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b506004818101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005830181905560069092018290556003546040805160e060020a63a9059cbb028152600160a060020a0387811694820194909452602481018690529051929091169263a9059cbb926044808401936020939083900390910190829087803b15801561073c57600080fd5b505af1158015610750573d6000803e3d6000fd5b505050506040513d602081101561076657600080fd5b5051151561077357600080fd5b6107f4565b61078184610c5a565b1561078f5761077384611d99565b82600501544211156100fa5760405184907f29026cb2acebe6d0a4b6d593ccadf76e3fc6d0a02254e078b0c4a619608089d790600090a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b60646108346040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250610be4565b111561083c57fe5b606461087c6040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250610be4565b111561088457fe5b61096660055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b61095a61090c6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b61095a61094d6040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250610be4565b429063ffffffff6121e116565b9063ffffffff6121e116565b50600084815260026020819052604082208281556001810183905590810182905590610995600383018261223e565b5060048101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005820181905560069091015550505050565b60026020818152600092835260409283902080546001808301548386015460038501805489519481161561010002600019011697909704601f8101879004870284018701909852878352929690959294919291830182828015610a6e5780601f10610a4357610100808354040283529160200191610a6e565b820191906000526020600020905b815481529060010190602001808311610a5157829003601f168201915b50505050600483015460058401546006909401549293600160a060020a039091169290915087565b600081815260026020526040812060050154115b919050565b60048054604080517f053e71a600000000000000000000000000000000000000000000000000000000815292830184905251600092600160a060020a039092169163053e71a691602480830192602092919082900301818787803b158015610b1657600080fd5b505af1158015610b2a573d6000803e3d6000fd5b505050506040513d6020811015610b4057600080fd5b50511515610b635750600081815260016020526040902060029081015402610aaa565b50600090815260016020526040902080546002918201549091020390565b8051825160009114610b9257600080fd5b5060005b8251811015610bdf57610bd78382815181101515610bb057fe5b906020019060200201518383815181101515610bc857fe5b906020019060200201516113ab565b600101610b96565b505050565b6000806000836040518082805190602001908083835b60208310610c195780518252601f199092019160209182019101610bfa565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6000610c64612285565b610c6c6122cc565b600084815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015610d295780601f10610cfe57610100808354040283529160200191610d29565b820191906000526020600020905b815481529060010190602001808311610d0c57829003601f168201915b50505091835250506004820154600160a060020a039081166020808401919091526005840154604080850191909152600690940154606093840152848101805160009081526001808452868220875160a08101895281548152918101549586169482019490945260a060020a90940460ff1615159584019590955260028201549383019390935260030154608082015290519294509250108015610dcf57506040810151155b8015610e6b575060048054602080850151604080517fee6848300000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a039092169263ee68483092602480830193928290030181600087803b158015610e3e57600080fd5b505af1158015610e52573d6000803e3d6000fd5b505050506040513d6020811015610e6857600080fd5b50515b949350505050565b6000610e7d612285565b6000838152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f810186900486028201860190945283815286958695869593949360608601939291830182828015610f3c5780601f10610f1157610100808354040283529160200191610f3c565b820191906000526020600020905b815481529060010190602001808311610f1f57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040808301919091526006909201546060909101528101519095509350610f8287610a96565b8015610f9057506020850151155b1515610f9b57600080fd5b60045460408051808201909152600b81527f70566f746551756f72756d0000000000000000000000000000000000000000006020820152600160a060020a03909116906332ed3d6090610fed90610be4565b61102b6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b6110696040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b505050506040513d60208110156110f357600080fd5b50516040805160e08101909152601060a082019081527f7044697370656e736174696f6e5063740000000000000000000000000000000060c083015291945090819061116e9060649061116290899061115690849061115190610be4565b6121ee565b9063ffffffff61220016565b9063ffffffff61222916565b81523360208083018290526000604080850182905260608086018b905260809586018390528983526001808552828420885181558886015181830180548b87015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a911515919091021790559289015160028083019190915598909701516003978801558e8452968452818320909601899055935484517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018a9052935193909416936323b872dd936064808501949192918390030190829087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b505115156112c157600080fd5b60048054604080517f6148fed500000000000000000000000000000000000000000000000000000000815292830186905251600160a060020a0390911691636148fed59160248083019260a09291908290030181600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050506040513d60a081101561135057600080fd5b50805160209182015160408051878152938401839052838101829052519194509250339189917fe94e3086c4bfe84acba4437b85a80fca3721dfc419d1f7afe4fa4e470e670b489181900360600190a3509095945050505050565b6000828152600160209081526040808320338452600401909152812054819060ff16156113d757600080fd5b600084815260016020819052604090912081015460a060020a900460ff1615151461140157600080fd5b60048054604080517fb43bd0690000000000000000000000000000000000000000000000000000000081523393810193909352602483018790526044830186905251600160a060020a039091169163b43bd0699160648083019260209291908290030181600087803b15801561147657600080fd5b505af115801561148a573d6000803e3d6000fd5b505050506040513d60208110156114a057600080fd5b505191506114af338585611624565b6000858152600160208181526040808420600381018054899003905580548690038155338086526004909101835293819020805460ff191690931790925581518481529151939450919287927f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f59957928290030190a36003546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561157a57600080fd5b505af115801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b505115156115b157600080fd5b50505050565b60016020819052600091825260409091208054918101546002820154600390920154600160a060020a0382169260a060020a90920460ff16919085565b6000828152600160209081526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152600160209081526040808320600381015490546004805484517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038b811693820193909352602481018a9052604481018990529451939592948794929091169263b43bd0699260648084019382900301818787803b1580156116b357600080fd5b505af11580156116c7573d6000803e3d6000fd5b505050506040513d60208110156116dd57600080fd5b50519050828282028115156116ee57fe5b04979650505050505050565b600080600061173d6040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250610be4565b915084846040518083805190602001908083835b602083106117705780518252601f199092019160209182019101611751565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f64697370656e736174696f6e50637400000000000000000000000000000000008552905193849003600f0184208a5191965094508993925082918401908083835b602083106117ff5780518252601f1990920191602091820191016117e0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614806118cc5750604080517f7044697370656e736174696f6e5063740000000000000000000000000000000081529051908190036010018120865190918791819060208401908083835b602083106118995780518252601f19909201916020918201910161187a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b156118df5760648411156118df57600080fd5b6118e881610a96565b156118f257600080fd5b836118fc86610be4565b141561190757600080fd5b604080516101208101909152600e60e082019081527f704170706c7953746167654c656e00000000000000000000000000000000000061010083015281906119529061094d90610be4565b81526020016000815260200183815260200186815260200133600160a060020a031681526020016119c060055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b8152602090810186905260008381526002808352604091829020845181558484015160018201559184015190820155606083015180519192611a0a92600385019290910190612307565b5060808201516004828101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0393841617905560a0840151600584015560c090930151600690920191909155600354604080517f23b872dd000000000000000000000000000000000000000000000000000000008152339481019490945230602485015260448401869052519116916323b872dd9160648083019260209291908290030181600087803b158015611abf57600080fd5b505af1158015611ad3573d6000803e3d6000fd5b505050506040513d6020811015611ae957600080fd5b50511515611af657600080fd5b6000818152600260209081526040808320548151808401899052918201859052606082018690526080820181905260a0808352895190830152885133947fb25bdef16105f099e5c185f9c7fd969571e8e0caa3f7bd75409512fe0a41a60b948b948b9489948b949193839260c0840192918a0191908190849084905b83811015611b8a578181015183820152602001611b72565b50505050905090810190601f168015611bb75780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a2949350505050565b6000611bda612285565b600083815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015611c975780601f10611c6c57610100808354040283529160200191611c97565b820191906000526020600020905b815481529060010190602001808311611c7a57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040820152600690910154606090910152805190915042118015611cde57508060a0015142105b8015611cec57506020810151155b9392505050565b60006020819052908152604090205481565b600354600160a060020a031681565b600454600160a060020a031681565b80600080846040518082805190602001908083835b60208310611d575780518252601f199092019160209182019101611d38565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b611da1612285565b6000828152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f81018690048602820186019094528381528695919492936060860193919291830182828015611e5e5780601f10611e3357610100808354040283529160200191611e5e565b820191906000526020600020905b815481529060010190602001808311611e4157829003601f168201915b505050505081526020016004820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160058201548152602001600682015481525050925060016000846020015181526020019081526020016000209150611ed28360200151610aaf565b60048054602080870151604080517f053e71a60000000000000000000000000000000000000000000000000000000081529485019190915251939450600160a060020a039091169263053e71a69260248082019392918290030181600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b505050506040513d6020811015611f6857600080fd5b5051600383015560018201805474ff0000000000000000000000000000000000000000191660a060020a17905560048054602085810151604080517f494031830000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a0390921692634940318392602480830193928290030181600087803b158015611ffd57600080fd5b505af1158015612011573d6000803e3d6000fd5b505050506040513d602081101561202757600080fd5b50511561212e57428360a00151111561204c5761204c83606001518460c00151611d23565b6020808401518354600385015460408051928352938201528251919287927fc4497224aa78dd50c9b3e344aab02596201ca1e6dca4057a91a6c02f83f4f6c19281900390910190a360035460808401516040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156120f257600080fd5b505af1158015612106573d6000803e3d6000fd5b505050506040513d602081101561211c57600080fd5b5051151561212957600080fd5b6115b1565b6020808401518354600385015460408051928352938201528251919287927f362a12431f779a2baff4f77f75ba7960ae993a5c41b425df11f7fd0af2b9cbe69281900390910190a360035460208085015160009081526001808352604080832090910154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb9360448084019491938390030190829087803b15801561157a57600080fd5b8181018281101561161e57fe5b6000828211156121fa57fe5b50900390565b60008215156122115750600061161e565b5081810281838281151561222157fe5b041461161e57fe5b6000818381151561223657fe5b049392505050565b50805460018160011615610100020316600290046000825580601f106122645750612282565b601f0160209004906000526020600020908101906122829190612385565b50565b60e060405190810160405280600081526020016000815260200160008152602001606081526020016000600160a060020a0316815260200160008152602001600081525090565b60a060405190810160405280600081526020016000600160a060020a0316815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061234857805160ff1916838001178555612375565b82800160010185558215612375579182015b8281111561237557825182559160200191906001019061235a565b50612381929150612385565b5090565b61239f91905b80821115612381576000815560010161238b565b905600a165627a7a723058202af51e140fd09e4cad9285f5633262726bdadf8b67c812e3a0ffa068e08495710029", "deployedBytecode": "0x6080604052600436106100fa5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166229514f81146100ff57806330490e911461012657806332ed5b1214610140578063353009901461020c57806350411552146102385780635f02116f14610250578063693ec85e146102de57806377609a41146103375780638240ae4b1461034f57806386bb8f37146103675780638f1d377614610382578063a5ba3b1e146103cd578063a7aad3db146103f1578063bade1c5414610418578063c51131fb14610473578063dc6ab5271461048b578063fc0c546a146104a3578063fce1ccca146104d4575b600080fd5b34801561010b57600080fd5b506101146104e9565b60408051918252519081900360200190f35b34801561013257600080fd5b5061013e6004356104ef565b005b34801561014c57600080fd5b506101586004356109ca565b604051808881526020018781526020018681526020018060200185600160a060020a0316600160a060020a03168152602001848152602001838152602001828103825286818151815260200191508051906020019080838360005b838110156101cb5781810151838201526020016101b3565b50505050905090810190601f1680156101f85780820380516001836020036101000a031916815260200191505b509850505050505050505060405180910390f35b34801561021857600080fd5b50610224600435610a96565b604080519115158252519081900360200190f35b34801561024457600080fd5b50610114600435610aaf565b34801561025c57600080fd5b506040805160206004803580820135838102808601850190965280855261013e95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610b819650505050505050565b3480156102ea57600080fd5b506040805160206004803580820135601f8101849004840285018401909552848452610114943694929360249392840191908190840183828082843750949750610be49650505050505050565b34801561034357600080fd5b50610224600435610c5a565b34801561035b57600080fd5b50610114600435610e73565b34801561037357600080fd5b5061013e6004356024356113ab565b34801561038e57600080fd5b5061039a6004356115b7565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b3480156103d957600080fd5b50610224600435600160a060020a03602435166115f4565b3480156103fd57600080fd5b50610114600160a060020a0360043516602435604435611624565b34801561042457600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261011494369492936024939284019190819084018382808284375094975050933594506116fa9350505050565b34801561047f57600080fd5b50610224600435611bd0565b34801561049757600080fd5b50610114600435611cf3565b3480156104af57600080fd5b506104b8611d05565b60408051600160a060020a039092168252519081900360200190f35b3480156104e057600080fd5b506104b8611d14565b60055481565b60008181526002602081905260409091206004810154918101549091600160a060020a03169061051e84611bd0565b1561077857600383018054604080516020601f600260001961010060018816150201909516949094049384018190048102820181019092528281526105c193909290918301828280156105b25780601f10610587576101008083540402835291602001916105b2565b820191906000526020600020905b81548152906001019060200180831161059557829003601f168201915b50505050508460060154611d23565b600683015460408051602081018390528181526003860180546002610100600183161502600019019091160492820183905287937f37f3986c71e1aa2c470cfc4a92af70820610c3065589d35ef1664ea27f3e73a5939192909181906060820190859080156106715780601f1061064657610100808354040283529160200191610671565b820191906000526020600020905b81548152906001019060200180831161065457829003601f168201915b5050935050505060405180910390a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b506004818101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005830181905560069092018290556003546040805160e060020a63a9059cbb028152600160a060020a0387811694820194909452602481018690529051929091169263a9059cbb926044808401936020939083900390910190829087803b15801561073c57600080fd5b505af1158015610750573d6000803e3d6000fd5b505050506040513d602081101561076657600080fd5b5051151561077357600080fd5b6107f4565b61078184610c5a565b1561078f5761077384611d99565b82600501544211156100fa5760405184907f29026cb2acebe6d0a4b6d593ccadf76e3fc6d0a02254e078b0c4a619608089d790600090a26000848152600260208190526040822082815560018101839055908101829055906106ae600383018261223e565b60646108346040805190810160405280600f81526020017f64697370656e736174696f6e5063740000000000000000000000000000000000815250610be4565b111561083c57fe5b606461087c6040805190810160405280601081526020017f7044697370656e736174696f6e50637400000000000000000000000000000000815250610be4565b111561088457fe5b61096660055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b61095a61090c6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b61095a61094d6040805190810160405280600e81526020017f704170706c7953746167654c656e000000000000000000000000000000000000815250610be4565b429063ffffffff6121e116565b9063ffffffff6121e116565b50600084815260026020819052604082208281556001810183905590810182905590610995600383018261223e565b5060048101805473ffffffffffffffffffffffffffffffffffffffff1916905560006005820181905560069091015550505050565b60026020818152600092835260409283902080546001808301548386015460038501805489519481161561010002600019011697909704601f8101879004870284018701909852878352929690959294919291830182828015610a6e5780601f10610a4357610100808354040283529160200191610a6e565b820191906000526020600020905b815481529060010190602001808311610a5157829003601f168201915b50505050600483015460058401546006909401549293600160a060020a039091169290915087565b600081815260026020526040812060050154115b919050565b60048054604080517f053e71a600000000000000000000000000000000000000000000000000000000815292830184905251600092600160a060020a039092169163053e71a691602480830192602092919082900301818787803b158015610b1657600080fd5b505af1158015610b2a573d6000803e3d6000fd5b505050506040513d6020811015610b4057600080fd5b50511515610b635750600081815260016020526040902060029081015402610aaa565b50600090815260016020526040902080546002918201549091020390565b8051825160009114610b9257600080fd5b5060005b8251811015610bdf57610bd78382815181101515610bb057fe5b906020019060200201518383815181101515610bc857fe5b906020019060200201516113ab565b600101610b96565b505050565b6000806000836040518082805190602001908083835b60208310610c195780518252601f199092019160209182019101610bfa565b51815160209384036101000a600019018019909216911617905260408051929094018290039091208652850195909552929092016000205495945050505050565b6000610c64612285565b610c6c6122cc565b600084815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015610d295780601f10610cfe57610100808354040283529160200191610d29565b820191906000526020600020905b815481529060010190602001808311610d0c57829003601f168201915b50505091835250506004820154600160a060020a039081166020808401919091526005840154604080850191909152600690940154606093840152848101805160009081526001808452868220875160a08101895281548152918101549586169482019490945260a060020a90940460ff1615159584019590955260028201549383019390935260030154608082015290519294509250108015610dcf57506040810151155b8015610e6b575060048054602080850151604080517fee6848300000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a039092169263ee68483092602480830193928290030181600087803b158015610e3e57600080fd5b505af1158015610e52573d6000803e3d6000fd5b505050506040513d6020811015610e6857600080fd5b50515b949350505050565b6000610e7d612285565b6000838152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f810186900486028201860190945283815286958695869593949360608601939291830182828015610f3c5780601f10610f1157610100808354040283529160200191610f3c565b820191906000526020600020905b815481529060010190602001808311610f1f57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040808301919091526006909201546060909101528101519095509350610f8287610a96565b8015610f9057506020850151155b1515610f9b57600080fd5b60045460408051808201909152600b81527f70566f746551756f72756d0000000000000000000000000000000000000000006020820152600160a060020a03909116906332ed3d6090610fed90610be4565b61102b6040805190810160405280600f81526020017f70436f6d6d697453746167654c656e0000000000000000000000000000000000815250610be4565b6110696040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808481526020018381526020018281526020019350505050602060405180830381600087803b1580156110c957600080fd5b505af11580156110dd573d6000803e3d6000fd5b505050506040513d60208110156110f357600080fd5b50516040805160e08101909152601060a082019081527f7044697370656e736174696f6e5063740000000000000000000000000000000060c083015291945090819061116e9060649061116290899061115690849061115190610be4565b6121ee565b9063ffffffff61220016565b9063ffffffff61222916565b81523360208083018290526000604080850182905260608086018b905260809586018390528983526001808552828420885181558886015181830180548b87015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a911515919091021790559289015160028083019190915598909701516003978801558e8452968452818320909601899055935484517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018a9052935193909416936323b872dd936064808501949192918390030190829087803b15801561128a57600080fd5b505af115801561129e573d6000803e3d6000fd5b505050506040513d60208110156112b457600080fd5b505115156112c157600080fd5b60048054604080517f6148fed500000000000000000000000000000000000000000000000000000000815292830186905251600160a060020a0390911691636148fed59160248083019260a09291908290030181600087803b15801561132657600080fd5b505af115801561133a573d6000803e3d6000fd5b505050506040513d60a081101561135057600080fd5b50805160209182015160408051878152938401839052838101829052519194509250339189917fe94e3086c4bfe84acba4437b85a80fca3721dfc419d1f7afe4fa4e470e670b489181900360600190a3509095945050505050565b6000828152600160209081526040808320338452600401909152812054819060ff16156113d757600080fd5b600084815260016020819052604090912081015460a060020a900460ff1615151461140157600080fd5b60048054604080517fb43bd0690000000000000000000000000000000000000000000000000000000081523393810193909352602483018790526044830186905251600160a060020a039091169163b43bd0699160648083019260209291908290030181600087803b15801561147657600080fd5b505af115801561148a573d6000803e3d6000fd5b505050506040513d60208110156114a057600080fd5b505191506114af338585611624565b6000858152600160208181526040808420600381018054899003905580548690038155338086526004909101835293819020805460ff191690931790925581518481529151939450919287927f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f59957928290030190a36003546040805160e060020a63a9059cbb028152336004820152602481018490529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b15801561157a57600080fd5b505af115801561158e573d6000803e3d6000fd5b505050506040513d60208110156115a457600080fd5b505115156115b157600080fd5b50505050565b60016020819052600091825260409091208054918101546002820154600390920154600160a060020a0382169260a060020a90920460ff16919085565b6000828152600160209081526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152600160209081526040808320600381015490546004805484517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038b811693820193909352602481018a9052604481018990529451939592948794929091169263b43bd0699260648084019382900301818787803b1580156116b357600080fd5b505af11580156116c7573d6000803e3d6000fd5b505050506040513d60208110156116dd57600080fd5b50519050828282028115156116ee57fe5b04979650505050505050565b600080600061173d6040805190810160405280600b81526020017f704d696e4465706f736974000000000000000000000000000000000000000000815250610be4565b915084846040518083805190602001908083835b602083106117705780518252601f199092019160209182019101611751565b51815160001960209485036101000a019081169019919091161790529201938452506040805193849003820184207f64697370656e736174696f6e50637400000000000000000000000000000000008552905193849003600f0184208a5191965094508993925082918401908083835b602083106117ff5780518252601f1990920191602091820191016117e0565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405180910390206000191614806118cc5750604080517f7044697370656e736174696f6e5063740000000000000000000000000000000081529051908190036010018120865190918791819060208401908083835b602083106118995780518252601f19909201916020918201910161187a565b6001836020036101000a038019825116818451168082178552505050505050905001915050604051809103902060001916145b156118df5760648411156118df57600080fd5b6118e881610a96565b156118f257600080fd5b836118fc86610be4565b141561190757600080fd5b604080516101208101909152600e60e082019081527f704170706c7953746167654c656e00000000000000000000000000000000000061010083015281906119529061094d90610be4565b81526020016000815260200183815260200186815260200133600160a060020a031681526020016119c060055461095a6108cb6040805190810160405280600f81526020017f7052657665616c53746167654c656e0000000000000000000000000000000000815250610be4565b8152602090810186905260008381526002808352604091829020845181558484015160018201559184015190820155606083015180519192611a0a92600385019290910190612307565b5060808201516004828101805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0393841617905560a0840151600584015560c090930151600690920191909155600354604080517f23b872dd000000000000000000000000000000000000000000000000000000008152339481019490945230602485015260448401869052519116916323b872dd9160648083019260209291908290030181600087803b158015611abf57600080fd5b505af1158015611ad3573d6000803e3d6000fd5b505050506040513d6020811015611ae957600080fd5b50511515611af657600080fd5b6000818152600260209081526040808320548151808401899052918201859052606082018690526080820181905260a0808352895190830152885133947fb25bdef16105f099e5c185f9c7fd969571e8e0caa3f7bd75409512fe0a41a60b948b948b9489948b949193839260c0840192918a0191908190849084905b83811015611b8a578181015183820152602001611b72565b50505050905090810190601f168015611bb75780820380516001836020036101000a031916815260200191505b50965050505050505060405180910390a2949350505050565b6000611bda612285565b600083815260026020818152604092839020835160e0810185528154815260018083015482850152828501548287015260038301805487516000199382161561010002939093011695909504601f810185900485028201850190965285815290949193606086019391929091830182828015611c975780601f10611c6c57610100808354040283529160200191611c97565b820191906000526020600020905b815481529060010190602001808311611c7a57829003601f168201915b50505091835250506004820154600160a060020a0316602082015260058201546040820152600690910154606090910152805190915042118015611cde57508060a0015142105b8015611cec57506020810151155b9392505050565b60006020819052908152604090205481565b600354600160a060020a031681565b600454600160a060020a031681565b80600080846040518082805190602001908083835b60208310611d575780518252601f199092019160209182019101611d38565b51815160209384036101000a60001901801990921691161790526040805192909401829003909120865285019590955292909201600020939093555050505050565b611da1612285565b6000828152600260208181526040808420815160e0810183528154815260018083015482860152828601548285015260038301805485516000199382161561010002939093011696909604601f81018690048602820186019094528381528695919492936060860193919291830182828015611e5e5780601f10611e3357610100808354040283529160200191611e5e565b820191906000526020600020905b815481529060010190602001808311611e4157829003601f168201915b505050505081526020016004820160009054906101000a9004600160a060020a0316600160a060020a0316600160a060020a0316815260200160058201548152602001600682015481525050925060016000846020015181526020019081526020016000209150611ed28360200151610aaf565b60048054602080870151604080517f053e71a60000000000000000000000000000000000000000000000000000000081529485019190915251939450600160a060020a039091169263053e71a69260248082019392918290030181600087803b158015611f3e57600080fd5b505af1158015611f52573d6000803e3d6000fd5b505050506040513d6020811015611f6857600080fd5b5051600383015560018201805474ff0000000000000000000000000000000000000000191660a060020a17905560048054602085810151604080517f494031830000000000000000000000000000000000000000000000000000000081529485019190915251600160a060020a0390921692634940318392602480830193928290030181600087803b158015611ffd57600080fd5b505af1158015612011573d6000803e3d6000fd5b505050506040513d602081101561202757600080fd5b50511561212e57428360a00151111561204c5761204c83606001518460c00151611d23565b6020808401518354600385015460408051928352938201528251919287927fc4497224aa78dd50c9b3e344aab02596201ca1e6dca4057a91a6c02f83f4f6c19281900390910190a360035460808401516040805160e060020a63a9059cbb028152600160a060020a039283166004820152602481018590529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156120f257600080fd5b505af1158015612106573d6000803e3d6000fd5b505050506040513d602081101561211c57600080fd5b5051151561212957600080fd5b6115b1565b6020808401518354600385015460408051928352938201528251919287927f362a12431f779a2baff4f77f75ba7960ae993a5c41b425df11f7fd0af2b9cbe69281900390910190a360035460208085015160009081526001808352604080832090910154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb9360448084019491938390030190829087803b15801561157a57600080fd5b8181018281101561161e57fe5b6000828211156121fa57fe5b50900390565b60008215156122115750600061161e565b5081810281838281151561222157fe5b041461161e57fe5b6000818381151561223657fe5b049392505050565b50805460018160011615610100020316600290046000825580601f106122645750612282565b601f0160209004906000526020600020908101906122829190612385565b50565b60e060405190810160405280600081526020016000815260200160008152602001606081526020016000600160a060020a0316815260200160008152602001600081525090565b60a060405190810160405280600081526020016000600160a060020a0316815260200160001515815260200160008152602001600081525090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061234857805160ff1916838001178555612375565b82800160010185558215612375579182015b8281111561237557825182559160200191906001019061235a565b50612381929150612385565b5090565b61239f91905b80821115612381576000815560010161238b565b905600a165627a7a723058202af51e140fd09e4cad9285f5633262726bdadf8b67c812e3a0ffa068e08495710029", "abi": [ { "constant": true, "inputs": [], "name": "PROCESSBY", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "proposals", "outputs": [ { "name": "appExpiry", "type": "uint256" }, { "name": "challengeID", "type": "uint256" }, { "name": "deposit", "type": "uint256" }, { "name": "name", "type": "string" }, { "name": "owner", "type": "address" }, { "name": "processBy", "type": "uint256" }, { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "winningTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "bytes32" } ], "name": "params", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_token", "type": "address" }, { "name": "_plcr", "type": "address" }, { "name": "_parameters", "type": "uint256[]" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" }, { "indexed": false, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": true, "name": "proposer", "type": "address" } ], "name": "_ReparameterizationProposal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_NewChallenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": false, "name": "name", "type": "string" }, { "indexed": false, "name": "value", "type": "uint256" } ], "name": "_ProposalAccepted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" } ], "name": "_ProposalExpired", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "propID", "type": "bytes32" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" }, { "constant": false, "inputs": [ { "name": "_name", "type": "string" }, { "name": "_value", "type": "uint256" } ], "name": "proposeReparameterization", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "challengeReparameterization", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "processProposal", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "canBeSet", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "propExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_propID", "type": "bytes32" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" } ], "name": "challengeWinnerReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_name", "type": "string" } ], "name": "get", "outputs": [ { "name": "value", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/RBAC.json ================================================ { "contractName": "RBAC", "bytecode": "0x608060405234801561001057600080fd5b5061029c806100206000396000f30060806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630988ca8c8114610050578063217fe6c6146100c6575b600080fd5b34801561005c57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100c495833573ffffffffffffffffffffffffffffffffffffffff1695369560449491939091019190819084018382808284375094975061014e9650505050505050565b005b3480156100d257600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261013a95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506101bc9650505050505050565b604080519115158252519081900360200190f35b6101b8826000836040518082805190602001908083835b602083106101845780518252601f199092019160209182019101610165565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061022f565b5050565b6000610228836000846040518082805190602001908083835b602083106101f45780518252601f1990920191602091820191016101d5565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610244565b9392505050565b6102398282610244565b15156101b857600080fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152602091909152604090205460ff16905600a165627a7a723058203723c3c36af110b67321f88290ee3cf1965c34a4d0c00a03d5c9cdf45d70c21a0029", "deployedBytecode": "0x60806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630988ca8c8114610050578063217fe6c6146100c6575b600080fd5b34801561005c57600080fd5b5060408051602060046024803582810135601f81018590048502860185019096528585526100c495833573ffffffffffffffffffffffffffffffffffffffff1695369560449491939091019190819084018382808284375094975061014e9650505050505050565b005b3480156100d257600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261013a95833573ffffffffffffffffffffffffffffffffffffffff169536956044949193909101919081908401838280828437509497506101bc9650505050505050565b604080519115158252519081900360200190f35b6101b8826000836040518082805190602001908083835b602083106101845780518252601f199092019160209182019101610165565b51815160209384036101000a600019018019909216911617905292019485525060405193849003019092209291505061022f565b5050565b6000610228836000846040518082805190602001908083835b602083106101f45780518252601f1990920191602091820191016101d5565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610244565b9392505050565b6102398282610244565b15156101b857600080fd5b73ffffffffffffffffffffffffffffffffffffffff166000908152602091909152604090205460ff16905600a165627a7a723058203723c3c36af110b67321f88290ee3cf1965c34a4d0c00a03d5c9cdf45d70c21a0029", "abi": [ { "anonymous": false, "inputs": [ { "indexed": true, "name": "operator", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "operator", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleRemoved", "type": "event" }, { "constant": true, "inputs": [ { "name": "_operator", "type": "address" }, { "name": "_role", "type": "string" } ], "name": "checkRole", "outputs": [], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_operator", "type": "address" }, { "name": "_role", "type": "string" } ], "name": "hasRole", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/RestrictedAddressRegistry.json ================================================ { "contractName": "RestrictedAddressRegistry", "bytecode": "0x60806040523480156200001157600080fd5b5060405162003066380380620030668339810160409081528151602083015191830151606084015191939091018383838383838383600160a060020a0384161515620000be57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f5f746f6b656e2061646472657373206973203000000000000000000000000000604482015290519081900360640190fd5b600160a060020a03831615156200013657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5f766f74696e6720616464726573732069732030000000000000000000000000604482015290519081900360640190fd5b600160a060020a0382161515620001ae57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f5f706172616d65746572697a6572206164647265737320697320300000000000604482015290519081900360640190fd5b60028054600160a060020a03808716600160a060020a03199283161790925560038054868416908316179055600480549285169290911691909117905580516200020090600590602084019062000213565b50505050505050505050505050620002b8565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200025657805160ff191683800117855562000286565b8280016001018555821562000286579182015b828111156200028657825182559160200191906001019062000269565b506200029492915062000298565b5090565b620002b591905b808211156200029457600081556001016200029f565b90565b612d9e80620002c86000396000f3006080604052600436106101195763ffffffff60e060020a60003504166301162b93811461011e57806306fdde03146101415780632ea9b696146101cb5780633af32abf1461020057806347e7ef241461022157806355246b9c146102455780635f02116f146102ae57806361a9a8ca1461033c57806365d96c821461035d5780636eefcab9146103b157806386bb8f37146103d25780638f1d3776146103ed578063a5ba3b1e14610438578063a7aad3db1461045c578063b42652e914610495578063bc4b010f146104b6578063c8187cf11461051d578063dd4e7cfd14610535578063e1e3f91514610556578063f3fef3a314610587578063f96c8720146105ab578063fc0c546a14610600578063fce1ccca14610615575b600080fd5b34801561012a57600080fd5b5061013f600160a060020a036004351661062a565b005b34801561014d57600080fd5b50610156610660565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610190578181015183820152602001610178565b50505050905090810190601f1680156101bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101d757600080fd5b506101ec600160a060020a03600435166106ee565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600160a060020a036004351661082a565b34801561022d57600080fd5b5061013f600160a060020a0360043516602435610850565b34801561025157600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261013f948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a0c9650505050505050565b3480156102ba57600080fd5b506040805160206004803580820135838102808601850190965280855261013f95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610af69650505050505050565b34801561034857600080fd5b506101ec600160a060020a0360043516610bca565b34801561036957600080fd5b5061037e600160a060020a0360043516610be6565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103bd57600080fd5b506101ec600160a060020a0360043516610c21565b3480156103de57600080fd5b5061013f600435602435610c6c565b3480156103f957600080fd5b50610405600435610f3e565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561044457600080fd5b506101ec600435600160a060020a0360243516610f7a565b34801561046857600080fd5b50610483600160a060020a0360043516602435604435610fa8565b60408051918252519081900360200190f35b3480156104a157600080fd5b5061013f600160a060020a0360043516611077565b3480156104c257600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610483958335600160a060020a03169536956044949193909101919081908401838280828437509497506112669650505050505050565b34801561052957600080fd5b50610483600435611b3c565b34801561054157600080fd5b506101ec600160a060020a0360043516611d68565b34801561056257600080fd5b5061056b611e0a565b60408051600160a060020a039092168252519081900360200190f35b34801561059357600080fd5b5061013f600160a060020a0360043516602435611e19565b3480156105b757600080fd5b506040805160206004803580820135838102808601850190965280855261013f953695939460249493850192918291850190849080828437509497506121bf9650505050505050565b34801561060c57600080fd5b5061056b6121f7565b34801561062157600080fd5b5061056b612206565b61063381611d68565b156106465761064181612215565b61065d565b61064f816106ee565b156101195761064181612299565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461071383610c21565b151561078e576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b1580156107f557600080fd5b505af1158015610809573d6000803e3d6000fd5b505050506040513d602081101561081f57600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108cf576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561094b57600080fd5b505af115801561095f573d6000803e3d6000fd5b505050506040513d602081101561097557600080fd5b505115156109bb576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b82600081905033600160a060020a031681600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610a5a57600080fd5b505af1158015610a6e573d6000803e3d6000fd5b505050506040513d6020811015610a8457600080fd5b5051600160a060020a031614610ae4576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f74206f776e6572206f6620636f6e747261637400604482015290519081900360640190fd5b610aef8585856125f8565b5050505050565b8051825160009114610b78576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610bc557610bbd8382815181101515610b9657fe5b906020019060200201518383815181101515610bae57fe5b90602001906020020151610c6c565b600101610b7c565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015610c65575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615610ce1576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff16151514610d56576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b158015610dca57600080fd5b505af1158015610dde573d6000803e3d6000fd5b505050506040513d6020811015610df457600080fd5b50519150610e03338585610fa8565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b158015610e9157600080fd5b505af1158015610ea5573d6000803e3d6000fd5b505050506040513d6020811015610ebb57600080fd5b50511515610f01576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b15801561103057600080fd5b505af1158015611044573d6000803e3d6000fd5b505050506040513d602081101561105a57600080fd5b505190508282820281151561106b57fe5b04979650505050505050565b600160a060020a0380821660009081526001602081905260409091209081015490913361010090920416146110f6576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6110ff8261082a565b151561117b576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600381015415806111a95750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611225576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b61122e8261265e565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d602081101561132857600080fd5b5051945061133589610bca565b806113445750600186015460ff165b15156113e6576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806114145750600386015460009081526020819052604090206001015460a060020a900460ff165b1515611490576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b84866002015410156114e2576114a58961265e565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611b30565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561156957600080fd5b505af115801561157d573d6000803e3d6000fd5b505050506040513d602081101561159357600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561160f57600080fd5b505af1158015611623573d6000803e3d6000fd5b505050506040513d602081101561163957600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b505050506040513d60208110156116df57600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b15801561172b57600080fd5b505af115801561173f573d6000803e3d6000fd5b505050506040513d602081101561175557600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e48401529251939750606496509092839261184892889261183c928c9261183092600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b1580156117f757600080fd5b505af115801561180b573d6000803e3d6000fd5b505050506040513d602081101561182157600080fd5b50518a9063ffffffff61284016565b9063ffffffff61285216565b9063ffffffff61287b16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b15801561196157600080fd5b505af1158015611975573d6000803e3d6000fd5b505050506040513d602081101561198b57600080fd5b505115156119d1576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b158015611a3857600080fd5b505af1158015611a4c573d6000803e3d6000fd5b505050506040513d60a0811015611a6257600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611af0578181015183820152602001611ad8565b50505050905090810190601f168015611b1d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611bad576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015611c1457600080fd5b505af1158015611c28573d6000803e3d6000fd5b505050506040513d6020811015611c3e57600080fd5b50511515611c96576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b158015611cfd57600080fd5b505af1158015611d11573d6000803e3d6000fd5b505050506040513d6020811015611d2757600080fd5b50511515611d4a575060008181526020819052604090206002908101540261084b565b50600090815260208190526040902080546002918201549091020390565b600160a060020a038116600090815260016020526040812060030154611d8d83610bca565b8015611db05750600160a060020a03831660009081526001602052604090205442115b8015611dc25750611dc08361082a565b155b8015611df35750801580611df35750600081815260208190526040902060019081015460a060020a900460ff161515145b15611e015760019150610824565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611e98576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115611f1a576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b60038101541580611f485750600381015460009081526020819052604090206001015460a060020a900460ff165b1561209d57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611fc757600080fd5b505af1158015611fdb573d6000803e3d6000fd5b505050506040513d6020811015611ff157600080fd5b50516002820154839003101561209d576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156120fe57600080fd5b505af1158015612112573d6000803e3d6000fd5b505050506040513d602081101561212857600080fd5b5051151561216e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156121f3576121eb82828151811015156121dc57fe5b9060200190602002015161062a565b6001016121c2565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561227057604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a038116600090815260016020526040812060030154906122bf82611b3c565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561235457600080fd5b505af1158015612368573d6000803e3d6000fd5b505050506040513d602081101561237e57600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156123f857600080fd5b505af115801561240c573d6000803e3d6000fd5b505050506040513d602081101561242257600080fd5b5051156124a65761243283612215565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610bc5565b6124af8361265e565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b15801561251357600080fd5b505af1158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511515612595576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b82803b60008111612653576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b610aef858585612890565b600160a060020a0381166000908152600160208190526040822090810154909190819060ff16156126c257604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a26126f7565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff1916905592850183905560039094018290556101009092049092169181111561283a576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b505050506040513d60208110156127e257600080fd5b5051151561283a576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b60008282111561284c57fe5b50900390565b600082151561286357506000610fa2565b5081810281838281151561287357fe5b0414610fa257fe5b6000818381151561288857fe5b049392505050565b600061289b8461082a565b156128f0576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b6128f984610bca565b15612974576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156129ee57600080fd5b505af1158015612a02573d6000803e3d6000fd5b505050506040513d6020811015612a1857600080fd5b5051831015612a97576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395612b879592169363693ec85e9360648084019491938390030190829087803b158015612b4e57600080fd5b505af1158015612b62573d6000803e3d6000fd5b505050506040513d6020811015612b7857600080fd5b5051429063ffffffff612d4516565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015612c0e57600080fd5b505af1158015612c22573d6000803e3d6000fd5b505050506040513d6020811015612c3857600080fd5b50511515612c7e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612d03578181015183820152602001612ceb565b50505050905090810190601f168015612d305780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b81810182811015610fa257fe00546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058201e4d09fb99989dd4e9691ec6d3e28ca0c62e600e576ec0c3033d2c5c26a08dbe0029", "deployedBytecode": "0x6080604052600436106101195763ffffffff60e060020a60003504166301162b93811461011e57806306fdde03146101415780632ea9b696146101cb5780633af32abf1461020057806347e7ef241461022157806355246b9c146102455780635f02116f146102ae57806361a9a8ca1461033c57806365d96c821461035d5780636eefcab9146103b157806386bb8f37146103d25780638f1d3776146103ed578063a5ba3b1e14610438578063a7aad3db1461045c578063b42652e914610495578063bc4b010f146104b6578063c8187cf11461051d578063dd4e7cfd14610535578063e1e3f91514610556578063f3fef3a314610587578063f96c8720146105ab578063fc0c546a14610600578063fce1ccca14610615575b600080fd5b34801561012a57600080fd5b5061013f600160a060020a036004351661062a565b005b34801561014d57600080fd5b50610156610660565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610190578181015183820152602001610178565b50505050905090810190601f1680156101bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101d757600080fd5b506101ec600160a060020a03600435166106ee565b604080519115158252519081900360200190f35b34801561020c57600080fd5b506101ec600160a060020a036004351661082a565b34801561022d57600080fd5b5061013f600160a060020a0360043516602435610850565b34801561025157600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261013f948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610a0c9650505050505050565b3480156102ba57600080fd5b506040805160206004803580820135838102808601850190965280855261013f95369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a998901989297509082019550935083925085019084908082843750949750610af69650505050505050565b34801561034857600080fd5b506101ec600160a060020a0360043516610bca565b34801561036957600080fd5b5061037e600160a060020a0360043516610be6565b604080519586529315156020860152600160a060020a039092168484015260608401526080830152519081900360a00190f35b3480156103bd57600080fd5b506101ec600160a060020a0360043516610c21565b3480156103de57600080fd5b5061013f600435602435610c6c565b3480156103f957600080fd5b50610405600435610f3e565b60408051958652600160a060020a0390941660208601529115158484015260608401526080830152519081900360a00190f35b34801561044457600080fd5b506101ec600435600160a060020a0360243516610f7a565b34801561046857600080fd5b50610483600160a060020a0360043516602435604435610fa8565b60408051918252519081900360200190f35b3480156104a157600080fd5b5061013f600160a060020a0360043516611077565b3480156104c257600080fd5b5060408051602060046024803582810135601f8101859004850286018501909652858552610483958335600160a060020a03169536956044949193909101919081908401838280828437509497506112669650505050505050565b34801561052957600080fd5b50610483600435611b3c565b34801561054157600080fd5b506101ec600160a060020a0360043516611d68565b34801561056257600080fd5b5061056b611e0a565b60408051600160a060020a039092168252519081900360200190f35b34801561059357600080fd5b5061013f600160a060020a0360043516602435611e19565b3480156105b757600080fd5b506040805160206004803580820135838102808601850190965280855261013f953695939460249493850192918291850190849080828437509497506121bf9650505050505050565b34801561060c57600080fd5b5061056b6121f7565b34801561062157600080fd5b5061056b612206565b61063381611d68565b156106465761064181612215565b61065d565b61064f816106ee565b156101195761064181612299565b50565b6005805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156106e65780601f106106bb576101008083540402835291602001916106e6565b820191906000526020600020905b8154815290600101906020018083116106c957829003601f168201915b505050505081565b600160a060020a03811660009081526001602052604081206003015461071383610c21565b151561078e576040805160e560020a62461bcd028152602060048201526024808201527f4368616c6c656e676520646f6573206e6f7420657869737420666f72204c697360448201527f74696e6700000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018490529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b1580156107f557600080fd5b505af1158015610809573d6000803e3d6000fd5b505050506040513d602081101561081f57600080fd5b505191505b50919050565b600160a060020a0381166000908152600160208190526040909120015460ff165b919050565b600160a060020a0380831660009081526001602081905260409091209081015490916101009091041633146108cf576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66204c697374696e670000604482015290519081900360640190fd5b600280820180548401905554604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018590529051600160a060020a03909216916323b872dd916064808201926020929091908290030181600087803b15801561094b57600080fd5b505af115801561095f573d6000803e3d6000fd5b505050506040513d602081101561097557600080fd5b505115156109bb576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927ffc2e298800eb7bcacdea96213f53962a6bdf27d2a560f831d4e42301492e8f6a92918290030190a3505050565b82600081905033600160a060020a031681600160a060020a0316638da5cb5b6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610a5a57600080fd5b505af1158015610a6e573d6000803e3d6000fd5b505050506040513d6020811015610a8457600080fd5b5051600160a060020a031614610ae4576040805160e560020a62461bcd02815260206004820152601f60248201527f53656e646572206973206e6f74206f776e6572206f6620636f6e747261637400604482015290519081900360640190fd5b610aef8585856125f8565b5050505050565b8051825160009114610b78576040805160e560020a62461bcd02815260206004820152603960248201527f4d69736d6174636820696e206c656e677468206f66205f6368616c6c656e676560448201527f49447320616e64205f73616c747320706172616d657465727300000000000000606482015290519081900360840190fd5b5060005b8251811015610bc557610bbd8382815181101515610b9657fe5b906020019060200201518383815181101515610bae57fe5b90602001906020020151610c6c565b600101610b7c565b505050565b600160a060020a03166000908152600160205260408120541190565b6001602081905260009182526040909120805491810154600282015460039092015460ff821692610100909204600160a060020a0316919085565b600160a060020a0381166000908152600160205260408120600301548181118015610c65575060008181526020819052604090206001015460a060020a900460ff16155b9392505050565b600082815260208181526040808320338452600401909152812054819060ff1615610ce1576040805160e560020a62461bcd02815260206004820152601660248201527f52657761726420616c726561647920636c61696d656400000000000000000000604482015290519081900360640190fd5b600084815260208190526040902060019081015460a060020a900460ff16151514610d56576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e6765206e6f7420796574207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fb43bd06900000000000000000000000000000000000000000000000000000000815233600482015260248101879052604481018690529051600160a060020a039092169163b43bd069916064808201926020929091908290030181600087803b158015610dca57600080fd5b505af1158015610dde573d6000803e3d6000fd5b505050506040513d6020811015610df457600080fd5b50519150610e03338585610fa8565b6000858152602081815260408083206003810180548890039055805485900381553380855260049182018452828520805460ff19166001179055600254835160e060020a63a9059cbb02815292830191909152602482018690529151949550600160a060020a039091169363a9059cbb93604480840194938390030190829087803b158015610e9157600080fd5b505af1158015610ea5573d6000803e3d6000fd5b505050506040513d6020811015610ebb57600080fd5b50511515610f01576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b604080518281529051339186917f6f4c982acc31b0af2cf1dc1556f21c0325d893782d65e83c68a5534a33f599579181900360200190a350505050565b60006020819052908152604090208054600182015460028301546003909301549192600160a060020a0382169260a060020a90920460ff169185565b600082815260208181526040808320600160a060020a038516845260040190915290205460ff165b92915050565b6000828152602081815260408083206003808201549154905483517fb43bd069000000000000000000000000000000000000000000000000000000008152600160a060020a038a81166004830152602482018a905260448201899052945193959294879492169263b43bd0699260648084019382900301818787803b15801561103057600080fd5b505af1158015611044573d6000803e3d6000fd5b505050506040513d602081101561105a57600080fd5b505190508282820281151561106b57fe5b04979650505050505050565b600160a060020a0380821660009081526001602081905260409091209081015490913361010090920416146110f6576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6110ff8261082a565b151561117b576040805160e560020a62461bcd02815260206004820152602860248201527f4c697374696e67206d7573742062652077686974656c697374656420746f206260448201527f6520657869746564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600381015415806111a95750600381015460009081526020819052604090206001015460a060020a900460ff165b1515611225576040805160e560020a62461bcd02815260206004820152603660248201527f4c697374696e67206d757374206e6f74206861766520616e206163746976652060448201527f6368616c6c656e676520746f2062652065786974656400000000000000000000606482015290519081900360840190fd5b61122e8261265e565b604051600160a060020a038316907f09a024f7311a15ac363521bddca1d9937c4244ab9a25e6c968e610b35ecc750390600090a25050565b600160a060020a03808316600090815260016020908152604080832060048054835160e160020a63349f642f028152918201859052600a60248301527f6d696e4465706f73697400000000000000000000000000000000000000000000604483015292519495919486948594859485948594929091169263693ec85e9260648084019382900301818787803b1580156112fe57600080fd5b505af1158015611312573d6000803e3d6000fd5b505050506040513d602081101561132857600080fd5b5051945061133589610bca565b806113445750600186015460ff165b15156113e6576040805160e560020a62461bcd02815260206004820152604c60248201527f4c697374696e67206d75737420626520696e206170706c69636174696f6e207060448201527f68617365206f7220616c72656164792077686974656c697374656420746f206260648201527f65206368616c6c656e6765640000000000000000000000000000000000000000608482015290519081900360a40190fd5b600386015415806114145750600386015460009081526020819052604090206001015460a060020a900460ff165b1515611490576040805160e560020a62461bcd02815260206004820152603760248201527f4c697374696e67206d757374206e6f742068617665206163746976652063686160448201527f6c6c656e676520746f206265206368616c6c656e676564000000000000000000606482015290519081900360840190fd5b84866002015410156114e2576114a58961265e565b604051600160a060020a038a16907fc88462fa6972b64560d1dd34c4d66f2ff9841b2f974bdb0fab0827133d692f6490600090a260009650611b30565b600354600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f766f746551756f72756d0000000000000000000000000000000000000000000060448201529051600160a060020a03948516946332ed3d609493169263693ec85e92606480820193918290030181600087803b15801561156957600080fd5b505af115801561157d573d6000803e3d6000fd5b505050506040513d602081101561159357600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f636f6d6d697453746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b15801561160f57600080fd5b505af1158015611623573d6000803e3d6000fd5b505050506040513d602081101561163957600080fd5b5051600480546040805160e160020a63349f642f0281526020938101849052600e60248201527f72657665616c53746167654c656e00000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156116b557600080fd5b505af11580156116c9573d6000803e3d6000fd5b505050506040513d60208110156116df57600080fd5b50516040805160e060020a63ffffffff87160281526004810194909452602484019290925260448301525160648083019260209291908290030181600087803b15801561172b57600080fd5b505af115801561173f573d6000803e3d6000fd5b505050506040513d602081101561175557600080fd5b50516040805160a0810180835260045460e160020a63349f642f02909152602060a48301819052600f60c48401527f64697370656e736174696f6e506374000000000000000000000000000000000060e48401529251939750606496509092839261184892889261183c928c9261183092600160a060020a039091169163693ec85e91610104808b01929190818c030181600087803b1580156117f757600080fd5b505af115801561180b573d6000803e3d6000fd5b505050506040513d602081101561182157600080fd5b50518a9063ffffffff61284016565b9063ffffffff61285216565b9063ffffffff61287b16565b81523360208083018290526000604080850182905260608086018c905260809586018390528a835282845281832087518155878501516001820180548a86015173ffffffffffffffffffffffffffffffffffffffff19909116600160a060020a039384161774ff0000000000000000000000000000000000000000191660a060020a91151591909102179055918801516002808301919091559790960151600396870155948c018a90558b860180548c90039055945485517f23b872dd0000000000000000000000000000000000000000000000000000000081526004810194909452306024850152604484018b9052945194909316936323b872dd936064808501948390030190829087803b15801561196157600080fd5b505af1158015611975573d6000803e3d6000fd5b505050506040513d602081101561198b57600080fd5b505115156119d1576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600354604080517f6148fed5000000000000000000000000000000000000000000000000000000008152600481018790529051600160a060020a0390921691636148fed59160248082019260a0929091908290030181600087803b158015611a3857600080fd5b505af1158015611a4c573d6000803e3d6000fd5b505050506040513d60a0811015611a6257600080fd5b5080516020918201516040805180850184905290810182905260608082528c51908201528b5192955090935033928792600160a060020a038e16927f9a8e3864cbacafc5547b8567796b4d12d51217a879192b61932f5151ce581310928e92899289929091829160808301919087019080838360005b83811015611af0578181015183820152602001611ad8565b50505050905090810190601f168015611b1d5780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a48396505b50505050505092915050565b60008181526020819052604081206001015460a060020a900460ff1615611bad576040805160e560020a62461bcd02815260206004820152601a60248201527f4368616c6c656e676520616c7265616479207265736f6c766564000000000000604482015290519081900360640190fd5b600354604080517fee684830000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163ee684830916024808201926020929091908290030181600087803b158015611c1457600080fd5b505af1158015611c28573d6000803e3d6000fd5b505050506040513d6020811015611c3e57600080fd5b50511515611c96576040805160e560020a62461bcd02815260206004820181905260248201527f506f6c6c20666f72206368616c6c656e676520686173206e6f7420656e646564604482015290519081900360640190fd5b600354604080517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018590529051600160a060020a039092169163053e71a6916024808201926020929091908290030181600087803b158015611cfd57600080fd5b505af1158015611d11573d6000803e3d6000fd5b505050506040513d6020811015611d2757600080fd5b50511515611d4a575060008181526020819052604090206002908101540261084b565b50600090815260208190526040902080546002918201549091020390565b600160a060020a038116600090815260016020526040812060030154611d8d83610bca565b8015611db05750600160a060020a03831660009081526001602052604090205442115b8015611dc25750611dc08361082a565b155b8015611df35750801580611df35750600081815260208190526040902060019081015460a060020a900460ff161515145b15611e015760019150610824565b50600092915050565b600454600160a060020a031681565b600160a060020a038083166000908152600160208190526040909120908101549091610100909104163314611e98576040805160e560020a62461bcd02815260206004820152601e60248201527f53656e646572206973206e6f74206f776e6572206f66206c697374696e670000604482015290519081900360640190fd5b6002810154821115611f1a576040805160e560020a62461bcd02815260206004820152603260248201527f43616e6e6f74207769746864726177206d6f7265207468616e2063757272656e60448201527f7420756e7374616b6564206465706f7369740000000000000000000000000000606482015290519081900360840190fd5b60038101541580611f485750600381015460009081526020819052604090206001015460a060020a900460ff165b1561209d57600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b158015611fc757600080fd5b505af1158015611fdb573d6000803e3d6000fd5b505050506040513d6020811015611ff157600080fd5b50516002820154839003101561209d576040805160e560020a62461bcd02815260206004820152605060248201527f5769746864726177616c2070726f686962697469656420617320697420776f7560448201527f6c6420707574204c697374696e6720756e7374616b6564206465706f7369742060648201527f62656c6f77206d696e4465706f73697400000000000000000000000000000000608482015290519081900360a40190fd5b600280820180548490039055546040805160e060020a63a9059cbb028152336004820152602481018590529051600160a060020a039092169163a9059cbb916044808201926020929091908290030181600087803b1580156120fe57600080fd5b505af1158015612112573d6000803e3d6000fd5b505050506040513d602081101561212857600080fd5b5051151561216e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b600281015460408051848152602081019290925280513392600160a060020a038716927f7b7771adeec078e4a338f627a52f307a7fd66d915cb133b5ace441bed26abc0b92918290030190a3505050565b60005b81518110156121f3576121eb82828151811015156121dc57fe5b9060200190602002015161062a565b6001016121c2565b5050565b600254600160a060020a031681565b600354600160a060020a031681565b600160a060020a0381166000908152600160208190526040909120015460ff16151561227057604051600160a060020a038216907fb268dc7f76f496fd307b40e0a3b57631a7e46123d9f708b1573bd4efbba3bdba90600090a25b600160a060020a031660009081526001602081905260409091208101805460ff19169091179055565b600160a060020a038116600090815260016020526040812060030154906122bf82611b3c565b600083815260208181526040808320600101805474ff0000000000000000000000000000000000000000191660a060020a17905560035481517f053e71a6000000000000000000000000000000000000000000000000000000008152600481018890529151949550600160a060020a03169363053e71a693602480840194938390030190829087803b15801561235457600080fd5b505af1158015612368573d6000803e3d6000fd5b505050506040513d602081101561237e57600080fd5b5051600083815260208181526040808320600390810194909455925483517f49403183000000000000000000000000000000000000000000000000000000008152600481018790529351600160a060020a039091169363494031839360248083019493928390030190829087803b1580156123f857600080fd5b505af115801561240c573d6000803e3d6000fd5b505050506040513d602081101561242257600080fd5b5051156124a65761243283612215565b600160a060020a038316600081815260016020908152604080832060020180548601905585835282825291829020805460039091015483519182529181019190915281518593927f3639145ca0a6a8008912a972730b5c8634e1fd1555ea44a257a8de53c30d72fb928290030190a3610bc5565b6124af8361265e565b60025460008381526020818152604080832060010154815160e060020a63a9059cbb028152600160a060020a03918216600482015260248101879052915194169363a9059cbb93604480840194938390030190829087803b15801561251357600080fd5b505af1158015612527573d6000803e3d6000fd5b505050506040513d602081101561253d57600080fd5b50511515612595576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b60008281526020818152604091829020805460039091015483519182529181019190915281518492600160a060020a038716927fe86031b52c5a57c0768c3f196b63abf60b5ed012de77ce1bb88fc63588f7603a929081900390910190a3505050565b82803b60008111612653576040805160e560020a62461bcd02815260206004820152601960248201527f41646472657373206973206e6f74206120636f6e747261637400000000000000604482015290519081900360640190fd5b610aef858585612890565b600160a060020a0381166000908152600160208190526040822090810154909190819060ff16156126c257604051600160a060020a038516907f5aebb54d5afe29103adbc464fd4e0313af619f4d19f10a0209128b76cd9d0b0790600090a26126f7565b604051600160a060020a038516907f8ad9ca8735c55207756208e8f59c7693e83d234fc6c8af2713f266468edff87190600090a25b5050600181810154600280840154600160a060020a038681166000908152602086905260408120818155958601805474ffffffffffffffffffffffffffffffffffffffffff1916905592850183905560039094018290556101009092049092169181111561283a576002546040805160e060020a63a9059cbb028152600160a060020a038581166004830152602482018590529151919092169163a9059cbb9160448083019260209291908290030181600087803b1580156127b857600080fd5b505af11580156127cc573d6000803e3d6000fd5b505050506040513d60208110156127e257600080fd5b5051151561283a576040805160e560020a62461bcd02815260206004820152601660248201527f546f6b656e207472616e73666572206661696c75726500000000000000000000604482015290519081900360640190fd5b50505050565b60008282111561284c57fe5b50900390565b600082151561286357506000610fa2565b5081810281838281151561287357fe5b0414610fa257fe5b6000818381151561288857fe5b049392505050565b600061289b8461082a565b156128f0576040805160e560020a62461bcd02815260206004820152601b60248201527f4c697374696e6720616c72656164792077686974656c69737465640000000000604482015290519081900360640190fd5b6128f984610bca565b15612974576040805160e560020a62461bcd02815260206004820152602960248201527f4170706c69636174696f6e20616c7265616479206d61646520666f722074686960448201527f7320616464726573730000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600480546040805160e160020a63349f642f0281526020938101849052600a60248201527f6d696e4465706f7369740000000000000000000000000000000000000000000060448201529051600160a060020a039092169263693ec85e926064808401938290030181600087803b1580156129ee57600080fd5b505af1158015612a02573d6000803e3d6000fd5b505050506040513d6020811015612a1857600080fd5b5051831015612a97576040805160e560020a62461bcd02815260206004820152602360248201527f4465706f73697420616d6f756e74206e6f742061626f7665206d696e4465706f60448201527f7369740000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b50600160a060020a038381166000908152600160208181526040808420928301805474ffffffffffffffffffffffffffffffffffffffff001916336101000217905560048054825160e160020a63349f642f028152918201849052600d60248301527f6170706c7953746167654c656e00000000000000000000000000000000000000604483015291519395612b879592169363693ec85e9360648084019491938390030190829087803b158015612b4e57600080fd5b505af1158015612b62573d6000803e3d6000fd5b505050506040513d6020811015612b7857600080fd5b5051429063ffffffff612d4516565b81556002808201849055546001820154604080517f23b872dd000000000000000000000000000000000000000000000000000000008152610100909204600160a060020a0390811660048401523060248401526044830187905290519216916323b872dd916064808201926020929091908290030181600087803b158015612c0e57600080fd5b505af1158015612c22573d6000803e3d6000fd5b505050506040513d6020811015612c3857600080fd5b50511515612c7e576040805160e560020a62461bcd0281526020600482015260156024820152600080516020612d53833981519152604482015290519081900360640190fd5b33600160a060020a031684600160a060020a03167f09cd8dcaf170a50a26316b5fe0727dd9fb9581a688d65e758b16a1650da65c0b858460000154866040518084815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612d03578181015183820152602001612ceb565b50505050905090810190601f168015612d305780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a350505050565b81810182811015610fa257fe00546f6b656e207472616e73666572206661696c65640000000000000000000000a165627a7a723058201e4d09fb99989dd4e9691ec6d3e28ca0c62e600e576ec0c3033d2c5c26a08dbe0029", "abi": [ { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "updateStatus", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "name", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeCanBeResolved", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "isWhitelisted", "outputs": [ { "name": "whitelisted", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "deposit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeIDs", "type": "uint256[]" }, { "name": "_salts", "type": "uint256[]" } ], "name": "claimRewards", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "appWasMade", "outputs": [ { "name": "exists", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "address" } ], "name": "listings", "outputs": [ { "name": "applicationExpiry", "type": "uint256" }, { "name": "whitelisted", "type": "bool" }, { "name": "owner", "type": "address" }, { "name": "unstakedDeposit", "type": "uint256" }, { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "challengeExists", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "claimReward", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "", "type": "uint256" } ], "name": "challenges", "outputs": [ { "name": "rewardPool", "type": "uint256" }, { "name": "challenger", "type": "address" }, { "name": "resolved", "type": "bool" }, { "name": "stake", "type": "uint256" }, { "name": "totalTokens", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" }, { "name": "_voter", "type": "address" } ], "name": "tokenClaims", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_voter", "type": "address" }, { "name": "_challengeID", "type": "uint256" }, { "name": "_salt", "type": "uint256" } ], "name": "voterReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "exit", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_data", "type": "string" } ], "name": "challenge", "outputs": [ { "name": "challengeID", "type": "uint256" } ], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_challengeID", "type": "uint256" } ], "name": "determineReward", "outputs": [ { "name": "", "type": "uint256" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "listingAddress", "type": "address" } ], "name": "canBeWhitelisted", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "parameterizer", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "_amount", "type": "uint256" } ], "name": "withdraw", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "listingAddresses", "type": "address[]" } ], "name": "updateStatuses", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "token", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "voting", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "inputs": [ { "name": "_token", "type": "address" }, { "name": "_voting", "type": "address" }, { "name": "_parameterizer", "type": "address" }, { "name": "_name", "type": "string" } ], "payable": false, "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "deposit", "type": "uint256" }, { "indexed": false, "name": "appEndDate", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": true, "name": "applicant", "type": "address" } ], "name": "_Application", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "data", "type": "string" }, { "indexed": false, "name": "commitEndDate", "type": "uint256" }, { "indexed": false, "name": "revealEndDate", "type": "uint256" }, { "indexed": true, "name": "challenger", "type": "address" } ], "name": "_Challenge", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "added", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Deposit", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": false, "name": "withdrew", "type": "uint256" }, { "indexed": false, "name": "newTotal", "type": "uint256" }, { "indexed": true, "name": "owner", "type": "address" } ], "name": "_Withdrawal", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationWhitelisted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ApplicationRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_ListingWithdrawn", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" } ], "name": "_TouchAndRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeFailed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "listingAddress", "type": "address" }, { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "rewardPool", "type": "uint256" }, { "indexed": false, "name": "totalTokens", "type": "uint256" } ], "name": "_ChallengeSucceeded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "challengeID", "type": "uint256" }, { "indexed": false, "name": "reward", "type": "uint256" }, { "indexed": true, "name": "voter", "type": "address" } ], "name": "_RewardClaimed", "type": "event" }, { "constant": false, "inputs": [ { "name": "listingAddress", "type": "address" }, { "name": "amount", "type": "uint256" }, { "name": "data", "type": "string" } ], "name": "apply", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/Roles.json ================================================ { "contractName": "Roles", "bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820411e0d4721f96631733368a475cbbbdfc3efbe0550f8a948c717c3bbe7388bb60029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fd00a165627a7a72305820411e0d4721f96631733368a475cbbbdfc3efbe0550f8a948c717c3bbe7388bb60029", "abi": [], "networks": {} } ================================================ FILE: packages/artifacts/v1/RootCommits.json ================================================ { "contractName": "RootCommits", "bytecode": "0x608060405234801561001057600080fd5b50610869806100206000396000f3006080604052600436106100615763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663079cf76e811461006657806318c9990b14610099578063ab481d23146100c7578063dab5f340146100f5575b600080fd5b34801561007257600080fd5b50610087600160a060020a036004351661010f565b60408051918252519081900360200190f35b3480156100a557600080fd5b50610087600160a060020a036004351667ffffffffffffffff60243516610150565b3480156100d357600080fd5b50610087600160a060020a036004351667ffffffffffffffff602435166103b5565b34801561010157600080fd5b5061010d600435610673565b005b600160a060020a03811660009081526020819052604081208054600019810190811061013757fe5b9060005260206000209060020201600101549050919050565b60008080804367ffffffffffffffff8616106101cd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6572724e6f467574757265416c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0386166000908152602081905260408120549093506000190191505b8183116103ac5750600160a060020a038516600090815260208190526040902080546002848401049167ffffffffffffffff8716918390811061022f57fe5b600091825260209091206002909102015467ffffffffffffffff16141561028d57600160a060020a038616600090815260208190526040902080548290811061027457fe5b90600052602060002090600202016001015493506103ac565b600160a060020a03861660009081526020819052604090208054829081106102b157fe5b600091825260209091206002909102015467ffffffffffffffff9081169086161180156103225750600160a060020a038616600090815260208190526040902080546001830190811061030057fe5b600091825260209091206002909102015467ffffffffffffffff908116908616105b1561034b57600160a060020a038616600090815260208190526040902080548290811061027457fe5b600160a060020a038616600090815260208190526040902080548290811061036f57fe5b600091825260209091206002909102015467ffffffffffffffff90811690861611156103a0578060010192506103a7565b6001810391505b6101f0565b50505092915050565b6000808080804267ffffffffffffffff87161061043357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6572724e6f467574757265416c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038716600090815260208190526040902054151561045a57839450610669565b600160a060020a0387166000908152602081905260408120549093506000190191505b8183116106695750600160a060020a038616600090815260208190526040902080546002848401049167ffffffffffffffff881691839081106104bc57fe5b600091825260209091206002909102015468010000000000000000900467ffffffffffffffff16141561052657600160a060020a038716600090815260208190526040902080548290811061050d57fe5b9060005260206000209060020201600101549450610669565b600160a060020a038716600090815260208190526040902080548290811061054a57fe5b600091825260209091206002909102015467ffffffffffffffff6801000000000000000090910481169087161180156105d35750600160a060020a03871660009081526020819052604090208054600183019081106105a557fe5b600091825260209091206002909102015467ffffffffffffffff680100000000000000009091048116908716105b156105fc57600160a060020a038716600090815260208190526040902080548290811061050d57fe5b600160a060020a038716600090815260208190526040902080548290811061062057fe5b600091825260209091206002909102015467ffffffffffffffff680100000000000000009091048116908716111561065d57806001019250610664565b6001810391505b61047d565b5050505092915050565b33600090815260208190526040812054111561075957336000908152602081905260409020805443919060001981019081106106ab57fe5b600091825260209091206002909102015467ffffffffffffffff16141561075957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6e6f206d756c7469706c652073657420696e207468652073616d6520626c6f6360448201527f6b00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3360008181526020818152604080832081516060818101845267ffffffffffffffff4381168084524282168488018181528588018c8152875460018181018a55988c529a8a902096516002909b0290960180549151851668010000000000000000026fffffffffffffffff0000000000000000199b90951667ffffffffffffffff1990921691909117999099169290921788559251969093019590955582519586529285019290925283810191909152908201839052517f1d3d3c252bc04ff83e8069c09279b4d8acb5264996a680b6d7dcf20db2b7417b9181900360800190a1505600a165627a7a7230582069ca536e56f7e2bb28612ad9fa8059b41a92c343de9077ed02583c6b14a172060029", "deployedBytecode": "0x6080604052600436106100615763ffffffff7c0100000000000000000000000000000000000000000000000000000000600035041663079cf76e811461006657806318c9990b14610099578063ab481d23146100c7578063dab5f340146100f5575b600080fd5b34801561007257600080fd5b50610087600160a060020a036004351661010f565b60408051918252519081900360200190f35b3480156100a557600080fd5b50610087600160a060020a036004351667ffffffffffffffff60243516610150565b3480156100d357600080fd5b50610087600160a060020a036004351667ffffffffffffffff602435166103b5565b34801561010157600080fd5b5061010d600435610673565b005b600160a060020a03811660009081526020819052604081208054600019810190811061013757fe5b9060005260206000209060020201600101549050919050565b60008080804367ffffffffffffffff8616106101cd57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6572724e6f467574757265416c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b600160a060020a0386166000908152602081905260408120549093506000190191505b8183116103ac5750600160a060020a038516600090815260208190526040902080546002848401049167ffffffffffffffff8716918390811061022f57fe5b600091825260209091206002909102015467ffffffffffffffff16141561028d57600160a060020a038616600090815260208190526040902080548290811061027457fe5b90600052602060002090600202016001015493506103ac565b600160a060020a03861660009081526020819052604090208054829081106102b157fe5b600091825260209091206002909102015467ffffffffffffffff9081169086161180156103225750600160a060020a038616600090815260208190526040902080546001830190811061030057fe5b600091825260209091206002909102015467ffffffffffffffff908116908616105b1561034b57600160a060020a038616600090815260208190526040902080548290811061027457fe5b600160a060020a038616600090815260208190526040902080548290811061036f57fe5b600091825260209091206002909102015467ffffffffffffffff90811690861611156103a0578060010192506103a7565b6001810391505b6101f0565b50505092915050565b6000808080804267ffffffffffffffff87161061043357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f6572724e6f467574757265416c6c6f7765640000000000000000000000000000604482015290519081900360640190fd5b600160a060020a038716600090815260208190526040902054151561045a57839450610669565b600160a060020a0387166000908152602081905260408120549093506000190191505b8183116106695750600160a060020a038616600090815260208190526040902080546002848401049167ffffffffffffffff881691839081106104bc57fe5b600091825260209091206002909102015468010000000000000000900467ffffffffffffffff16141561052657600160a060020a038716600090815260208190526040902080548290811061050d57fe5b9060005260206000209060020201600101549450610669565b600160a060020a038716600090815260208190526040902080548290811061054a57fe5b600091825260209091206002909102015467ffffffffffffffff6801000000000000000090910481169087161180156105d35750600160a060020a03871660009081526020819052604090208054600183019081106105a557fe5b600091825260209091206002909102015467ffffffffffffffff680100000000000000009091048116908716105b156105fc57600160a060020a038716600090815260208190526040902080548290811061050d57fe5b600160a060020a038716600090815260208190526040902080548290811061062057fe5b600091825260209091206002909102015467ffffffffffffffff680100000000000000009091048116908716111561065d57806001019250610664565b6001810391505b61047d565b5050505092915050565b33600090815260208190526040812054111561075957336000908152602081905260409020805443919060001981019081106106ab57fe5b600091825260209091206002909102015467ffffffffffffffff16141561075957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f6e6f206d756c7469706c652073657420696e207468652073616d6520626c6f6360448201527f6b00000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b3360008181526020818152604080832081516060818101845267ffffffffffffffff4381168084524282168488018181528588018c8152875460018181018a55988c529a8a902096516002909b0290960180549151851668010000000000000000026fffffffffffffffff0000000000000000199b90951667ffffffffffffffff1990921691909117999099169290921788559251969093019590955582519586529285019290925283810191909152908201839052517f1d3d3c252bc04ff83e8069c09279b4d8acb5264996a680b6d7dcf20db2b7417b9181900360800190a1505600a165627a7a7230582069ca536e56f7e2bb28612ad9fa8059b41a92c343de9077ed02583c6b14a172060029", "abi": [ { "anonymous": false, "inputs": [ { "indexed": false, "name": "addr", "type": "address" }, { "indexed": false, "name": "blockN", "type": "uint64" }, { "indexed": false, "name": "timestamp", "type": "uint64" }, { "indexed": false, "name": "root", "type": "bytes32" } ], "name": "RootUpdated", "type": "event" }, { "constant": false, "inputs": [ { "name": "_root", "type": "bytes32" } ], "name": "setRoot", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_address", "type": "address" } ], "name": "getRoot", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_address", "type": "address" }, { "name": "_blockN", "type": "uint64" } ], "name": "getRootByBlock", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_address", "type": "address" }, { "name": "_timestamp", "type": "uint64" } ], "name": "getRootByTime", "outputs": [ { "name": "", "type": "bytes32" } ], "payable": false, "stateMutability": "view", "type": "function" } ], "networks": { "1": { "events": {}, "links": {}, "address": "0x632668f86cC051E8648f0015F8e6347026d45825", "transactionHash": "0xc6ec76e9572d31674034e056273b142a9c5b2ba133f81c377c73f734975dba34" }, "4": { "events": {}, "links": {}, "address": "0x84B7e0A06bc4474d9B44da1F29E58F6623562ee1", "transactionHash": "0xf55693f4e7d239d1cb3cc32ab0ea3d7522e2d1931d3b01b688f8e586dfbdeb7a" }, "50": { "events": {}, "links": {}, "address": "0x6BBDd7B1a289C5bE8fAa29Cb1c0be66cb2582060", "transactionHash": "0xad84e507ac0e96d255cb28d23685cd78841998b5bb2812a5072d23225390546f" } } } ================================================ FILE: packages/artifacts/v1/SafeMath.json ================================================ { "contractName": "SafeMath", "bytecode": "0x604c602c600b82828239805160001a60731460008114601c57601e565bfe5b5030600052607381538281f30073000000000000000000000000000000000000000030146080604052600080fd00a165627a7a7230582004b5f2ab0275bb300a24ca9c601c901760a0cb39deac580fc403fc7fccaeb4d90029", "deployedBytecode": "0x73000000000000000000000000000000000000000030146080604052600080fd00a165627a7a7230582004b5f2ab0275bb300a24ca9c601c901760a0cb39deac580fc403fc7fccaeb4d90029", "abi": [], "networks": {} } ================================================ FILE: packages/artifacts/v1/TokenTelemetryI.json ================================================ { "contractName": "TokenTelemetryI", "bytecode": "0x", "deployedBytecode": "0x", "abi": [ { "constant": false, "inputs": [ { "name": "user", "type": "address" }, { "name": "tokenAmount", "type": "uint256" } ], "name": "onRequestVotingRights", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/artifacts/v1/UniswapExchange.json ================================================ { "contractName": "UniswapExchange", "abi": [ { "name": "TokenPurchase", "inputs": [ { "type": "address", "name": "buyer", "indexed": true }, { "type": "uint256", "name": "eth_sold", "indexed": true }, { "type": "uint256", "name": "tokens_bought", "indexed": true } ], "anonymous": false, "type": "event" }, { "name": "EthPurchase", "inputs": [ { "type": "address", "name": "buyer", "indexed": true }, { "type": "uint256", "name": "tokens_sold", "indexed": true }, { "type": "uint256", "name": "eth_bought", "indexed": true } ], "anonymous": false, "type": "event" }, { "name": "AddLiquidity", "inputs": [ { "type": "address", "name": "provider", "indexed": true }, { "type": "uint256", "name": "eth_amount", "indexed": true }, { "type": "uint256", "name": "token_amount", "indexed": true } ], "anonymous": false, "type": "event" }, { "name": "RemoveLiquidity", "inputs": [ { "type": "address", "name": "provider", "indexed": true }, { "type": "uint256", "name": "eth_amount", "indexed": true }, { "type": "uint256", "name": "token_amount", "indexed": true } ], "anonymous": false, "type": "event" }, { "name": "Transfer", "inputs": [ { "type": "address", "name": "_from", "indexed": true }, { "type": "address", "name": "_to", "indexed": true }, { "type": "uint256", "name": "_value", "indexed": false } ], "anonymous": false, "type": "event" }, { "name": "Approval", "inputs": [ { "type": "address", "name": "_owner", "indexed": true }, { "type": "address", "name": "_spender", "indexed": true }, { "type": "uint256", "name": "_value", "indexed": false } ], "anonymous": false, "type": "event" }, { "name": "setup", "outputs": [], "inputs": [{ "type": "address", "name": "token_addr" }], "constant": false, "payable": false, "type": "function", "gas": 175875 }, { "name": "addLiquidity", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "min_liquidity" }, { "type": "uint256", "name": "max_tokens" }, { "type": "uint256", "name": "deadline" } ], "constant": false, "payable": true, "type": "function", "gas": 82605 }, { "name": "removeLiquidity", "outputs": [{ "type": "uint256", "name": "out" }, { "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "amount" }, { "type": "uint256", "name": "min_eth" }, { "type": "uint256", "name": "min_tokens" }, { "type": "uint256", "name": "deadline" } ], "constant": false, "payable": false, "type": "function", "gas": 116814 }, { "name": "__default__", "outputs": [], "inputs": [], "constant": false, "payable": true, "type": "function" }, { "name": "ethToTokenSwapInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "min_tokens" }, { "type": "uint256", "name": "deadline" }], "constant": false, "payable": true, "type": "function", "gas": 12757 }, { "name": "ethToTokenTransferInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "min_tokens" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" } ], "constant": false, "payable": true, "type": "function", "gas": 12965 }, { "name": "ethToTokenSwapOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "deadline" }], "constant": false, "payable": true, "type": "function", "gas": 50455 }, { "name": "ethToTokenTransferOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" } ], "constant": false, "payable": true, "type": "function", "gas": 50663 }, { "name": "tokenToEthSwapInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_eth" }, { "type": "uint256", "name": "deadline" } ], "constant": false, "payable": false, "type": "function", "gas": 47503 }, { "name": "tokenToEthTransferInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_eth" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" } ], "constant": false, "payable": false, "type": "function", "gas": 47712 }, { "name": "tokenToEthSwapOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "eth_bought" }, { "type": "uint256", "name": "max_tokens" }, { "type": "uint256", "name": "deadline" } ], "constant": false, "payable": false, "type": "function", "gas": 50175 }, { "name": "tokenToEthTransferOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "eth_bought" }, { "type": "uint256", "name": "max_tokens" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" } ], "constant": false, "payable": false, "type": "function", "gas": 50384 }, { "name": "tokenToTokenSwapInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_tokens_bought" }, { "type": "uint256", "name": "min_eth_bought" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "token_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 51007 }, { "name": "tokenToTokenTransferInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_tokens_bought" }, { "type": "uint256", "name": "min_eth_bought" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" }, { "type": "address", "name": "token_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 51098 }, { "name": "tokenToTokenSwapOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "max_tokens_sold" }, { "type": "uint256", "name": "max_eth_sold" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "token_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 54928 }, { "name": "tokenToTokenTransferOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "max_tokens_sold" }, { "type": "uint256", "name": "max_eth_sold" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" }, { "type": "address", "name": "token_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 55019 }, { "name": "tokenToExchangeSwapInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_tokens_bought" }, { "type": "uint256", "name": "min_eth_bought" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "exchange_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 49342 }, { "name": "tokenToExchangeTransferInput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_sold" }, { "type": "uint256", "name": "min_tokens_bought" }, { "type": "uint256", "name": "min_eth_bought" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" }, { "type": "address", "name": "exchange_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 49532 }, { "name": "tokenToExchangeSwapOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "max_tokens_sold" }, { "type": "uint256", "name": "max_eth_sold" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "exchange_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 53233 }, { "name": "tokenToExchangeTransferOutput", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [ { "type": "uint256", "name": "tokens_bought" }, { "type": "uint256", "name": "max_tokens_sold" }, { "type": "uint256", "name": "max_eth_sold" }, { "type": "uint256", "name": "deadline" }, { "type": "address", "name": "recipient" }, { "type": "address", "name": "exchange_addr" } ], "constant": false, "payable": false, "type": "function", "gas": 53423 }, { "name": "getEthToTokenInputPrice", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "eth_sold" }], "constant": true, "payable": false, "type": "function", "gas": 5542 }, { "name": "getEthToTokenOutputPrice", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "tokens_bought" }], "constant": true, "payable": false, "type": "function", "gas": 6872 }, { "name": "getTokenToEthInputPrice", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "tokens_sold" }], "constant": true, "payable": false, "type": "function", "gas": 5637 }, { "name": "getTokenToEthOutputPrice", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "uint256", "name": "eth_bought" }], "constant": true, "payable": false, "type": "function", "gas": 6897 }, { "name": "tokenAddress", "outputs": [{ "type": "address", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1413 }, { "name": "factoryAddress", "outputs": [{ "type": "address", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1443 }, { "name": "balanceOf", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "address", "name": "_owner" }], "constant": true, "payable": false, "type": "function", "gas": 1645 }, { "name": "transfer", "outputs": [{ "type": "bool", "name": "out" }], "inputs": [{ "type": "address", "name": "_to" }, { "type": "uint256", "name": "_value" }], "constant": false, "payable": false, "type": "function", "gas": 75034 }, { "name": "transferFrom", "outputs": [{ "type": "bool", "name": "out" }], "inputs": [ { "type": "address", "name": "_from" }, { "type": "address", "name": "_to" }, { "type": "uint256", "name": "_value" } ], "constant": false, "payable": false, "type": "function", "gas": 110907 }, { "name": "approve", "outputs": [{ "type": "bool", "name": "out" }], "inputs": [{ "type": "address", "name": "_spender" }, { "type": "uint256", "name": "_value" }], "constant": false, "payable": false, "type": "function", "gas": 38769 }, { "name": "allowance", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [{ "type": "address", "name": "_owner" }, { "type": "address", "name": "_spender" }], "constant": true, "payable": false, "type": "function", "gas": 1925 }, { "name": "name", "outputs": [{ "type": "bytes32", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1623 }, { "name": "symbol", "outputs": [{ "type": "bytes32", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1653 }, { "name": "decimals", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1683 }, { "name": "totalSupply", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 1713 } ], "networks": { "1": { "events": {}, "links": {}, "address": "0xd7d070728c947645af47f8cd0731a4100695a503", "transactionHash": "0x7d18df21ec6a35ab3df8d35af02b08cf641037f6c1ee4ecbdbabf263b4746915" }, "4": { "events": {}, "links": {}, "address": "0x0Df32619bBe4CEb6c56e1F27C520521669283e62", "transactionHash": "0x714744f4c4b6d4ce7a6eb829be7e82f99f6ebe6c3e2a09abb196c9c73afd886d" } } } ================================================ FILE: packages/artifacts/v1/UniswapFactory.json ================================================ { "contractName": "UniswapFactory", "abi": [ { "name": "NewExchange", "inputs": [ { "type": "address", "name": "token", "indexed": true }, { "type": "address", "name": "exchange", "indexed": true } ], "anonymous": false, "type": "event" }, { "name": "initializeFactory", "outputs": [], "inputs": [{ "type": "address", "name": "template" }], "constant": false, "payable": false, "type": "function", "gas": 35725 }, { "name": "createExchange", "outputs": [{ "type": "address", "name": "out" }], "inputs": [{ "type": "address", "name": "token" }], "constant": false, "payable": false, "type": "function", "gas": 187911 }, { "name": "getExchange", "outputs": [{ "type": "address", "name": "out" }], "inputs": [{ "type": "address", "name": "token" }], "constant": true, "payable": false, "type": "function", "gas": 715 }, { "name": "getToken", "outputs": [{ "type": "address", "name": "out" }], "inputs": [{ "type": "address", "name": "exchange" }], "constant": true, "payable": false, "type": "function", "gas": 745 }, { "name": "getTokenWithId", "outputs": [{ "type": "address", "name": "out" }], "inputs": [{ "type": "uint256", "name": "token_id" }], "constant": true, "payable": false, "type": "function", "gas": 736 }, { "name": "exchangeTemplate", "outputs": [{ "type": "address", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 633 }, { "name": "tokenCount", "outputs": [{ "type": "uint256", "name": "out" }], "inputs": [], "constant": true, "payable": false, "type": "function", "gas": 663 } ], "networks": { "1": { "address": "0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95" }, "4": { "address": "0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36" } } } ================================================ FILE: packages/artifacts/v1/Whitelist.json ================================================ { "contractName": "Whitelist", "bytecode": "0x608060405260008054600160a060020a031916331790556109b7806100256000396000f3006080604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630988ca8c81146100b357806318b919e91461011c578063217fe6c6146101a657806324953eaa14610221578063286dd3f514610276578063715018a6146102975780637b9417c8146102ac5780638da5cb5b146102cd5780639b19251a146102fe578063e2ec6ec31461031f578063f2fde38b14610374575b600080fd5b3480156100bf57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011a958335600160a060020a03169536956044949193909101919081908401838280828437509497506103959650505050505050565b005b34801561012857600080fd5b50610131610403565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561016b578181015183820152602001610153565b50505050905090810190601f1680156101985780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101b257600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261020d958335600160a060020a03169536956044949193909101919081908401838280828437509497506104289650505050505050565b604080519115158252519081900360200190f35b34801561022d57600080fd5b506040805160206004803580820135838102808601850190965280855261011a9536959394602494938501929182918501908490808284375094975061049b9650505050505050565b34801561028257600080fd5b5061011a600160a060020a03600435166104e8565b3480156102a357600080fd5b5061011a61052f565b3480156102b857600080fd5b5061011a600160a060020a036004351661059b565b3480156102d957600080fd5b506102e26105df565b60408051600160a060020a039092168252519081900360200190f35b34801561030a57600080fd5b5061020d600160a060020a03600435166105ee565b34801561032b57600080fd5b506040805160206004803580820135838102808601850190965280855261011a953695939460249493850192918291850190849080828437509497506106239650505050505050565b34801561038057600080fd5b5061011a600160a060020a0360043516610670565b6103ff826001836040518082805190602001908083835b602083106103cb5780518252601f1990920191602091820191016103ac565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610690565b5050565b604080518082019091526009815260008051602061096c833981519152602082015281565b6000610494836001846040518082805190602001908083835b602083106104605780518252601f199092019160209182019101610441565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220929150506106a5565b9392505050565b60008054600160a060020a031633146104b357600080fd5b5060005b81518110156103ff576104e082828151811015156104d157fe5b906020019060200201516104e8565b6001016104b7565b600054600160a060020a031633146104ff57600080fd5b61052c8160408051908101604052806009815260200160008051602061096c8339815191528152506106c4565b50565b600054600160a060020a0316331461054657600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146105b257600080fd5b61052c8160408051908101604052806009815260200160008051602061096c8339815191528152506107d5565b600054600160a060020a031681565b600061061d8260408051908101604052806009815260200160008051602061096c833981519152815250610428565b92915050565b60008054600160a060020a0316331461063b57600080fd5b5060005b81518110156103ff57610668828281518110151561065957fe5b9060200190602002015161059b565b60010161063f565b600054600160a060020a0316331461068757600080fd5b61052c816108a7565b61069a82826106a5565b15156103ff57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b61072e826001836040518082805190602001908083835b602083106106fa5780518252601f1990920191602091820191016106db565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610924565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561079757818101518382015260200161077f565b50505050905090810190601f1680156107c45780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b61083f826001836040518082805190602001908083835b6020831061080b5780518252601f1990920191602091820191016107ec565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610946565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b700489826040518080602001828103825283818151815260200191508051906020019080838360008381101561079757818101518382015260200161077f565b600160a060020a03811615156108bc57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a723058206ef1746ac83ff9f12c5ba42cffd57fd462a9f15a78f7698f763183b093635fee0029", "deployedBytecode": "0x6080604052600436106100ae5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416630988ca8c81146100b357806318b919e91461011c578063217fe6c6146101a657806324953eaa14610221578063286dd3f514610276578063715018a6146102975780637b9417c8146102ac5780638da5cb5b146102cd5780639b19251a146102fe578063e2ec6ec31461031f578063f2fde38b14610374575b600080fd5b3480156100bf57600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261011a958335600160a060020a03169536956044949193909101919081908401838280828437509497506103959650505050505050565b005b34801561012857600080fd5b50610131610403565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561016b578181015183820152602001610153565b50505050905090810190601f1680156101985780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101b257600080fd5b5060408051602060046024803582810135601f810185900485028601850190965285855261020d958335600160a060020a03169536956044949193909101919081908401838280828437509497506104289650505050505050565b604080519115158252519081900360200190f35b34801561022d57600080fd5b506040805160206004803580820135838102808601850190965280855261011a9536959394602494938501929182918501908490808284375094975061049b9650505050505050565b34801561028257600080fd5b5061011a600160a060020a03600435166104e8565b3480156102a357600080fd5b5061011a61052f565b3480156102b857600080fd5b5061011a600160a060020a036004351661059b565b3480156102d957600080fd5b506102e26105df565b60408051600160a060020a039092168252519081900360200190f35b34801561030a57600080fd5b5061020d600160a060020a03600435166105ee565b34801561032b57600080fd5b506040805160206004803580820135838102808601850190965280855261011a953695939460249493850192918291850190849080828437509497506106239650505050505050565b34801561038057600080fd5b5061011a600160a060020a0360043516610670565b6103ff826001836040518082805190602001908083835b602083106103cb5780518252601f1990920191602091820191016103ac565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610690565b5050565b604080518082019091526009815260008051602061096c833981519152602082015281565b6000610494836001846040518082805190602001908083835b602083106104605780518252601f199092019160209182019101610441565b51815160209384036101000a60001901801990921691161790529201948552506040519384900301909220929150506106a5565b9392505050565b60008054600160a060020a031633146104b357600080fd5b5060005b81518110156103ff576104e082828151811015156104d157fe5b906020019060200201516104e8565b6001016104b7565b600054600160a060020a031633146104ff57600080fd5b61052c8160408051908101604052806009815260200160008051602061096c8339815191528152506106c4565b50565b600054600160a060020a0316331461054657600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031633146105b257600080fd5b61052c8160408051908101604052806009815260200160008051602061096c8339815191528152506107d5565b600054600160a060020a031681565b600061061d8260408051908101604052806009815260200160008051602061096c833981519152815250610428565b92915050565b60008054600160a060020a0316331461063b57600080fd5b5060005b81518110156103ff57610668828281518110151561065957fe5b9060200190602002015161059b565b60010161063f565b600054600160a060020a0316331461068757600080fd5b61052c816108a7565b61069a82826106a5565b15156103ff57600080fd5b600160a060020a03166000908152602091909152604090205460ff1690565b61072e826001836040518082805190602001908083835b602083106106fa5780518252601f1990920191602091820191016106db565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610924565b81600160a060020a03167fd211483f91fc6eff862467f8de606587a30c8fc9981056f051b897a418df803a826040518080602001828103825283818151815260200191508051906020019080838360005b8381101561079757818101518382015260200161077f565b50505050905090810190601f1680156107c45780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b61083f826001836040518082805190602001908083835b6020831061080b5780518252601f1990920191602091820191016107ec565b51815160209384036101000a6000190180199092169116179052920194855250604051938490030190922092915050610946565b81600160a060020a03167fbfec83d64eaa953f2708271a023ab9ee82057f8f3578d548c1a4ba0b5b700489826040518080602001828103825283818151815260200191508051906020019080838360008381101561079757818101518382015260200161077f565b600160a060020a03811615156108bc57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600160a060020a0316600090815260209190915260409020805460ff19169055565b600160a060020a0316600090815260209190915260409020805460ff19166001179055560077686974656c6973740000000000000000000000000000000000000000000000a165627a7a723058206ef1746ac83ff9f12c5ba42cffd57fd462a9f15a78f7698f763183b093635fee0029", "abi": [ { "constant": true, "inputs": [ { "name": "_operator", "type": "address" }, { "name": "_role", "type": "string" } ], "name": "checkRole", "outputs": [], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [], "name": "ROLE_WHITELISTED", "outputs": [ { "name": "", "type": "string" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": true, "inputs": [ { "name": "_operator", "type": "address" }, { "name": "_role", "type": "string" } ], "name": "hasRole", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [], "name": "renounceOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [], "name": "owner", "outputs": [ { "name": "", "type": "address" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_newOwner", "type": "address" } ], "name": "transferOwnership", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "operator", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleAdded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "operator", "type": "address" }, { "indexed": false, "name": "role", "type": "string" } ], "name": "RoleRemoved", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" } ], "name": "OwnershipRenounced", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "name": "previousOwner", "type": "address" }, { "indexed": true, "name": "newOwner", "type": "address" } ], "name": "OwnershipTransferred", "type": "event" }, { "constant": false, "inputs": [ { "name": "_operator", "type": "address" } ], "name": "addAddressToWhitelist", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": true, "inputs": [ { "name": "_operator", "type": "address" } ], "name": "whitelist", "outputs": [ { "name": "", "type": "bool" } ], "payable": false, "stateMutability": "view", "type": "function" }, { "constant": false, "inputs": [ { "name": "_operators", "type": "address[]" } ], "name": "addAddressesToWhitelist", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_operator", "type": "address" } ], "name": "removeAddressFromWhitelist", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" }, { "constant": false, "inputs": [ { "name": "_operators", "type": "address[]" } ], "name": "removeAddressesFromWhitelist", "outputs": [], "payable": false, "stateMutability": "nonpayable", "type": "function" } ], "networks": {} } ================================================ FILE: packages/components/.babelrc ================================================ { "presets": [ ["@babel/preset-env", { "targets": { "node": "current" } }], "@babel/preset-typescript", "@babel/preset-react" ], "plugins": ["@babel/plugin-proposal-class-properties"], "env": { "test": { "plugins": ["require-context-hook"] } } } ================================================ FILE: packages/components/.gitignore ================================================ /out ================================================ FILE: packages/components/.releaserc ================================================ { "plugins": [ [ "@semantic-release/commit-analyzer", { "preset": "angular", "releaseRules": [ { "type": "docs", "scope": "README", "release": "patch" }, { "type": "refactor", "release": "patch" }, { "type": "style", "release": "patch" } ], "parserOpts": { "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"] } } ], [ "@semantic-release/release-notes-generator", { "preset": "angular", "parserOpts": { "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"] }, "writerOpts": { "commitsSort": ["subject", "scope"] } } ], "@semantic-release/npm" ] } ================================================ FILE: packages/components/.storybook/config.ts ================================================ import { configure, addDecorator } from "@storybook/react"; import { withInfo } from "@storybook/addon-info"; // automatically import all files ending in *.stories.tsx const req = require.context("../src", true, /.stories.tsx$/); function loadStories() { addDecorator(withInfo); req.keys().forEach(req); } configure(loadStories, module); ================================================ FILE: packages/components/.storybook/preview-head.html ================================================ ================================================ FILE: packages/components/.storybook/register-context.ts ================================================ // @ts-ignore import registerRequireContextHook from "babel-plugin-require-context-hook/register"; registerRequireContextHook(); ================================================ FILE: packages/components/.storybook/webpack.config.js ================================================ module.exports = ({ config, mode }) => { config.module.rules.push({ test: /\.tsx?$/, use: [ { loader: require.resolve("babel-loader"), options: { presets: [require.resolve("babel-preset-react-app")], }, }, require.resolve("react-docgen-typescript-loader"), ], }); config.resolve.extensions.push(".ts", ".tsx"); config.node = { global: true, fs: "empty" }; return config; }; ================================================ FILE: packages/components/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: packages/components/jest.config.js ================================================ module.exports = { transform: { "^.+\\.(ts|tsx)?$": "babel-jest", }, testPathIgnorePatterns: ["/node_modules/", "src/__test__/setupTests.ts", "build"], moduleNameMapper: { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css)$": "src/__mocks__/fileMock.js", }, testRegex: "(src/__test__/.*|\\.(test|spec))\\.(ts|tsx)$", setupFiles: [".storybook/register-context.ts"], setupFilesAfterEnv: ["src/__test__/setupTests.ts"], moduleFileExtensions: ["ts", "tsx", "js", "json"], }; ================================================ FILE: packages/components/package.json ================================================ { "name": "@joincivil/components", "version": "1.9.10", "description": "React components for Civil", "main": "build/index.js", "types": "build/index.d.ts", "license": "Apache-2.0", "sideEffects": false, "scripts": { "copy:images": "mkdir -p build/images && cp -a src/images/. build/images", "build": "yarn clean && tsc && yarn copy:images", "build:watch": "yarn clean && yarn copy:images && tsc -w", "lint": "tslint --exclude \"**/storyFixtures/**\" --project ./", "clean": "rimraf build/", "prepublish": "run-s build", "storybook": "start-storybook -p 9001", "storybook:build": "build-storybook -c .storybook -o out", "test": "NODE_ENV=test jest" }, "devDependencies": { "@babel/core": "^7.5.5", "@babel/plugin-proposal-class-properties": "^7.4.0", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.3.3", "@joincivil/typescript-types": "^1.4.9", "@storybook/addon-actions": "^5.1.0", "@storybook/addon-info": "^5.1.0", "@storybook/addon-storyshots": "^5.1.0", "@storybook/react": "^5.1.0", "@types/classnames": "^2.2.3", "@types/enzyme": "^3.1.9", "@types/jest": "^23.3.5", "@types/prop-types": "15.7.0", "@types/react": "^16.9.0", "@types/react-avatar-editor": "^10.3.4", "@types/react-dom": "^16.9.0", "@types/react-dropzone": "^4.2.2", "@types/react-test-renderer": "^16.9.1", "@types/storybook__addon-info": "^4.1.1", "@types/storybook__react": "^3.0.7", "@types/stripe-v3": "^3.1.15", "babel-jest": "^24.7.1", "babel-loader": "^8.0.5", "babel-plugin-require-context-hook": "^1.0.0", "core-js": "^3.2.1", "enzyme": "^3.3.0", "enzyme-adapter-react-16": "^1.1.1", "jest": "^24.6", "npm-run-all": ">=4.1.5", "react-docgen-typescript-webpack-plugin": "^1.1.0", "react-test-renderer": "^16.11.0", "rimraf": "^2.6.2", "storybook-react-router": "^1.0.1", "strip-ansi": "^5.0.0", "ts-jest": "^23.10.4", "ts-loader": "^4", "typescript": "^3.6.2", "web3-providers-http": "^1.2.4", "webpack": "^4", "webpack-hot-middleware": "^2.21.1" }, "peerDependencies": { "immutable": "^3.8.2", "prop-types": "^15.7.2", "react": "^16.11.0", "react-dom": "^16.11.0" }, "resolutions": { "ethers": "4.0.27", "**/ethers": "4.0.27" }, "dependencies": { "@joincivil/core": "^4.8.11", "@joincivil/elements": "^0.0.1", "@joincivil/ethapi": "^0.4.9", "@joincivil/utils": "^1.9.9", "@kirby-web3/ethereum-react": "^1.2.17", "@kirby-web3/parent-core": "^1.3.2", "@kirby-web3/plugin-ethereum": "^1.11.0", "@types/styled-components": "^4.1.18", "apollo-client": "^2.6.8", "apollo-storybook-react": "^0.1.8", "classnames": "^2.2.5", "graphql-tag": "^2.10.0", "graphql-tools": "^4.0.3", "lodash": "^4.17.10", "react-add-to-calendar": "^0.1.5", "react-apollo": "^2.3.3", "react-async-script": "^1.0.0", "react-avatar-editor": "^11.0.7", "react-docgen-typescript-loader": "^3.1.0", "react-dropzone": "^10.1.4", "react-helmet": "^5.2.0", "react-input-slider": "^5.1.2", "react-router-dom": "^5.1.2", "react-rte": "^0.16.1", "react-stripe-elements": "^6.0.0", "rxjs": "^5.5.6", "stripe": "^8.19.0", "styled-components": "^5.0.0-beta.8", "web3": "^1.2.4" }, "publishConfig": { "access": "public" } } ================================================ FILE: packages/components/src/Account/Auth/AuthStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../../styleConstants"; import checkEmailImage from "../../images/auth/img-check-email@2x.png"; import confirmedEmailImage from "../../images/auth/img-confirm-email@2x.png"; import iconError from "../../images/icons/ico-error-red@2x.png"; import { urlConstants as links } from "@joincivil/utils"; import { AuthTextFooter, AuthTextVerifyTokenConfirmed, AuthTextVerifyTokenVerifying, AuthTextVerifyTokenError, AuthTextEthAuthNext, } from "./AuthTextComponents"; import { Button, buttonSizes } from "../.."; export const CheckboxContainer = styled.ul` list-style: none; padding-left: 0; margin-top: 0; max-width: 300px; `; export const CheckboxSection = styled.li` margin-bottom: 10px; `; export const CheckboxLabel = styled.span` color: ${colors.primary.CIVIL_GRAY_1}; font: 400 15px/20px ${fonts.SANS_SERIF}; padding-left: 7px; vertical-align: middle; `; export const ConfirmButtonContainer = styled.div` display: flex; justify-content: center; padding-top: 20px; `; export const SkipForNowButtonContainer = styled.div` display: flex; justify-content: center; padding-top: 20px; ${mediaQueries.MOBILE} { padding-top: 5px; } `; export const CheckEmailLetterIcon = styled.div` width: 108px; height: 108px; background-position: center center; background-image: url(${checkEmailImage}); background-size: cover; margin: 30px 0; `; export const ConfirmedEmailLetterIcon = styled(CheckEmailLetterIcon)` background-image: url(${confirmedEmailImage}); `; export const CenterWrapper: React.FunctionComponent = ({ children }) => (
{children}
); export const CheckEmailSection = () => ( ); export const CenteredText = styled.div` text-align: center; `; export const FooterTextCentered = styled.div` text-align: center; `; export const AuthOuterWrapperContainer = styled.div` display: flex; justify-content: center; width: 700px; ${mediaQueries.MOBILE} { width: 100%; } `; export const AuthOuterWrapper: React.FunctionComponent = ({ children }) => ( {children} ); export const AuthWrapper: React.FunctionComponent = ({ children }) => ( {children} } /> ); export const AuthInnerWrapper = styled.div` margin: 71px 115px 0; ${mediaQueries.MOBILE} { margin: 71px 15px 0; } `; export const AuthPageFooterLink = styled.div` text-align: center; font-size: 12px; text-decoration: underline; padding-top: 60px; `; export const AuthFooterContainer = styled.div` border-top: 1px solid #d8d8d8; margin-top: 40px; padding-top: 20px; `; export const BenefitsLink = styled(AuthPageFooterLink)` padding: 0; `; export interface AuthFooterTermsProps { textEl: JSX.Element; } export const AuthFooterTerms: React.FunctionComponent = ({ textEl }) => ( {textEl} Read more about those benefits. ); export interface AuthEmailVerifyProps { hasVerified: boolean; errorMessage: string | undefined; ethAuthNextExt?: boolean; onAuthenticationContinue(): void; } export const AuthEmailVerify = ({ hasVerified, errorMessage, onAuthenticationContinue, ethAuthNextExt, }: AuthEmailVerifyProps) => { if (errorMessage) { return ; } return ( <> {hasVerified ? : } {ethAuthNextExt && (
)} ); }; export interface ConfirmEmailVerifyProps { hasVerified: boolean; errorMessage: string | undefined; ethAuthNextExt?: boolean; onEmailConfirmContinue(): void; } export const EmailConfirmVerify = ({ hasVerified, errorMessage, onEmailConfirmContinue, ethAuthNextExt, }: ConfirmEmailVerifyProps) => { if (errorMessage) { return ; } return ( <> {hasVerified ? : } {ethAuthNextExt && (
)} ); }; export const AuthErrorMessage = styled.div` border: 1px solid rgba(242, 82, 74, 0.56); border-radius: 4px; background-color: #fff7f8; background-position: 10px center; background-image: url(${iconError}); background-size: 30px; background-repeat: no-repeat; color: #555555; font-family: ${fonts.SANS_SERIF}; font-size: 14px; /* TODO(jorgelo): This is terrible, but the error message breaks out of the parent box. There has to be a better way. */ margin: 0 -116px 17px -116px; padding: 18px 0; text-align: center; `; ================================================ FILE: packages/components/src/Account/Auth/AuthTextComponents.tsx ================================================ import * as React from "react"; import { PageHeadingTextCenteredSmall, PageHeadingTextCentered, PageSubHeadingCentered, PageHeadingCentered, PageHeadingTextCenteredLarge, PageHeadingLeftAligned, PageHeadingTextLeftAligned, } from "../../Heading"; import { Link } from "react-router-dom"; export const AuthTextFooter: React.FunctionComponent = () => ( // TODO(jorgelo): For the store front, the text should be: By joining Civil, you will get a direct say in running the Civil platform, connect with journalists and fund great journalism projects. ); export const AuthTextEmailSent: React.FunctionComponent<{ emailAddress: string; }> = ({ emailAddress }) => ( <> Check your email! We sent you an email to {emailAddress} that includes a link to confirm your email address. It expires soon, so please check your email and click on the link. Once confimed, you can continue. ); export const AuthTextVerifyTokenConfirmed: React.FunctionComponent = () => ( <> Email Address Confirmed! Thanks for confirming your email address. ); export const AuthTextVerifyTokenVerifying: React.FunctionComponent = () => ( <> Confirming your email address... ); export const AuthTextEthAuthNext: React.FunctionComponent = () => ( <> Next, we'll set up your secure crypto wallet. ); // TODO(jorgelo): Jorge made this up, it should probably be nicer. export const AuthTextVerifyTokenError: React.FunctionComponent<{ errorMessage: string }> = ({ errorMessage }) => ( <> Uh oh. {errorMessage} ); export const AuthTextCreateAccount: React.FunctionComponent = () => ( <> Create your Civil account First, please enter your email address. Your email is used to send account related updates from Civil. Let's get started ); export const AuthTextCheckSpam: React.FunctionComponent = () => ( Please check your spam folder if you don’t see the email. ); export const AuthTextSigninWithEmail: React.FunctionComponent = () => ( <> Sign in with email Enter the address associated with your account, and we'll send a magic link to your inbox. ); export const AuthTextSetHandle: React.FunctionComponent = () => ( <> Welcome to the Civil community To help the Civil community identify you, please enter a username. ); export const AuthTextSetAvatar: React.FunctionComponent = () => ( <> Add profile photo To help the Civil community identify you, add a profile image. ); export const AuthTextEmailNotFoundError: React.FunctionComponent<{ signupPath: string }> = ({ signupPath }) => ( <> The email address you entered does not exist. Try again? or{" "} create a Civil account to continue. ); export const AuthTextEmailExistsError: React.FunctionComponent<{ loginPath: string }> = ({ loginPath }) => ( <> Your account already exists. Login to continue. ); // TODO(jorgelo): Make this text nicer. export const AuthTextUnknownError: React.FunctionComponent = () => ( <>An internal error has occured, please try again. ); ================================================ FILE: packages/components/src/Account/Auth/ConfirmEmailToken.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { EmailConfirmVerify } from "./AuthStyledComponents"; import { ApolloConsumer } from "react-apollo"; import ApolloClient from "apollo-client"; const verifyMutation = gql` mutation($token: String!) { channelsSetEmailConfirm(jwt: $token) { ChannelID } } `; export interface ConfirmEmailTokenProps { token: string; ethAuthNextExt?: boolean; apolloClient: ApolloClient; onEmailConfirmContinue?(): void; onMutationSuccess?(): Promise; } export interface ConfirmEmailTokenState { hasVerified: boolean; errorMessage: string | undefined; } class ConfirmEmailTokenWithApolloClient extends React.Component { public state = { hasVerified: false, errorMessage: undefined, }; constructor(props: ConfirmEmailTokenProps) { super(props); } public async componentDidMount(): Promise { return this.handleTokenVerification(); } public handleTokenVerification = async (): Promise => { const token = this.props.token; const client = this.props.apolloClient; try { const { error } = await client.mutate({ mutation: verifyMutation, variables: { token }, }); if (error) { console.log("Error authenticating:", error); const errorMessage = error.graphQLErrors.map((e: any) => e.message).join(" ,"); this.setState({ errorMessage, hasVerified: true }); } else { if (this.props.onMutationSuccess) { await this.props.onMutationSuccess(); } this.setState({ errorMessage: undefined, hasVerified: true }); } } catch (err) { console.error("Error validating token:", err); this.setState({ errorMessage: "There was a problem validating your token.", hasVerified: true }); } }; public render(): JSX.Element { const { hasVerified, errorMessage } = this.state; const { onEmailConfirmContinue, ethAuthNextExt } = this.props; return ( ); } } export class ConfirmEmailToken extends React.Component { public render(): JSX.Element { return ( {client => } ); } } ================================================ FILE: packages/components/src/Account/Auth/EmailAuth.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import apolloStorybookDecorator from "apollo-storybook-react"; import { AccountEmailAuth, AuthApplicationEnum } from "../"; import StoryRouter from "storybook-react-router"; const typeDefs = ` type User { uid: String email: String ethAddress: String } type AuthLoginResponse { token: String refreshToken: String uid: String } type Query { currentUser: User } type Mutation { authSignupEmailSendForApplication( email: String application: String ): String authSignupEmailConfirm( signupJWT: String! ): AuthLoginResponse authSignupEmailSend( emailAddress: String! ): String } schema { query: Query mutation: Mutation } `; const mocks = { Query: () => { return { currentUser: () => { return "cool"; }, }; }, Mutation: () => { return { authSignupEmailSend: (email: string) => { return "ok"; }, authSignupEmailSendForApplication: (email: string, application: string) => { return "ok"; }, }; }, }; storiesOf("Common / Auth / Email Signup Flow", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("AccountEmailAuth", () => { return ( { console.log("Sent"); }} signupPath="" loginPath="" /> ); }); ================================================ FILE: packages/components/src/Account/Auth/EmailAuth.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { AuthApplicationEnum } from "../index"; import { Mutation, MutationFn } from "react-apollo"; import { Checkbox, CheckboxSizes } from "../../input/Checkbox"; import { Button, buttonSizes } from "../../Button"; import { TextInput } from "../../input"; import { CheckboxSection, CheckboxContainer, CheckboxLabel, ConfirmButtonContainer, AuthErrorMessage, } from "./AuthStyledComponents"; import { isValidEmail } from "@joincivil/utils"; import { AuthTextEmailNotFoundError, AuthTextEmailExistsError, AuthTextUnknownError } from "./AuthTextComponents"; export interface AuthMutationVariables { emailAddress: string; application: AuthApplicationEnum; addToMailing?: boolean; } const signupMutation = gql` mutation($emailAddress: String!, $application: AuthApplicationEnum!, $addToMailing: Boolean!) { authSignupEmailSendForApplication( emailAddress: $emailAddress application: $application addToMailing: $addToMailing ) } `; const loginMutation = gql` mutation($emailAddress: String!, $application: AuthApplicationEnum!) { authLoginEmailSendForApplication(emailAddress: $emailAddress, application: $application) } `; export interface AuthSignupEmailSendResult { data: { authSignupEmailSend: string; }; } export interface AccountEmailAuthProps { applicationType: AuthApplicationEnum; isNewUser: boolean; headerComponent?: JSX.Element; signupPath: string; loginPath: string; onEmailSend(isNewUser: boolean, emailAddress: string): void; } export type AuthEmailError = "unknown" | "emailexists" | "emailnotfound" | undefined; export interface AccountEmailAuthState { emailAddress: string; errorMessage: AuthEmailError; hasAgreedToTOS: boolean; hasSelectedToAddToNewsletter: boolean; hasBlurred: boolean; } export class AccountEmailAuth extends React.Component { constructor(props: AccountEmailAuthProps) { super(props); this.state = { emailAddress: "", errorMessage: undefined, hasAgreedToTOS: false, hasSelectedToAddToNewsletter: false, hasBlurred: false, }; } public renderEmailInput(): JSX.Element { const { emailAddress, hasBlurred } = this.state; const isValid = !hasBlurred || isValidEmail(emailAddress); return ( this.setState({ emailAddress: value, hasBlurred: false })} onBlur={() => this.setState({ hasBlurred: true })} /> ); } public renderCheckboxes(): JSX.Element { const { hasAgreedToTOS, hasSelectedToAddToNewsletter } = this.state; return ( ); } public renderAuthError(): JSX.Element { const { errorMessage } = this.state; const { loginPath, signupPath } = this.props; if (!errorMessage) { return <>; } if (errorMessage === "emailnotfound") { return ( ); } if (errorMessage === "emailexists") { return ( ); } return ( ); } public render(): JSX.Element { const { isNewUser, headerComponent } = this.props; const { hasAgreedToTOS } = this.state; const emailMutation = isNewUser ? signupMutation : loginMutation; const isButtonDisabled = isNewUser && !hasAgreedToTOS; return ( <> {this.renderAuthError()} {headerComponent} mutation={emailMutation}> {sendEmail => { return (
this.handleSubmit(event, sendEmail)}> {this.renderEmailInput()} {isNewUser && this.renderCheckboxes()}
); }} ); } public toggleHasAgreedToTOS = (): void => { const { hasAgreedToTOS } = this.state; this.setState({ hasAgreedToTOS: !hasAgreedToTOS }); }; public toggleHasSelectedToAddToNewsletter = (): void => { const { hasSelectedToAddToNewsletter } = this.state; this.setState({ hasSelectedToAddToNewsletter: !hasSelectedToAddToNewsletter }); }; private async handleSubmit(event: React.FormEvent, mutation: MutationFn): Promise { event.preventDefault(); this.setState({ errorMessage: undefined, hasBlurred: true }); const { emailAddress, hasSelectedToAddToNewsletter } = this.state; const { applicationType, onEmailSend, isNewUser } = this.props; if (!isValidEmail(emailAddress)) { return; } const resultKey = isNewUser ? "authSignupEmailSendForApplication" : "authLoginEmailSendForApplication"; try { const variables: AuthMutationVariables = { emailAddress, application: applicationType }; if (isNewUser) { variables.addToMailing = hasSelectedToAddToNewsletter; } const res: any = await mutation({ variables, }); const authResponse: string = res.data[resultKey]; if (authResponse === "ok") { onEmailSend(isNewUser, emailAddress); } this.setState({ errorMessage: authResponse as AuthEmailError }); return; } catch (err) { this.setState({ errorMessage: "unknown" }); } } } ================================================ FILE: packages/components/src/Account/Auth/EmailSent.tsx ================================================ import * as React from "react"; import { RouteComponentProps } from "react-router-dom"; import { CheckEmailSection, AuthPageFooterLink } from "./AuthStyledComponents"; import { AuthTextEmailSent, AuthTextCheckSpam } from "./AuthTextComponents"; export interface AccountEmailSentProps extends Partial { isNewUser: boolean; emailAddress: string; onSendAgain?(): void; } export class AccountEmailSent extends React.Component { public render(): JSX.Element { const { emailAddress, onSendAgain } = this.props; return ( <> {/* // TODO(jorgelo): The link below should have a hover hand. */} Hey, I didn’t get an email. Can you send one again? ); } } ================================================ FILE: packages/components/src/Account/Auth/EthAuth.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Mutation, MutationFunc } from "react-apollo"; import { Civil } from "@joincivil/core"; import { EthSignedMessage, EthAddress } from "@joincivil/typescript-types"; import { Transaction, TransactionButtonNoModal, MetaMaskLogoButton, ManagerSectionHeading, MetaMaskModal, ModalHeading, metaMaskSignImgUrl, } from "../../"; import { CivilContext, ICivilContext } from "../../context"; export interface AccountEthAuthProps { civil?: Civil; buttonText?: string; buttonOnly?: boolean; onAuthenticated?(address: EthAddress): void; } export interface AccountEthAuthState { errorMessage?: string; isWaitingSignatureOpen?: boolean; isSignRejectionOpen?: boolean; } const setEthAddressMutation = gql` mutation($input: UserSignatureInput!) { userSetEthAddress(input: $input) } `; const userEthAddressQuery = gql` query { currentUser { ethAddress } } `; export class AccountEthAuth extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; private _isMounted?: boolean; constructor(props: AccountEthAuthProps) { super(props); this.state = {}; } public render(): JSX.Element { if (this.props.buttonOnly) { return this.renderTransactionUI(); } return ( <> Log into Civil with your crypto wallet

Almost there! To set up your Civil account, you need to authenticate your account with a signature. This is similar to signing in with a password. It verifies your account with your crypto wallet.

MetaMask will open a new window, and will require you to sign a message.

{this.renderTransactionUI()}
); } public componentDidMount(): void { this._isMounted = true; } public componentWillUnmount(): void { this._isMounted = false; } private renderTransactionUI(): JSX.Element { return ( mutation={setEthAddressMutation} update={(cache, { data: { userSetEthAddress } }) => { cache.writeQuery({ query: userEthAddressQuery, data: { currentUser: { ethAddress: userSetEthAddress, __typename: "User", }, }, }); }} > {userSetEthAddress => ( <> { return ( {this.props.buttonText || "Open MetaMask"} ); }} /> {this.renderWaitingSignModal()} {this.renderSignRejectionModal(userSetEthAddress)} {this.renderSaveErrorModal()} )} ); } private renderWaitingSignModal(): JSX.Element | null { if (!this.state.isWaitingSignatureOpen) { return null; } return ( Please sign the text in MetaMask to authenticate ); } private renderSignRejectionModal(userSetEthAddress: MutationFunc): JSX.Element | null { if (!this.state.isSignRejectionOpen) { return null; } return ( Failed to authenticate your wallet address ); } private renderSaveErrorModal(): JSX.Element | null { if (!this.state.errorMessage) { return null; } return ( Failed to save your wallet address ); } private signTransactions = (userSetEthAddress: MutationFunc): Transaction[] => { let { civil } = this.context; if (this.props.civil) { civil = this.props.civil; } return [ { transaction: async (): Promise => { this.setState({ isWaitingSignatureOpen: true, isSignRejectionOpen: false, errorMessage: undefined }); const message = "I control this address @ " + new Date().toISOString(); return civil!.signMessage(message); }, postTransaction: async (sig: EthSignedMessage): Promise => { try { delete sig.rawMessage; // gql endpoint doesn't want this and errors out const res = await userSetEthAddress({ variables: { input: sig, }, }); if (res && res.data && res.data.userSetEthAddress) { if (this.props.onAuthenticated) { this.props.onAuthenticated(sig.signer); } if (this._isMounted) { // A bit of an antipattern, but cancelling async/await is hard this.setState({ isWaitingSignatureOpen: false }); } } else { console.error("Failed to validate and save ETH address. Response:", res); throw Error("Failed to validate and save ETH address"); } } catch (err) { this.setState({ isWaitingSignatureOpen: false, errorMessage: err, }); } }, handleTransactionError: (err: Error) => { this.setState({ isWaitingSignatureOpen: false }); if (err.message.indexOf("Error: MetaMask Message Signature: User denied message signature.") !== -1) { this.setState({ isSignRejectionOpen: true }); } else { console.error("Transaction failed:", err); this.setState({ errorMessage: "Transaction failed: " + err.message, }); } }, }, ]; }; private cancelTransaction = () => { this.setState({ isWaitingSignatureOpen: false, isSignRejectionOpen: false, errorMessage: undefined, }); }; } ================================================ FILE: packages/components/src/Account/Auth/UserSetAvatar.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import apolloStorybookDecorator from "apollo-storybook-react"; import { UserSetAvatar } from "../"; import StoryRouter from "storybook-react-router"; const typeDefs = ` type User { uid: String email: String ethAddress: String } type Query { currentUser: User } type Mutation { setAvatarMutation( channelID: String avatarDataURL: String ): String skipSetAvatarMutation( hasSeen: Boolean! ): String } schema { query: Query mutation: Mutation } `; const mocks = { Query: () => { return { currentUser: () => { return "cool"; }, }; }, Mutation: () => { return { setAvatarMutation: (channelID: string, avatarDataURL: string) => { return "ok"; }, skipSetAvatarMutation: (hasSeen: boolean) => { return "ok"; }, }; }, }; storiesOf("Common / Web3Auth", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("UserSetAvatar", () => { return ( { console.log("Sent"); }} /> ); }); ================================================ FILE: packages/components/src/Account/Auth/UserSetAvatar.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Mutation, MutationFn, ApolloConsumer } from "react-apollo"; import { Button, InvertedButton, buttonSizes } from "../../Button"; import { SkipForNowButtonContainer } from "./AuthStyledComponents"; import AvatarEditor from "react-avatar-editor"; import styled from "styled-components"; import ApolloClient from "apollo-client"; import { fonts, mediaQueries } from "../../styleConstants"; import Slider from "react-input-slider"; import { colors, ZoomInIcon, ZoomOutIcon } from "@joincivil/elements"; import { ClipLoader } from "../../ClipLoader"; import { SimpleImageFileToDataUri } from "../../input"; const setAvatarMutation = gql` mutation($input: ChannelsSetAvatarInput!) { channelsSetAvatar(input: $input) { id } } `; const skipSetAvatarMutation = gql` mutation { skipUserChannelAvatarPrompt { uid } } `; const UserSetAvatarContainer = styled.div` width: 400px; ${mediaQueries.MOBILE} { width: 280px; } `; const AvatarEditorDiv = styled.div` display: flex; flex-direction: column; align-items: center; justify-content: space-between; `; const CropSpan = styled.span` margin-top: 15px; color: #676767; font-size: 14px; font-weight: 400; letter-spacing: 0.16px; line-height: 17px; `; const AvatarEditorContainerDiv = styled.div` margin-bottom: 25px; `; const AvatarEditorInnerDiv = styled.div` margin-top: 15px; `; const ZoomContainer = styled.div` display: flex; flex-direction: row; align-items: center; justify-content: space-around; width: 336px; ${mediaQueries.MOBILE} { width: 200px; } margin-top: 10px; `; const ZoomSliderContainer = styled.div``; const ZoomIconContainer = styled.div``; const SaveButtonContainer = styled.div` margin-left: 10px; `; const SkipAndSaveButtonsContainer = styled.div` width: 400px; ${mediaQueries.MOBILE} { width: 280px; } display: flex; justify-content: flex-end; `; const SkipButton = styled.span` cursor: pointer; color: #2b56ff; font-family: ${fonts.SANS_SERIF}; font-size: 13px; font-weight: 700; line-height: 16px; width: 158px; text-align: center; `; export interface UserSetAvatarProps { headerComponent?: JSX.Element; channelID: string; isProfileEdit?: boolean; // true if component is displayed via profile edit flow (as opposed to sign up flow) onSetAvatarComplete?(): void; onSetAvatarCancelled?(): void; } export interface UserSetAvatarState { avatarDataURL: string; errorMessage: string | undefined; scale: number; image?: any; preview?: PreviewImageState; saveInProgress: boolean; useSmallAvatarEditor: boolean; } export interface PreviewImageState { image: string; rect: any; scale: number; width: number; height: number; borderRadius: number; } export class UserSetAvatar extends React.Component { public editor: AvatarEditor | null; constructor(props: UserSetAvatarProps) { super(props); const useSmallAvatarEditor = window.innerWidth < 500; this.state = { avatarDataURL: "", errorMessage: undefined, scale: 1.4, saveInProgress: false, useSmallAvatarEditor, }; this.editor = null; } public render(): JSX.Element { const skipText = this.props.isProfileEdit ? "Cancel" : "Skip for now"; const { headerComponent, channelID } = this.props; return ( {headerComponent} mutation={setAvatarMutation}> {setAvatar => { return (
this.handleSubmit(event, setAvatar, channelID)}> {this.renderAvatarSelector()} {this.state.image && ( this.setState({ image: undefined })} disabled={this.state.saveInProgress} > Go back )}
); }} {!this.state.image && ( {client => ( { if (this.props.isProfileEdit) { this.onCancelClicked(); } else { await this.onSkipForNowClicked(client); } }} > {skipText} )} )}
); } public handleNewImage = (e: any) => { this.setState({ image: e }); }; private async onSkipForNowClicked(client: ApolloClient): Promise { const { error } = await client.mutate({ mutation: skipSetAvatarMutation, }); if (error) { this.setState({ errorMessage: error }); } else { if (this.props.onSetAvatarComplete) { this.props.onSetAvatarComplete(); } } } private onCancelClicked(): void { if (this.props.onSetAvatarCancelled) { this.props.onSetAvatarCancelled(); } } private renderAvatarSelector(): JSX.Element { return ( {this.state.image && ( { this.editor = el; }} image={this.state.image ? this.state.image : ""} width={this.state.useSmallAvatarEditor ? 200 : 336} height={this.state.useSmallAvatarEditor ? 200 : 336} border={0} borderRadius={this.state.useSmallAvatarEditor ? 100 : 168} color={[255, 255, 255, 0.6]} // RGBA scale={this.state.scale} rotate={0} /> Crop your photo { this.setState({ scale: xy.x / 100 }); }} /> )} {!this.state.image && ( )} ); } private async handleSubmit(event: React.FormEvent, mutation: MutationFn, channelID: string): Promise { event.preventDefault(); this.setState({ errorMessage: undefined, saveInProgress: true }); const croppingRect = this.editor!.getCroppingRect(); const img = document.createElement("img"); img.onload = async (): Promise => { try { const startingX = img.width * croppingRect.x; const startingY = img.height * croppingRect.y; const startingWidth = img.width * croppingRect.width; const startingHeight = img.height * croppingRect.height; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = 336; canvas.height = 336; ctx!.drawImage(img, startingX, startingY, startingWidth, startingHeight, 0, 0, 336, 336); const avatarDataURL = canvas.toDataURL(); const res: any = await mutation({ variables: { input: { channelID, avatarDataURL }, }, }); if (res.data && res.data.channelsSetAvatar && res.data.channelsSetAvatar.id === channelID) { if (this.props.onSetAvatarComplete) { this.props.onSetAvatarComplete(); } } if (res.error) { console.log("res.error: ", res.error); } return; } catch (err) { const errorMessage = "Unknown Error when setting avatar. Please contact support@civil.co if problem persists."; this.setState({ errorMessage, saveInProgress: false }); } }; img.src = this.state.image!; } } ================================================ FILE: packages/components/src/Account/Auth/UserSetEmail.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import apolloStorybookDecorator from "apollo-storybook-react"; import { UserSetEmail } from "../"; import StoryRouter from "storybook-react-router"; const typeDefs = ` type User { uid: String email: String ethAddress: String } type AuthLoginResponse { token: String refreshToken: String uid: String } type Query { currentUser: User } type Mutation { authSignupEmailSendForApplication( email: String application: String ): String authSignupEmailConfirm( signupJWT: String! ): AuthLoginResponse authSignupEmailSend( emailAddress: String! ): String } schema { query: Query mutation: Mutation } `; const mocks = { Query: () => { return { currentUser: () => { return "cool"; }, }; }, Mutation: () => { return { authSignupEmailSend: (email: string) => { return "ok"; }, authSignupEmailSendForApplication: (email: string, application: string) => { return "ok"; }, }; }, }; storiesOf("Common / Web3Auth", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("UserSetEmail", () => { return ( { console.log("Sent"); }} /> ); }); ================================================ FILE: packages/components/src/Account/Auth/UserSetEmail.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Mutation, MutationFn, ApolloConsumer } from "react-apollo"; import { Checkbox, CheckboxSizes } from "../../input/Checkbox"; import { Button, buttonSizes } from "../../Button"; import { TextInput } from "../../input"; import { CheckboxSection, CheckboxContainer, CheckboxLabel, ConfirmButtonContainer, AuthErrorMessage, SkipForNowButtonContainer, } from "./AuthStyledComponents"; import { isValidEmail } from "@joincivil/utils"; import { AuthTextUnknownError } from "./AuthTextComponents"; import styled from "styled-components"; import { fonts } from "../../styleConstants"; import ApolloClient from "apollo-client"; const HeaderDiv = styled.div` color: #000000; font-family: ${fonts.SANS_SERIF}; font-size: 24px; font-weight: 700; line-height: 32px; width: 298px; text-align: left; `; const SubHeaderDiv = styled.div` color: #3f3c39; font-family: ${fonts.SANS_SERIF}; font-size: 16px; font-weight: 400; line-height: 26px; width: 298px; text-align: left; `; const SkipButton = styled.span` cursor: pointer; color: #2b56ff; font-family: ${fonts.SANS_SERIF}; font-size: 14px; font-weight: 400; line-height: 26px; width: 82px; text-align: center; background-color: #ffffff; `; const setEmailMutation = gql` mutation($input: ChannelsSetEmailInput!) { userChannelSetEmail(input: $input) { id } } `; const skipSetEmailMutation = gql` mutation { skipUserChannelEmailPrompt { uid } } `; export interface UserSetEmailProps { channelID: string; isProfileEdit?: boolean; // true if component is displayed via profile edit flow (as opposed to sign up flow) onSetEmailComplete?(): void; onSetEmailCancelled?(): void; } export type UserSetEmailError = "unknown" | "emailexists" | "emailnotfound" | undefined; export interface UserSetEmailState { emailAddress: string; errorMessage: UserSetEmailError; hasSelectedToAddToNewsletter: boolean; hasBlurred: boolean; disabled: boolean; } export class UserSetEmail extends React.Component { constructor(props: UserSetEmailProps) { super(props); this.state = { emailAddress: "", errorMessage: undefined, hasSelectedToAddToNewsletter: true, hasBlurred: false, disabled: false, }; } public renderEmailInput(): JSX.Element { const { emailAddress, hasBlurred } = this.state; const isValid = !hasBlurred || isValidEmail(emailAddress); return ( this.setState({ emailAddress: value, hasBlurred: false })} onBlur={() => this.setState({ hasBlurred: true })} /> ); } public renderAuthError(): JSX.Element { const { errorMessage } = this.state; if (!errorMessage) { return <>; } return ( ); } public render(): JSX.Element { const headerText = this.props.isProfileEdit ? "Set Email" : "Almost done!"; const skipText = this.props.isProfileEdit ? "Cancel" : "Skip for now"; return ( <> {this.renderAuthError()} {headerText} To receive payment confirmations and account-related alerts, please enter your email address. mutation={setEmailMutation}> {sendEmail => { return (
this.handleSubmit(event, sendEmail)}> {this.renderEmailInput()} {this.renderCheckboxes()}
); }} {client => ( { if (!this.state.disabled) { if (this.props.isProfileEdit) { this.onCancelClicked(); } else { await this.onSkipForNowClicked(client); } } }} > {skipText} )} ); } public renderCheckboxes(): JSX.Element { const { hasSelectedToAddToNewsletter } = this.state; return ( ); } public toggleHasSelectedToAddToNewsletter = (): void => { const { hasSelectedToAddToNewsletter } = this.state; this.setState({ hasSelectedToAddToNewsletter: !hasSelectedToAddToNewsletter }); }; private async onSkipForNowClicked(client: ApolloClient): Promise { this.setState({ disabled: true }); const { error } = await client.mutate({ mutation: skipSetEmailMutation, }); if (error) { this.setState({ errorMessage: error, disabled: false }); } else { if (this.props.onSetEmailComplete) { this.setState({ disabled: false }); this.props.onSetEmailComplete(); } } } private onCancelClicked(): void { this.setState({ disabled: true }); if (this.props.onSetEmailCancelled) { this.setState({ disabled: false }); this.props.onSetEmailCancelled(); } } private async handleSubmit(event: React.FormEvent, mutation: MutationFn): Promise { event.preventDefault(); this.setState({ errorMessage: undefined, hasBlurred: true, disabled: true }); const { emailAddress, hasSelectedToAddToNewsletter } = this.state; const { channelID } = this.props; if (!isValidEmail(emailAddress)) { return; } try { const variables = { input: { emailAddress, channelID, addToMailing: hasSelectedToAddToNewsletter, }, }; await mutation({ variables, }); if (this.props.onSetEmailComplete) { this.props.onSetEmailComplete(); this.setState({ disabled: false }); } return; } catch (err) { this.setState({ errorMessage: "unknown", disabled: false }); } } } ================================================ FILE: packages/components/src/Account/Auth/UserSetHandle.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Mutation, MutationFn, ApolloConsumer } from "react-apollo"; import { Button, buttonSizes } from "../../Button"; import { TextInput } from "../../input"; import { ConfirmButtonContainer } from "./AuthStyledComponents"; import { isValidHandle, getCurrentUserQuery } from "@joincivil/utils"; import ApolloClient from "apollo-client"; import { debounce } from "lodash"; const setHandleMutation = gql` mutation($input: ChannelsSetHandleInput!) { channelsSetHandle(input: $input) { id } } `; const checkHandleUniqueQuery = gql` query($handle: String!) { channelsIsHandleAvailable(handle: $handle) } `; export interface UserSetHandleAuthProps { headerComponent?: JSX.Element; channelID: string; onSetHandleComplete?(): void; } const ERROR_MESSAGE_INVALID_HANDLE = "Please enter a valid username. Usernames must be 4-15 characters, with no spaces or special characters other than underscores."; const ERROR_MESSAGE_NOT_UNIQUE = "That username is already in use. Please try another."; export interface UserSetHandleAuthState { handle: string; errorMessage: string | undefined; hasBlurred: boolean; isHandleUnique: boolean; } export class UserSetHandle extends React.Component { constructor(props: UserSetHandleAuthProps) { super(props); this.state = { handle: "", errorMessage: undefined, hasBlurred: false, isHandleUnique: true, }; this.checkHandleUniqueness = debounce(this.checkHandleUniqueness.bind(this), 1000); } public renderHandleInput(): JSX.Element { const { handle, isHandleUnique, errorMessage } = this.state; let isError = false; if (errorMessage) { isError = true; } const isValid = isValidHandle(handle); let invalidMessage: string | undefined = errorMessage; if (!isValid) { invalidMessage = ERROR_MESSAGE_INVALID_HANDLE; } else if (!isHandleUnique) { invalidMessage = ERROR_MESSAGE_NOT_UNIQUE; } return ( {client => ( { this.setState({ handle: value, hasBlurred: false, errorMessage: undefined, isHandleUnique: true }); // tslint:disable-next-line this.checkHandleUniqueness(value, client); }} onBlur={() => this.setState({ hasBlurred: true })} /> )} ); } public render(): JSX.Element { const { headerComponent, channelID } = this.props; const isButtonDisabled = !isValidHandle(this.state.handle) || !this.state.isHandleUnique; return ( <> {headerComponent} mutation={setHandleMutation}> {setHandle => { return (
this.handleSubmit(event, setHandle, channelID)}> {this.renderHandleInput()}
); }} ); } private checkHandleUniqueness = async (val: any, client: ApolloClient): Promise => { const result = await client.query({ query: checkHandleUniqueQuery, variables: { handle: val } }); const isHandleUnique = result.data && result.data.channelsIsHandleAvailable; this.setState({ isHandleUnique }); }; private async handleSubmit(event: React.FormEvent, mutation: MutationFn, channelID: string): Promise { event.preventDefault(); this.setState({ errorMessage: undefined, hasBlurred: true }); const { handle } = this.state; if (!isValidHandle(handle)) { return; } try { const res: any = await mutation({ variables: { input: { channelID, handle }, }, refetchQueries: [ { query: getCurrentUserQuery, }, ], }); if (res.data && res.data.channelsSetHandle && res.data.channelsSetHandle.id === channelID) { if (this.props.onSetHandleComplete) { this.props.onSetHandleComplete(); } } if (res.error) { console.log("res.error: ", res.error); } return; } catch (err) { let errorMessage = "Unknown Error when setting username. Please contact support@civil.co if problem persists."; if (err.toString().includes("invalid handle")) { errorMessage = ERROR_MESSAGE_INVALID_HANDLE; } else if (err.toString().includes("not unique")) { errorMessage = ERROR_MESSAGE_NOT_UNIQUE; } this.setState({ errorMessage }); } } } ================================================ FILE: packages/components/src/Account/Auth/VerifyToken.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { AuthEmailVerify } from "./AuthStyledComponents"; const onAuthenticationContinue = (): void => { console.log("Click"); return; }; storiesOf("Common / Auth / VerifyToken", module) .add("Loading", () => { return ( ); }) .add("Error", () => { return ( ); }) .add("Complete", () => { return ( ); }); ================================================ FILE: packages/components/src/Account/Auth/VerifyToken.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { setApolloSession, getApolloClient } from "@joincivil/utils"; import { AuthLoginResponse } from ".."; import { AuthEmailVerify } from "./AuthStyledComponents"; const verifySignUpTokenMutation = gql` mutation($token: String!) { authSignupEmailConfirm(signupJWT: $token) { token refreshToken uid } } `; const verifyLoginTokenMutation = gql` mutation($token: String!) { authLoginEmailConfirm(loginJWT: $token) { token refreshToken uid } } `; export interface AccountVerifyTokenProps { isNewUser: boolean; token: string; ethAuthNextExt?: boolean; onAuthenticationContinue(isNewUser: boolean): void; } export interface VerifyTokenState { hasVerified: boolean; errorMessage: string | undefined; } export class AccountVerifyToken extends React.Component { public state = { hasVerified: false, errorMessage: undefined, }; constructor(props: AccountVerifyTokenProps) { super(props); } public async componentDidMount(): Promise { return this.handleTokenVerification(); } public handleTokenVerification = async (): Promise => { const { isNewUser } = this.props; const token = this.props.token; const client = getApolloClient(); const verifyMutation = isNewUser ? verifySignUpTokenMutation : verifyLoginTokenMutation; const resultKey = isNewUser ? "authSignupEmailConfirm" : "authLoginEmailConfirm"; try { const { data, error } = await client.mutate({ mutation: verifyMutation, variables: { token }, }); if (error) { console.log("Error authenticating:", error); const errorMessage = error.graphQLErrors.map((e: any) => e.message).join(" ,"); this.setState({ errorMessage, hasVerified: true }); } else { const authResponse: AuthLoginResponse = data[resultKey]; setApolloSession(authResponse); this.setState({ errorMessage: undefined, hasVerified: true }); } } catch (err) { console.error("Error validating token:", err); this.setState({ errorMessage: "There was a problem validating your token.", hasVerified: true }); } }; public render(): JSX.Element { const { hasVerified, errorMessage } = this.state; const { onAuthenticationContinue, isNewUser, ethAuthNextExt } = this.props; return ( onAuthenticationContinue(isNewUser)} /> ); } } ================================================ FILE: packages/components/src/Account/Auth/__snapshots__/EmailAuth.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Auth / Email Signup Flow AccountEmailAuth 1`] = `

Common / Auth / Email Signup Flow

AccountEmailAuth

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Account/Auth/__snapshots__/EthAuth.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Auth / ETH AccountEthAuth Component 1`] = `

Log into Civil with your crypto wallet

Almost there! To set up your Civil account, you need to authenticate your account with a signature. This is similar to signing in with a password. It verifies your account with your crypto wallet.

MetaMask will open a new window, and will require you to sign a message.

Common / Auth / ETH

AccountEthAuth Component

Story Source

            
< StorybookProvider >
< Unknown value = { {
civil
: { ethApi : {
rpcId
: 10000 ,
web3
: {
currentProvider
: {
host
: 'http://localhost:8033' ,
httpAgent
: {
domain
: null ,
_events
: { free : anonymous } ,
_eventsCount
: 1 ,

}
,
timeout
: 0 ,

}
,
_requestManager
: { provider : {
host
: 'http://localhost:8033' ,
httpAgent
: {
domain
: null ,
_events
: { free : anonymous } ,
_eventsCount
: 1 ,

}
,
timeout
: 0 ,

}
, providers : { WebsocketProvider : WebsocketProvider , HttpProvider : HttpProvider , IpcProvider : IpcProvider } , subscriptions : { } }
,
givenProvider
: null ,

}
,
abiDecoder
: { savedABIs : [
{
constant
: true ,
inputs
: [ ] ,
name
: 'PROCESSBY' ,

}
,
{
constant
: false ,
inputs
: [ { name : '_propID' , type : 'bytes32' } ] ,
name
: 'processProposal' ,

}
,
{
constant
: true ,
inputs
: [ { name : '' , type : 'bytes32' } ] ,
name
: 'proposals' ,

}
,

]
, methodIds : {
0xb25bdef16105f099e5c185f9c7fd969571e8e0caa3f7bd75409512fe0a41a60b
: {
anonymous
: false ,
inputs
: [
{ indexed : false , name : 'name' , type : 'string' }
,
{ indexed : false , name : 'value' , type : 'uint256' }
,
{ indexed : false , name : 'propID' , type : 'bytes32' }
,

]
,
name
: '_ReparameterizationProposal' ,

}
,
0xe94e3086c4bfe84acba4437b85a80fca3721dfc419d1f7afe4fa4e470e670b48
: {
anonymous
: false ,
inputs
: [
{ indexed : true , name : 'propID' , type : 'bytes32' }
,
{ indexed : false , name : 'challengeID' , type : 'uint256' }
,
{ indexed : false , name : 'commitEndDate' , type : 'uint256' }
,

]
,
name
: '_NewChallenge' ,

}
,
0x37f3986c71e1aa2c470cfc4a92af70820610c3065589d35ef1664ea27f3e73a5
: {
anonymous
: false ,
inputs
: [ { indexed : true , name : 'propID' , type : 'bytes32' } , { indexed : false , name : 'name' , type : 'string' } , { indexed : false , name : 'value' , type : 'uint256' } ] ,
name
: '_ProposalAccepted' ,

}
,

}
}
,

}
, contentProvider : { providers : [ { } ] } }
,
auth
: {
currentUser
: null ,
loading
: false ,
apolloClient
: null ,

}
,
features
: { featureFlags : [ ] } ,

}
}
>
< styled.div >
< AccountEthAuth onAuthenticated = { onAuthenticated } />
</ styled.div >
</ Unknown >
</ StorybookProvider >

Prop Types

" AccountEthAuth " Component

No propTypes defined!

" StorybookProvider " Component

No propTypes defined!

" Unknown " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Account/Auth/__snapshots__/UserSetAvatar.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Web3Auth UserSetAvatar 1`] = `

Drag and drop an image here
or
Skip for now

Common / Web3Auth

UserSetAvatar

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Account/Auth/__snapshots__/UserSetEmail.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Web3Auth UserSetEmail 1`] = `
Almost done!
To receive payment confirmations and account-related alerts, please enter your email address.
Skip for now

Common / Web3Auth

UserSetEmail

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Account/Auth/__snapshots__/VerifyToken.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Auth / VerifyToken Complete 1`] = `

Email Address Confirmed!

Thanks for confirming your email address.

Common / Auth / VerifyToken

Complete

Story Source

            
< AuthEmailVerify hasVerified errorMessage = { null } onAuthenticationContinue = { onAuthenticationContinue } />

Prop Types

" AuthEmailVerify " Component

No propTypes defined!
`; exports[`Storyshots Common / Auth / VerifyToken Error 1`] = `

Uh oh.

Error is bad

Common / Auth / VerifyToken

Error

Story Source

            
< AuthEmailVerify hasVerified errorMessage = " Error is bad " onAuthenticationContinue = { onAuthenticationContinue } />

Prop Types

" AuthEmailVerify " Component

No propTypes defined!
`; exports[`Storyshots Common / Auth / VerifyToken Loading 1`] = `

Confirming your email address...

Common / Auth / VerifyToken

Loading

Story Source

            
< AuthEmailVerify hasVerified = { false } errorMessage = { null } onAuthenticationContinue = { onAuthenticationContinue } />

Prop Types

" AuthEmailVerify " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Account/LoadUser.tsx ================================================ import * as React from "react"; import { getApolloSessionKey, getCurrentUserQuery } from "@joincivil/utils"; import { Query } from "react-apollo"; import useStateWithLocalStorage from "../hooks/useStateWithLocalStorage"; export interface LoadUserChildrenProps { user: any; loading: boolean; refetch?: any; } export interface LoadUserProps { children(props: LoadUserChildrenProps): any; } export const LoadUser: React.FunctionComponent = props => { const apolloSessionKey = getApolloSessionKey(); const [auth] = useStateWithLocalStorage(apolloSessionKey); useStateWithLocalStorage("network"); // basically just pay attention to when network is set const renderFunction = props.children; const hasAuthToken = auth && auth.token; if (!hasAuthToken) { return <>{renderFunction({ user: null, loading: false })}; } return ( query={getCurrentUserQuery}> {({ loading, error, data, refetch }) => { if (loading || error) { return renderFunction({ user: null, loading, refetch }); } return renderFunction({ user: data.currentUser, loading, refetch }); }} ); }; ================================================ FILE: packages/components/src/Account/index.ts ================================================ export * from "./Auth/VerifyToken"; export * from "./Auth/ConfirmEmailToken"; export * from "./Auth/EmailAuth"; export * from "./Auth/EmailSent"; export * from "./Auth/EthAuth"; export * from "./Auth/UserSetHandle"; export * from "./Auth/UserSetAvatar"; export * from "./Auth/UserSetEmail"; export * from "./LoadUser"; export { AuthOuterWrapper, AuthInnerWrapper, AuthPageFooterLink, AuthFooterTerms, AuthFooterContainer, AuthWrapper, } from "./Auth/AuthStyledComponents"; export * from "./Auth/AuthTextComponents"; export enum AuthApplicationEnum { DEFAULT = "DEFAULT", NEWSROOM = "NEWSROOM", STOREFRONT = "STOREFRONT", } export interface AuthLoginResponse { token: string; refreshToken: string; uid: string; } ================================================ FILE: packages/components/src/AddressWithCopyButton.tsx ================================================ import * as React from "react"; import { copyToClipboard } from "@joincivil/utils"; import styled from "styled-components"; import { colors } from "./styleConstants"; import { SecondaryButton, buttonSizes } from "./Button"; export interface AddressWithCopyButtonProps { address?: string; } const Box = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-right: none; background-color: ${colors.basic.WHITE}; padding: 9px; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; width: calc(100% - 21px); `; const Wrapper = styled.div` display: flex; flex-direction: row; justify-content: start; align-items: center; margin-bottom: 10px; `; const Button = styled(SecondaryButton)` padding: 10px; font-size: 14px; `; export class AddressWithCopyButton extends React.Component { public addressBox?: HTMLDivElement; public render(): JSX.Element { return ( (this.addressBox = el)}>{this.props.address} ); } } ================================================ FILE: packages/components/src/AddressWithMetaMaskIcon.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { MetaMaskFrontIcon } from "./"; import { fonts } from "./styleConstants"; export interface AddressWithMetaMaskIconProps { address?: string; } const Wrapper = styled.div` display: inline-block; margin-bottom: 16px; `; const Box = styled.div` display: flex; position: relative; top: 4px; margin-top: -4px; align-items: center; font-family: ${fonts.MONOSPACE}; padding: 8px 12px 4px 8px; border: 1px solid #dddddd; word-break: break-word; img { position: relative; top: -2px; margin-right: 12px; } `; export class AddressWithMetaMaskIcon extends React.Component { public render(): JSX.Element { return ( {this.props.address} ); } } ================================================ FILE: packages/components/src/ApplicationPhaseStatusLabels.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { AwaitingApprovalStatusLabel, AwaitingAppealRequestLabel, AwaitingDecisionStatusLabel, AwaitingAppealChallengeStatusLabel, CommitVoteStatusLabel, RevealVoteStatusLabel, ReadyToCompleteStatusLabel, } from "./ApplicationPhaseStatusLabels"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 400px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Registry / Application Status Labels", module).add("Labels", () => { return (





); }); ================================================ FILE: packages/components/src/ApplicationPhaseStatusLabels.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "./styleConstants"; export const StyledBaseStatus = styled.div` background-color: ${colors.primary.BLACK}; color: ${colors.basic.WHITE}; display: inline-block; font: bold 12px/15px ${fonts.SANS_SERIF}; letter-spacing: 1px; margin: 0 0 9px; padding: 5px 8px; text-transform: uppercase; `; const StyledAwaitingStatuslabel = styled(StyledBaseStatus)` background-color: ${colors.accent.CIVIL_BLUE_FADED_2}; color: ${colors.primary.BLACK}; `; const StyledAwaitingAppealStatuslabel = styled(StyledBaseStatus)` background-color: ${colors.accent.CIVIL_RED_VERY_FADED}; color: ${colors.primary.BLACK}; `; const StyledCommitVoteStatus = styled(StyledBaseStatus)` background-color: ${colors.accent.CIVIL_YELLOW}; color: ${colors.primary.BLACK}; `; const StyledRevealVoteStatus = styled(StyledBaseStatus)` background-color: ${colors.accent.CIVIL_TEAL_FADED}; color: ${colors.primary.BLACK}; `; const StyledReadyToCompleteStatus = styled(StyledBaseStatus)` background-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.basic.WHITE}; `; export const AwaitingApprovalStatusLabel: React.FunctionComponent = props => { return Awaiting Approval; }; export const AwaitingAppealRequestLabel: React.FunctionComponent = props => { return Awaiting Request to Appeal; }; export const AwaitingDecisionStatusLabel: React.FunctionComponent = props => { return Awaiting Council Decision; }; export const AwaitingAppealChallengeStatusLabel: React.FunctionComponent = props => { return Challenge Council Decision; }; export const CommitVoteStatusLabel: React.FunctionComponent = props => { return Submit Vote; }; export const RevealVoteStatusLabel: React.FunctionComponent = props => { return Confirm Vote; }; export const ReadyToCompleteStatusLabel: React.FunctionComponent = props => { return Ready To Update; }; ================================================ FILE: packages/components/src/AuthenticatedRoute.tsx ================================================ import * as React from "react"; import { Route, RouteProps, Redirect } from "react-router-dom"; import { getCurrentUserQuery, getApolloSession } from "@joincivil/utils"; import { Query } from "react-apollo"; export interface AuthenticatedRouteProps extends RouteProps { redirectTo: string; onlyAllowUnauthenticated?: boolean; authUrl: string; } export const AuthenticatedRoute = ({ render, redirectTo, authUrl, onlyAllowUnauthenticated = false, ...otherProps }: AuthenticatedRouteProps) => { const auth = getApolloSession(); const hasAuthToken = !!auth && !!auth.token; // TODO(jorgelo): Refactor this boolean logic. if (onlyAllowUnauthenticated) { if (hasAuthToken) { return ; } } else { if (!hasAuthToken) { return ; } } if (!render) { throw new Error("Please set a render function"); } // TODO(jorgelo): Get the line below working without the ts-ignore // @ts-ignore const renderChildren = () => render(otherProps); if (onlyAllowUnauthenticated && !hasAuthToken) { if (render) { return renderChildren(); } return null; } return ( query={getCurrentUserQuery}> {({ loading, error, data }) => { if (loading) { return null; } if (error && !onlyAllowUnauthenticated) { return ; } if (render) { return renderChildren(); } return null; }} ); }; export const UnauthenticatedRoute = (props: AuthenticatedRouteProps) => ( ); ================================================ FILE: packages/components/src/BrowserCompatible/BrowserCompatible.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import StoryRouter from "storybook-react-router"; import { BrowserCompatible } from "./BrowserCompatible"; storiesOf("Common / Browser Compatible Message", module) .addDecorator(StoryRouter()) .add("Browser Compatible", () => { return ; }); ================================================ FILE: packages/components/src/BrowserCompatible/BrowserCompatible.tsx ================================================ import * as React from "react"; import { buttonSizes, OBSmallestParagraph } from "../"; import { BrowserCompatWrapper, BrowserLogo, BrowserButtons, BrowserButton, BrowserCompatLinks, } from "./BrowserCompatibleStyledComponents"; import { BrowserCompatHeadingText, BrowserCompatIntroText } from "./BrowserCompatibleTextComponents"; import chromeLogoImgUrl from "../images/img-chrome-logo@2x.png"; import firefoxLogoImgUrl from "../images/img-firefox-logo@2x.png"; import { urlConstants as links } from "@joincivil/utils"; export const BrowserCompatible: React.FunctionComponent = props => { return ( Get Google Chrome Get Firefox Contact Us Visit Support ); }; ================================================ FILE: packages/components/src/BrowserCompatible/BrowserCompatibleStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { InvertedButton, OBSectionDescription, mediaQueries } from "../"; export const BrowserCompatWrapper = styled.div` padding: 80px 0; text-align: center; ${mediaQueries.MOBILE} { padding: 30px 0; } `; export const BrowserLogo = styled.img` height: 24px; margin-right: 15px; vertical-align: bottom; width: 24px; `; export const BrowserButtons = styled.div` margin: 32px 0 70px; `; export const BrowserButton = styled(InvertedButton)` border-width: 1px; font-size: 13px; font-weight: bold; margin-bottom: 16px; min-width: 210px; padding: 5px 16px 7px; text-transform: none; &:first-child { margin-right: 16px; } ${mediaQueries.MOBILE} { &:first-child { margin-right: 0; } } `; export const BrowserCompatLinks = styled.a` &:first-child { margin-right: 48px; } `; export const BrowserCompatIntroStyled = styled(OBSectionDescription)` margin-left: auto; margin-right: auto; max-width: 600px; `; ================================================ FILE: packages/components/src/BrowserCompatible/BrowserCompatibleTextComponents.tsx ================================================ import * as React from "react"; import { OBSectionTitle } from "../"; import { BrowserCompatIntroStyled } from "./BrowserCompatibleStyledComponents"; export const BrowserCompatHeadingText: React.FunctionComponent = props => ( Can we switch to a different browser? ); export const BrowserCompatIntroText: React.FunctionComponent = props => ( <> Civil Registry applications and token purchases currently only work in browsers with Ethereum wallet support, like desktop Chrome and Firefox. We’re working to support other browsers. In the meantime, please… ); ================================================ FILE: packages/components/src/BrowserCompatible/__snapshots__/BrowserCompatible.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Browser Compatible Message Browser Compatible 1`] = `

Can we switch to a different browser?

Civil Registry applications and token purchases currently only work in browsers with Ethereum wallet support, like desktop Chrome and Firefox. We’re working to support other browsers.

In the meantime, please…

Contact Us Visit Support

Common / Browser Compatible Message

Browser Compatible

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/BrowserCompatible/index.ts ================================================ export * from "./BrowserCompatible"; ================================================ FILE: packages/components/src/Button.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import StoryRouter from "storybook-react-router"; import * as React from "react"; import styled from "styled-components"; import { Button, SecondaryButton, DarkButton, InvertedButton, buttonSizes } from "./Button"; import { MetaMaskLogoButton } from "./MetaMaskLogoButton"; import { CardTransactionButton } from "./CardTransactionButton"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 400px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Pattern Library / Buttons", module) .addDecorator(StoryRouter()) .add("Button", () => { return (


); }) .add("sizes", () => { return (




); }) .add("SecondaryButton", () => { return ( Secondary Button ); }) .add("InvertedButton", () => { return ( Inverted Button ); }) .add("DarkButton", () => { return ( Dark Button ); }) .add("MetaMaskLogoButton", () => { return ( console.log("You clicked me!")}> MetaMaskLogo Transaction Button ); }) .add("CardTransactionButton", () => { return (

This is a Transaction Button styled as a Card, and can contain any markup

console.log("You clicked me!")}>Transaction
); }); ================================================ FILE: packages/components/src/Button.tsx ================================================ export { buttonSizes, ButtonProps, ButtonTheme, DEFAULT_BUTTON_THEME, ButtonComponent, Button, InvertedButton, SecondaryButton, DarkButton, CancelButton, BorderlessButton, } from "@joincivil/elements"; ================================================ FILE: packages/components/src/Card/Card.stories.tsx ================================================ import * as React from "react"; import { storiesOf } from "@storybook/react"; import styled from "styled-components"; import { CardClickable } from "./Card"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 400px; `; const Container: React.FunctionComponent = ({ children }) => {children}; const handleClick = () => console.log("You clicked it."); storiesOf("Pattern Library / Cards", module).add("Clickable Card", () => { return ( I am a basic clickable card. ); }); ================================================ FILE: packages/components/src/Card/Card.tsx ================================================ import * as React from "react"; import { StyledCardClickable } from "./CardStyledComponents"; export interface CardClickableProps { disabled?: boolean; onClick?(...args: any[]): void; } export const CardClickable: React.FunctionComponent = props => { const onClick = (...args: any[]) => { if (!props.disabled && props.onClick) { props.onClick(...args); } }; return {props.children}; }; ================================================ FILE: packages/components/src/Card/CardStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export const StyledCardBase = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 4px; box-shadow: 0 2px 4px 0 ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_0}; font-family: ${fonts.SANS_SERIF}; font-size: 16px; letter-spacing: 0; line-height: 26px; padding: 18px; transition: border-color 0.2s ease; `; export const StyledCardClickable = styled(StyledCardBase)` cursor: pointer; &:hover { background-color: ${colors.basic.WHITE}; border-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.accent.CIVIL_GRAY_0}; } `; ================================================ FILE: packages/components/src/Card/__snapshots__/Card.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Cards Clickable Card 1`] = `
I am a basic clickable card.

Pattern Library / Cards

Clickable Card

Story Source

            
< Container >
< CardClickable onClick = { handleClick } >
I am a basic clickable card.
</ CardClickable >
</ Container >

Prop Types

" CardClickable " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Card/index.ts ================================================ export * from "./Card"; ================================================ FILE: packages/components/src/CardTransactionButton.tsx ================================================ import * as React from "react"; import { CardClickable } from "./Card"; import { TransactionButtonInnerProps } from "./TransactionButton"; import styled from "styled-components"; export const CardTransactionButton = (props: TransactionButtonInnerProps): JSX.Element => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/ChallengeResultsChart/ChallengeResults.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { fonts } from "../styleConstants"; import { ChallengeResults } from "./ChallengeResults"; const StyledDiv = styled.div` display: flex; font-family: ${fonts.SANS_SERIF}; width: 335px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); const totalVotes = "100000"; const votesFor = "73000"; const votesAgainst = "27000"; const percentFor = "73"; const percentAgainst = "27"; const didChallengeSucceed = false; storiesOf("Registry", module).add("Challenge Results Chart", () => { return ( ); }); ================================================ FILE: packages/components/src/ChallengeResultsChart/ChallengeResults.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StyledListingDetailPhaseCardSectionHeader } from "../ListingDetailPhaseCard/styledComponents"; import { ChallengeResultsProps } from "./types"; import { VoteTypeSummary, VoteTypeSummaryContainer, VotesPerTokenTotal, TotalVotesLabelContainer, TotalVotesCount, StyledExplainerText, } from "./styledComponents"; import { CHALLENGE_RESULTS_VOTE_TYPES } from "./constants"; import { VoteTypeSummaryRow } from "./VoteTypeSummaryRow"; import { Collapsable } from "../Collapsable"; const DefaultHeader = styled(StyledListingDetailPhaseCardSectionHeader)` & + ${VoteTypeSummaryContainer} { margin-top: 14px; } `; const StyledInner = styled.div` padding-top: 14px; `; const ExplainerText: React.FunctionComponent = props => { let explainerText; if (props.didChallengeSucceed) { if (props.isAppealChallenge) { explainerText = ( <> The Civil Community voted to overturn the Civil Council's decision. ); } else { explainerText = ( <> The Civil Community voted to reject this newsroom on the grounds that it is in violation of the Civil Constitution. ); } } else { if (props.isAppealChallenge) { explainerText = ( <> The Civil Community voted to uphold The Civil Council's decision. ); } else { explainerText = ( <> The Civil Community voted to accept this newsroom on the grounds that it adheres to the Civil Constitution. ); } } return {explainerText}; }; const ChallengeResultsInner: React.FunctionComponent = props => { const Header = props.styledHeaderComponent || DefaultHeader; const defaultHeaderText = props.challengeID ? `Challenge ${props.challengeID} Results` : "Challenge Results"; const explainerText = !props.noExplainerText && ; return ( <> {!props.noHeader &&
{props.headerText || defaultHeaderText}
} {props.noHeader && } {explainerText} Total Votes {props.totalVotes} ); }; export const ChallengeResults: React.FunctionComponent = props => { if (props.collapsable) { const Header = props.styledHeaderComponent || DefaultHeader; const headerElement =
{props.headerText || "Challenge Results"}
; const open = props.open !== undefined ? props.open : true; return ( ); } return ; }; ================================================ FILE: packages/components/src/ChallengeResultsChart/ChallengeResultsChartTextComponents.tsx ================================================ import * as React from "react"; import { HollowGreenCheck, HollowRedNoGood } from "../icons"; import { VoteTypeLabelProps } from "./types"; import { CHALLENGE_RESULTS_VOTE_TYPES } from "./constants"; export const voteTypeLabel: VoteTypeLabelProps = { [CHALLENGE_RESULTS_VOTE_TYPES.REMAIN]: ( <> Accept ), [CHALLENGE_RESULTS_VOTE_TYPES.REMOVE]: ( <> Reject ), [CHALLENGE_RESULTS_VOTE_TYPES.OVERTURN]: <>Overturn, [CHALLENGE_RESULTS_VOTE_TYPES.UPHOLD]: <>Uphold, }; ================================================ FILE: packages/components/src/ChallengeResultsChart/UserVotingSummary.tsx ================================================ import * as React from "react"; import { UserVotingSummaryProps } from "./types"; import { voteTypeLabel } from "./ChallengeResultsChartTextComponents"; import { UserVotingSummaryContainer, UserVotingSummaryColumn, UserVotingSummaryColHeader } from "./styledComponents"; export const UserVotingSummary: React.FunctionComponent = props => { return ( Voted For {voteTypeLabel[props.choice]} Voting Tokens Committed {props.numTokens} ); }; ================================================ FILE: packages/components/src/ChallengeResultsChart/VoteTypeSummaryRow.tsx ================================================ import * as React from "react"; import { VoteTypeSummary, VotesPerTokenContainer, VotesPerTokenVote, VotesPerTokenCount, BreakdownBarContainer, BreakdownBarPercentageLabel, BreakdownBarTotalContainer, BreakdownBarTotal, BreakdownBarPercentage, } from "./styledComponents"; import { VoteTypeSummaryRowProps } from "./types"; import { voteColor } from "./constants"; import { voteTypeLabel } from "./ChallengeResultsChartTextComponents"; export const VoteTypeSummaryRow: React.FunctionComponent = props => { const color = voteColor[props.voteType]; return ( {voteTypeLabel[props.voteType]} {props.votesPercent && (props.votesPercent.indexOf("NaN") < 0 ? props.votesPercent : "0")}% {props.votesCount} ); }; ================================================ FILE: packages/components/src/ChallengeResultsChart/__snapshots__/ChallengeResults.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry Challenge Results Chart 1`] = `

Challenge Results

The Civil Community voted to accept this newsroom on the grounds that it adheres to the Civil Constitution.

Accept
73 %
73000
Reject
27 %
27000
Total Votes
100000

Registry

Challenge Results Chart

Story Source

            
< Container >
< ChallengeResults
  
totalVotes = " 100000 "

  
votesFor = " 73000 "

  
votesAgainst = " 27000 "

  
percentFor = " 73 "

  
percentAgainst = " 27 "

  
didChallengeSucceed = { false }
/>
</ Container >

Prop Types

" ChallengeResults " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/ChallengeResultsChart/constants.ts ================================================ import { colors } from "../styleConstants"; import { VoteTypeColorProps } from "./types"; export enum CHALLENGE_RESULTS_VOTE_TYPES { REMAIN = "REMAIN", REMOVE = "REMOVE", OVERTURN = "OVERTURN", UPHOLD = "UPHOLD", } export const voteColor: VoteTypeColorProps = { [CHALLENGE_RESULTS_VOTE_TYPES.REMAIN]: colors.accent.CIVIL_TEAL, [CHALLENGE_RESULTS_VOTE_TYPES.REMOVE]: colors.accent.CIVIL_RED, [CHALLENGE_RESULTS_VOTE_TYPES.OVERTURN]: colors.accent.CIVIL_ORANGE, [CHALLENGE_RESULTS_VOTE_TYPES.UPHOLD]: colors.accent.CIVIL_GREEN, }; ================================================ FILE: packages/components/src/ChallengeResultsChart/index.ts ================================================ export * from "./ChallengeResults"; export * from "./VoteTypeSummaryRow"; export * from "./UserVotingSummary"; export * from "./types"; export * from "./constants"; ================================================ FILE: packages/components/src/ChallengeResultsChart/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../styleConstants"; import { CHALLENGE_RESULTS_VOTE_TYPES } from "./constants"; import { BreakdownBarPercentageProps, VotesPerTokenVoteProps } from "./types"; export const VoteTypeSummaryContainer = styled.div` box-shadow: inset 0 1px 0 0 ${colors.accent.CIVIL_GRAY_4}; font-size: 14px; line-height: 17px; padding: 14px 0 10px; `; export const VoteTypeSummary = styled.div` display: flex; color: ${colors.accent.CIVIL_GRAY_0}; `; export const BreakdownBarContainer = styled.div` display: flex; width: 75%; `; export const BreakdownBarPercentageLabel = styled.div` font-weight: bold; width: 60px; `; export const BreakdownBarTotalContainer = styled.div` margin-top: 4px; width: 100%; `; export const BreakdownBarTotal = styled.div` background-color: ${colors.accent.CIVIL_GRAY_4}; box-sizing: border-box; height: 8px; position: relative; width: 100%; `; export const BreakdownBarPercentage = styled.div` display: inline-block; background-color: ${props => props.color}; height: 8px; left: 0; top: 0; position: absolute; transition: width 500ms ease; width: ${props => props.percentage}%; `; export const VotesPerTokenContainer = styled.div` display: flex; white-space: nowrap; width: 25%; position: relative; margin-left: 20px; `; export const TotalVotesLabelContainer = styled.div` display: flex; white-space: nowrap; width: 39%; `; export const VotesPerTokenVote = styled.div` font-weight: bold; width: 95px; & > span { color: ${props => props.vote === CHALLENGE_RESULTS_VOTE_TYPES.REMAIN || props.vote === CHALLENGE_RESULTS_VOTE_TYPES.UPHOLD ? colors.accent.CIVIL_TEAL : colors.accent.CIVIL_RED}; margin-right: 4px; } `; export const VotesPerTokenTotal = styled(VotesPerTokenVote)` color: ${colors.accent.CIVIL_GRAY_3}; text-transform: uppercase; width: 95px; `; export const VotesPerTokenCount = styled.div` color: ${colors.primary.BLACK}; font-size: 12px; line-height: 15px; margin: 6px 0 0; `; export const TotalVotesCount = styled.div` color: ${colors.primary.BLACK}; `; export const StyledExplainerText = styled.p` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; `; // User Voting Summary export const UserVotingSummaryContainer = styled.div` display: flex; `; export const UserVotingSummaryColumn = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; width: 50%; `; export const UserVotingSummaryColHeader = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 12px; font-weight: 800; letter-spacing: 0.93px; line-height: 15px; margin: 0 0 10px; text-transform: uppercase; `; ================================================ FILE: packages/components/src/ChallengeResultsChart/types.d.ts ================================================ o; ================================================ FILE: packages/components/src/ChallengeResultsChart/types.ts ================================================ import * as React from "react"; export interface ChallengeResultsProps { challengeID?: string; totalVotes: string; votesFor: string; votesAgainst: string; percentFor: string; percentAgainst: string; didChallengeOriginallySucceed?: boolean; didChallengeSucceed?: boolean; isAppealChallenge?: boolean; headerText?: string; noHeader?: boolean; noExplainerText?: boolean; styledHeaderComponent?: React.FunctionComponent; collapsable?: boolean; open?: boolean; } export interface BreakdownBarPercentageProps { vote: string; percentage: string; color: string; } export interface VotesPerTokenVoteProps { vote?: string; } export interface VoteTypeSummaryRowProps { voteType: string; votesCount: string; votesPercent: string; } export interface VoteTypeLabelProps { [index: string]: JSX.Element; } export interface VoteTypeColorProps { [index: string]: string; } export interface UserVotingSummaryProps { choice: string; numTokens: string; } ================================================ FILE: packages/components/src/ChevronAnchor.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { ChevronAnchor } from "./ChevronAnchor"; import { ChevronAnchorLeft } from "./ChevronAnchorLeft"; import { colors } from "@joincivil/elements"; import styled from "styled-components"; const ThemedContainer = styled.div` a { color: ${colors.primary.CIVIL_BLUE_1}; text-decoration: none; &:hover { text-decoration: underline; } } `; storiesOf("Pattern Library / Typography / Chevron Anchor", module) .add("Default", () => { return Check this out; }) .add("Civil Themed", () => { return ( Check this out ); }) .add("Civil Themed, Left", () => { return ( Go back to that thing ); }); ================================================ FILE: packages/components/src/ChevronAnchor.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Chevron } from "@joincivil/elements"; // @NOTE: See also `DisclosureArrowIcon` - slightly thicker version, we could maybe make an anchor tag helper for that too. export interface ChevronAnchorProps extends React.AnchorHTMLAttributes { /** Defaults to tag. */ component?: React.ComponentType; to?: string; } export const ChevronAnchor: React.FunctionComponent = props => React.createElement( props.component || "a", { ...props, // passing prop with name `component` breaks some components component: undefined, }, <> {props.children} , ); ================================================ FILE: packages/components/src/ChevronAnchorLeft.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Chevron } from "@joincivil/elements"; const ChevronLeft = styled(Chevron)` transform: scaleX(-1); `; export interface ChevronAnchorLeftProps extends React.AnchorHTMLAttributes { /** Defaults to tag. */ component?: React.ComponentType; to?: string; } export const ChevronAnchorLeft: React.FunctionComponent = props => React.createElement( props.component || "a", props, <> {props.children} , ); ================================================ FILE: packages/components/src/ClaimRewards.tsx ================================================ import * as React from "react"; import { TextInput } from "./input/"; import { TransactionButton } from "./TransactionButton"; import { FormCopy, FormHeader } from "./ListingDetailPhaseCard/styledComponents"; export interface ClaimRewardsProps { challengeID: string; transactions: any[]; modalContentComponents?: any; } export class ClaimRewards extends React.Component { public render(): JSX.Element { return ( <> Claim Your Rewards Congratulations, you have a reward available! Claim Rewards ); } } ================================================ FILE: packages/components/src/ClipLoader.tsx ================================================ export { ClipLoader } from "@joincivil/elements"; ================================================ FILE: packages/components/src/Collapsable.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Collapsable } from "./Collapsable"; const Wrapper = styled.div` margin: 50px; max-width: 500px; `; storiesOf("Pattern Library / Collapsable", module) .add("open", () => { return ( Hello} open={true}>

Some Content

); }) .add("closed", () => { return ( Hello} open={false}>

Some Content

); }) .add("disabled", () => { return ( Hello} open={false}>

Some Content

); }) .add("with custom arrow", () => { const Arrow = styled.div<{ open: boolean }>` width: 8px; height: 8px; border-left: 3px solid blue; border-bottom: 3px solid blue; transform: ${props => (props.open ? "rotate(135deg)" : "rotate(-45deg)")}; transition: transform 1s; display: inline-block; vertical-align: middle; `; return (

Some Content

); }) .add("with open text", () => { return (

Some Content

); }); ================================================ FILE: packages/components/src/Collapsable.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "./styleConstants"; export interface OpenBool { open: boolean; } export interface ArrowProps extends OpenBool { disabled?: boolean; } export interface CollapsableProps extends OpenBool { header: React.ReactNode; headerOpen?: React.ReactNode; ArrowComponent?: any; disabled?: boolean; className?: string; // for use as styled component } export interface CollapseAreaProps extends OpenBool { height: number | null; } export const CollapseArea = styled.div` height: ${props => (props.open ? `${props.height ? `${props.height}px` : "auto"}` : "0px")}; transition: height 1s; overflow: ${props => (props.open ? "visible" : "hidden")}; `; export const Arrow = styled.div` width: 8px; height: 8px; border-left: 3px solid ${props => (props.disabled ? colors.accent.CIVIL_GRAY_3 : colors.primary.CIVIL_GRAY_1)}; border-bottom: 3px solid ${props => (props.disabled ? colors.accent.CIVIL_GRAY_3 : colors.primary.CIVIL_GRAY_1)}; transform: ${props => (props.open ? "rotate(135deg)" : "rotate(-45deg)")}; transition: transform 1s; position: absolute; right: 0; top: 10px; `; export const HeaderWrapper = styled.div` position: relative; cursor: pointer; `; export class Collapsable extends React.Component { public collapseArea: HTMLDivElement | null; constructor(props: CollapsableProps) { super(props); this.state = { open: props.open, height: null, }; this.collapseArea = null; } public componentDidMount(): void { if (this.collapseArea) { this.collapseArea!.addEventListener("transitionend", () => { if (this.state.open) { this.setState({ height: null }); } }); } } public componentWillReceiveProps(nextProps: CollapsableProps): void { if (nextProps.open !== this.props.open) { this.setState({ open: nextProps.open }); } } public render(): JSX.Element { let header = this.props.header; if (this.state.open && this.props.headerOpen) { header = this.props.headerOpen; } return (
{header}{" "} {this.props.ArrowComponent ? ( ) : ( )} (this.collapseArea = el)} height={this.state.height} open={this.state.open}> {this.props.children}
); } private open = (): void => { if (!this.props.disabled) { if (this.state.open) { this.setState({ height: this.collapseArea!.clientHeight }); } setImmediate(() => { this.setState({ open: !this.state.open }); }); } }; } ================================================ FILE: packages/components/src/Comments/CommentsCount.tsx ================================================ import * as React from "react"; import { CommentsCountStyled, CommentsLabel } from "./CommentsStyledComponents"; export interface CommentsCountProps { numComments: number; } export class CommentsCount extends React.Component { public render(): JSX.Element { return ( {this.props.numComments !== 0 ? ( this.renderContributers() ) : ( Be the first to Comment )} ); } private renderContributers = (): JSX.Element => { return ( <> {this.props.numComments} {this.props.numComments === 1 ? " Comment" : " Comments"} ); }; } ================================================ FILE: packages/components/src/Comments/CommentsStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "@joincivil/elements"; export const CommentsCountStyled = styled.div` align-items: center; color: ${colors.accent.CIVIL_GRAY_1}; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 11px; font-weight: 600; line-height: 13px; `; export const CommentsLabel = styled.span` color: ${colors.accent.CIVIL_GRAY_2}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; font-weight: 400; line-height: 14px; svg { opacity: 0.3; } `; ================================================ FILE: packages/components/src/Comments/index.ts ================================================ export * from "./CommentsCount"; export * from "./CommentsStyledComponents"; ================================================ FILE: packages/components/src/Contributors/ContributorCount.tsx ================================================ import * as React from "react"; import { ContributorCountStyled, ContributorsLabel, ContributorCountAvatars, ContributorCountAvatar, } from "./ContributorsStyledComponents"; import { ContributorData } from "./types"; import { ContributorsDefaultAvatar } from "./ContributorsDefaultAvatar"; export interface ContributorsCountProps { displayedContributors: ContributorData[]; totalContributors: number; } export class ContributorCount extends React.Component { public render(): JSX.Element { return ( {this.props.totalContributors !== 0 ? ( this.renderContributers() ) : ( Be the first to Boost )} ); } private renderContributers = (): JSX.Element => { return ( <> {this.props.displayedContributors.slice(0, 3).map((contributor: any, i: number) => { return ( {contributor.payerChannel && contributor.payerChannel.tiny72AvatarDataUrl ? ( ) : ( )} ); })} {this.props.totalContributors} {this.props.totalContributors === 1 ? " Booster" : " Boosters"} ); }; } ================================================ FILE: packages/components/src/Contributors/Contributors.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Contributors } from "./Contributors"; import { ContributorCount } from "./ContributorCount"; import { ContributorsDefaultAvatar } from "./ContributorsDefaultAvatar"; const Container = styled.div` width: 400px; `; const contributors = [ { usdEquivalent: 2.5, payerChannel: { handle: "violetnight13", tiny72AvatarDataUrl: "https://picsum.photos/50", }, }, { usdEquivalent: 3, payerChannel: { handle: "CaryRay", tiny72AvatarDataUrl: "https://picsum.photos/50", }, }, { usdEquivalent: 5, payerChannel: { handle: "ronburgundy", tiny72AvatarDataUrl: "https://picsum.photos/50", }, }, ]; storiesOf("Common / Contributors", module) .add("Contributors", () => { return ( ); }) .add("Contributor Count", () => { return ( ); }) .add("Contributor Default Avatar", () => { return ( ); }); ================================================ FILE: packages/components/src/Contributors/Contributors.tsx ================================================ import * as React from "react"; import { ContributorsStyled, ContributorsTitle, ContributorsLabel, ContributorsPrompt, ContributorItem, ContributorAvatar, ContributorUserName, ContributorAmount, ContributorsIconBorder, } from "./ContributorsStyledComponents"; import { ContributorData } from "./types"; import { TipIcon } from "@joincivil/elements"; import { ContributorsDefaultAvatar } from "./ContributorsDefaultAvatar"; export interface ContributorsProps { sortedContributors: ContributorData[]; } export const Contributors: React.FunctionComponent = props => { return ( Recent Boosters {props.sortedContributors ? ( props.sortedContributors.slice(0, 3).map((contributor: any, i: number) => { return ( {contributor.payerChannel && contributor.payerChannel.tiny72AvatarDataUrl ? ( ) : ( )}
{contributor.payerChannel && contributor.payerChannel.handle} {"$" + contributor.usdEquivalent.toFixed(2)}
); }) ) : ( Be the first to Boost )}
); }; ================================================ FILE: packages/components/src/Contributors/ContributorsDefaultAvatar.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, AvatarGenericIcon } from "@joincivil/elements"; export interface ContributorsDefaultAvatarProps { contributor: any; index: number; size: number; } export interface ContributorsDefaultAvatarStyledProps { backgroundColor: string; size: number; } export const ContributorsDefaultAvatarStyled = styled.div` align-items: center; background-color: ${(props: ContributorsDefaultAvatarStyledProps) => props.backgroundColor}; border: 1px solid ${colors.basic.WHITE}; border-radius: 50%; color: ${colors.basic.WHITE}; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 10px; height: ${(props: ContributorsDefaultAvatarStyledProps) => props.size + "px"}; justify-content: center; margin-right: 10px; text-transform: uppercase; width: ${(props: ContributorsDefaultAvatarStyledProps) => props.size + "px"}; `; const AvatarGenericIconStyled = styled.div` border: 1px solid ${colors.basic.WHITE}; border-radius: 50%; margin-right: 10px; `; export const ContributorsDefaultAvatar: React.FunctionComponent = props => { const avatarColors = ["#EF6B4A", "#9452B5", "#A5CE52"]; // user has an account but no avatar if (props.contributor && props.contributor.payerChannel && props.contributor.payerChannel.handle) { const initial = props.contributor.payerChannel.handle.charAt(0); return ( {initial} ); } // guest user, no handle return ( ); }; ================================================ FILE: packages/components/src/Contributors/ContributorsStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "@joincivil/elements"; export const ContributorsStyled = styled.div` margin-bottom: 15px; `; export const ContributorsTitle = styled.label` display: block; font-family: ${fonts.SANS_SERIF}; font-size: 10px; font-weight: 700; letter-spacing: 0.82px; line-height: 12px; margin-bottom: 10px; text-transform: uppercase; `; export const ContributorItem = styled.div` align-items: center; display: flex; margin-bottom: 10px; `; export const ContributorAvatar = styled.img` border-radius: 50%; height: 25px; margin-right: 10px; width: 25px; `; export const ContributorUserName = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; line-height: 14px; margin-bottom: 2px; `; export const ContributorAmount = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 11px; font-weight: 600; line-height: 13px; `; export const ContributorCountStyled = styled.div` align-items: center; color: ${colors.accent.CIVIL_GRAY_1}; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 11px; font-weight: 600; line-height: 13px; `; export const ContributorCountAvatars = styled.div` display: flex; margin-right: 5px; `; export const ContributorCountAvatar = styled.span` & > div { margin: 0; } &:nth-of-type(2), &:nth-of-type(3) { margin-left: -4px; } img { border: 1px solid ${colors.basic.WHITE}; border-radius: 50%; height: 17px; width: 17px; } `; export const ContributorsLabel = styled.span` color: ${colors.accent.CIVIL_GRAY_2}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; font-weight: 400; line-height: 14px; svg { opacity: 0.3; } `; export const ContributorsPrompt = styled.div` align-items: center; display: flex; `; export const ContributorsIconBorder = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 50%; height: 26px; margin-right: 6px; padding: 3px; width: 26px; svg { opacity: 0.3; } `; ================================================ FILE: packages/components/src/Contributors/__snapshots__/Contributors.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Contributors Contributor Count 1`] = `
30 Boosters

Common / Contributors

Contributor Count

Story Source

            
< styled.div >
< ContributorCount displayedContributors = { [ { usdEquivalent : 2.5 , payerChannel : { handle : 'violetnight13' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } , { usdEquivalent : 3 , payerChannel : { handle : 'CaryRay' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } , { usdEquivalent : 5 , payerChannel : { handle : 'ronburgundy' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } ] } totalContributors = { 30 } />
</ styled.div >

Prop Types

" ContributorCount " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Common / Contributors Contributor Default Avatar 1`] = `
v

Common / Contributors

Contributor Default Avatar

Story Source

            
< styled.div >
< ContributorsDefaultAvatar contributor = { { usdEquivalent : 2.5 , payerChannel : { handle : 'violetnight13' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } } index = { 1 } size = { 17 } />
</ styled.div >

Prop Types

" ContributorsDefaultAvatar " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Common / Contributors Contributors 1`] = `
violetnight13
$2.50
CaryRay
$3.00
ronburgundy
$5.00

Common / Contributors

Contributors

Story Source

            
< styled.div >
< Contributors sortedContributors = { [ { usdEquivalent : 2.5 , payerChannel : { handle : 'violetnight13' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } , { usdEquivalent : 3 , payerChannel : { handle : 'CaryRay' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } , { usdEquivalent : 5 , payerChannel : { handle : 'ronburgundy' , tiny72AvatarDataUrl : 'https://picsum.photos/50' } } ] } />
</ styled.div >

Prop Types

" Contributors " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Contributors/index.ts ================================================ export * from "./Contributors"; export * from "./ContributorCount"; export * from "./ContributorsStyledComponents"; export * from "./types"; ================================================ FILE: packages/components/src/Contributors/types.ts ================================================ export interface ContributorData { usdEquivalent: number; payerChannel: { handle: string; tiny72AvatarDataUrl: string; }; } ================================================ FILE: packages/components/src/CopyToClipboard/CopyStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { InvertedButton } from "../Button"; export const CopyBtn = styled(InvertedButton)` background-color: transparent; border: none; font-size: 13px; font-weight: 700; letter-spacing: 0.3px; padding: 0; text-transform: none; &:hover, &:focus { background-color: transparent; color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } `; export const CopyURLSuccess = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 13px; font-weight: bold; line-height: 24px; text-align: center; svg { vertical-align: sub; } `; ================================================ FILE: packages/components/src/CopyToClipboard/CopyURL.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { CopyURL } from "./CopyURL"; import styled from "styled-components"; const Container = styled.div` width: 300px; `; storiesOf("Common / Copy", module).add("Copy URL", () => { return ( ); }); ================================================ FILE: packages/components/src/CopyToClipboard/CopyURL.tsx ================================================ import * as React from "react"; import { copyToClipboard } from "@joincivil/utils"; import { CopyBtn, CopyURLSuccess } from "./CopyStyledComponents"; import { HollowGreenCheck } from "../icons"; export interface CopyURLProps { copyText?: string; } export interface CopyURLStates { copied: boolean; } export class CopyURL extends React.Component { public constructor(props: CopyURLProps) { super(props); this.state = { copied: false, }; } public render(): JSX.Element { if (this.state.copied) { return ( Copied ); } return this.copy()}>{this.props.copyText || "Copy the URL"}; } private copy = () => { copyToClipboard(window.location.href); this.setState({ copied: true, }); }; } ================================================ FILE: packages/components/src/CopyToClipboard/__snapshots__/CopyURL.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Copy Copy URL 1`] = `

Common / Copy

Copy URL

Story Source

            
< styled.div >
< CopyURL copyText = " Copy the URL to open in your own wallet " />
</ styled.div >

Prop Types

" CopyURL " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/CopyToClipboard/index.ts ================================================ export * from "./CopyURL"; ================================================ FILE: packages/components/src/CurrencyConverter/CurrencyConverted.tsx ================================================ import * as React from "react"; import { CurrencyConvertedBox, CurrencyCode, CurrencyConvertedPrice } from "./CurrencyConverterStyledComponents"; export interface CurrencyConvertedProps { currencyCode?: string | JSX.Element; currentPrice?: number; } export interface CurrencyConvertedStates { convertedCurrency?: number; } export class CurrencyConverted extends React.Component { constructor(props: any) { super(props); this.state = { convertedCurrency: this.props.currentPrice || 0, }; } public render(): JSX.Element { return ( <> {this.props.currentPrice} {this.props.currencyCode} ); } } ================================================ FILE: packages/components/src/CurrencyConverter/CurrencyConverter.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import apolloStorybookDecorator from "apollo-storybook-react"; import { CurrencyConverter } from "./CurrencyConverter"; import styled from "styled-components"; const Container = styled.div` width: 500px; `; const typeDefs = ` type Query { storefrontEthPrice: Float storefrontCvlPrice: Float storefrontCvlQuoteUsd(usdToSpend: Float!): Float } schema { query: Query } `; const mocks = { Query: () => { return { storefrontEthPrice: () => { return 102.98; }, storefrontCvlPrice: () => { return 0.2; }, storefrontCvlQuoteUsd: () => { return 500.48635; }, }; }, }; storiesOf("Common / Currency / Currency Converter", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .add("USD to ETH", () => { return (
(exchange rate is 0.5x)
null} doConversion={async (from: number) => from * 2} onNotEnoughEthError={(error: boolean) => console.log(error)} />
); }) .add("CVL to ETH", () => { return (
(exchange rate is 2x)
null} doConversion={async (from: number) => from * 2} />
); }); ================================================ FILE: packages/components/src/CurrencyConverter/CurrencyConverter.tsx ================================================ import * as React from "react"; import { CurrencyConverterContain, CurrencyContain, CurrencyLabel, StyledCurrencyInputWithButton, CurrencyErrorMsg, CurrencyIconContain, } from "./CurrencyConverterStyledComponents"; import { ExchangeArrowsIcon, WarningIcon } from "../icons"; import { CurrencyConverted } from "./CurrencyConverted"; import { CurrencyInputWithoutButton } from "../input"; import { debounce } from "lodash"; import { CivilContext, ICivilContext } from "../context"; import { colors } from "../styleConstants"; export interface CurrencyConverterProps { currencyCodeFrom: string; currencyLabelFrom?: string | JSX.Element; currencyCodeTo: string; currencyLabelTo?: string | JSX.Element; displayErrorMsg?: boolean; fromValue?: string; className?: string; doConversion(fromValue: number): Promise; onConversion(fromValue: number, toValue: number): void; onNotEnoughEthError?(error: boolean): void; } export interface CurrencyConverterState { fromValue: number; toValue: number; balance: number; enoughEthError: boolean; } export class CurrencyConverter extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; private handleConversionDebounced: (fromValueString: string) => Promise; constructor(props: any) { super(props); this.state = { fromValue: 0, toValue: 0, balance: 0, enoughEthError: false, }; this.handleConversionDebounced = debounce(this.handleConversion.bind(this), 500, { maxWait: 2000 }); } public async componentDidMount(): Promise { const civil = this.context.civil; if (this.props.fromValue) { await this.handleConversionDebounced(this.props.fromValue); } if (civil) { await civil.currentProviderEnable(); const account = await civil.accountStream.first().toPromise(); if (account) { await this.setState({ balance: await civil.accountBalance(account), }); // Now that we have balance we should do conversion again where we check if they have enough ETH for it if (this.props.fromValue) { await this.handleConversion(this.props.fromValue); } } } } public render(): JSX.Element { return ( {this.props.currencyLabelFrom} {this.props.currencyCodeFrom}} onChange={async (_, amount) => this.handleConversionDebounced(amount)} value={this.props.fromValue} /> {this.props.currencyLabelTo} {this.props.displayErrorMsg && this.state.enoughEthError && this.renderErrorMsg()} ); } private async handleConversion(fromValueString: string): Promise { let fromValue = Number.parseFloat(fromValueString); if (isNaN(fromValue)) { fromValue = 0; } const toValue = await this.props.doConversion(fromValue); const enoughEthError = toValue > this.state.balance ? true : false; this.onNotEnoughEthError(enoughEthError); const nextState = { fromValue, toValue, enoughEthError }; this.setState(nextState); this.props.onConversion(nextState.fromValue, nextState.toValue); } private onNotEnoughEthError = (error: boolean) => { if (this.props.onNotEnoughEthError) { this.props.onNotEnoughEthError(error); } }; private renderErrorMsg = () => { return (

You don’t have enough ETH in your wallet.

); }; } ================================================ FILE: packages/components/src/CurrencyConverter/CurrencyConverterStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; export const CurrencyConverterSection = styled.div` font-family: ${fonts.SANS_SERIF}; padding: 20px 0 10px; text-align: left; `; export const CurrencyConverterContain = styled.div` align-items: flex-end; display: flex; justify-content: space-between; position: relative; width: 100%; * { box-sizing: border-box; } `; export const CurrencyContain = styled.div` max-width: 250px; padding-bottom: 35px; width: 45%; `; export const CurrencyLabel = styled.label` color: ${colors.accent.CIVIL_GRAY_2}; font-size: 14px; line-height: 32px; `; export const StyledCurrencyInputWithButton = styled.div` & > div { font-size: 15px; line-height: 24px; padding: 12px 15px; ${mediaQueries.MOBILE} { padding: 10px; } } input { line-height: 24px; } & > div > div + div { font-size: 14px; line-height: 17px; right: 30px; ${mediaQueries.MOBILE} { right: 25px; } } `; export const CurrencyConvertedBox = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-radius: 3px; font-size: 15px; line-height: 24px; padding: 12px 53px 12px 12px; position: relative; width: 100%; ${mediaQueries.MOBILE} { padding: 10px 53px 10px 10px; } `; export const CurrencyConvertedPrice = styled.div` overflow: hidden; width: 100%; `; export const CurrencyCode = styled.div` color: ${colors.accent.CIVIL_GRAY_2}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 17px; position: absolute; right: 20px; text-align: right; top: calc(50% - 8px); `; export const CurrencyIconContain = styled.div` margin: 16px 16px 53px; ${mediaQueries.MOBILE} { margin: 10px 10px 53px; } `; export const CurrencyCalcCVL = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; text-align: center; span { font-size: 14px; font-weight: 600; line-height: 22px; } h4 { font-size: 28px; font-weight: 500; letter-spacing: -0.58px; line-height: 39px; margin: 0; } p { font-size: 14px; line-height: 22px; margin: 0; } `; export const CurrencyErrorMsg = styled.div` bottom: 10px; padding-left: 22px; position: absolute; width: 100%; ${mediaQueries.MOBILE} { bottom: 0; } svg { left: 0; position: absolute; top: 0; } p { color: ${colors.accent.CIVIL_RED}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; line-height: 15px; margin: 0; } `; ================================================ FILE: packages/components/src/CurrencyConverter/CurrencyConverterTextComponents.tsx ================================================ import * as React from "react"; export interface CurrencyCVLTextProps { pricePerCvl: number; totalPrice: number; } export const CurrencyCVLPriceText: React.FunctionComponent = props => ( <> You are buying

{props.totalPrice} CVL

approx. @ ${props.pricePerCvl} per CVL

); ================================================ FILE: packages/components/src/CurrencyConverter/UsdEthConverter.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Query } from "react-apollo"; import { CurrencyConverter } from "./CurrencyConverter"; const ethPriceQuery = gql` query { storefrontEthPrice } `; export interface UsdEthConverterProps { fromValue?: string; displayErrorMsg?: boolean; className?: string; onNotEnoughEthError?(error: boolean): void; onConversion(usdValue: number, ethValue: number): void; } export const UsdEthConverter = (props: UsdEthConverterProps) => { return ( query={ethPriceQuery}> {({ loading, error, data }) => { if (loading) { return
; } return ( <> convertToETH(usdAmount, data.storefrontEthPrice)} onConversion={(usdValue, ethValue) => props.onConversion(usdValue, ethValue)} onNotEnoughEthError={props.onNotEnoughEthError} /> ); }} ); async function convertToETH(usdAmount: number, storefrontEthPrice: number): Promise { const newConvertedEth = usdAmount / storefrontEthPrice; return newConvertedEth; } }; ================================================ FILE: packages/components/src/CurrencyConverter/UsdEthCvlConverter.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import { Query } from "react-apollo"; import { CurrencyConverterSection, CurrencyCalcCVL } from "./CurrencyConverterStyledComponents"; import { CurrencyCVLPriceText } from "./CurrencyConverterTextComponents"; import { UsdEthConverter } from "./UsdEthConverter"; const cvlPriceQuery = gql` query($usdToSpend: Float!) { storefrontCvlPrice storefrontCvlQuoteUsd(usdToSpend: $usdToSpend) } `; export interface CurrencyConverterProps { currencyLabelLeft?: string | JSX.Element; currencyLabelRight?: string | JSX.Element; onConversion(usdValue: number, ethValue: number): void; onCVLToBuyUpdate(cvlToBuy: number): void; } export interface CurrencyConverterStates { usdToSpend: number; convertedEth: number; } export class UsdEthCvlConverter extends React.Component { constructor(props: any) { super(props); this.state = { usdToSpend: 0, convertedEth: 0, }; } public render(): JSX.Element { const usdToSpend = this.state.usdToSpend; const updateConversion = this.updateConversion.bind(this); return ( query={cvlPriceQuery} variables={{ usdToSpend }}> {({ loading, error, data }) => { return ( ); }} ); } private updateConversion(usdValue: number, ethValue: number): void { this.setState({ usdToSpend: usdValue }); this.props.onConversion(usdValue, ethValue); } } ================================================ FILE: packages/components/src/CurrencyConverter/__snapshots__/CurrencyConverter.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Currency / Currency Converter CVL to ETH 1`] = `
(exchange rate is 2x)
CVL
0
ETH

Common / Currency / Currency Converter

CVL to ETH

Story Source

            
< StorybookProvider >
< styled.div >
< div >
(exchange rate is 2x)
</ div >
< CurrencyConverter
  
currencyCodeFrom = " CVL "

  
currencyCodeTo = " ETH "

  
currencyLabelFrom = " Enter CVL Amount "

  
currencyLabelTo = " Converted ETH "

  
onConversion = { onConversion }

  
doConversion = { doConversion }
/>
</ styled.div >
</ StorybookProvider >

Prop Types

" CurrencyConverter " Component

No propTypes defined!

" StorybookProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Common / Currency / Currency Converter USD to ETH 1`] = `
(exchange rate is 0.5x)
USD
0
ETH

Common / Currency / Currency Converter

USD to ETH

Story Source

            
< StorybookProvider >
< styled.div >
< div >
(exchange rate is 0.5x)
</ div >
< CurrencyConverter
  
fromValue = " 3 "

  
currencyCodeFrom = " USD "

  
currencyCodeTo = " ETH "

  
currencyLabelFrom = " Enter USD Amount "

  
currencyLabelTo = " Converted ETH "

  
displayErrorMsg

  
onConversion = { onConversion }

  
doConversion = { doConversion }

  
onNotEnoughEthError = { onNotEnoughEthError }
/>
</ styled.div >
</ StorybookProvider >

Prop Types

" CurrencyConverter " Component

No propTypes defined!

" StorybookProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/CurrencyConverter/index.ts ================================================ export * from "./CurrencyConverted"; export * from "./CurrencyConverterStyledComponents"; export * from "./UsdEthCvlConverter"; export * from "./UsdEthConverter"; ================================================ FILE: packages/components/src/DAppMessageContent/ErrorLoadingData.tsx ================================================ import * as React from "react"; import { OctopusErrorIcon } from "../icons"; import { StyledErrorIconContainer, StyledLargeModalText } from "./styledComponents"; export interface ErrorLoadingDataProps { toggleGraphQL?(): void | Promise; } export const ErrorLoadingData: React.FunctionComponent = props => { return ( <> Oops. Looks like we're having trouble loading what you're looking for. ); }; const SuggestedAction: React.FunctionComponent = () => { return <>; }; ================================================ FILE: packages/components/src/DAppMessageContent/ErrorNotFound.tsx ================================================ import * as React from "react"; import { OctopusErrorIcon } from "../icons"; import { StyledErrorIconContainer, StyledLargeModalText } from "./styledComponents"; export interface ErrorNotFoundProps { className?: string; } export const ErrorNotFound: React.FunctionComponent = props => { const defaultCopy = "This page could not be found."; return (
Oops. {props.children || defaultCopy}
); }; ================================================ FILE: packages/components/src/DAppMessageContent/InsufficientCVL.tsx ================================================ import * as React from "react"; import { InvertedButton, buttonSizes } from "../Button"; import { WarningIcon } from "../icons"; import { StyledErrorMessage, StyledBuyCVLButtonContainer, StyledMessageIconContainer, StyledMessageWithIconContainer, } from "./styledComponents"; import { InsufficientCVLProps, BuyCVLButtonProps } from "./types"; import { InsufficientCVLForChallengeText, InsufficientCVLForAppealText, InsufficientCVLForAppealChallengeText, } from "./textComponents"; export const InsufficientCVL: React.FunctionComponent = props => { const { buyCVLURL } = props; let buyBtnProps: any = { href: buyCVLURL }; if (buyCVLURL.charAt(0) === "/") { buyBtnProps = { to: buyCVLURL }; } return ( {props.children} {props.buyCVLURL && ( Buy CVL )} ); }; export const InsufficientCVLForChallenge: React.FunctionComponent = props => { return ( ); }; export const InsufficientCVLForAppeal: React.FunctionComponent = props => { return ( ); }; export const InsufficientCVLForAppealChallenge: React.FunctionComponent< InsufficientCVLProps & BuyCVLButtonProps > = props => { return ( ); }; ================================================ FILE: packages/components/src/DAppMessageContent/WrongNetwork.tsx ================================================ import * as React from "react"; import { urlConstants } from "@joincivil/utils"; import metaMaskNetworkSwitchUrl from "../images/img-metamask-networkswitch@2x.png"; import { Modal } from "../Modal"; import { MetaMaskMockImage, MetaMaskIcon, StyledLargeModalText, StyledSmallModalText } from "./styledComponents"; export interface WrongNetworkComponentProps { requiredNetworkNiceName: string; } export const WrongNetworkComponent: React.FunctionComponent = props => { return ( <> Change your network. Looks like you’re using an unsupported Ethereum network. Make sure you're using the{" "} {props.requiredNetworkNiceName}.
Read this tutorial {" "} to switch networks in MetaMask ); }; export const WrongNetworkModal: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/DAppMessageContent/index.ts ================================================ export * from "./ErrorLoadingData"; export * from "./ErrorNotFound"; export * from "./InsufficientCVL"; export * from "./WrongNetwork"; ================================================ FILE: packages/components/src/DAppMessageContent/styledComponents.tsx ================================================ import * as React from "react"; import { InvertedButton } from "../Button"; import styled from "styled-components"; import { colors } from "../styleConstants"; import { MetaMaskSideIcon } from "@joincivil/elements"; export const StyledMessageIconContainer = styled.span` display: inline-block; margin-right: 25px; `; export const StyledBuyCVLButtonContainer = styled.div` margin-left: 40px; & ${InvertedButton} { white-space: nowrap; } `; export const StyledErrorMessage = styled.span` color: ${colors.accent.CIVIL_RED}; font-size: 16px; letter-spacing: -0.11px; line-height: 24px; `; export const StyledMessageWithIconContainer = styled.div` display: flex; align-items: center; & ${StyledMessageIconContainer}, & ${StyledErrorMessage} { display: block; } `; export const MetaMaskMockImage = styled.img` display: block; margin: 0 auto; max-width: 255px; `; export const MetaMaskIcon = styled(MetaMaskSideIcon)` position: relative; top: 3px; `; export const StyledLargeModalText = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 18px; line-height: 24px; `; export const StyledSmallModalText = styled.p` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; } `; export const StyledErrorIconContainer = styled.div` align-items: center; display: flex; background: ${colors.accent.CIVIL_RED_VERY_FADED}; border-radius: 50%; justify-content: center; height: 100px; margin: 0 auto 40px; text-align: center; width: 100px; `; ================================================ FILE: packages/components/src/DAppMessageContent/textComponents.tsx ================================================ import * as React from "react"; import { InsufficientCVLProps } from "./types"; export const InsufficientCVLForChallengeText: React.FunctionComponent = props => { return ( <> Sorry, you don’t have enough CVL tokens to challenge this newsroom. A deposit of {props.minDeposit} tokens is required to challenge newsrooms. ); }; export const InsufficientCVLForAppealText: React.FunctionComponent = props => { return ( <> Sorry, you don’t have enough CVL tokens to request an appeal. A deposit of {props.minDeposit} tokens is required to submit an appeal request. ); }; export const InsufficientCVLForAppealChallengeText: React.FunctionComponent = props => { return ( <> Sorry, you don’t have enough CVL tokens to challenge this granted appeal. A deposit of {props.minDeposit} tokens is required to challenge a granted appeal. ); }; ================================================ FILE: packages/components/src/DAppMessageContent/types.ts ================================================ export interface InsufficientCVLProps { minDeposit?: string; appealFee?: string; } export interface BuyCVLButtonProps { buyCVLURL: string; } ================================================ FILE: packages/components/src/DetailTransactionButton.stories.tsx ================================================ import { Civil, TwoStepEthTransaction } from "@joincivil/core"; import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { DetailTransactionButton } from "./DetailTransactionButton"; import { DarkTransactionButton } from "./TransactionButton"; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } const createNewsroom = async (): Promise> => { return civil!.newsroomDeployNonMultisigTrusted("hello"); }; const Wrapper = styled.div` margin: 50px; max-width: 500px; `; storiesOf("Common / Ethereum / DetailTransactionButton", module) .add("detail transaction button", () => { return ( {process.env.NODE_ENV !== "test" && ( Create Newsroom )} ); }) .add("detail transaction button with visible progress modal", () => { return ( {process.env.NODE_ENV !== "test" && ( Create Newsroom )} ); }); ================================================ FILE: packages/components/src/DetailTransactionButton.tsx ================================================ import { Civil } from "@joincivil/core"; import { EthAddress } from "@joincivil/typescript-types"; import { debounce } from "lodash"; import * as React from "react"; import { Subscription } from "rxjs/Subscription"; import styled from "styled-components"; import { TransactionButton, Transaction, TransactionButtonNoModal, TransactionButtonInnerProps, } from "./TransactionButton"; import { fonts, colors } from "./styleConstants"; import { QuestionToolTip } from "./QuestionToolTip"; export interface DetailTransactionButtonProps { civil?: Civil; transactions: Transaction[]; estimateFunctions?: Array<(...args: any[]) => Promise>; requiredNetwork?: string; Button?: React.FunctionComponent; noModal?: boolean; disabled?: boolean; preExecuteTransactions?(): any; } export interface DetailTransactionButtonState { price: number; priceFailed: boolean; isProgressModalVisible: boolean; currentNetwork: string; currentAccount?: EthAddress; ethereumUpdates?: Subscription; } const Wrapper = styled.div` display: flex; flex-direction: row; justify-content: space-between; align-items: top; margin-bottom: 15px; `; const DetailSection = styled.div` width: 50%; `; const SmallHeader = styled.h4` font-family: ${fonts.SANS_SERIF}; font-weight: 500; font-size: 14px; margin-bottom: 10px; margin-top: 0px; `; const SmallText = styled.p` font-family: ${fonts.SANS_SERIF}; color: ${colors.accent.CIVIL_GRAY_2}; font-size: 13px; line-height: 18px; display: flex; align-items: center; margin: 0; `; const Link = styled.a` font-family: ${fonts.SANS_SERIF}; font-size: 11px; text-decoration: none; font-weight: 600; color: ${colors.primary.CIVIL_BLUE_1}; `; const ToolTipLink = styled.a` color: ${colors.basic.WHITE}; `; export const TransactionPopUpWarning = styled.p` && { color: ${colors.accent.CIVIL_GRAY_2}; font-size: 12px; } `; const ButtonWrapper = styled.div` max-width: 200px; `; export class DetailTransactionButton extends React.Component< DetailTransactionButtonProps, DetailTransactionButtonState > { constructor(props: DetailTransactionButtonProps) { super(props); this.state = { price: 0, priceFailed: false, isProgressModalVisible: false, currentNetwork: "", }; this.divinePrice = debounce(this.divinePrice.bind(this), 1000); } public async componentWillReceiveProps(nextProps: DetailTransactionButtonProps): Promise { await this.divinePrice(nextProps.estimateFunctions); } public async divinePrice(estimateFunctions?: Array<() => Promise>): Promise { if (!this.isDisabled() && estimateFunctions && estimateFunctions.length) { try { const gas = (await Promise.all(estimateFunctions.map(async item => item()))).reduce( (acc: number, item: number) => acc + item, 0, ); const gasPrice = await this.props.civil!.getGasPrice(); this.setState({ price: gasPrice .mul(this.props.civil!.toBigNumber(gas)) .div(this.props.civil!.toBigNumber(10).pow(18)) .toNumber(), priceFailed: false, }); } catch (error) { this.setState({ priceFailed: true }); } } else { this.setState({ priceFailed: true }); } } public async componentDidMount(): Promise { this.createEthereumSubscription(this.props.civil); await this.divinePrice(this.props.estimateFunctions); } public async componentWillUnmount(): Promise { this.unbscribeEthereum(); } public createEthereumSubscription(civil?: Civil): void { this.unbscribeEthereum(); let subscription: Subscription | undefined; if (civil) { subscription = civil.accountStream .subscribe(currentAccount => this.setState({ currentAccount })) .add(civil.networkNameStream.subscribe(currentNetwork => this.setState({ currentNetwork }))); } this.setState({ ethereumUpdates: subscription, }); } public unbscribeEthereum(): void { if (this.state.ethereumUpdates) { this.state.ethereumUpdates.unsubscribe(); } } public render(): JSX.Element { const TransactionButtonComponent = this.props.noModal ? TransactionButtonNoModal : TransactionButton; return ( {this.renderDetails()} {this.props.children} This will open a new window to confirm and process your transaction. ); } public isDisabled(): boolean { const onRequiredNetwork = !this.props.requiredNetwork || this.props.requiredNetwork.includes(this.state.currentNetwork); return this.props.disabled || !this.props.civil || !this.state.currentAccount || !onRequiredNetwork; } public renderNoMetaMask(): JSX.Element { return ( Set up your MetaMask wallet Download the MetaMask browser plugin and follow the instructions to set up your wallet. Get MetaMask ); } public renderMetaMaskLocked(): JSX.Element { return ( MetaMask is locked Please unlock MetaMask to create a newsroom contract ); } public renderWrongNetwork(): JSX.Element { return ( MetaMask is on the wrong network Please change your network to the {this.props.requiredNetwork!.replace(/^\w/, c => c.toUpperCase())} Network before proceeding ); } public renderCostsEstimates(): JSX.Element { if (this.state.price === 0 && !this.state.priceFailed) { return Estimating cost.; } else if (this.state.priceFailed) { return Could not estimate cost.; } else { return ETH: {this.state.price.toFixed(5)}; } } public renderTransactionDetails(): JSX.Element { return ( Estimated Cost{" "} Current Prices based on{" "} {"https://ethgasstation.info/"} } /> {this.renderCostsEstimates()} ); } public renderDetails(): JSX.Element { if (!this.props.civil) { return this.renderNoMetaMask(); } else if (!this.state.currentAccount) { return this.renderMetaMaskLocked(); } else if (this.props.requiredNetwork && this.props.requiredNetwork !== this.state.currentNetwork) { return this.renderWrongNetwork(); } else { return this.renderTransactionDetails(); } } } ================================================ FILE: packages/components/src/DetailsButtonComponent.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { buttonSizes } from "./Button"; const Wrapper = styled.div` display: flex; flex-direction: row; justify-content: space-between; align-items: center; `; const DetailsSection = styled.div` width: 50%; `; export interface DetailsButtonComponentProps { detailsComponent: JSX.Element | undefined; buttonComponent: JSX.Element | undefined; } export class DetailsButtonComponent extends React.Component { public render(): JSX.Element { return ( {this.props.detailsComponent} {this.renderButtonComponent()} ); } private renderButtonComponent = (): JSX.Element => { return React.cloneElement(this.props.buttonComponent as React.ReactElement, { size: buttonSizes.SMALL, }); }; } ================================================ FILE: packages/components/src/EmailSignup/EmailSignup.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { EmailSignup } from "./EmailSignup"; import { EmailSignupSuccess } from "./EmailSignupSuccess"; import { addToMailingList } from "@joincivil/utils"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 400px; `; const Container: React.FunctionComponent = ({ children }) => {children}; let email: string; function onChange(name: string, value: string): void { if (name === "EmailSignupTextInput") { email = value; } } async function onSubmit(): Promise { console.log("On Submit", email); try { await addToMailingList(email, "5353193"); } catch (err) { console.error("Error adding to mailing list:", { err }); } } storiesOf("Registry / Mailing List Signup Component", module) .add("Mailing List Signup Signup", () => { return ( ); }) .add("Mailing List Signup Success", () => { return ( ); }); ================================================ FILE: packages/components/src/EmailSignup/EmailSignup.tsx ================================================ import * as React from "react"; import { BellIcon } from "../icons"; import { Button, buttonSizes } from "../Button"; import { InputGroup } from "../input"; import { StyledEmailSignupContainer, StyledEmailSignupTitle, StyledEmailSignupCopy } from "./EmailStyledComponents"; export interface EmailSignupProps { email?: string; errorMessage?: string; isRequestPending?: boolean; onChange(key: string, value: string): void; onSubmit(): void; } export const EmailSignup: React.FunctionComponent = props => { const SignUpButton = ( ); const { email, errorMessage } = props; return ( Get the Civil Registry Alerts Receive real-time email alerts when a new event occurs on the Civil Registry. These events include new applications, challenges, when voting begins / ends and more. By subscribing, you'll ensure you have maximum time to make decisions about how you will participate in Civil's governance. Follow us on twitter for alerts{" "} @Civil_Alerts ); }; ================================================ FILE: packages/components/src/EmailSignup/EmailSignupSuccess.tsx ================================================ import * as React from "react"; import { GreenCheckMark } from "../icons"; import { StyledEmailSignupSuccessContainer, StyledEmailSignupTitle, StyledEmailSignupCopy, } from "./EmailStyledComponents"; export const EmailSignupSuccess: React.FunctionComponent = props => { return ( Thanks for signing up! Please check your email to confirm your subscription. Follow us on twitter for alerts{" "} @Civil_Alerts ); }; ================================================ FILE: packages/components/src/EmailSignup/EmailStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export const StyledEmailSignupTitle = styled.div` color: ${colors.primary.BLACK}; font-size: 24px; font-weight: 900; line-height: 29px; margin: 0 0 6px; `; export const StyledEmailSignupCopy = styled.p` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 14px; letter-spacing: -0.09px; line-height: 20px; `; export const StyledEmailSignupContainer = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; box-shadow: inset 0 5px 0 0 ${colors.primary.BLACK}; padding: 38px 39px 24px; `; export const StyledEmailSignupSuccessContainer = styled(StyledEmailSignupContainer)` padding-top: 92px; text-align: center; & > ${StyledEmailSignupCopy}:first-of-type { font-size: 18px; letter-spacing: normal; line-height: 33px; margin: 0 0 133px; } `; ================================================ FILE: packages/components/src/EmailSignup/__snapshots__/EmailSignup.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Mailing List Signup Component Mailing List Signup Signup 1`] = `
Get the Civil Registry Alerts

Receive real-time email alerts when a new event occurs on the Civil Registry. These events include new applications, challenges, when voting begins / ends and more. By subscribing, you'll ensure you have maximum time to make decisions about how you will participate in Civil's governance.

Follow us on twitter for alerts @Civil_Alerts

Registry / Mailing List Signup Component

Mailing List Signup Signup

Story Source

            
< Container >
< EmailSignup onChange = { onChange } onSubmit = { onSubmit } />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" EmailSignup " Component

No propTypes defined!
`; exports[`Storyshots Registry / Mailing List Signup Component Mailing List Signup Success 1`] = `
Thanks for signing up!

Please check your email to confirm your subscription.

Follow us on twitter for alerts @Civil_Alerts

Registry / Mailing List Signup Component

Mailing List Signup Success

Story Source

            
< Container >
< EmailSignupSuccess />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" EmailSignupSuccess " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/EmailSignup/index.ts ================================================ export * from "./EmailSignup"; export * from "./EmailSignupSuccess"; ================================================ FILE: packages/components/src/EthAddressViewer/EthAddressViewer.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { EthAddressViewer } from "./EthAddressViewer"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 690px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Common / Ethereum / EthAddress Viewer", module).add("EthAddress Viewer", () => { return ( ); }); ================================================ FILE: packages/components/src/EthAddressViewer/EthAddressViewer.tsx ================================================ import * as React from "react"; import { copyToClipboard } from "@joincivil/utils"; import { colors } from "../styleConstants"; import { Button, InvertedButton, buttonSizes } from "../Button"; import { NorthEastArrow } from "../icons"; import { StyledEthAddressViewer, StyledDisplayName, StyledEthAddressContainer, StyledEthAddress, } from "./StyledEthAddressViewer"; export interface EthAddressViewerProps { address: string; displayName: string | JSX.Element; etherscanBaseURL?: string; } export const EthAddressViewer: React.FunctionComponent = props => { const { address, displayName, etherscanBaseURL } = props; const etherscanURL = etherscanBaseURL && `${etherscanBaseURL}/address/${address.replace(/ /g, "")}`; return ( {displayName} {props.address} {!!etherscanURL && ( Etherscan )} ); }; ================================================ FILE: packages/components/src/EthAddressViewer/StyledEthAddressViewer.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Button, InvertedButton } from "../Button"; import { colors, fonts, mediaQueries } from "../styleConstants"; export const StyledEthAddressViewer = styled.div` font-family: ${fonts.SANS_SERIF}; margin: 0 0 30px; `; export const StyledDisplayName = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 13px; font-weight: 500; letter-spacing: -0.14px; line-height: 21px; margin: 0 0 10px; `; export const StyledEthAddressContainer = styled.div` display: flex; ${mediaQueries.MOBILE} { display: block; } & > ${Button} { margin: 0 12px; } & > ${InvertedButton} { line-height: 28px; } ${mediaQueries.MOBILE} { display: block; & > ${Button} { margin: 10px 12px 0 0; line-height: 32px; width: 57%; } & > ${InvertedButton} { margin: 10px 0 0; } } `; export const StyledEthAddress = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_0}; font-family: ${fonts.MONOSPACE}; font-size: 14px; letter-spacing: -0.15px; line-height: 24px; padding: 11px 12px; `; ================================================ FILE: packages/components/src/EthAddressViewer/__snapshots__/EthAddressViewer.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Ethereum / EthAddress Viewer EthAddress Viewer 1`] = `
CVL Token Contract Address
0x 3e39 fa98 3abc d349 d95a ed60 8e79 8817 397c f0d1
Etherscan

Common / Ethereum / EthAddress Viewer

EthAddress Viewer

Story Source

            
< Container >
< EthAddressViewer address = " 0x 3e39 fa98 3abc d349 d95a ed60 8e79 8817 397c f0… " displayName = " CVL Token Contract Address " etherscanBaseURL = " https://rinkeby.etherscan.io " />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" EthAddressViewer " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/EthAddressViewer/index.ts ================================================ export * from "./EthAddressViewer"; ================================================ FILE: packages/components/src/ExecuteOnMount.tsx ================================================ import * as React from "react"; export interface ExecuteOnMountProps { onDidMount(): any; } export class ExecuteOnMount extends React.Component { public async componentDidMount(): Promise { const { onDidMount } = this.props; if (!onDidMount) { return; } onDidMount(); } public render(): JSX.Element { return <>{this.props.children}; } } ================================================ FILE: packages/components/src/FullscreenModal.tsx ================================================ import * as React from "react"; import * as ReactDom from "react-dom"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "@joincivil/elements"; export interface ModalWrapperProps { solidBackground?: boolean; } export const ModalWrapper = styled.div` align-items: ${(props: ModalWrapperProps) => (props.solidBackground ? "flex-start" : "center")}; background-color: ${(props: ModalWrapperProps) => props.solidBackground ? colors.basic.WHITE : "rgba(0, 0, 0, 0.4)"}; bottom: 0; display: flex; justify-content: center; left: 0; padding: ${(props: ModalWrapperProps) => (props.solidBackground ? "90px 0" : "0")}; position: fixed; overflow: auto; right: 0; top: 0; z-index: ${(props: ModalWrapperProps) => (props.solidBackground ? "9999999" : "2")}; ${mediaQueries.MOBILE_SMALL} { display: block; } `; export const ModalInner = styled.div` align-items: ${(props: ModalWrapperProps) => (props.solidBackground ? "flex-start" : "center")}; background-color: ${colors.basic.WHITE}; border: ${(props: ModalWrapperProps) => (props.solidBackground ? "none" : "1px solid " + colors.accent.CIVIL_GRAY_4)}; display: flex; flex-direction: column; font-family: ${fonts.SANS_SERIF}; justify-content: space-around; margin: auto; min-width: 250px; ${(props: ModalWrapperProps) => (props.solidBackground ? "width: 100%" : "")}; ${mediaQueries.MOBILE_SMALL} { bottom: 0; left: 0; overflow: auto; position: fixed; top: 54px; width: 100%; } `; export interface FullScreenModalProps { solidBackground?: boolean; open: boolean; dismissOnOutsideClick?: boolean; className?: string; handleClose?(): void; } export class FullScreenModal extends React.Component { public el: HTMLDivElement | undefined; constructor(props: FullScreenModalProps) { super(props); this.state = {}; if (typeof document !== "undefined") { this.el = document.createElement("div"); } this.handleClickOutside = this.handleClickOutside.bind(this); } public componentDidMount(): void { if (this.el) { document.body.appendChild(this.el); if (this.props.dismissOnOutsideClick) { document.addEventListener("mousedown", ev => this.handleClickOutside(ev)); } } } public componentWillUnmount(): void { if (this.el) { document.body.removeChild(this.el); document.removeEventListener("mousedown", ev => this.handleClickOutside(ev)); } } public render(): React.ReactPortal | JSX.Element | null { if (!this.props.open || this.el === undefined) { return null; } return ReactDom.createPortal( {this.props.children} , this.el, ); } private handleClickOutside(event: any): void { if ( this.el && this.el.children[0] && this.el.children[0].children[0] && !this.el.children[0].children[0].contains(event.target) ) { this.close(); } } private close(): void { if (this.props.handleClose) { this.props.handleClose(); } } } ================================================ FILE: packages/components/src/GasEstimate.tsx ================================================ import * as React from "react"; import { Civil } from "@joincivil/core"; import { fonts, colors } from "./styleConstants"; import styled from "styled-components"; export interface GasEstimateProps { civil: Civil; estimateFunctions: Array<() => Promise>; } export interface GasEstimateState { price: number; priceFailed: boolean; } const SmallText = styled.p` font-family: ${fonts.SANS_SERIF}; color: ${colors.accent.CIVIL_GRAY_2}; font-size: 13px; line-height: 18px; display: flex; align-items: center; margin: 0; `; export class GasEstimate extends React.Component { constructor(props: GasEstimateProps) { super(props); this.state = { price: 0, priceFailed: false, }; } public async componentDidMount(): Promise { await this.divinePrice(this.props.estimateFunctions); } public async divinePrice(estimateFunctions?: Array<() => Promise>): Promise { if (estimateFunctions && estimateFunctions.length) { try { const gas = (await Promise.all(estimateFunctions.map(async item => item()))).reduce( (acc: number, item: number) => acc + item, 0, ); const gasPrice = await this.props.civil!.getGasPrice(); this.setState({ price: gasPrice .mul(this.props.civil!.toBigNumber(gas)) .div(this.props.civil!.toBigNumber(10).pow(18)) .toNumber(), priceFailed: false, }); } catch (error) { console.error(error); this.setState({ priceFailed: true }); } } else { this.setState({ priceFailed: true }); } } public render(): JSX.Element { if (this.state.price === 0 && !this.state.priceFailed) { return Estimating cost...; } else if (this.state.priceFailed) { return Could not estimate cost.; } else { return ETH: {this.state.price.toFixed(5)}; } } } ================================================ FILE: packages/components/src/Heading.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Heading, SubHeading, SectionHeading, BlockHeading } from "./Heading"; const StyledDiv = styled.div` display: flex; width: 200px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Pattern Library / Typography / Headings", module).add("Headings", () => { return ( Heading Sub Heading Section Heading Block Heading ); }); ================================================ FILE: packages/components/src/Heading.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { fonts, colors } from "./styleConstants"; const headingDefaultProps = { theme: { sansSerifFont: fonts.SANS_SERIF, serifFont: fonts.SERIF, }, }; export const Heading = styled.h1` font-family: ${props => props.theme.serifFont}; font-size: 24px; font-weight: 300; margin: 5px 0; `; Heading.defaultProps = headingDefaultProps; export const SectionHeading = styled.h1` font-family: ${props => props.theme.serifFont}; font-size: 22px; font-weight: 700; margin: 15px 0; `; SectionHeading.defaultProps = headingDefaultProps; export const SubHeading = styled.h2` font-family: ${props => props.theme.serifFont}; font-weight: 200; font-size: 20px; margin: 0; `; SubHeading.defaultProps = headingDefaultProps; export const BlockHeading = styled.h3` font-family: ${props => props.theme.sansSerifFont}; font-weight: 600; font-size: 15px; text-transform: uppercase; margin: 0; `; BlockHeading.defaultProps = headingDefaultProps; export const ManagerHeading = styled.h3` font-family: ${props => props.theme.sansSerifFont}; font-weight: 600; font-size: 18px; `; ManagerHeading.defaultProps = headingDefaultProps; export const ManagerSectionHeading = styled.h4` font-family: ${props => props.theme.sansSerifFont}; font-weight: 500; font-size: 17px; `; ManagerSectionHeading.defaultProps = headingDefaultProps; export const PageHeadingCentered = styled.h2` font-family: ${fonts.SANS_SERIF}; font-weight: 800; font-size: 28px; line-height: 34px; letter-spacing: -0.58px; margin: 8px 0; text-align: center; `; export const PageHeadingLeftAligned = styled.h2` font-family: ${fonts.SANS_SERIF}; font-weight: 800; font-size: 28px; line-height: 50px; letter-spacing: -0.58px; margin: 0; text-align: left; `; PageHeadingCentered.defaultProps = headingDefaultProps; export const PageSubHeadingCentered = styled.h2` font-family: ${fonts.SANS_SERIF}; font-weight: 500; font-size: 21px; font-weight: bold; line-height: 50px; text-align: center; `; PageSubHeadingCentered.defaultProps = headingDefaultProps; export const PageHeadingTextCentered = styled.div` text-align: center; color: ${colors.primary.CIVIL_GRAY_0}; font-size: 16px; line-height: 25px; font-family: ${props => props.theme.sansSerifFont}; padding: 10px 0; `; export const PageHeadingTextLeftAligned = styled.div` text-align: left; color: ${colors.primary.CIVIL_GRAY_0}; font-size: 16px; line-height: 25px; font-family: ${props => props.theme.sansSerifFont}; padding: 10px 0; `; export const PageHeadingTextCenteredLarge = styled(PageHeadingTextCentered)` font-size: 16px; line-height: 24px; `; export const PageHeadingTextCenteredSmall = styled(PageHeadingTextCentered)` font-size: 14px; line-height: 20px; color: ${colors.primary.CIVIL_GRAY_0}; `; ================================================ FILE: packages/components/src/HelmetHelper.tsx ================================================ import * as React from "react"; import { Helmet } from "react-helmet"; export interface HelmetHelperProps { title?: string; description?: string; image?: string; meta?: { [key: string]: string }; } export const HelmetHelper: React.FunctionComponent = props => { const meta: { [key: string]: string | undefined } = { "og:title": props.title, "twitter:title": props.title, "og:description": props.description, "twitter:description": props.description, "og:image": props.image, "twitter:image": props.image, ...props.meta, }; return ( {Object.keys(meta).map( metaName => meta[metaName] && , )} ); }; ================================================ FILE: packages/components/src/Hero/Hero.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import StoryRouter from "storybook-react-router"; import * as React from "react"; import { Hero } from "./Hero"; import { HomepageHero } from "./HomepageHero"; import heroImgUrl from "./img-hero-listings.png"; storiesOf("Registry / Hero", module) .addDecorator(StoryRouter()) .add("Homepage", () => { return ( ); }); ================================================ FILE: packages/components/src/Hero/Hero.tsx ================================================ import * as React from "react"; import { HeroOuter, HeroInner } from "./HeroStyledComponents"; export interface HeroProps { backgroundImage?: string; } export class Hero extends React.Component { public render(): JSX.Element { return ( {this.props.children} ); } } ================================================ FILE: packages/components/src/Hero/HeroStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { DarkButton } from "../Button"; import { HeroProps } from "./Hero"; export const HeroOuter = styled.div` background-color: ${colors.primary.BLACK}; background-image: ${(props: HeroProps) => (props.backgroundImage ? "url(" + props.backgroundImage + ")" : "none")}; background-repeat: no-repeat; background-size: cover; font-family: ${fonts.SANS_SERIF}; padding: 78px 15px 32px; ${mediaQueries.MOBILE} { display: none; } `; export const HeroInner = styled.div` align-items: center; color: ${colors.basic.WHITE}; display: flex; flex-direction: column; margin: 0 auto; max-width: 920px; text-align: center; width: 100%; `; export const StyledHeroHeading = styled.h2` font-family: ${fonts.SERIF}; font-size: 48px; font-weight: 200; letter-spacing: -1px; line-height: 40px; margin: 0 auto 10px; `; export const StyledHeroCopy = styled.div` font-size: 18px; letter-spacing: -0.12px; line-height: 33px; margin: 0 0 40px; text-align: center; p { margin: 0 0 18px; } a { color: ${colors.basic.WHITE}; border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_3}; } `; export const StyledButtonContainer = styled.div` display: flex; justify-content: center; `; export const CTAButton = styled(DarkButton)` border: 2px solid ${colors.basic.WHITE}; font-size: 14px; font-weight: bold; letter-spacing: 1px; margin-left: 30px; text-align: center; width: 180px; &:hover { background: ${colors.basic.WHITE}; color: ${colors.primary.BLACK}; } `; export const StyledExplore = styled.div` color: ${colors.accent.CIVIL_GRAY_3}; font-size: 12px; font-weight: bold; line-height: 15px; text-transform: uppercase; text-align: center; margin: 88px 0 0; div { margin: 12px 0 0; } `; ================================================ FILE: packages/components/src/Hero/HeroTextComponents.tsx ================================================ import * as React from "react"; import { HomepageHeroProps } from "./HomepageHero"; export const HeroTitleText: React.FunctionComponent = props => <>The Civil Registry; export const HeroCopyText: React.FunctionComponent = props => ( <>

A community-driven space for curating quality journalism.

Use Civil tokens to apply, challenge and vote on which newsrooms can publish on the Civil platform.{" "} Learn how .

); export const ExploreTCRText: React.FunctionComponent = props => <>Explore The Civil Registry; ================================================ FILE: packages/components/src/Hero/HomepageHero.tsx ================================================ import * as React from "react"; import { buttonSizes } from "../Button"; import { ExpandDownArrow } from "../icons"; import { StyledHeroHeading, StyledHeroCopy, StyledExplore, StyledButtonContainer, CTAButton, } from "./HeroStyledComponents"; import { HeroTitleText, HeroCopyText, ExploreTCRText } from "./HeroTextComponents"; export interface HomepageHeroProps { buyCvlUrl: string; applyURL: string; learnMoreURL: string; } export const HomepageHero: React.FunctionComponent = props => { const { buyCvlUrl, applyURL } = props; let buyBtnProps: any = { href: buyCvlUrl }; if (buyCvlUrl.charAt(0) === "/") { buyBtnProps = { to: buyCvlUrl }; } let applyBtnProps: any = { href: applyURL }; if (applyURL.charAt(0) === "/") { applyBtnProps = { to: applyURL }; } return ( <> Join as a member Join as a newsroom
); }; ================================================ FILE: packages/components/src/Hero/__snapshots__/Hero.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Hero Homepage 1`] = `

The Civil Registry

A community-driven space for curating quality journalism.

Use Civil tokens to apply, challenge and vote on which newsrooms can publish on the Civil platform. Learn how .

Explore The Civil Registry

Registry / Hero

Homepage

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Hero/index.ts ================================================ export * from "./HomepageHero"; export * from "./Hero"; ================================================ FILE: packages/components/src/Layout/index.ts ================================================ export * from "./styledComponents"; ================================================ FILE: packages/components/src/Layout/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { mediaQueries } from "../styleConstants"; export interface ContentRowProps { reverseDirection?: boolean; } export interface ContentWellProps { offsetTop?: number; } export const StyledMainContainer = styled.div` margin-top: 74px; ${mediaQueries.MOBILE} { margin-top: 52px; } `; export const StyledContentRow = styled.div` display: flex; flex-direction: ${(props: ContentRowProps) => (props.reverseDirection ? "row-reverse" : "row")}; margin: 0 auto; width: 1110px; ${mediaQueries.MOBILE} { display: block; margin: 0; width: auto; } `; export const StyledLeftContentWell = styled.div` width: 636px; ${(props: ContentWellProps) => (props.offsetTop ? `margin-top: ${props.offsetTop.toString()}px` : "")}; ${mediaQueries.MOBILE} { margin: 0 16px; width: auto; } `; export const StyledRightContentWell = styled.div` margin-left: 31px; ${(props: ContentWellProps) => (props.offsetTop ? `margin-top: ${props.offsetTop.toString()}px` : "")}; width: 440px; ${mediaQueries.MOBILE} { margin: 0 16px; ${(props: ContentWellProps) => (props.offsetTop ? `margin-top: ${(props.offsetTop / 2).toString()}px` : "")}; width: auto; } `; ================================================ FILE: packages/components/src/ListingDetailHeader/EthereumInfoModal.tsx ================================================ import * as React from "react"; import { EthAddress } from "@joincivil/typescript-types"; import { EthAddressViewer } from "../EthAddressViewer"; import { Modal } from "../Modal"; import { CloseXIcon } from "../icons"; import { colors } from "../styleConstants"; import { StyledEthereumInfoModalInner, StyledEthereumAddressDescription, StyledModalHeader, StyledCloseModal, } from "./ListingDetailHeaderStyledComponents"; export interface EthereumInfoModalProps { listingAddress: EthAddress; owner: EthAddress; etherscanBaseURL: string; ethInfoModalLearnMoreURL: string; handleCloseClick(): void; } const EthereumInfoModal: React.FunctionComponent = props => { return (
Ethereum Info

This public wallet address is the Newsroom's identity on the blockchain.

You can send CVL and ETH to this wallet address.

Smart contract address allow you to see the Newsroom's activities on the blockchain.

Do not send CVL or ETH to this contract address. You will lose your cryptocurrency, and the Civil Media Company can not help you to retrieve it.{" "} Learn more .

); }; export default EthereumInfoModal; ================================================ FILE: packages/components/src/ListingDetailHeader/ListingDetailHeader.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { CharterData } from "@joincivil/typescript-types"; import { ListingDetailHeader, ListingDetailHeaderProps } from "./ListingDetailHeader"; const StyledDiv = styled.div` display: flex; width: 100vh; height: 100vw; background-color: #fff; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); const charter = { tagline: "Civil is the decentralized marketplace for sustainable journalism.", newsroomUrl: "https://civil.co", }; storiesOf("Registry / Listing / Listing Details Header", module) .add("No phase label", () => { const props: ListingDetailHeaderProps = { listingAddress: "0x0", newsroomName: "The Civil Times", charter: charter as CharterData, owner: "0x0", etherscanBaseURL: "https://rinkeby.etherscan.io", ethInfoModalLearnMoreURL: "#faq", unstakedDeposit: "100 CVL", isInApplication: false, inChallengeCommitVotePhase: false, inChallengeRevealPhase: false, }; return ( ); }) .add("In Application", () => { const props: ListingDetailHeaderProps = { listingAddress: "0x0", newsroomName: "The Civil Times", charter: charter as CharterData, owner: "0x0", unstakedDeposit: "100 CVL", etherscanBaseURL: "https://rinkeby.etherscan.io", ethInfoModalLearnMoreURL: "#faq", isInApplication: true, inChallengeCommitVotePhase: false, inChallengeRevealPhase: false, }; return ( ); }) .add("Accepting Votes", () => { const props: ListingDetailHeaderProps = { listingAddress: "0x0", newsroomName: "The Civil Times", charter: charter as CharterData, owner: "0x0", unstakedDeposit: "100 CVL", etherscanBaseURL: "https://rinkeby.etherscan.io", ethInfoModalLearnMoreURL: "#faq", isInApplication: false, inChallengeCommitVotePhase: true, inChallengeRevealPhase: false, }; return ( ); }) .add("Revealing Votes", () => { const props: ListingDetailHeaderProps = { listingAddress: "0x0", newsroomName: "The Civil Times", charter: charter as CharterData, owner: "0x0", etherscanBaseURL: "https://rinkeby.etherscan.io", ethInfoModalLearnMoreURL: "#faq", unstakedDeposit: "100 CVL", isInApplication: false, inChallengeCommitVotePhase: false, inChallengeRevealPhase: true, }; return ( ); }); ================================================ FILE: packages/components/src/ListingDetailHeader/ListingDetailHeader.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { CharterData } from "@joincivil/typescript-types"; import { NorthEastArrow, TwitterIcon, FacebookIcon } from "../icons"; import { buttonSizes } from "../Button"; import { StyledContentRow } from "../Layout"; import ListingPhaseLabel from "../ListingSummary/ListingPhaseLabel"; import { colors } from "../styleConstants"; import defaultNewsroomImgUrl from "../images/img-default-newsroom@2x.png"; import { ListingDetailOuter, StyledListingDetailHeader, StyledNewsroomIcon, StyledNewsroomLogo, StyledEthereumInfoToggle, ListingDetailNewsroomName, ListingDetailNewsroomDek, StyledRegistryLinkContainer, NewsroomLinks, VisitNewsroomButtonWrap, FollowNewsroom, FollowNewsroomHeading, FollowNewsroomLink, StyledListingURLButton, } from "./ListingDetailHeaderStyledComponents"; import EthereumInfoModal from "./EthereumInfoModal"; export interface ListingDetailHeaderProps { listingAddress: string; logoURL?: string; newsroomName: string; charter?: CharterData; registryURL?: string; registryLinkText?: string; owner: string; etherscanBaseURL: string; unstakedDeposit: string; isWhitelisted?: boolean; isRejected?: boolean; isInApplication?: boolean; canBeChallenged?: boolean; canBeWhitelisted?: boolean; inChallengeCommitVotePhase?: boolean; inChallengeRevealPhase?: boolean; canResolveChallenge?: boolean; isAwaitingAppealJudgement?: boolean; isAwaitingAppealChallenge?: boolean; isInAppealChallengeCommitPhase?: boolean; isInAppealChallengeRevealPhase?: boolean; canListingAppealChallengeBeResolved?: boolean; ethInfoModalLearnMoreURL: string; } export interface ListingDetailHeaderState { isEthereumInfoVisible: boolean; } export class ListingDetailHeader extends React.Component { public state = { isEthereumInfoVisible: false, }; public render(): JSX.Element { let newsroomDescription = ""; let newsroomUrl = ""; let logoURL; const { charter, listingAddress, owner, etherscanBaseURL, ethInfoModalLearnMoreURL } = this.props; if (charter) { newsroomDescription = charter.tagline; newsroomUrl = charter.newsroomUrl; logoURL = charter.logoUrl; } return ( {this.renderRegistryLink()} {logoURL && ( { (e.target as any).src = defaultNewsroomImgUrl; }} /> )}
{this.props.newsroomName} Ethereum Info {this.state.isEthereumInfoVisible && ( )} {newsroomDescription} {newsroomUrl && ( {newsroomUrl} )} {this.props.charter && this.props.charter.socialUrls && (this.props.charter.socialUrls.facebook || this.props.charter.socialUrls.twitter) && ( Follow Newsroom {this.props.charter.socialUrls.twitter && ( )} {this.props.charter.socialUrls.facebook && ( )} )}
); } private toggleEthereumInfoDisplay = (): void => { this.setState({ isEthereumInfoVisible: !this.state.isEthereumInfoVisible }); }; private renderRegistryLink(): JSX.Element | undefined { if (!this.props.registryURL) { return; } const label = this.props.registryLinkText || "Registry"; return ( < Back to {label} ); } } ================================================ FILE: packages/components/src/ListingDetailHeader/ListingDetailHeaderStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { Button, DarkButton } from "../Button"; import { StyledDisplayName, StyledEthAddressContainer, StyledEthAddress, } from "../EthAddressViewer/StyledEthAddressViewer"; export const ListingDetailOuter = styled.div` background: ${colors.primary.BLACK}; display: flex; justify-content: center; `; export const StyledListingDetailHeader = styled.div` color: ${colors.basic.WHITE}; font-family: ${fonts.SANS_SERIF}; padding: 24px 0 62px; ${mediaQueries.MOBILE} { padding: 30px 20px 42px; } `; export const StyledNewsroomIcon = styled.figure` margin: 0 30px 0 0; min-width: 130px; padding-top: 50px; ${mediaQueries.MOBILE} { margin: 45px auto; padding: 0; } `; export const StyledNewsroomLogo = styled.span` img { height: 130px; min-width: 130px; min-height: 130px; object-fit: contain; width: 130px; background: ${colors.basic.WHITE}; } `; export const StyledEthereumInfoToggle = styled(DarkButton)` background: ${colors.accent.CIVIL_GRAY_0}; color: ${colors.accent.CIVIL_GRAY_4}; cursor: pointer; font-size: 12px; font-weight: bold; letter-spacing: normal; line-height: 15px; padding: 4px 12px; margin: 0 0 14px; white-space: nowrap; `; export const StyledListingURLButton = styled(DarkButton)` border: 1px solid ${colors.accent.CIVIL_GRAY_1}; font-size: 13px; font-weight: bold; letter-spacing: 0.2px; line-height: 14px; padding: 15px 21px; white-space: nowrap; svg { margin: 0 0 -2px 3px; } `; export const StyledModalHeader = styled.div` color: ${colors.primary.BLACK}; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 18px; line-height: 24px; justify-content: space-between; `; export const StyledCloseModal = styled.span` cursor: pointer; margin-top: -10px; `; export const StyledEthereumInfoModalInner = styled.div` display: flex; & ~ & { border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding-top: 26px; } & > div { width: 48%; } ${mediaQueries.MOBILE} { display: block; & > div { width: 100%; } } ${StyledDisplayName} { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 16px; font-weight: bold; line-height: 26px; } ${StyledEthAddressContainer} { flex-wrap: wrap; width: 100%; } ${StyledEthAddress} { margin: 0 0 17px; width: 100%; } ${Button} { margin: 0 12px 0 0; padding: 16px 0; width: 133px; } `; export const StyledEthereumAddressDescription = styled.div` font-size: 14px; font-family: ${fonts.SANS_SERIF}; line-height: 22px; margin-left: 28px; padding-top: 28px; p { margin: 0 0 14px; } ${mediaQueries.MOBILE} { margin-left: 0; } `; export const ListingDetailNewsroomName = styled.h1` font: 200 48px/40px ${fonts.SERIF}; letter-spacing: -0.19px; margin: 0 0 18px; ${mediaQueries.MOBILE} { font-size: 32px; letter-spacing: -0.12px; line-height: 36px; } `; export const ListingDetailNewsroomDek = styled.p` font: normal 21px/35px ${fonts.SANS_SERIF}; font-weight: 300; letter-spacing: -0.11px; margin: 0 0 35px; ${mediaQueries.MOBILE} { font-size: 16px; letter-spacing: -0.11px; line-height: 26px; margin: 0 0 32px; } `; export const StyledRegistryLinkContainer = styled.div` padding: 0 0 43px; & a { color: ${colors.basic.WHITE}B3; } `; export const NewsroomLinks = styled.div` display: flex; margin-top: 40px; ${mediaQueries.MOBILE} { display: block; padding-bottom: 20px; } `; export const VisitNewsroomButtonWrap = styled.div` line-height: 32px; margin-right: 45px; ${mediaQueries.MOBILE} { width: 100%; } `; export const FollowNewsroom = styled.div` display: inline-block; width: 50%; ${mediaQueries.MOBILE} { width: 100%; } `; export const FollowNewsroomHeading = styled.h5` margin-bottom: 10px; font: 500 14px/14px ${fonts.SANS_SERIF}; letter-spacing: 1px; color: ${colors.basic.WHITE}; text-transform: uppercase; `; export const FollowNewsroomLink = styled.a` margin-right: 20px; `; ================================================ FILE: packages/components/src/ListingDetailHeader/__snapshots__/ListingDetailHeader.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Listing / Listing Details Header Accepting Votes 1`] = `
Submit Vote

The Civil Times

Civil is the decentralized marketplace for sustainable journalism.

Registry / Listing / Listing Details Header

Accepting Votes

Story Source

            
< Container >
< ListingDetailHeader
  
listingAddress = " 0x0 "

  
newsroomName = " The Civil Times "

  
charter = { { tagline : 'Civil is the decentralized marketplace for sustain…' , newsroomUrl : 'https://civil.co' } }

  
owner = " 0x0 "

  
unstakedDeposit = " 100 CVL "

  
etherscanBaseURL = " https://rinkeby.etherscan.io "

  
ethInfoModalLearnMoreURL = " #faq "

  
isInApplication = { false }

  
inChallengeCommitVotePhase

  
inChallengeRevealPhase = { false }
/>
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ListingDetailHeader " Component

No propTypes defined!
`; exports[`Storyshots Registry / Listing / Listing Details Header In Application 1`] = `
Awaiting Approval

The Civil Times

Civil is the decentralized marketplace for sustainable journalism.

Registry / Listing / Listing Details Header

In Application

Story Source

            
< Container >
< ListingDetailHeader
  
listingAddress = " 0x0 "

  
newsroomName = " The Civil Times "

  
charter = { { tagline : 'Civil is the decentralized marketplace for sustain…' , newsroomUrl : 'https://civil.co' } }

  
owner = " 0x0 "

  
unstakedDeposit = " 100 CVL "

  
etherscanBaseURL = " https://rinkeby.etherscan.io "

  
ethInfoModalLearnMoreURL = " #faq "

  
isInApplication

  
inChallengeCommitVotePhase = { false }

  
inChallengeRevealPhase = { false }
/>
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ListingDetailHeader " Component

No propTypes defined!
`; exports[`Storyshots Registry / Listing / Listing Details Header No phase label 1`] = `

The Civil Times

Civil is the decentralized marketplace for sustainable journalism.

Registry / Listing / Listing Details Header

No phase label

Story Source

            
< Container >
< ListingDetailHeader
  
listingAddress = " 0x0 "

  
newsroomName = " The Civil Times "

  
charter = { { tagline : 'Civil is the decentralized marketplace for sustain…' , newsroomUrl : 'https://civil.co' } }

  
owner = " 0x0 "

  
etherscanBaseURL = " https://rinkeby.etherscan.io "

  
ethInfoModalLearnMoreURL = " #faq "

  
unstakedDeposit = " 100 CVL "

  
isInApplication = { false }

  
inChallengeCommitVotePhase = { false }

  
inChallengeRevealPhase = { false }
/>
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ListingDetailHeader " Component

No propTypes defined!
`; exports[`Storyshots Registry / Listing / Listing Details Header Revealing Votes 1`] = `
Confirm Vote

The Civil Times

Civil is the decentralized marketplace for sustainable journalism.

Registry / Listing / Listing Details Header

Revealing Votes

Story Source

            
< Container >
< ListingDetailHeader
  
listingAddress = " 0x0 "

  
newsroomName = " The Civil Times "

  
charter = { { tagline : 'Civil is the decentralized marketplace for sustain…' , newsroomUrl : 'https://civil.co' } }

  
owner = " 0x0 "

  
etherscanBaseURL = " https://rinkeby.etherscan.io "

  
ethInfoModalLearnMoreURL = " #faq "

  
unstakedDeposit = " 100 CVL "

  
isInApplication = { false }

  
inChallengeCommitVotePhase = { false }

  
inChallengeRevealPhase
/>
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ListingDetailHeader " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/ListingDetailHeader/index.ts ================================================ export * from "./ListingDetailHeader"; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealAwaitingDecisionCard.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, PhaseWithExpiryProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, StyledPhaseKicker, CTACopy, MetaRow, MetaItem, MetaItemValue, MetaItemValueLong, MetaItemLabel, } from "./styledComponents"; import { WaitingCouncilDecisionToolTipText } from "./textComponents"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ProgressBarCountdownTimer } from "../PhaseCountdown/"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import NeedHelp from "./NeedHelp"; import { TextInput } from "../input"; export interface AppealProps { requester: string; appealFeePaid: string; txIdToConfirm?: number; uriValue?: string; onChange?(name: string, value: string): any; } export interface AppealAwaitingDecisionCardState { grantURI: string; } export type AppealAwaitingDecisionCardProps = ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & ChallengeResultsProps & AppealProps; const GrantAppealButton: React.FunctionComponent = props => { let text = "Grant Appeal"; if (props.txIdToConfirm) { text = "Confirm Appeal"; } return (
{!props.txIdToConfirm && } {text}
); }; export const AppealAwaitingDecisionCard: React.FunctionComponent = props => { const localDateTime = getLocalDateTimeStrings(props.endTime); return ( Challenge ID {props.challengeID} Appeal to Council } flavorText="under Appeal to Council" /> Requester {props.requester} Appeal Fee Paid {props.appealFeePaid} Check back on {localDateTime[0]} for Civil Council’s decision to reject or grant the appeal. Read more for details of this appeal. {props.transactions && } ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealChallengeCommitVoteCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, PhaseWithExpiryProps, ChallengePhaseProps, CommitVoteProps, AppealDecisionProps, AppealChallengePhaseProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, StyledCardStage, StyledCard, StyledCardClose, StyledCardFront, StyledCardBack, FormHeader, FormCopy, FullWidthButton, } from "./styledComponents"; import { CommitVoteCalloutHeaderText, AppealChallengeCommitVoteCalloutCopyText, CommitVoteAlreadyVotedHeaderText, CommitVoteAlreadyVotedCopyText, CommitVoteToolTipText, ConfirmVoteToolTipText, } from "./textComponents"; import { buttonSizes } from "../Button"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { CommitVote } from "./CommitVote"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; import NeedHelp from "./NeedHelp"; export type AppealChallengeCommitVoteCardProps = ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & ChallengeResultsProps & CommitVoteProps & AppealDecisionProps & AppealChallengePhaseProps; export interface AppealChallengeCommitVoteCardState { flipped: boolean; } export class AppealChallengeCommitVoteCard extends React.Component< AppealChallengeCommitVoteCardProps, AppealChallengeCommitVoteCardState > { constructor(props: AppealChallengeCommitVoteCardProps) { super(props); this.state = { flipped: false }; } public render(): JSX.Element { return ( Challenge ID {this.props.challengeID} Appeal Challenge ID {this.props.appealChallengeID} Challenge Appeal Decision } secondaryDisplayLabel="Confirm Vote Phase" secondaryToolTipText={} flavorText="under challenge" activePhaseIndex={0} /> {this.renderCommitVoteCallout()} {this.renderCommitVoteButtonText()} {this.renderCommitVoteCallout()} Appeal Challenge ID {this.props.appealChallengeID} ); } private swapFlipped = (): void => { this.setState(() => ({ flipped: !this.state.flipped })); }; private renderCommitVoteCallout = (): JSX.Element => { if (this.props.userHasCommittedVote) { return ( <> ); } return ( <> ); }; private renderCommitVoteButtonText = (): JSX.Element => { if (this.props.userHasCommittedVote) { return <>Change My Vote; } return <>Ready To Commit My Vote; }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealChallengeResolveCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, AppealDecisionProps, AppealChallengePhaseProps, AppealChallengeResultsProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { ReadyToCompletePhaseDisplayNameText, ResolveChallengeToolTipText } from "./textComponents"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import NeedHelp from "./NeedHelp"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; import { QuestionToolTip } from "../QuestionToolTip"; export type AppealChallengeResolveCardProps = ListingDetailPhaseCardComponentProps & ChallengePhaseProps & ChallengeResultsProps & AppealDecisionProps & AppealChallengePhaseProps & AppealChallengeResultsProps; export const AppealChallengeResolveCard: React.FunctionComponent = props => { const showAppealChallenge = props.appealChallengeTotalVotes && props.appealChallengeVotesFor && props.appealChallengeVotesAgainst && props.appealChallengePercentFor && props.appealChallengePercentAgainst; return ( Challenge ID {props.challengeID} Appeal Challenge ID {props.appealChallengeID} } positionBottom={true} /> {showAppealChallenge && ( )} This challenge is complete. To update this Newsroom's status on the Civil Registry, please resolve this appeal challenge. Resolve Appeal Challenge ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealChallengeRevealVoteCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, PhaseWithExpiryProps, ChallengePhaseProps, RevealVoteProps, AppealDecisionProps, AppealChallengePhaseProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledCardStage, StyledCard, StyledCardClose, StyledCardFront, StyledCardBack, StyledPhaseKicker, StyledPhaseDisplayName, FormHeader, FormCopy, FullWidthButton, } from "./styledComponents"; import { CommitVoteToolTipText, ConfirmVoteToolTipText, RevealVoteCallToActionHeaderText, RevealVoteCallToActionCopyText, RevealVoteDidNotCommitHeaderText, RevealVoteDidNotCommitCopyText, RevealVoteDoneHeaderText, RevealVoteDoneCopyText, RevealVoteButtonText, RevealVoteCalloutCopyText, } from "./textComponents"; import { buttonSizes } from "../Button"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { RevealVote } from "./RevealVote"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; import NeedHelp from "./NeedHelp"; export type AppealChallengeRevealVoteCardProps = ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & RevealVoteProps & ChallengeResultsProps & AppealDecisionProps & AppealChallengePhaseProps; export interface AppealChallengeRevealVoteCardState { flipped: boolean; } export class AppealChallengeRevealVoteCard extends React.Component< AppealChallengeRevealVoteCardProps, AppealChallengeRevealVoteCardState > { constructor(props: AppealChallengeRevealVoteCardProps) { super(props); this.state = { flipped: false }; } public render(): JSX.Element { return ( Challenge ID {this.props.challengeID} Appeal Challenge ID {this.props.appealChallengeID} Challenge Appeal Decision } secondaryDisplayLabel="Submit Vote Phase" secondaryToolTipText={} flavorText="under challenge" activePhaseIndex={1} /> {this.renderRevealVote()} Confirm Your Secret Vote for Appeal Challenge #{this.props.appealChallengeID} ); } private renderRevealVote = (): JSX.Element => { if (this.props.userHasCommittedVote === false) { return ( <> ); } else if (this.props.userHasRevealedVote) { return ( <> ); } else { return ( <> ); } }; private swapFlipped = (): void => { this.setState(() => ({ flipped: !this.state.flipped })); }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealDecisionCard.tsx ================================================ import * as React from "react"; import { AppealDecisionProps, ListingDetailPhaseCardComponentProps, ChallengePhaseProps, PhaseWithExpiryProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { ChallangeCouncilToolTipText } from "./textComponents"; import { ProgressBarCountdownTimer } from "../PhaseCountdown/"; import { TransactionButtonNoModal } from "../TransactionButton"; import { Button, buttonSizes } from "../Button"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import NeedHelp from "./NeedHelp"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; export const AppealDecisionCard: React.FunctionComponent< ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & AppealDecisionProps & ChallengeResultsProps > = props => { const renderSubmitChallengeButton = (): JSX.Element => { if (props.submitAppealChallengeURI) { return ( <> ); } return Submit a Challenge; }; return ( Challenge ID {props.challengeID} Appeal to Council } flavorText="under Appeal to Council" /> If you believe this newsroom does not align with the Civil Constitution, you may challenge the Council’s decision. {renderSubmitChallengeButton()} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealDecisionDetail.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StyledListingDetailPhaseCardSection, StyledListingDetailPhaseCardSectionHeader, FormCopy, } from "./styledComponents"; import { buttonSizes, InvertedButton } from "../Button"; import { Collapsable } from "../Collapsable"; export interface AppealDecisionDetailProps { appealGranted?: boolean; collapsable?: boolean; open?: boolean; appealGrantedStatementURI?: string; } const StyledInner = styled.div` padding-top: 14px; `; const AppealDecisionDetailInner: React.FunctionComponent = props => { const decisionText = props.appealGranted ? "granted" : "not granted"; return ( The Civil Council has {decisionText} the appeal.{" "} {props.appealGranted && "Read more about their methodology and how they’ve come to this decision."} {props.appealGranted && ( Read about this decision )} ); }; export const AppealDecisionDetail: React.FunctionComponent = props => { const headerElement = ( Civil Council Decision ); if (props.collapsable) { const open = props.open !== undefined ? props.open : true; return ( ); } return ( {headerElement} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/AppealResolveCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, AppealDecisionProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import NeedHelp from "./NeedHelp"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; export const AppealResolveCard: React.FunctionComponent< ListingDetailPhaseCardComponentProps & ChallengePhaseProps & AppealDecisionProps & ChallengeResultsProps > = props => { return ( Challenge ID {props.challengeID} Ready to Complete This challenge is complete. To update this Newsroom's status on the Civil Registry, please resolve this appeal. Resolve Appeal ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ChallengeCommitVoteCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, PhaseWithExpiryProps, ChallengePhaseProps, CommitVoteProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, StyledCardStage, StyledCard, StyledCardClose, StyledCardFront, StyledCardBack, FormHeader, FormCopy, FullWidthButton, } from "./styledComponents"; import { UnderChallengePhaseDisplayNameText, CommitVoteCalloutHeaderText, CommitVoteCalloutCopyText, CommitVoteAlreadyVotedHeaderText, CommitVoteAlreadyVotedCopyText, UnderChallengeToolTipText, CommitVoteToolTipText, ConfirmVoteToolTipText, } from "./textComponents"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { buttonSizes } from "../Button"; import NeedHelp from "./NeedHelp"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { CommitVote } from "./CommitVote"; import { QuestionToolTip } from "../QuestionToolTip"; export type ChallengeCommitVoteCardProps = ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & CommitVoteProps; export interface ChallengeCommitVoteCardState { flipped: boolean; } export class ChallengeCommitVoteCard extends React.Component< ChallengeCommitVoteCardProps, ChallengeCommitVoteCardState > { constructor(props: ChallengeCommitVoteCardProps) { super(props); this.state = { flipped: false }; } public render(): JSX.Element { return ( Challenge ID {this.props.challengeID} } positionBottom={true} /> } secondaryDisplayLabel="Confirm Vote Phase" secondaryToolTipText={} flavorText="under challenge" activePhaseIndex={0} /> {this.renderCommitVoteCallout()} {this.renderCommitVoteButtonText()} Submit a Secret Vote for Challenge #{this.props.challengeID} ); } private swapFlipped = (): void => { this.setState(() => ({ flipped: !this.state.flipped })); }; private renderCommitVoteCallout = (): JSX.Element => { if (this.props.userHasCommittedVote) { return ( <> ); } return ( <> ); }; private renderCommitVoteButtonText = (): JSX.Element => { if (this.props.userHasCommittedVote) { return <>Change My Vote; } return <>Ready To Commit My Vote; }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ChallengePhaseDetail.tsx ================================================ import * as React from "react"; import { getFormattedEthAddress } from "@joincivil/utils"; import { ChallengePhaseProps } from "./types"; import { MetaRow, MetaItem, MetaItemValue, MetaItemValueEthAddress, MetaItemLabel } from "./styledComponents"; import { RewardPoolToolTipText, DepositsToolTipText } from "./textComponents"; import { QuestionToolTip } from "../QuestionToolTip"; export const ChallengePhaseDetail: React.FunctionComponent = props => { return ( <> Reward Pool } positionBottom={true} /> {props.rewardPool} Challenger Deposit } positionBottom={true} /> {props.stake} Newsroom Deposit } positionBottom={true} /> {props.stake} {props.isViewingUserChallenger ? "You are the challenger" : "Challenger"} {getFormattedEthAddress(props.challenger!)} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ChallengeRequestAppealCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, PhaseWithExpiryProps, RequestAppealProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { UnderChallengePhaseDisplayNameText, UnderChallengeToolTipText, RequestAppealToolTipText, } from "./textComponents"; import { buttonSizes, InvertedButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ProgressBarCountdownTimer } from "../PhaseCountdown/"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import NeedHelp from "./NeedHelp"; import { QuestionToolTip } from "../QuestionToolTip"; const RequestAppealButton: React.FunctionComponent< ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & ChallengeResultsProps & RequestAppealProps > = props => { if (props.requestAppealURI) { return ( <> Request an Appeal ); } return ( Request Appeal from Civil Council ); }; export const ChallengeRequestAppealCard: React.FunctionComponent< ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & ChallengeResultsProps & RequestAppealProps > = props => { return ( Challenge ID {props.challengeID} } positionBottom={true} /> } flavorText="under challenge" /> If you disagree with the community, you may request an appeal to the Civil Council. ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ChallengeResolveCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps } from "./types"; import { CTACopy, StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, } from "./styledComponents"; import { ReadyToCompletePhaseDisplayNameText, ResolveChallengeToolTipText } from "./textComponents"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import NeedHelp from "./NeedHelp"; import { QuestionToolTip } from "../QuestionToolTip"; export const ChallengeResolveCard: React.FunctionComponent< ListingDetailPhaseCardComponentProps & ChallengePhaseProps & ChallengeResultsProps > = props => { return ( Challenge ID {props.challengeID} } positionBottom={true} /> This challenge is complete. To update this Newsroom's status on the Civil Registry, please resolve this challenge. Resolve Challenge ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ChallengeRevealVoteCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, PhaseWithExpiryProps, ChallengePhaseProps, RevealVoteProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseKicker, StyledPhaseDisplayName, StyledCardStage, StyledCard, StyledCardClose, StyledCardFront, StyledCardBack, FormHeader, FormCopy, FullWidthButton, } from "./styledComponents"; import { UnderChallengePhaseDisplayNameText, UnderChallengeToolTipText, CommitVoteToolTipText, ConfirmVoteToolTipText, RevealVoteCallToActionHeaderText, RevealVoteCallToActionCopyText, RevealVoteDidNotCommitHeaderText, RevealVoteDidNotCommitCopyText, RevealVoteDoneHeaderText, RevealVoteDoneCopyText, RevealVoteButtonText, RevealVoteCalloutCopyText, } from "./textComponents"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { buttonSizes } from "../Button"; import { ChallengePhaseDetail } from "./ChallengePhaseDetail"; import NeedHelp from "./NeedHelp"; import { RevealVote } from "./RevealVote"; import { QuestionToolTip } from "../QuestionToolTip"; export type ChallengeRevealVoteCardProps = ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & ChallengePhaseProps & RevealVoteProps; export interface ChallengeRevealVoteCardState { flipped: boolean; } export class ChallengeRevealVoteCard extends React.Component< ChallengeRevealVoteCardProps, ChallengeRevealVoteCardState > { constructor(props: ChallengeRevealVoteCardProps) { super(props); this.state = { flipped: false }; } public render(): JSX.Element { return ( Challenge ID {this.props.challengeID} } positionBottom={true} /> } secondaryDisplayLabel="Submit Vote Phase" secondaryToolTipText={} flavorText="under challenge" activePhaseIndex={1} /> {this.renderRevealVote()} Confirm Your Secret Vote for Challenge #{this.props.challengeID} ); } private renderRevealVote = (): JSX.Element => { if (!this.props.userHasCommittedVote) { return ( <> ); } else if (this.props.userHasRevealedVote) { return ( <> ); } else { return ( <> ); } }; private swapFlipped = (): void => { this.setState(() => ({ flipped: !this.state.flipped })); }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/CommitVote.tsx ================================================ import * as React from "react"; import { buttonSizes, Button } from "../Button"; import { CurrencyInputWithButton } from "../input/"; import { QuestionToolTip } from "../QuestionToolTip"; import { CommitVoteProps } from "./types"; import { FormQuestion, VoteOptionsContainer, StyledOrText, buttonTheme, ProgressBarProgress, ProgressBarTotal, StyledBalanceRow, StyledBalanceRowRight, StyledStep, StyledStepLabel, StyledOneTokenOneVote, StyledButtonsContainer, StyledTextActionButton, StyledAppMessage, StyledVoteCTAButton, } from "./styledComponents"; import { CommitVoteReviewButtonText, VoteCallToActionText, AppealChallengeVoteCallToActionText, AvailableTokenBalanceText, AvailableTokenBalanceTooltipText, VotingTokenBalanceText, VotingTokenBalanceTooltipText, SelectNumTokensText, OneTokenOneVoteText, OneTokenOneVoteTooltipText, CommitVoteInsufficientTokensText, CommitVoteMaxTokensWarningText, } from "./textComponents"; import VoteButton from "./VoteButton"; export interface CommitVoteState { numTokensError?: string; } export interface CommitVoteStepState { displayStep: number; } export class CommitVote extends React.Component { constructor(props: CommitVoteProps) { super(props); this.state = { numTokensError: undefined, displayStep: 0, }; } public render(): JSX.Element { const canReview = this.props.voteOption !== undefined && this.props.numTokens && typeof parseInt(this.props.numTokens, 10) === "number"; const DefaultCTATextComponent = this.props.isAppealChallenge ? AppealChallengeVoteCallToActionText : VoteCallToActionText; return ( <> Step 1 of 2 {this.props.children || } or Step 2 of 2 } positionBottom={true} /> {this.renderTokenBalance()} {this.renderNumTokensInput()} {this.renderAppMessages()}
this.setState({ displayStep: 0 })}> Back
); } private renderTokenBalance = (): JSX.Element => { let tokenBalanceLabel: JSX.Element; let toolTipText: JSX.Element; let displayBalance: string; let progress: number; if (this.props.votingTokenBalance) { tokenBalanceLabel = ; toolTipText = ; displayBalance = this.props.votingTokenBalanceDisplay; progress = this.props.numTokens ? parseFloat(this.props.numTokens) / this.props.votingTokenBalance : 0; } else { tokenBalanceLabel = ; toolTipText = ; displayBalance = this.props.tokenBalanceDisplay; progress = this.props.numTokens ? parseFloat(this.props.numTokens) / this.props.tokenBalance : 0; } if (progress > 1) { progress = 1; } const style = { width: `${(progress * 100).toString()}%` }; return ( <>
{tokenBalanceLabel}
{displayBalance}
); }; private renderNumTokensInput = (): JSX.Element => { return ( CVL} value={this.props.numTokens} onChange={this.setNumTokens} onButtonClick={() => this.props.onCommitMaxTokens()} /> ); }; private renderAppMessages = (): JSX.Element | null => { let message; const { numTokens, tokenBalance, votingTokenBalance } = this.props; if (numTokens && parseFloat(numTokens) > tokenBalance + votingTokenBalance) { message = ; } else if (numTokens && parseFloat(numTokens) === tokenBalance + votingTokenBalance) { message = ; } if (message) { return {message}; } return null; }; private setNumTokens = (name: string, value: string | null): void => { let cleanValue = value && parseFloat(value); if (cleanValue) { cleanValue = Math.abs(cleanValue as number); this.props.onInputChange({ numTokens: cleanValue }); return; } this.props.onInputChange({ numTokens: value }); }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/CompleteChallengeResults.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, AppealDecisionProps, AppealChallengePhaseProps, AppealChallengeResultsProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection } from "./styledComponents"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; export interface CompleteChallengeResultsProps { listingRemovedTimestamp?: number; } export type CompleteChallengeResultsAllProps = ListingDetailPhaseCardComponentProps & ChallengePhaseProps & ChallengeResultsProps & AppealDecisionProps & AppealChallengePhaseProps & AppealChallengeResultsProps & CompleteChallengeResultsProps; export const CompleteChallengeResults: React.FunctionComponent = props => { const showAppealChallenge = props.appealChallengeTotalVotes && props.appealChallengeVotesFor && props.appealChallengeVotesAgainst && props.appealChallengePercentFor && props.appealChallengePercentAgainst; return ( {props.appealRequested && } {showAppealChallenge && ( )} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/InApplicationCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps, PhaseWithExpiryProps, SubmitChallengeProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { NewApplicationDisplayNameText, NewApplicationToolTipText } from "./textComponents"; import { buttonSizes, InvertedButton } from "../Button"; import { TransactionInvertedButton } from "../TransactionButton"; import { ProgressBarCountdownTimer } from "../PhaseCountdown/"; import NeedHelp from "./NeedHelp"; export class InApplicationCard extends React.Component< ListingDetailPhaseCardComponentProps & PhaseWithExpiryProps & SubmitChallengeProps > { public render(): JSX.Element { return ( } flavorText="under community review" /> If you believe this newsroom does not align with the{" "} Civil Constitution, you may challenge this newsroom.{" "} Learn More. {this.renderSubmitChallengeButton()} ); } private renderSubmitChallengeButton = (): JSX.Element => { if (this.props.submitChallengeURI) { return ( <> Submit a Challenge ); } return ( Submit a Challenge ); }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/InApplicationResolveCard.tsx ================================================ import * as React from "react"; import { ListingDetailPhaseCardComponentProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, CTACopy, } from "./styledComponents"; import { TransactionButtonNoModal } from "../TransactionButton"; import NeedHelp from "./NeedHelp"; export const InApplicationResolveCard: React.FunctionComponent = props => { return ( Application Accepted This application is complete. To update this Newsroom's status on the Civil Registry, please add to registry. Add To Registry ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/ListingDetailsPhaseCard.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import StoryRouter from "storybook-react-router"; import { InApplicationCard, InApplicationResolveCard, ChallengeCommitVoteCard, ChallengeRevealVoteCard, ChallengeRequestAppealCard, ChallengeResolveCard, AppealAwaitingDecisionCard, AppealDecisionCard, AppealResolveCard, AppealChallengeCommitVoteCard, AppealChallengeRevealVoteCard, AppealChallengeResolveCard, WhitelistedCard, RejectedCard, } from "./index"; const StyledDiv = styled.div` display: flex; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); const now = Date.now() / 1000; const oneDay = 86400; const endTime = now + oneDay * 4.25; const phaseLength = oneDay * 7; const secondaryPhaseLength = phaseLength * 2; const challengeID = "420"; const challenger = "0x0"; const rewardPool = "1000000"; const stake = "100000"; const requester = "0x01"; const appealFeePaid = "10.00 CVL"; const appealChallengeID = "1420"; const totalVotes = "100000"; const votesFor = "73000"; const votesAgainst = "27000"; const percentFor = "73"; const percentAgainst = "27"; const didChallengeSucceed = false; const tokenBalance = 10000; let commitVoteState = { salt: "9635457449074", numTokens: (tokenBalance * 0.67).toString(), voteOption: undefined, }; function commitVoteChange(data: any, callback?: () => any): void { commitVoteState = { ...commitVoteState, ...data }; if (callback) { callback(); } } const noop = () => { console.log("noop"); }; storiesOf("Registry / Listing / Listing Details Phase Card", module) .addDecorator(StoryRouter()) .add("In Application", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Resolve Application", () => { return ( {process.env.NODE_ENV !== "test" && } ); }) .add("Under Challenge: Commit Vote", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Challenge: Reveal Vote - User Did Not Commit", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Challenge: Reveal Vote - User Already Revealed", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Challenge: Reveal Vote - User committed and has not revealed", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Challenge: Request Appeal", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Challenge: Resolve", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Appeal: Awaiting Appeal Decision", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Appeal: Awaiting Appeal Decision, Civil Council Multisig", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Appeal: Decision / Can Challenge", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Under Appeal: Resolve", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Appeal Challenge: Commit Vote", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Appeal Challenge: Reveal Vote - User Did Not Commit", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Appeal Challenge: Reveal Vote - User Already Revealed", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Appeal Challenge: Reveal Vote - User committed and has not revealed", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Appeal Challenge: Resolve", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Whitelisted", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Rejected", () => { return ( {process.env.NODE_ENV !== "test" && ( )} ); }); ================================================ FILE: packages/components/src/ListingDetailPhaseCard/NeedHelp.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StyledListingDetailPhaseCardSection } from "./styledComponents"; import { colors } from "../styleConstants"; export interface NeedHelpProps { faqURL: string; } const NeedHelpCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; letter-spacing: 0.68px; line-height: 20px; a, a:visited { color: ${colors.accent.CIVIL_BLUE}; } `; const NeedHelp: React.FunctionComponent = props => { return ( Need help?{" "} Check out our guide ); }; export default NeedHelp; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/RejectedCard.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { ListingDetailPhaseCardComponentProps, ChallengePhaseProps, AppealDecisionProps, AppealChallengePhaseProps, AppealChallengeResultsProps, } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, MetaItemValue, MetaItemLabel, } from "./styledComponents"; import { RejectedNewroomDisplayNameText, RejectedNewsroomsToolTipText } from "./textComponents"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { QuestionToolTip } from "../QuestionToolTip"; import { AppealDecisionDetail } from "./AppealDecisionDetail"; export interface RejectedCardProps { listingRemovedTimestamp?: number; } export type RejectedCardAllProps = ListingDetailPhaseCardComponentProps & ChallengePhaseProps & ChallengeResultsProps & AppealDecisionProps & AppealChallengePhaseProps & AppealChallengeResultsProps & RejectedCardProps; export const RejectedCard: React.FunctionComponent = props => { let displayDateTime; const showAppealChallenge = props.appealChallengeTotalVotes && props.appealChallengeVotesFor && props.appealChallengeVotesAgainst && props.appealChallengePercentFor && props.appealChallengePercentAgainst; if (props.listingRemovedTimestamp) { const listingRemovedDateTime = getLocalDateTimeStrings(props.listingRemovedTimestamp); displayDateTime = `${listingRemovedDateTime[0]} ${listingRemovedDateTime[1]}`; } return ( } positionBottom={true} /> Rejected date {displayDateTime} {props.appealRequested && } {showAppealChallenge && ( )} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/RevealVote.tsx ================================================ import * as React from "react"; import { SaltInput } from "../input/"; import { TransactionButtonNoModal } from "../TransactionButton"; import { StyledOrText, VoteOptionsContainer, StyledButtonsContainer, StyledStepCopy, StyledStepCopyNum, } from "./styledComponents"; import { RevealVoteButtonText } from "./textComponents"; import { RevealVoteProps } from "./types"; import VoteButton from "./VoteButton"; export interface RevealVoteState { saltError?: string; } interface StepCopyProps { step: string; } const StepCopy: React.FunctionComponent = props => { return ( {props.step}
{props.children}
); }; export class RevealVote extends React.Component { constructor(props: RevealVoteProps) { super(props); this.state = { saltError: undefined }; } public render(): JSX.Element { const canReveal = this.props.voteOption !== undefined && !this.state.saltError; return ( <> {this.props.children || "Reveal the vote option you chose in the submit vote phase"} or Enter your 4-word voting code ); } private validateSalt = (): boolean => { let isValid = true; if (!this.props.salt || this.props.salt.length === 0) { isValid = false; this.setState({ saltError: "Please enter a valid salt phrase", }); } else { this.setState({ saltError: undefined }); } return isValid; }; private onChange = (name: string, value: string): void => { let validateFn; if (name === "salt") { validateFn = this.validateSalt; } this.props.onInputChange({ [name]: value }, validateFn); }; } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/SaltField.tsx ================================================ import { saltToWords } from "@joincivil/utils"; import * as React from "react"; import { TextInput } from "../input/"; export interface SaltFieldProps { salt?: string; } export class SaltField extends React.Component { public render(): JSX.Element { const label = "Write down your salt please."; const saltWords = this.getSaltyWords(); return ; } private getSaltyWords(): string { const { salt } = this.props; if (!salt) { return ""; } return saltToWords(salt).join(" "); } } ================================================ FILE: packages/components/src/ListingDetailPhaseCard/VoteButton.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { VoteBaseProps } from "./types"; import { colors } from "../styleConstants"; import { buttonSizes, Button, InvertedButton } from "../Button"; import { HollowGreenCheck, HollowRedNoGood } from "../icons"; const StyledVoteButton = styled.span` flex-grow: 1; svg { margin: 0 8px -3px 0; } ${Button}, ${InvertedButton} { font-size: 13px; font-weight: bold; letter-spacing: 0; line-height: 14px; padding: 18px 0; text-transform: uppercase; width: 100%; } ${Button} { border: 2px solid ${colors.accent.CIVIL_BLUE}; border-radius: 2px; } ${InvertedButton}:hover .svg-fill { fill: ${colors.basic.WHITE}; } ${InvertedButton}:hover .svg-stroke { stroke: ${colors.basic.WHITE}; } `; export interface VoteButtonProps extends VoteBaseProps { buttonVoteOptionValue: string; } import { buttonTheme } from "./styledComponents"; import { WhitelistActionText, RemoveActionText, UpholdActionText, OverturnActionText } from "./textComponents"; const VoteButton: React.FunctionComponent = props => { let buttonText; const { voteOption, buttonVoteOptionValue, isAppealChallenge } = props; const isSelected = voteOption === buttonVoteOptionValue; const ButtonComponent = isSelected ? Button : InvertedButton; const iconColor = isSelected ? colors.basic.WHITE : colors.accent.CIVIL_BLUE; const onClick = () => { props.onInputChange({ voteOption: buttonVoteOptionValue }); }; if (buttonVoteOptionValue === "1") { if (isAppealChallenge) { buttonText = ; } else { buttonText = ( <> ); } } else if (props.buttonVoteOptionValue === "0") { if (props.isAppealChallenge) { buttonText = ; } else { buttonText = ( <> ); } } return ( {buttonText} ); }; export default VoteButton; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/WhitelistedCard.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { ListingDetailPhaseCardComponentProps, SubmitChallengeProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, MetaItemValue, MetaItemLabel, CTACopy, } from "./styledComponents"; import { WhitelistedNewroomsDisplayNameText, WhitelistedNewroomsToolTipText } from "./textComponents"; import { buttonSizes, InvertedButton } from "../Button"; import { TransactionInvertedButton } from "../TransactionButton"; import { QuestionToolTip } from "../QuestionToolTip"; import NeedHelp from "./NeedHelp"; export interface WhitelistedCardProps { whitelistedTimestamp?: number; } export const WhitelistedCard: React.FunctionComponent< ListingDetailPhaseCardComponentProps & SubmitChallengeProps & WhitelistedCardProps > = props => { let displayDateTime; if (props.whitelistedTimestamp) { const listingRemovedDateTime = getLocalDateTimeStrings(props.whitelistedTimestamp); displayDateTime = `${listingRemovedDateTime[0]} ${listingRemovedDateTime[1]}`; } return ( } positionBottom={true} /> Approved date {displayDateTime} If you believe this newsroom does not align with the Civil Constitution, you may submit a challenge. {renderSubmitChallengeButton(props)} ); }; const renderSubmitChallengeButton: React.FunctionComponent< ListingDetailPhaseCardComponentProps & SubmitChallengeProps & WhitelistedCardProps > = props => { if (props.submitChallengeURI) { return ( <> Submit a Challenge ); } return Submit a Challenge; }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/WithdrawnCard.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { ListingDetailPhaseCardComponentProps } from "./types"; import { StyledListingDetailPhaseCardContainer, StyledListingDetailPhaseCardSection, StyledPhaseDisplayName, MetaItemValue, MetaItemLabel, } from "./styledComponents"; import { WithdrawnNewroomDisplayNameText, WithdrawnNewsroomsToolTipText } from "./textComponents"; import { QuestionToolTip } from "../QuestionToolTip"; export interface WithdrawnCardProps { listingRemovedTimestamp?: number; } export type WithdrawnCardAllProps = ListingDetailPhaseCardComponentProps & WithdrawnCardProps; export const WithdrawnCard: React.FunctionComponent = props => { let displayDateTime; if (props.listingRemovedTimestamp) { const listingRemovedDateTime = getLocalDateTimeStrings(props.listingRemovedTimestamp); displayDateTime = `${listingRemovedDateTime[0]} ${listingRemovedDateTime[1]}`; } return ( } positionBottom={true} /> Withdrawn date {displayDateTime} ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/__snapshots__/ListingDetailsPhaseCard.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Listing / Listing Details Phase Card Appeal Challenge: Commit Vote 1`] = `

Registry / Listing / Listing Details Phase Card

Appeal Challenge: Commit Vote

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Appeal Challenge: Resolve 1`] = `

Registry / Listing / Listing Details Phase Card

Appeal Challenge: Resolve

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Appeal Challenge: Reveal Vote - User Already Revealed 1`] = `

Registry / Listing / Listing Details Phase Card

Appeal Challenge: Reveal Vote - User Already Revealed

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Appeal Challenge: Reveal Vote - User Did Not Commit 1`] = `

Registry / Listing / Listing Details Phase Card

Appeal Challenge: Reveal Vote - User Did Not Commit

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Appeal Challenge: Reveal Vote - User committed and has not revealed 1`] = `

Registry / Listing / Listing Details Phase Card

Appeal Challenge: Reveal Vote - User committed and has not revealed

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card In Application 1`] = `

Registry / Listing / Listing Details Phase Card

In Application

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Rejected 1`] = `

Registry / Listing / Listing Details Phase Card

Rejected

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Resolve Application 1`] = `

Registry / Listing / Listing Details Phase Card

Resolve Application

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Appeal: Awaiting Appeal Decision 1`] = `

Registry / Listing / Listing Details Phase Card

Under Appeal: Awaiting Appeal Decision

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Appeal: Awaiting Appeal Decision, Civil Council Multisig 1`] = `

Registry / Listing / Listing Details Phase Card

Under Appeal: Awaiting Appeal Decision, Civil Council Multisig

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Appeal: Decision / Can Challenge 1`] = `

Registry / Listing / Listing Details Phase Card

Under Appeal: Decision / Can Challenge

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Appeal: Resolve 1`] = `

Registry / Listing / Listing Details Phase Card

Under Appeal: Resolve

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Commit Vote 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Commit Vote

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Request Appeal 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Request Appeal

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Resolve 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Resolve

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Reveal Vote - User Already Revealed 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Reveal Vote - User Already Revealed

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Reveal Vote - User Did Not Commit 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Reveal Vote - User Did Not Commit

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Under Challenge: Reveal Vote - User committed and has not revealed 1`] = `

Registry / Listing / Listing Details Phase Card

Under Challenge: Reveal Vote - User committed and has not revealed

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Details Phase Card Whitelisted 1`] = `

Registry / Listing / Listing Details Phase Card

Whitelisted

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/index.ts ================================================ export * from "./InApplicationCard"; export * from "./InApplicationResolveCard"; export * from "./ChallengeCommitVoteCard"; export * from "./ChallengeRevealVoteCard"; export * from "./ChallengeRequestAppealCard"; export * from "./ChallengeResolveCard"; export * from "./AppealAwaitingDecisionCard"; export * from "./AppealDecisionCard"; export * from "./AppealResolveCard"; export * from "./AppealChallengeCommitVoteCard"; export * from "./AppealChallengeRevealVoteCard"; export * from "./AppealChallengeResolveCard"; export * from "./WhitelistedCard"; export * from "./RejectedCard"; export * from "./WithdrawnCard"; export * from "./CompleteChallengeResults"; export * from "./types"; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { Button, ButtonTheme, DEFAULT_BUTTON_THEME } from "../Button"; const BACKGROUND_ACCENT_COLORS: any = { COMMIT_VOTE: colors.accent.CIVIL_YELLOW, REVEAL_VOTE: colors.accent.CIVIL_TEAL_FADED, }; export const StyledListingDetailPhaseCardContainer = styled.div` box-sizing: border-box; background: ${colors.basic.WHITE}; box-shadow: 0 2px 10px 0 ${colors.accent.CIVIL_GRAY_3}; font-family: ${fonts.SANS_SERIF}; padding: 30px 0 50px; position: relative; width: 440px; ${mediaQueries.MOBILE} { padding: 7px 0; width: auto; } `; export interface StyledListingDetailPhaseCardSectionProps { bgAccentColor?: string; } export const StyledListingDetailPhaseCardSection = styled.div` background: ${props => (props.bgAccentColor ? BACKGROUND_ACCENT_COLORS[props.bgAccentColor] : "transparent")}; border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.primary.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; padding: 23px 40px 26px; text-align: left; &:nth-child(1) { border-top: 0; } ${mediaQueries.MOBILE} { padding-left: 16px; padding-right: 16px; width: auto; } `; export const StyledListingDetailPhaseCardSectionHeader = styled.h4` color: ${colors.accent.CIVIL_BLUE}; font-size: 18px; font-weight: 500; line-height: 21px; margin: 0; `; export const StyledPhaseKicker = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 12px; font-weight: bold; line-height: 15px; margin-bottom: 8px; text-transform: uppercase; `; export const StyledPhaseDisplayName = styled.h3` color: ${colors.primary.BLACK}; font-size: 24px; font-weight: bold; letter-spacing: -0.51px; line-height: 29px; margin: 0 0 24px; `; export const StyledListingDetailPhaseCardHed = styled.div` display: flex; padding: 27px 23px 30px; `; export const MetaRow = styled.div` display: flex; margin: 0 0 16px; `; export const MetaItem = styled.div` &:first-child:nth-last-child(1) { width: 100%; } &:first-child:nth-last-child(2), &:first-child:nth-last-child(2) ~ & { width: 50%; } `; export const MetaItemValue = styled.div` font-size: 18px; line-height: 21px; overflow: hidden; text-overflow: ellipsis; `; export const MetaItemValueEthAddress = styled(MetaItemValue)` font-family: ${fonts.MONOSPACE}; font-size: 15px; letter-spacing: -0.11px; line-height: 20px; `; export const MetaItemValueLong = styled(MetaItemValue)` font-size: 16px; `; export const MetaItemValueAccent = styled(MetaItemValue)` color: ${colors.primary.CIVIL_BLUE_1}; `; export const MetaItemLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 12px; font-weight: bold; line-height: 15px; margin-bottom: 8px; text-transform: uppercase; `; export const CTACopy = styled.p` font-size: 18px; font-weight: bold; line-height: 33px; & a { text-decoration: none; } `; export const FormCopy = styled.p` font-size: 16px; line-height: 26px; margin: 0 0 10px; `; export const VoteOptionsContainer = styled.div` display: flex; justify-content: space-between; margin: 20px 0 40px; `; export const StyledOrText = styled.div` font: italic normal 20px/30px ${fonts.SERIF}; padding: 10px 13px; text-align: center; `; export const StyledVoteCTAButton = styled.div` ${Button} { font-size: 13px; line-height: 14px; padding: 18px 0; width: 100%; } `; export const FormHeader = styled.h4` font-size: 21px; line-height: 25px; margin: 0 0 5px; `; export const AccentHRule = styled.div` box-shadow: inset 0 5px 0 0 ${colors.accent.CIVIL_BLUE}; height: 12px; margin: 10px 0; width: 45px; `; export const FormQuestion = styled.p` font-size: 21px; line-height: 34px; margin: 0 0 24px; text-align: center; `; export interface StyledCardStageProps { width?: string; } export interface StyledCardProps { flipped?: boolean; } export const StyledCardStage = styled.div` perspective: 800px; width: ${props => (props.width ? props.width + "px" : "440")}; ${mediaQueries.MOBILE} { width: auto; } & ${StyledListingDetailPhaseCardContainer} { box-shadow: none; } `; export const StyledCard = styled.div` position: relative; transition: transform 500ms; transform-style: preserve-3d; ${props => (!!props.flipped ? "transform:rotateY(180deg)" : "")}; height: 100%; width: 100%; `; export const StyledCardClose = styled.div` cursor: pointer; font-size: 18px; position: absolute; right: 15px; top: 15px; &:hover { color: ${colors.accent.CIVIL_BLUE}; } `; export const StyledCardFace = styled.div` background-color: ${colors.basic.WHITE}; backface-visibility: hidden; box-shadow: 0 2px 10px 0 ${colors.accent.CIVIL_GRAY_3}; height: 100%; position: relative; min-height: 100%; width: 100%; `; export const StyledCardFront = styled(StyledCardFace)` z-index: ${props => (!!props.flipped ? "1" : "-1")}; `; export const StyledCardBack = styled(StyledCardFace)` top: 0; bottom: 0; left: 0; right: 0; position: absolute; transform: rotateY(180deg); z-index: ${props => (!!props.flipped ? "-1" : "1")}; ${StyledListingDetailPhaseCardContainer} { padding-top: 0; } `; export const FullWidthButton = styled(Button)` margin: 14px 0 0; width: 100%; `; export const buttonTheme: ButtonTheme = { ...DEFAULT_BUTTON_THEME, primaryButtonDisabledBackground: colors.accent.CIVIL_GRAY_4, primaryButtonDisabledColor: colors.accent.CIVIL_GRAY_3, darkButtonTextTransform: "uppercase", }; export const ToolTipHdr = styled.p` font-size: 14px; font-weight: 700; line-height: 17px; margin: 0 0 12px; `; export const ToolTipItalic = styled.p` font-style: italic; margin: 0 0 12px; `; export interface StyledStepPropsState { visible: boolean; } export const StyledStep = styled.div` display: ${(props: StyledStepPropsState) => (props.visible ? "block" : "none")}; `; export const StyledStepLabel = styled(StyledPhaseKicker)` margin: 0 0 20px; text-align: center; `; export const StyledOneTokenOneVote = styled.div` background-color: ${colors.accent.CIVIL_GRAY_4}; color: ${colors.primary.CIVIL_GRAY_2}; font-size: 16px; line-height: 26px; margin: 0 -40px 39px; padding: 13px 0 15px; text-align: center; `; export const StyledBalanceRow = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; display: flex; font-size: 14px; line-height: 17px; justify-content: space-between; `; export const StyledBalanceRowRight = styled.div` text-align: right; `; export const ProgressBarBase = styled.div` height: 8px; border-radius: 5px; `; export const ProgressBarTotal = styled(ProgressBarBase)` background-color: ${colors.accent.CIVIL_TEAL_FADED_2}; box-sizing: border-box; margin: 13px 0 16px; position: relative; width: 100%; `; export const ProgressBarProgress = styled(ProgressBarBase)` display: inline-block; background-color: ${colors.accent.CIVIL_TEAL}; left: 0; top: 0; position: absolute; transition: width 500ms ease; `; export const StyledAppMessage = styled.div` color: ${colors.accent.CIVIL_RED}; font-size: 14px; line-height: 17px; margin: 20px 0; padding: 0 20px; text-align: center; `; export const StyledStepCopy = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; display: flex; font-size: 18px; line-height: 21px; margin: 0 0 16px; `; export const StyledStepCopyNum = styled.div` color: ${colors.primary.BLACK}; font-size: 21px; line-height: 25px; margin-right: 15px; `; export const StyledButtonsContainer = styled.div` display: flex; flex-direction: column; justify-content: space-between; margin-top: 23px; ${Button} { font-size: 13px; line-height: 14px; letter-spacing: 0.3px; text-transform: none; padding: 18px; margin: 0 0 35px; width: 100%; } `; export const StyledTextActionButton = styled.span` color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; `; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/textComponents.tsx ================================================ import * as React from "react"; import { getReadableDuration } from "@joincivil/utils"; import { ToolTipHdr, ToolTipItalic } from "./styledComponents"; // Text for reviewing a vote to commit export const CommitVoteReviewButtonText: React.FunctionComponent = props => <>Review My Vote; // Text for whitelisting action. Used in buttons and calls to action export const WhitelistActionText: React.FunctionComponent = props => <>approve; // Text for removing action. Used in buttons and calls to action export const RemoveActionText: React.FunctionComponent = props => <>reject; // Text for upholding granted appeal action. Used in buttons and calls to action export const UpholdActionText: React.FunctionComponent = props => <>upheld; // Text for overturning granted appeal action. Used in buttons and calls to action export const OverturnActionText: React.FunctionComponent = props => <>overturned; // Call to action text. Used on Commit Vote form export interface VoteCallToActionTextProps { newsroomName?: string; } export const VoteCallToActionText: React.FunctionComponent = props => { return ( <> Do you{" "} {" "} or{" "} {" "} {props.newsroomName || "this newsroom"} from being listed on the Civil Registry? ); }; export const AppealChallengeVoteCallToActionText: React.FunctionComponent = props => { return ( <> Should the Civil Council's decision be{" "} {" "} or{" "} {" "} ? ); }; export const RevealVoteCallToActionHeaderText: React.FunctionComponent = props => ( <>Confirm Your Secret Vote and Make It Count! ); export const RevealVoteCallToActionCopyText: React.FunctionComponent = props => ( <> To finalize the vote, you must complete this step to be eligible for rewards. Similar to the actual elections, votes are not revealed until after polls closed. ); export const RevealVoteDidNotCommitHeaderText: React.FunctionComponent = props => ( <>You did not participate in this challenge ); export const RevealVoteDidNotCommitCopyText: React.FunctionComponent = props => ( <>You did not commit a vote, so there is nothing here for you to reveal ); export const RevealVoteDoneHeaderText: React.FunctionComponent = props => <>You have revealed your vote; export const RevealVoteDoneCopyText: React.FunctionComponent = props => ( <>Thank you for participating! Please check back after the challenge ends to see if you have earned a reward. ); export interface RevealVoteCalloutCopyTextProps { votingSmartContractFaqURL: string; } export const RevealVoteCalloutCopyText: React.FunctionComponent = props => ( <> Civil does not store your vote information. It is stored in the{" "} voting smart contract . For your convenience, it is also stored in your browser cache. Please confirm your vote below. ); // Label for Commit Vote num tokens form export const CommitVoteNumTokensLabelText: React.FunctionComponent = props => { return <>Enter amount of tokens to vote. 1 vote equals 1 token ; }; // Commit Vote callouts export const CommitVoteCalloutHeaderText: React.FunctionComponent = props => { return <>You're Invited to Vote!; }; export const CommitVoteCalloutCopyText: React.FunctionComponent = props => { return ( <> Evaluate the Newsroom based on the Civil Constitution and vote accordingly. You will never lose tokens for participating in a vote. ); }; export const AppealChallengeCommitVoteCalloutCopyText: React.FunctionComponent = props => { return ( <> Evaluate whether the Granted Appeal should be upheld or overturned and cast your vote accordingly. Voters will never lose tokens for participating in a vote. ); }; export const CommitVoteAlreadyVotedHeaderText: React.FunctionComponent = props => { return <>You have already submitted your vote. Thank you.; }; // TODO(jon): Pass in and render commit vote expiry export const CommitVoteAlreadyVotedCopyText: React.FunctionComponent = props => { return <>You may revise your vote until the deadline.; }; export const CommitVoteCalloutButtonText: React.FunctionComponent = props => <>Submit My Vote; // Reveal Vote export const RevealVoteButtonText: React.FunctionComponent = props => <>Confirm My Vote; // Phase Card Display Names export const UnderChallengePhaseDisplayNameText: React.FunctionComponent = props => <>Under Challenge; export const ReadyToCompletePhaseDisplayNameText: React.FunctionComponent = props => <>Ready to Complete; export const NewApplicationDisplayNameText: React.FunctionComponent = props => <>New Application; export const RejectedNewroomDisplayNameText: React.FunctionComponent = props => <>Rejected Newsroom; export const WithdrawnNewroomDisplayNameText: React.FunctionComponent = props => <>Withdrawn Newsroom; export const WhitelistedNewroomsDisplayNameText: React.FunctionComponent = props => <>Approved Newsroom; // Tooltips export interface ToolTipTextProps { phaseLength?: number; dispensationPct?: string; } export const DurationToolTipText: React.FunctionComponent = props => { const duration = getReadableDuration(props.phaseLength || 0); return <>Time duration: {duration}; }; export const NewApplicationToolTipText: React.FunctionComponent = props => { return ( <> Under review by the community

CVL token holders may challenge a Newsroom if their mission, charter, or roster is perceived to misalign with the Civil Constitution. Newsroom will be approved if there are no challenges.

); }; export const UnderChallengeToolTipText: React.FunctionComponent = props => { return ( <> A CVL token holder is challenging this newsroom

This Newsroom is being challenged by a CVL token holder who believes it violates one of principles outlined in the Civil Constitution. Read the challenger's statement in the Discussion section.

The challenge phase consists of 2 subphases: Submit Vote and Confirm Vote.

); }; export const WhitelistedNewroomsToolTipText: React.FunctionComponent = props => { return ( <>

This Newsroom has committed to uphold the values of the Civil Constitution and has been approved by the Civil community to be on the Civil Registry.

The community of CVL token holders are the stewards of ethical journalism on the Civil Registry. If for any reason you believe that a Newsroom has violated either the Civil Constitution or the Newsroom's own stated mission and charter, you may challenge them at any time.

); }; export const RejectedNewsroomsToolTipText: React.FunctionComponent = props => { return ( <>

This Newsroom has been rejected by the CVL token-holding community due to misalignment with the Civil Constitution.

Rejected Newsrooms may reapply to the Civil Registry at any time.

); }; export const WithdrawnNewsroomsToolTipText: React.FunctionComponent = props => { return ( <>

This Newsroom has been withdrawn from the registry by its owner.

Withdrawn Newsrooms may reapply to the Civil Registry at any time.

); }; export const ResolveChallengeToolTipText: React.FunctionComponent = props => { return ( <> Resolve Challenge

Challenge results are in, and any CVL token holder may resolve this challenge. When this is resolved, Newsroom will be listed or delisted from The Civil Registry. Please note that this requires paying some Ethereum gas to complete.

); }; export const CommitVoteToolTipText: React.FunctionComponent = props => { return ( <> Commit tokens to cast a secret vote

Decide how many tokens you would like to put towards this vote. Note that the more tokens you include, the more power your vote carries. You can never lose your vote, but you will not be able to withdraw them until the end of the voting process. All votes will be hidden, using a unique 4-word voting code, until the end of the voting period. You have to come back and confirm your vote for it to count.

); }; export const ConfirmVoteToolTipText: React.FunctionComponent = props => { return ( <> Finalize vote using a unique 4-word voting code

Voters must enter the unique 4-word voting code they received during the commit vote stage of the process in order to confirm their vote. Votes can not be counted and rewards can not be claimed unless voters confirm their earlier vote.

); }; export const RewardPoolToolTipText: React.FunctionComponent = props => { return ( <> Amount of tokens to be distributed to voters of the winning party at the conclusion of the challenge. The amount comes from{" "} {!!props.dispensationPct ? `${props.dispensationPct}%` : "a percentage (defined by the dispensationPct Parameter)"}{" "} of the challenger or Newsroom's deposit. ); }; export const DepositsToolTipText: React.FunctionComponent = props => { return ( <> Amount of CVL tokens staked by the Newsroom when they apply to The Civil Registry, and by the Challenger upon challenging this Newsroom. ); }; export const RequestAppealToolTipText: React.FunctionComponent = props => { return ( <>

CVL token holders, (including newsrooms or challengers) can appeal a vote outcome if they believe it is not in keeping with the Civil Constitution. This system of checks and balances ensures that all voices and perspectives have an opportunity to be heard in the Civil community.

); }; export const WaitingCouncilDecisionToolTipText: React.FunctionComponent = props => { return ( <>

After The Civil Council reaches a decision on the appeal, they will publish a document explaining their choice and citing the section of the Civil Constitution they used to reach their decision. This system of checks and balances ensures that all voices and views have an opportunity to be heard in the Civil community.

); }; export const ChallangeCouncilToolTipText: React.FunctionComponent = props => { return ( <>

The challenger must submit a statement with evidence to make their case, and deposit CVL tokens equal to the amount of the Newsroom's deposit. The CVL token deposit for the challenge is set aside for the duration of the challenge process, like an escrow account.

); }; // Num tokens for Commit Vote text export const VotingTokenBalanceText: React.FunctionComponent = props => { return <>Voting Token Balance; }; export const AvailableTokenBalanceText: React.FunctionComponent = props => { return <>Available Token Balance; }; export const VotingTokenBalanceTooltipText: React.FunctionComponent = props => { return ( <> Voting tokens are tokens locked in voting contracts until the challenge is completed. If a token is locked in a vote, it can be used for other votes, but can NOT be used for applications, challenges, appeals, or exchanged for currency. If you’re planning on taking other actions, we recommend reserving some CVL in your available balance. ); }; export const AvailableTokenBalanceTooltipText: React.FunctionComponent = props => { return ( <> CVL tokens you can use to tip journalists, use for deposits to challenge, request appeal, and challenge appeal, or cash out for fiat currency. To vote, you will need to approve and transfer them to your Voting Token Balance. Committing CVL tokens from your Available Balance with any vote will automatically transfer those tokens into your Voting Token Balance. If you’re planning on taking other actions, we recommend reserving some CVL in your Available Balance ); }; export const SelectNumTokensText: React.FunctionComponent = props => { return <>Select amount of CVL tokens to commit to your vote.; }; export const OneTokenOneVoteText: React.FunctionComponent = props => { return <>1 token equals 1 vote.; }; export const OneTokenOneVoteTooltipText: React.FunctionComponent = props => { return ( <> Your vote is weighted based on the amount of CVL tokens you put towards your vote. If you have 1 CVL, you have 1 vote; 10 CVL gives you the power of 10 votes. This ensures that those who have the most tokens are incentivized to vote for the side that abides by the Civil Constitution. Note that you can not lose any CVL as a result of voting. ); }; export const CommitVoteInsufficientTokensText: React.FunctionComponent = props => { return <>You don't have enough CVL tokens in your available balance; }; export const CommitVoteMaxTokensWarningText: React.FunctionComponent = props => { return ( <> You are commiting all of your CVL tokens to this vote. If you’re planning on taking other actions - tipping journalists, challenging listings, requesting appeals, challenging granted appeals, or cashing out for fiat currency - we recommend reserving some CVL in your Available Balance. ); }; ================================================ FILE: packages/components/src/ListingDetailPhaseCard/types.ts ================================================ import { EthAddress } from "@joincivil/typescript-types"; export interface ListingDetailPhaseCardComponentProps { challenge?: any; listing?: any; listingAddress?: EthAddress; transactions?: any[]; constitutionURI?: string; learnMoreURL?: string; faqURL: string; onMobileTransactionClick?(): any; } export interface PhaseWithExpiryProps { endTime: number; phaseLength: number; secondaryPhaseLength?: number; } export interface SubmitChallengeProps { submitChallengeURI?: string; } export interface RequestAppealProps { requestAppealURI?: string; } export interface ChallengePhaseProps { challengeID?: string; isViewingUserChallenger?: boolean; challenger?: EthAddress; rewardPool?: string; stake?: string; dispensationPct?: string; userHasCommittedVote?: boolean; userHasRevealedVote?: boolean; } export interface VoteBaseProps { newsroomName?: string; isAppealChallenge?: boolean; salt?: string; voteOption?: string; onInputChange(propsData: any, validateFn?: () => boolean): void; postExecuteTransactions?(): any; } export interface CommitVoteProps extends VoteBaseProps { tokenBalance: number; votingTokenBalance: number; tokenBalanceDisplay: string; votingTokenBalanceDisplay: string; numTokens?: string; userHasCommittedVote?: boolean; userHasRevealedVote?: boolean; buttonText?: string | JSX.Element; onCommitMaxTokens(): void; onReviewVote(): void; } export interface RevealVoteProps extends VoteBaseProps { votingSmartContractFaqURL: string; transactions: any[]; } export interface AppealDecisionProps { appealRequested?: boolean; appealGranted?: boolean; appealGrantedStatementURI?: string; submitAppealChallengeURI?: string; } export interface AppealChallengePhaseProps { appealChallengeID?: string; } export interface AppealChallengeResultsProps { appealChallengeTotalVotes?: string; appealChallengeVotesFor?: string; appealChallengeVotesAgainst?: string; appealChallengePercentFor?: string; appealChallengePercentAgainst?: string; didAppealChallengeSucceed?: boolean; } ================================================ FILE: packages/components/src/ListingHistoryEvent/AppealGrantedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export const AppealGrantedEvent: React.FunctionComponent = props => { return ( The Council has Granted the requested appeal, reversing the outcome of the original challenge, although the community may still challenge this decision to overturn it. ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/AppealRequestedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export const AppealRequestedEvent: React.FunctionComponent = props => { return ( A user requested an appeal of the challenge results. The council will decide whether or not to grant the appeal after deliberating. ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ApplicationEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export interface ApplicationEventProps extends ListingHistoryEventTimestampProps { deposit: string; } export const ApplicationEvent: React.FunctionComponent = props => { return ( {props.deposit} deposited ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ChallengeEvent.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { EthAddress } from "@joincivil/typescript-types"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export interface ChallengeEventProps extends ListingHistoryEventTimestampProps { challengeID: string; challenger: EthAddress; challengeURI: string; } export const ChallengeEvent: React.FunctionComponent = props => { return ( by {props.challenger} View Historical Challenge - Challenge ID: {props.challengeID} ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ChallengeFailedEvent.tsx ================================================ import * as React from "react"; import { ChallengeResults } from "../ChallengeResultsChart"; import { ChallengeCompletedEventProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent } from "./ListingHistoryEvent"; export const ChallengeFailedEvent: React.FunctionComponent = props => { const { totalVotes, votesFor, votesAgainst, percentFor, percentAgainst, didChallengeOriginallySucceed, appealRequested, appealGranted, appealChallengeTotalVotes, appealChallengeVotesFor, appealChallengeVotesAgainst, appealChallengePercentFor, appealChallengePercentAgainst, didAppealChallengeSucceed, } = props; let councilDecision; let councilContext; if (appealRequested) { if (appealGranted) { councilDecision = didChallengeOriginallySucceed ? "approve" : "reject"; councilContext = "overturn"; } else { councilDecision = didChallengeOriginallySucceed ? "reject" : "approve"; councilContext = "uphold"; } } return ( {councilDecision && (

The Civil Council decided to {councilDecision} this Newsroom, {councilContext}ing the Civil Community's vote

)} {appealChallengeTotalVotes && ( )}
); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ChallengeSucceededEvent.tsx ================================================ import * as React from "react"; import { ChallengeResults } from "../ChallengeResultsChart"; import { ChallengeCompletedEventProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent } from "./ListingHistoryEvent"; export const ChallengeSucceededEvent: React.FunctionComponent = props => { const { totalVotes, votesFor, votesAgainst, percentFor, percentAgainst, didChallengeOriginallySucceed, appealRequested, appealGranted, appealChallengeTotalVotes, appealChallengeVotesFor, appealChallengeVotesAgainst, appealChallengePercentFor, appealChallengePercentAgainst, didAppealChallengeSucceed, } = props; let councilDecision; let councilContext; if (appealRequested) { if (appealGranted) { councilDecision = didChallengeOriginallySucceed ? "approve" : "reject"; councilContext = "overturn"; } else { councilDecision = didChallengeOriginallySucceed ? "reject" : "approve"; councilContext = "uphold"; } } return ( {councilDecision && (

The Civil Council decided to {councilDecision} this Newsroom, {councilContext}ing the Civil Community's vote

)} {appealChallengeTotalVotes && ( )}
); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/DepositEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export interface DepositEventProps extends ListingHistoryEventTimestampProps { deposit: string; } export const DepositEvent: React.FunctionComponent = props => { return ( {props.deposit} deposited ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/EventDate.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { colors } from "../styleConstants"; import { ListingHistoryEventTimestampProps } from "./types"; const StyledEventDate = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 13px; font-weight: bold; line-height: 16px; padding: 5px 0 0; width: 148px; min-width: 148px; max-width: 148px; `; const EventDate: React.FunctionComponent = props => { const eventDateTimeStrings = getLocalDateTimeStrings(props.timestamp); return {eventDateTimeStrings[0]}; }; export default EventDate; ================================================ FILE: packages/components/src/ListingHistoryEvent/GrantedAppealChallengedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export const GrantedAppealChallengedEvent: React.FunctionComponent = props => { return ( A member of the community has challenged the Council's decision to grant the appeal. If the challenge succeeds, the appeal will be overturned and the original challenge outcome will stand. ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ListingHistoryEvent.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import StoryRouter from "storybook-react-router"; import * as React from "react"; import styled from "styled-components"; import { ListingHistoryEvent } from "./ListingHistoryEvent"; import { ApplicationEvent } from "./ApplicationEvent"; import { ChallengeEvent } from "./ChallengeEvent"; import { ChallengeFailedEvent } from "./ChallengeFailedEvent"; import { ChallengeSucceededEvent } from "./ChallengeSucceededEvent"; import { RejectedEvent } from "./RejectedEvent"; import { WhitelistedEvent } from "./WhitelistedEvent"; const StyledDiv = styled.div` width: 600px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Registry / Listing / Listing History Event", module) .addDecorator(StoryRouter()) .add("Default", () => { const props = { timestamp: new Date().valueOf() / 1000, title: "A Default Event", }; return ( {process.env.NODE_ENV !== "test" && ( <> )} ); }) .add("History Events Timelime", () => { const timestamp = new Date().valueOf() / 1000; const deposit = "100.00 CVL"; const challengeID = "1"; const challenger = "0x8c722b8ac728add7780a66017e8dadba530ee261"; return ( {process.env.NODE_ENV !== "test" && ( <> )} ); }); ================================================ FILE: packages/components/src/ListingHistoryEvent/ListingHistoryEvent.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { ListingHistoryEventDetailsProps, ListingHistoryEventProps } from "./types"; import EventDate from "./EventDate"; export enum ListingHistoryEventStyles { WHITELISTED = "WHITELISTED", REJECTED = "REJECTED", } const StyledListingHistoryEvent = styled.div` display: flex; font-family: ${fonts.SANS_SERIF}; `; export interface StyledEventDetailProps { eventStyle?: string; } const eventColors: any = { [ListingHistoryEventStyles.WHITELISTED]: colors.accent.CIVIL_TEAL, [ListingHistoryEventStyles.REJECTED]: colors.accent.CIVIL_RED, }; const StyledEventDetail = styled.div` border-left: 4px solid ${colors.accent.CIVIL_GRAY_4}; padding: 0 0 40px 33px; position: relative; & svg { background: ${colors.basic.WHITE}; position: absolute; left: -15px; top: 0; z-index: 2; } `; const StyledEventCircle = styled.div` & circle { fill: ${props => (props.eventStyle ? eventColors[props.eventStyle] : colors.accent.CIVIL_GRAY_2)}; stroke: ${props => (props.eventStyle ? eventColors[props.eventStyle] : colors.accent.CIVIL_GRAY_2)}; } `; const StyledEventTitle = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 21px; font-weight: 600; line-height: 25px; margin: 0 0 8px 12px; `; export const StyledEventCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 16px; line-height: 19px; letter-spacing: -0.39px; & > strong { color: ${colors.primary.CIVIL_GRAY_1}; font-weight: normal; } `; export const ListingHistoryEvent: React.FunctionComponent = props => { return ( {props.children} ); }; const EventDetail: React.FunctionComponent = props => { return ( {props.title} {props.children} ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/ListingWithdrawnEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export const ListingWithdrawnEvent: React.FunctionComponent = props => { return ( Listing withdrawn from registry ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/RejectedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, ListingHistoryEventStyles } from "./ListingHistoryEvent"; export const RejectedEvent: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/TouchAndRemovedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export const TouchAndRemovedEvent: React.FunctionComponent = props => { return ( Listing removed from registry because its deposit was too low ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/WhitelistedEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, ListingHistoryEventStyles } from "./ListingHistoryEvent"; export const WhitelistedEvent: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/WithdrawalEvent.tsx ================================================ import * as React from "react"; import { ListingHistoryEventTimestampProps } from "./types"; import { ListingEventTitles } from "./constants"; import { ListingHistoryEvent, StyledEventCopy } from "./ListingHistoryEvent"; export interface WithdrawalEventProps extends ListingHistoryEventTimestampProps { deposit: string; } export const WithdrawalEvent: React.FunctionComponent = props => { return ( {props.deposit} withdrawn ); }; ================================================ FILE: packages/components/src/ListingHistoryEvent/__snapshots__/ListingHistoryEvent.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Listing / Listing History Event Default 1`] = `

Registry / Listing / Listing History Event

Default

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing History Event History Events Timelime 1`] = `

Registry / Listing / Listing History Event

History Events Timelime

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/ListingHistoryEvent/constants.ts ================================================ export enum ListingEventTitles { APPEAL_GRANTED = "Appeal Granted", APPEAL_REQUESTED = "Appeal Requested", APPLICATION = "Application Submitted", CHALLENGE = "Newsroom Challenged", CHALLENGE_FAILED = "Challenge Failed", CHALLENGE_SUCCEEDED = "Challenge Succeeded", REJECTED = "Newsroom Removed from Civil Registry", WHITELISTED = "Newsroom Whitelisted to Civil Registry", DEPOSIT = "Newsroom Deposited CVL to Listing", WITHDRAWAL = "Newsroom Withdrew CVL from Listing", LISTING_WITHDRAWN = "Listing Withdrawn from Civil Registry by owner", TOUCH_AND_REMOVED = "Listing Removed from Civil Registry", GRANTED_APPEAL_CHALLENGED = "The Appeal Granted by the Council has been Challenged", } ================================================ FILE: packages/components/src/ListingHistoryEvent/index.tsx ================================================ export * from "./AppealGrantedEvent"; export * from "./AppealRequestedEvent"; export * from "./ApplicationEvent"; export * from "./ChallengeEvent"; export * from "./ChallengeFailedEvent"; export * from "./ChallengeSucceededEvent"; export * from "./DepositEvent"; export * from "./GrantedAppealChallengedEvent"; export * from "./ListingHistoryEvent"; export * from "./ListingWithdrawnEvent"; export * from "./RejectedEvent"; export * from "./TouchAndRemovedEvent"; export * from "./WhitelistedEvent"; export * from "./WithdrawalEvent"; export * from "./types"; ================================================ FILE: packages/components/src/ListingHistoryEvent/types.ts ================================================ import { ChallengeResultsProps } from "../ChallengeResultsChart"; export interface ListingHistoryEventTimestampProps { timestamp: number; } export interface ListingHistoryEventDetailsProps { title: string; eventStyle?: string; } export interface ListingHistoryEventProps extends ListingHistoryEventTimestampProps, ListingHistoryEventDetailsProps {} export interface ChallengeCompletedEventProps extends ListingHistoryEventTimestampProps, ChallengeResultsProps { appealRequested?: boolean; appealGranted?: boolean; appealChallengeTotalVotes?: string; appealChallengeVotesFor?: string; appealChallengeVotesAgainst?: string; appealChallengePercentFor?: string; appealChallengePercentAgainst?: string; didAppealChallengeSucceed?: boolean; } ================================================ FILE: packages/components/src/ListingSummary/AppealJudgementBanner.tsx ================================================ import * as React from "react"; import { HollowGreenCheck, HollowRedNoGood, HollowGrayNotGranted } from "../icons"; import { ListingSummaryComponentProps } from "./types"; import { StyledBaseResultsBanner, StyledRejectedResultsBanner, StyledNotGrantedResultsBanner, } from "./styledComponents"; const AppealDecisionBanner: React.FunctionComponent = props => { const { appeal, appealGranted, doesChallengeHaveAppeal, isAwaitingAppealJudgement, didChallengeOriginallySucceed, } = props; if (!doesChallengeHaveAppeal && !isAwaitingAppealJudgement) { return <>; } let decisionText = <>; if (isAwaitingAppealJudgement) { decisionText = ( Appeal requested ); } else if (appeal) { if (appeal.appealGranted || appealGranted) { if (didChallengeOriginallySucceed) { // Challenge succeeded (newsroom rejected) and appeal was granted, so newsroom is accepted decisionText = ( Appeal granted to accept Newsroom ); // Challenge failed (newsroom accepted) and appeal was granted, so newsroom is rejected // } else { decisionText = ( Appeal granted to reject Newsroom ); } } else { decisionText = ( Appeal requested but not granted ); } } return decisionText; }; export default AppealDecisionBanner; ================================================ FILE: packages/components/src/ListingSummary/ChallengeOrAppealStatementSummary.tsx ================================================ import * as React from "react"; import { ListingSummaryComponentProps, ChallengeOrAppealStatementSummaryProps } from "./types"; import { StyledListingChallengeOrAppealStatement } from "./styledComponents"; const ChallengeOrAppealStatementSummary: React.FunctionComponent< ListingSummaryComponentProps & ChallengeOrAppealStatementSummaryProps > = props => { const { challengeID, challengeStatementSummary, appealStatementSummary, appealChallengeID, appealChallengeStatementSummary, inChallengeCommitVotePhase, inChallengeRevealPhase, isAwaitingAppealJudgement, isInAppealChallengeCommitPhase, isInAppealChallengeRevealPhase, } = props; if (isInAppealChallengeCommitPhase || (isInAppealChallengeRevealPhase && appealChallengeStatementSummary)) { const appealChallengeIDDisplay = appealChallengeID ? `#${appealChallengeID}` : ""; return ( Challenge {appealChallengeIDDisplay} Summary
{appealChallengeStatementSummary}
); } else if (isAwaitingAppealJudgement && appealStatementSummary) { return ( Appeal Summary
{appealStatementSummary}
); } else if (inChallengeCommitVotePhase || (inChallengeRevealPhase && challengeStatementSummary)) { const challengeIDDisplay = challengeID ? `#${challengeID}` : ""; return ( Challenge {challengeIDDisplay} Summary
{challengeStatementSummary}
); } return null; }; export default ChallengeOrAppealStatementSummary; ================================================ FILE: packages/components/src/ListingSummary/ChallengeResults.tsx ================================================ import * as React from "react"; import { ListingSummaryComponentProps, ListingSummaryAppealChallengeResultsProps as AppealChallengeResultsProps, } from "./types"; import { ChallengeResults as ChallengeResultsComponent, ChallengeResultsProps } from "../ChallengeResultsChart"; export interface ListingSummaryChallengeResultsProps extends ListingSummaryComponentProps, Partial {} export interface ListingSummaryAppealChallengeResultsProps extends ListingSummaryComponentProps, Partial {} import { StyledChallengeResultsHeader, ChallengeResultsContain } from "./styledComponents"; const ChallengeResults: React.FunctionComponent = props => { const { canBeWhitelisted, canResolveChallenge, isAwaitingAppealRequest, isAwaitingAppealJudgement, canListingAppealBeResolved, isAwaitingAppealChallenge, isInAppealChallengeCommitPhase, isInAppealChallengeRevealPhase, isUnderChallenge, isRejected, canListingAppealChallengeBeResolved, challengeID, totalVotes, votesFor, votesAgainst, percentFor, percentAgainst, didChallengeOriginallySucceed, } = props; if ( !( canBeWhitelisted || canResolveChallenge || isAwaitingAppealRequest || isAwaitingAppealJudgement || canListingAppealBeResolved || isAwaitingAppealChallenge || isInAppealChallengeCommitPhase || isInAppealChallengeRevealPhase || canListingAppealChallengeBeResolved || (isRejected && !isUnderChallenge) ) || (canBeWhitelisted && !isUnderChallenge) ) { return null; } const challengeIDDisplay = !!challengeID ? `#${challengeID}` : ""; return ( ); }; export const AppealChallengeResults: React.FunctionComponent = props => { const { canListingAppealChallengeBeResolved, appealChallengeID, appealChallengeTotalVotes, appealChallengeVotesFor, appealChallengeVotesAgainst, appealChallengePercentFor, appealChallengePercentAgainst, didAppealChallengeSucceed, isRejected, isUnderChallenge, } = props; if ( (!canListingAppealChallengeBeResolved && !(isRejected && !isUnderChallenge)) || !appealChallengeID || appealChallengeID === "0" ) { return null; } const challengeIDDisplay = !!appealChallengeID ? `#${appealChallengeID}` : ""; return ( ); }; export default ChallengeResults; ================================================ FILE: packages/components/src/ListingSummary/ChallengeResultsBanner.tsx ================================================ import * as React from "react"; import { HollowGreenCheck, HollowRedNoGood } from "../icons"; import { ListingSummaryComponentProps } from "./types"; import { StyledBaseResultsBanner, StyledRejectedResultsBanner } from "./styledComponents"; const ChallengeResultsBanner: React.FunctionComponent = props => { const { appeal, didChallengeOriginallySucceed, canBeWhitelisted } = props; let decisionText = null; if (appeal && appeal.appealGranted) { if (didChallengeOriginallySucceed) { // Challenge succeeded (newsroom rejected) and appeal was granted, so newsroom is accepted decisionText = ( Appeal granted to accept Newsroom ); } else { // Challenge failed (newsroom accepted) and appeal was granted, so newsroom is rejected decisionText = ( Appeal granted to reject Newsroom ); } } else if (didChallengeOriginallySucceed) { // Challenge succeeded (newsroom rejected) decisionText = ( Community voted to reject Newsroom ); } else if (canBeWhitelisted) { // Challenge failed (newsroom accepted) decisionText = ( Newsroom application passed without challenge ); } else if (!didChallengeOriginallySucceed) { // Challenge failed (newsroom accepted) decisionText = ( Community voted to accept Newsroom ); } return decisionText; }; export default ChallengeResultsBanner; ================================================ FILE: packages/components/src/ListingSummary/DepositOrStakeAmount.tsx ================================================ import * as React from "react"; import { ListingSummaryComponentProps } from "./types"; import { MetaRow, MetaItemValue, MetaItemLabel } from "./styledComponents"; import { AmountDepositedLabelText, AmountStakedChallengeLabelText } from "./textComponents"; const DepositOrStakeAmount: React.FunctionComponent = props => { if ( props.inChallengeCommitVotePhase || props.isInAppealChallengeCommitPhase || props.inChallengeRevealPhase || props.isInAppealChallengeRevealPhase || props.canResolveChallenge || props.canListingAppealChallengeBeResolved || props.isAwaitingAppealJudgement || props.isAwaitingAppealChallenge ) { return ; } else if (props.isInApplication || props.canBeWhitelisted || props.isWhitelisted) { return ; } return null; }; const UnstakedDeposit: React.FunctionComponent = props => { if (!props.unstakedDeposit && !props.isWhitelisted) { return null; } return ( {props.unstakedDeposit} ); }; const ChallengeStake: React.FunctionComponent = props => { if (!props.challengeStake) { return null; } return ( {props.challengeStake} ); }; export default DepositOrStakeAmount; ================================================ FILE: packages/components/src/ListingSummary/ListingPhaseLabel.tsx ================================================ import * as React from "react"; import { AwaitingApprovalStatusLabel, CommitVoteStatusLabel, RevealVoteStatusLabel, AwaitingAppealRequestLabel, ReadyToCompleteStatusLabel, AwaitingDecisionStatusLabel, AwaitingAppealChallengeStatusLabel, } from "../ApplicationPhaseStatusLabels"; import { ListingChallengeStatusProps } from "./types"; const ListingPhaseLabel: React.FunctionComponent = props => { const { isInApplication, inChallengeCommitVotePhase, isInAppealChallengeCommitPhase, inChallengeRevealPhase, isInAppealChallengeRevealPhase, isAwaitingAppealRequest, canBeWhitelisted, canResolveChallenge, canListingAppealBeResolved, canListingAppealChallengeBeResolved, isAwaitingAppealJudgement, isAwaitingAppealChallenge, } = props; if (isInApplication) { return ; } else if (inChallengeCommitVotePhase || isInAppealChallengeCommitPhase) { return ; } else if (inChallengeRevealPhase || isInAppealChallengeRevealPhase) { return ; } else if (isAwaitingAppealRequest) { return ; } else if ( canBeWhitelisted || canResolveChallenge || canListingAppealChallengeBeResolved || canListingAppealBeResolved ) { return ; } else if (isAwaitingAppealJudgement) { return ; } else if (isAwaitingAppealChallenge) { return ; } return null; }; export default ListingPhaseLabel; ================================================ FILE: packages/components/src/ListingSummary/ListingSummary.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import StoryRouter from "storybook-react-router"; import { ListingSummaryComponentProps } from "./types"; import { ListingSummaryComponent } from "./ListingSummary"; import { ListingSummaryRejectedComponent } from "./ListingSummaryRejected"; import { ListingSummaryList } from "./ListingSummaryList"; const StyledDiv = styled.div` display: flex; width: 600px; `; const totalVotes = "100000"; const votesFor = "73000"; const votesAgainst = "27000"; const percentFor = "73"; const percentAgainst = "27"; const didChallengeSucceed = false; const newsroomData: ListingSummaryComponentProps[] = [ { listingAddress: "0x0a", name: "Block Club Chicago", charter: { tagline: "Block Club Chicago is a nonprofit, neighborhood news organization dedicated to delivering reliable, nonpartisan and essential coverage of Chicago's diverse neighborhoods.", } as any, }, { listingAddress: "0x0b", name: "Cannabis Wire", charter: { tagline: "Cannabis Wire is an independent publication covering the multi-billion dollar cannabis industry, focusing on investigation into the complexities that come with legaliation.", } as any, }, { listingAddress: "0x0c", name: "Documented", charter: { tagline: "Documented covers New York City’s immigrants and the policies that affect their lives. We are an independent and nonpartisan publication.", } as any, }, { listingAddress: "0x0d", name: "Block Club Chicago", charter: { tagline: "Block Club Chicago is a nonprofit, neighborhood news organization dedicated to delivering reliable, nonpartisan and essential coverage of Chicago's diverse neighborhoods.", } as any, }, { listingAddress: "0x0e", name: "Cannabis Wire", charter: { tagline: "Cannabis Wire is an independent publication covering the multi-billion dollar cannabis industry, focusing on investigation into the complexities that come with legaliation.", } as any, }, { listingAddress: "0x0f", name: "Documented", charter: { tagline: "Documented covers New York City’s immigrants and the policies that affect their lives. We are an independent and nonpartisan publication.", } as any, }, ]; const newsrooms = newsroomData.map((newsroom: ListingSummaryComponentProps) => { const listingDetailURL = `/listing/${newsroom.listingAddress}`; return { ...newsroom, listingDetailURL }; }); const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Registry / Listing / Listing Summary", module) .addDecorator(StoryRouter()) .add("Card", () => { const newsroom = newsrooms[0]; return ( ); }) .add("Card Rejected", () => { const newsroom = newsrooms[0]; return ( {process.env.NODE_ENV !== "test" && ( )} ); }) .add("Card Grid", () => { return ( ); }); ================================================ FILE: packages/components/src/ListingSummary/ListingSummary.tsx ================================================ import * as React from "react"; import { HollowGreenCheck, HollowRedNoGood } from "../icons"; import { ListingSummaryComponentProps } from "./types"; import { StyledListingSummary, StyledListingSummarySection, StyledAppealJudgementContainer } from "./styledComponents"; import ListingSummaryBase from "./ListingSummaryBase"; import ChallengeOrAppealStatementSummary from "./ChallengeOrAppealStatementSummary"; import NewsroomInfo from "./NewsroomInfo"; import SummaryActionButton from "./SummaryActionButton"; export const ListingSummaryComponent: React.FunctionComponent = props => { const { challengeID, challengeStatementSummary, appealStatementSummary } = props; const renderAppealJudgement = (): JSX.Element => { const { appeal, didChallengeOriginallySucceed } = props; if (!appeal || !appeal.appealGranted) { return <>; } let decisionText; // Challenge succeeded (newsroom rejected) and appeal was granted, so newsroom is accepted if (didChallengeOriginallySucceed) { decisionText = ( <> Appeal granted to accept Newsroom ); // Challenge failed (newsroom accepted) and appeal was granted, so newsroom is rejected } else { decisionText = ( <> Appeal granted to reject Newsroom ); } return {decisionText}; }; return ( {renderAppealJudgement()} ); }; ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryApproved.tsx ================================================ import * as React from "react"; import { ListingSummaryComponentProps } from "./types"; import { ChallengeResultsProps } from "../ChallengeResultsChart"; import { StyledListingSummary, StyledListingSummarySection, StyledUnderChallengeBanner } from "./styledComponents"; import ListingSummaryBase from "./ListingSummaryBase"; import { UnderChallengeBannerText } from "./textComponents"; import ChallengeOrAppealStatementSummary from "./ChallengeOrAppealStatementSummary"; import ListingPhaseLabel from "./ListingPhaseLabel"; import NewsroomInfo from "./NewsroomInfo"; import SummaryActionButton from "./SummaryActionButton"; import PhaseCountdownOrTimestamp from "./PhaseCountdownOrTimestamp"; import AppealJudgementBanner from "./AppealJudgementBanner"; import ChallengeResults, { AppealChallengeResults } from "./ChallengeResults"; export interface ListingSummaryApprovedComponentProps extends ListingSummaryComponentProps, Partial {} export const ListingSummaryApprovedComponent: React.FunctionComponent = props => { const { challengeID, canListingAppealBeResolved, canListingAppealChallengeBeResolved } = props; let banner; if (canListingAppealBeResolved || canListingAppealChallengeBeResolved) { banner = ; } else if (challengeID) { banner = ( ); } return ( {banner} ); }; ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryBase.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { ListingSummaryComponentProps } from "./types"; import { StyledListingSummaryContainer } from "./styledComponents"; const ListingSummaryBase: React.FunctionComponent = props => { return ( {props.listingDetailURL && {props.children}} {!props.listingDetailURL && <>{props.children}} ); }; export default ListingSummaryBase; ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryList.tsx ================================================ import * as React from "react"; import { ListingSummaryComponentProps } from "./types"; import { ListingSummaryComponent } from "./ListingSummary"; import { StyledListingSummaryList } from "./styledComponents"; export interface ListingSummaryListProps { listings: ListingSummaryComponentProps[]; } export class ListingSummaryList extends React.Component { public render(): JSX.Element { const listingViews = this.props.listings.map((listing: any) => (
)); return {listingViews}; } } ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryReadyToUpdate.tsx ================================================ import * as React from "react"; import { ChallengeResultsProps } from "../ChallengeResultsChart"; import { ListingSummaryComponentProps } from "./types"; import { StyledListingSummary, StyledListingSummarySection } from "./styledComponents"; import ListingSummaryBase from "./ListingSummaryBase"; import ChallengeResults, { AppealChallengeResults } from "./ChallengeResults"; import ChallengeOrAppealStatementSummary from "./ChallengeOrAppealStatementSummary"; import NewsroomInfo from "./NewsroomInfo"; import SummaryActionButton from "./SummaryActionButton"; import ChallengeResultsBanner from "./ChallengeResultsBanner"; export interface ListingSummaryReadyToUpdateComponentProps extends ListingSummaryComponentProps, Partial {} export const ListingSummaryReadyToUpdateComponent: React.FunctionComponent< ListingSummaryReadyToUpdateComponentProps > = props => { return ( ); }; ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryRejected.tsx ================================================ import * as React from "react"; import { ChallengeResultsProps } from "../ChallengeResultsChart"; import { ListingSummaryComponentProps } from "./types"; import { StyledListingSummary, StyledListingSummarySection } from "./styledComponents"; import ListingSummaryBase from "./ListingSummaryBase"; import NewsroomInfo from "./NewsroomInfo"; import SummaryActionButton from "./SummaryActionButton"; import ChallengeResults, { AppealChallengeResults } from "./ChallengeResults"; import AppealJudgementBanner from "./AppealJudgementBanner"; export const ListingSummaryRejectedComponent: React.FunctionComponent< ListingSummaryComponentProps & ChallengeResultsProps > = props => { const { doesChallengeHaveAppeal, isAwaitingAppealJudgement } = props; const hasTopPadding = !doesChallengeHaveAppeal && !isAwaitingAppealJudgement; return ( ); }; ================================================ FILE: packages/components/src/ListingSummary/ListingSummaryUnderChallenge.tsx ================================================ import * as React from "react"; import { ChallengeResultsProps } from "../ChallengeResultsChart"; import { ListingSummaryComponentProps } from "./types"; import { StyledListingSummary, StyledListingSummarySection } from "./styledComponents"; import ListingSummaryBase from "./ListingSummaryBase"; import ChallengeOrAppealStatementSummary from "./ChallengeOrAppealStatementSummary"; import ListingPhaseLabel from "./ListingPhaseLabel"; import NewsroomInfo from "./NewsroomInfo"; import SummaryActionButton from "./SummaryActionButton"; import ChallengeResults from "./ChallengeResults"; import PhaseCountdownOrTimestamp from "./PhaseCountdownOrTimestamp"; import AppealJudgementBanner from "./AppealJudgementBanner"; export interface ListingSummaryUnderChallengeComponentProps extends ListingSummaryComponentProps, Partial {} export const ListingSummaryUnderChallengeComponent: React.FunctionComponent< ListingSummaryUnderChallengeComponentProps > = props => { const { doesChallengeHaveAppeal, isAwaitingAppealJudgement } = props; const hasTopPadding = !doesChallengeHaveAppeal && !isAwaitingAppealJudgement; return ( ); }; ================================================ FILE: packages/components/src/ListingSummary/NewsroomInfo.tsx ================================================ import * as React from "react"; import defaultNewsroomImgUrl from "../images/img-default-newsroom@2x.png"; import { ListingSummaryComponentProps } from "./types"; import { NewsroomIcon, StyledListingSummaryTop, StyledListingSummaryNewsroomName } from "./styledComponents"; import NewsroomTagline from "./NewsroomTagline"; const NewsroomInfo: React.FunctionComponent = props => { const description = props.charter && props.charter.tagline; const logoURL = props.charter && props.charter.logoUrl; return ( {logoURL && ( { (e.target as any).src = defaultNewsroomImgUrl; }} /> )}
{props.name}
); }; export default NewsroomInfo; ================================================ FILE: packages/components/src/ListingSummary/NewsroomTagline.tsx ================================================ import * as React from "react"; import { NewsroomTaglineProps } from "./types"; import { StyledListingSummaryDescription } from "./styledComponents"; const NewsroomTagline: React.FunctionComponent = props => { let { description } = props; if (!description) { return null; } const maxDescriptionLength = 120; if (description && description.length > maxDescriptionLength) { description = description.substring(0, maxDescriptionLength) + "..."; } return {description}; }; export default NewsroomTagline; ================================================ FILE: packages/components/src/ListingSummary/PhaseCountdownOrTimestamp.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings } from "@joincivil/utils"; import { TextCountdownTimer } from "../PhaseCountdown"; import { ListingSummaryComponentProps } from "./types"; import { MetaRow, MetaItemValue, MetaItemLabel } from "./styledComponents"; import { ApplicationPhaseEndedLabelText, ApprovedLabelText, ChallengeEndedLabelText } from "./textComponents"; const PhaseCountdown: React.FunctionComponent = props => { let expiry: number | undefined; const { isInApplication, inChallengeCommitVotePhase, inChallengeRevealPhase, isAwaitingAppealRequest, isAwaitingAppealJudgement, isAwaitingAppealChallenge, isInAppealChallengeCommitPhase, isInAppealChallengeRevealPhase, appExpiry, commitEndDate, revealEndDate, requestAppealExpiry, appealPhaseExpiry, appealOpenToChallengeExpiry, appealChallengeCommitEndDate, appealChallengeRevealEndDate, } = props; if (isInApplication) { expiry = appExpiry; } else if (inChallengeCommitVotePhase) { expiry = commitEndDate; } else if (inChallengeRevealPhase) { expiry = revealEndDate; } else if (isAwaitingAppealRequest) { expiry = requestAppealExpiry; } else if (isAwaitingAppealJudgement) { expiry = appealPhaseExpiry; } else if (isAwaitingAppealChallenge) { expiry = appealOpenToChallengeExpiry; } else if (isInAppealChallengeCommitPhase) { expiry = appealChallengeCommitEndDate; } else if (isInAppealChallengeRevealPhase) { expiry = appealChallengeRevealEndDate; } const warn = inChallengeCommitVotePhase || inChallengeRevealPhase || isInAppealChallengeCommitPhase || isInAppealChallengeRevealPhase; if (!expiry) { return null; } expiry = parseInt(expiry.toString(), 10); return ; }; /** * Renders a human-readable timestamp for phases that have no expiry */ const Timestamp: React.FunctionComponent = props => { let timestamp: number = 0; let LabelTextComponent: React.FunctionComponent = () => <>; const { canBeWhitelisted, appExpiry, canResolveChallenge, revealEndDate, canListingAppealChallengeBeResolved, appealChallengeRevealEndDate, isWhitelisted, isUnderChallenge, whitelistedTimestamp, } = props; // Unchallenged application if (canBeWhitelisted && appExpiry) { timestamp = appExpiry; LabelTextComponent = ApplicationPhaseEndedLabelText; // Resolve Challenge } else if (canResolveChallenge && revealEndDate) { timestamp = revealEndDate; LabelTextComponent = ChallengeEndedLabelText; // Resolve Appeal Challenge } else if (canListingAppealChallengeBeResolved && appealChallengeRevealEndDate) { timestamp = appealChallengeRevealEndDate; LabelTextComponent = ChallengeEndedLabelText; // Whitelisted and not Under Challenge } else if (isWhitelisted && !isUnderChallenge && whitelistedTimestamp) { timestamp = whitelistedTimestamp; LabelTextComponent = ApprovedLabelText; } if (!timestamp) { return null; } const timestampStrings: [string, string] = getLocalDateTimeStrings(timestamp); return ( {timestampStrings![0]} {timestampStrings![1]} ); }; const PhaseCountdownOrTimestamp: React.FunctionComponent = props => { const { isInApplication, inChallengeCommitVotePhase, inChallengeRevealPhase, isAwaitingAppealRequest, isAwaitingAppealJudgement, isAwaitingAppealChallenge, isInAppealChallengeCommitPhase, isInAppealChallengeRevealPhase, } = props; if ( isInApplication || inChallengeCommitVotePhase || inChallengeRevealPhase || isAwaitingAppealRequest || isAwaitingAppealJudgement || isAwaitingAppealChallenge || isInAppealChallengeCommitPhase || isInAppealChallengeRevealPhase ) { return ; } else { return ; } }; export default PhaseCountdownOrTimestamp; ================================================ FILE: packages/components/src/ListingSummary/SummaryActionButton.tsx ================================================ import * as React from "react"; import { buttonSizes, InvertedButton } from "../Button"; import { ListingSummaryComponentProps } from "./types"; import { ViewDetailsButtonText } from "./textComponents"; const SummaryActionButton: React.FunctionComponent = props => { return ( ); }; const ButtonText: React.FunctionComponent = props => { return ; }; export default SummaryActionButton; ================================================ FILE: packages/components/src/ListingSummary/__snapshots__/ListingSummary.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Listing / Listing Summary Card 1`] = `

Registry / Listing / Listing Summary

Card

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Summary Card Grid 1`] = `

Registry / Listing / Listing Summary

Card Grid

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / Listing / Listing Summary Card Rejected 1`] = `

Registry / Listing / Listing Summary

Card Rejected

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/ListingSummary/index.ts ================================================ export * from "./ListingSummaryList"; export * from "./ListingSummary"; export * from "./ListingSummaryApproved"; export * from "./ListingSummaryUnderChallenge"; export * from "./ListingSummaryReadyToUpdate"; export * from "./ListingSummaryRejected"; export * from "./types"; export { StyledListingSummaryList } from "./styledComponents"; ================================================ FILE: packages/components/src/ListingSummary/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { SectionHeading } from "../Heading"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { InvertedButton } from "../Button"; import { StyledBaseStatus } from "../ApplicationPhaseStatusLabels"; export const StyledListingSummaryList = styled.div` display: flex; flex-wrap: wrap; margin: 0 auto; width: 1200px; ${mediaQueries.MOBILE} { display: block; width: auto; } `; export const StyledListingSummaryContainer = styled.div` margin: 0 30px 48px 0; width: 379px; & > a { color: inherit; } &:nth-child(3n + 3) { margin-right: 0; } ${mediaQueries.MOBILE} { width: auto; margin: 0 16px 31px; &:nth-child(3n + 3) { margin-right: 16px; } } `; export interface StyledListingSummaryProps { hasTopPadding?: boolean; } export const StyledListingSummary = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; box-shadow: inset 0 1px 0 0 ${colors.accent.CIVIL_GRAY_4}, 0 2px 4px 0 ${colors.accent.CIVIL_GRAY_3}; box-sizing: border-box; ${(props: StyledListingSummaryProps) => (props.hasTopPadding ? "padding-top: 25px;" : "")}; & ${StyledBaseStatus} { margin: 0 22px 10px; } `; export const StyledListingSummaryTop = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; display: flex; height: 190px; padding: 0 22px 25px; `; export const StyledBaseResultsBanner = styled.div` align-items: center; border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.primary.BLACK}; display: flex; font-size: 14px; justify-content: center; line-height: 18px; padding: 22px 0; margin-bottom: 22px; & svg { margin-right: 4px; } `; export const StyledUnderChallengeBanner = styled(StyledBaseResultsBanner)` background-color: ${colors.primary.BLACK}; color: ${colors.basic.WHITE}; font-size: 12px; font-weight: 800; letter-spacing: 0.93px; line-height: 15px; padding: 11px 0 8px; margin-bottom: 12px; text-transform: uppercase; `; export const StyledNotGrantedResultsBanner = styled(StyledBaseResultsBanner)` background-color: ${colors.basic.WHITE}; `; export const StyledRejectedResultsBanner = styled(StyledBaseResultsBanner)` background-color: ${colors.accent.CIVIL_RED_VERY_FADED}; `; export const StyledAppealJudgementContainer = styled.div` align-items: center; display: flex; background: ${colors.primary.BLACK}; border-radius: 3px; color: ${colors.basic.WHITE}; font-size: 14px; justify-content: center; line-height: 18px; margin: 9px 8px 2px; padding: 15px 0; & svg { margin-right: 4px; } `; export const StyledListingSummarySection = styled.div` background-color: ${colors.accent.CIVIL_BLUE_FADED_2}; color: ${colors.primary.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; padding: 25px 22px 50px; & ${InvertedButton} { font-size: 14px; font-weight: bold; letter-spacing: 1px; line-height: 14px; padding: 14px 0; text-transform: none; text-align: center; width: 100%; } `; export const StyledListingSummaryNewsroomName = styled(SectionHeading)` color: ${colors.primary.BLACK}; line-height: 26px; margin: 0 0 8px; `; export const StyledListingSummaryDescription = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font: 400 14px/20px ${fonts.SANS_SERIF}; `; export const StyledListingChallengeOrAppealStatement = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 16px; line-height: 26px; margin: 0 0 19px; `; export const ChallengeResultsContain = styled.div` font-family: ${fonts.SANS_SERIF}; padding: 25px 22px 50px; `; export const NewsroomIcon = styled.figure` background: ${colors.accent.CIVIL_GRAY_4}; height: 80px; margin: 0 17px 0 0; min-width: 80px; img { width: 80px; height: 80px; min-width: 80px; min-height: 80px; object-fit: contain; background: ${colors.basic.WHITE}; } `; export const SmallNewsroomIcon = styled.span` img { width: 52px; height: 52px; min-width: 52px; min-height: 52px; object-fit: contain; background: ${colors.basic.WHITE}; } `; export const MetaRow = styled.div` margin: 16px 0; `; export const TimestampLabel = styled.div` font-size: 16px; line-height: 16px; `; export const TimestampValue = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; line-height: 17px; margin-bottom: 4px; `; export const MetaItemValue = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 16px; line-height: 19px; `; export const MetaItemLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 12px; font-weight: bold; line-height: 15px; margin-bottom: 5px; text-transform: uppercase; `; export const StyledChallengeResultsHeader = styled.h4` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 16px; line-height: 19px; margin: 0 0 6px; `; ================================================ FILE: packages/components/src/ListingSummary/textComponents.tsx ================================================ import * as React from "react"; export const ViewDetailsButtonText: React.FunctionComponent = props => { return <>View Details; }; export const VoteNowButtonText: React.FunctionComponent = props => { return <>Vote Now; }; export const ConfirmVoteNowButtonText: React.FunctionComponent = props => { return <>Confirm Vote Now; }; export const RequestAppealNowButtonText: React.FunctionComponent = props => { return <>Request Appeal Now; }; export const SubmitAppealChallengeNowButtonText: React.FunctionComponent = props => { return <>Challenge Appeal Now; }; export const UpdateStatusButtonText: React.FunctionComponent = props => { return <>Update Status; }; export const AmountDepositedLabelText: React.FunctionComponent = props => { return <>Amount Deposited; }; export const AmountStakedChallengeLabelText: React.FunctionComponent = props => { return <>Amount staked in this challenge; }; export const ChallengeEndedLabelText: React.FunctionComponent = props => { return <>Challenge Ended; }; export const ApplicationPhaseEndedLabelText: React.FunctionComponent = props => { return <>Application ended; }; export const ApprovedLabelText: React.FunctionComponent = props => { return <>Approved; }; export const UnderChallengeBannerText: React.FunctionComponent = props => { return <>This Newsroom Has Been Challenged; }; ================================================ FILE: packages/components/src/ListingSummary/types.ts ================================================ import { EthAddress, AppealData, CharterData } from "@joincivil/typescript-types"; export interface ListingChallengeStatusProps { isInApplication?: boolean; canBeChallenged?: boolean; canBeWhitelisted?: boolean; inChallengeCommitVotePhase?: boolean; inChallengeRevealPhase?: boolean; isAwaitingAppealRequest?: boolean; didChallengeSucceed?: boolean; didChallengeOriginallySucceed?: boolean; canResolveChallenge?: boolean; doesChallengeHaveAppeal?: boolean; isAwaitingAppealJudgement?: boolean; isAwaitingAppealChallenge?: boolean; canListingAppealBeResolved?: boolean; isInAppealChallengeCommitPhase?: boolean; isInAppealChallengeRevealPhase?: boolean; isRejected?: boolean; isWhitelisted?: boolean; isUnderChallenge?: boolean; canListingAppealChallengeBeResolved?: boolean; } export interface ListingSummaryComponentProps extends ListingChallengeStatusProps { listingAddress?: EthAddress; name?: string; charter?: CharterData; listingDetailURL?: string; challengeID?: string; challengeStatementSummary?: string; appeal?: AppealData; appealRequested?: boolean; appealGranted?: boolean; appealStatementSummary?: string; whitelistedTimestamp?: number; appExpiry?: number; commitEndDate?: number; revealEndDate?: number; requestAppealExpiry?: number; appealPhaseExpiry?: number; appealOpenToChallengeExpiry?: number; unstakedDeposit?: string; challengeStake?: string; appealChallengeCommitEndDate?: number; appealChallengeRevealEndDate?: number; appealChallengeID?: string; appealChallengeStatementSummary?: string; } export interface ListingSummaryAppealChallengeResultsProps { appealChallengeTotalVotes: string; appealChallengeVotesFor: string; appealChallengeVotesAgainst: string; appealChallengePercentFor: string; appealChallengePercentAgainst: string; didAppealChallengeSucceed?: boolean; } export interface ChallengeOrAppealStatementSummaryProps { challengeID?: string; challengeStatementSummary?: string; appealStatementSummary?: string; appealChallengeID?: string; appealChallengeStatementSummary?: string; } export interface NewsroomTaglineProps { description?: string; } ================================================ FILE: packages/components/src/LoadingIndicator.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { LoadingIndicator } from "./LoadingIndicator"; const StyledDiv = styled.div` display: flex; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Pattern Library / Loading / Loading Indicator", module) .add("Default Size (32px x 32px)", () => { return ( ); }) .add("Prop-defined size (100px x 100px)", () => { return ( ); }); ================================================ FILE: packages/components/src/LoadingIndicator.tsx ================================================ import * as React from "react"; import { colors } from "./styleConstants"; export interface LoadingIndicatorProps { className?: string; inline?: boolean; height?: string | number; width?: string | number; } export const LoadingIndicator: React.FunctionComponent = props => { let height = props.height || "32"; if (typeof height === "number") { height = height.toString(); } let width = props.width || height; if (typeof width === "number") { width = width.toString(); } const getCenterY = (): string => { return Math.floor(parseInt(height as string, 10) / 2).toString(); }; const getViewbox = (): string => { return `0 0 ${width} ${height}`; }; const getCircleRadius = (): string => { return Math.floor(parseInt(height as string, 10) / 8).toString(); }; const getAnimatedCircleRadius = (): string => { const circleR = getCircleRadius(); return `0; ${circleR}; 0; 0`; }; const getCircleOffsetX = (circleNum: number): string => { return Math.floor((parseInt(width as string, 10) / 4) * circleNum).toString(); }; const getCircleTranslate = (circleNum: number): string => { const translateX = getCircleOffsetX(circleNum + 1); return `translate(${translateX} 0)`; }; return ( ); }; ================================================ FILE: packages/components/src/LoadingMessage.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { LoadingMessage } from "./LoadingMessage"; const StyledDiv = styled.div` display: flex; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Pattern Library / Loading / Loading Message", module) .add("Default size (32px x 32px), default text", () => { return ( ); }) .add("Prop-defined size (100px x 100px), default text", () => { return ( ); }) .add("Default size (32px x 32px), custom text", () => { return ( Please wait while we load all the stuff. ); }); ================================================ FILE: packages/components/src/LoadingMessage.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { LoadingIndicator, LoadingIndicatorProps } from "./LoadingIndicator"; import { colors } from "./styleConstants"; const Wrapper = styled.div` padding-top: 100px; text-align: center; width: 100%; `; const Message = styled.p` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 18px; line-height: 24px; margin: 36px 0 0; `; export const LoadingMessage: React.FunctionComponent = props => { const defaultCopy = "Loading"; return ( {props.children || defaultCopy} ); }; ================================================ FILE: packages/components/src/Message.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { InfoMessage } from "./Message"; const StyledDiv = styled.div` display: flex; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Pattern Library / Notices / Messages (deprecate this?)", module).add("Info Message", () => { return ( Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. ); }); ================================================ FILE: packages/components/src/Message.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "./styleConstants"; export interface MessageProps { className?: string; text?: string; children?: any; } const MessageBase = (props: MessageProps) => { return
{props.children}
; }; export const Message = styled(MessageBase)` margin: 10px 0; padding: 15px; font-size: 15px; font-family: ${fonts.SERIF}; color: black; `; export const InfoMessage = styled(Message)` background-color: ${colors.accent.CIVIL_BLUE_VERY_FADED}; color: black; `; ================================================ FILE: packages/components/src/MetaMaskLogoButton.tsx ================================================ import * as React from "react"; import { MetaMaskSideIcon, Button, buttonSizes, TransactionButtonInnerProps } from "."; import styled from "styled-components"; const B = styled(Button)` position: relative; display: flex; align-items: center; height: 46px; padding-left: 75px; `; const ImgWrapper = styled.div` width: 44px; height: 44px; background-color: #ffffff; position: absolute; top: 1px; left: 1px; display: flex; justify-content: center; align-items: center; `; export const MetaMaskLogoButton = (props: TransactionButtonInnerProps): JSX.Element => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/MetaMaskModal.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { MetaMaskModal } from "./MetaMaskModal"; import { ModalHeading } from "."; import styled from "styled-components"; const func = () => { return; }; storiesOf("Common / Ethereum / MetaMaskModal", module) .add("preMetaMaskModal", () => { return process.env.NODE_ENV !== "test" ? ( test ) : (
test
); }) .add("waitingMetaMaskModal", () => { return process.env.NODE_ENV !== "test" ? ( test ) : (
test
); }) .add("deniedMetaMaskModal", () => { return process.env.NODE_ENV !== "test" ? ( test ) : (
test
); }) .add("SignatureMetaMaskModal", () => { return process.env.NODE_ENV !== "test" ? ( test ) : (
test
); }) .add("SignatureMetaMaskModal waiting", () => { return process.env.NODE_ENV !== "test" ? ( test ) : (
test
); }); ================================================ FILE: packages/components/src/MetaMaskModal.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Modal, Button, buttonSizes, BorderlessButton, ClipLoader, TransactionButtonNoModal, Transaction, MetaMaskSideIcon, MetaMaskLogoButton, } from "."; import metaMaskModalUrl from "./images/img-metamask-modalconfirm@2x.png"; import confirmButton from "./images/img-metamask-confirm@2x.png"; import signImage from "./images/img-metamaskmodal-new-signature.png"; const ModalP = styled.p` font-size: 16px; color: #5f5f5f; line-height: 26px; && { margin: 16px 0; } `; const HalfPWrapper = styled.div` width: 55%; `; const MainImg = styled.img` width: 40%; height: 240px; object-fit: cover; `; export interface ContentSectionWrapperProps { row?: boolean; } export const MetaMaskStepCounter = styled.div` font-weight: 600; `; const ContentSectionWrapper = styled.div` display: flex; flex-direction: ${(props: ContentSectionWrapperProps) => (props.row ? "row" : "column")}; justify-content: space-between; margin-top: -20px; `; const IB = styled(BorderlessButton)` font-weight: 400; margin-right: 30px; `; const ImgWrapperSmall = styled.span` border-radius: 2px; padding: 4px 5px 1px 5px; border: 1px solid #dddddd; display: inline-blocks; vertical-align: middle; `; const ImgWrapperFull = styled.div` text-align: center; line-height: 0; `; const ButtonContainer = styled.div` display: flex; justify-content: flex-end; padding: 19px 24px; margin: 0 -25px; border-top: 1px solid #dddddd; margin-top: -1px; `; const WaitingButton = styled.div` border: 1px solid #dddddd; padding: 12px 23px; color: #5f5f5f; display: flex; align-items: center; justify-content: space-around; `; const SpanWithMargin = styled.span` margin-right: 10px; font-weight: 600; font-size: 14px; `; export interface MetaMaskModalProps { waiting?: boolean; alert?: boolean; errored?: boolean; denied?: boolean; signing?: boolean; ipfsPost?: boolean; bodyText?: string; denialText?: string; errorText?: string; restartTransactions?: Transaction[]; cancelTransaction?(): void; startTransaction?(): void; } export const MetaMaskModal: React.FunctionComponent = props => { let buttonSection; if (props.ipfsPost && !props.restartTransactions) { } else if (props.alert) { buttonSection = ( ); } else if (!props.waiting) { buttonSection = ( Cancel {props.restartTransactions ? ( {" "} Try Again{" "} ) : ( Open MetaMask )} ); } else { buttonSection = ( Waiting for {props.signing ? "signature" : "confirmation"} ); } let paragraph; if (props.ipfsPost) { paragraph = Your statement is being uploaded to IPFS; } else if (props.signing) { paragraph = !props.waiting ? ( {props.bodyText || "MetaMask will open a new window and request a signature."} ) : ( You need to sign this message in your wallet. MetaMask will open a new window to confirm. If you don't see it, please click the icon{" "} {" "} in the browser bar. ); } else { paragraph = !props.waiting ? ( {props.bodyText || "MetaMask will open a new window for you to confirm this transaction with your wallet."} ) : ( This transaction needs to be confirmed in your wallet. MetaMask will open a new window for you to confirm. If you don't see it, please click the MetaMask icon{" "} {" "} in your browser bar. ); } if (props.denied) { paragraph = ( You have canceled this transaction in your wallet. {!!props.denialText && {props.denialText}} ); } if (props.errored) { paragraph = ( There was an error executing this transaction. {!!props.errorText && ( {props.errorText} )} ); } let image; if (props.ipfsPost || props.alert) { image = undefined; } else if (props.denied || props.errored) { image = ; } else { image = ( ); } return ( {props.children} {paragraph} {image} {buttonSection} ); }; ================================================ FILE: packages/components/src/Modal.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Modal } from "./Modal"; import { FullScreenModal } from "./FullscreenModal"; const StyledDiv = styled.div` display: flex; width: 100vh; height: 100vw; background-color: #fff; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Pattern Library / Modals", module) .add("Modal", () => { return (

Some good stuff was already on the page which is pretty exciting

{process.env.NODE_ENV !== "test" && (

Hello

lorem ipsum whatever you know what i mean. It gets pretty long because thats more useful

)}
); }) .add("Fullscreen Modal", () => { const handleClose = () => { console.log("Modal closed"); }; return (

Some good stuff was already on the page which is pretty exciting

{process.env.NODE_ENV !== "test" && (

Hello

lorem ipsum whatever you know what i mean. It gets pretty long because thats more useful

)}
); }); ================================================ FILE: packages/components/src/Modal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import styled from "styled-components"; import { mediaQueries } from "./styleConstants"; import { RENDER_CONTEXT } from "./context"; interface ToggleDisplayEl { visible: boolean; } interface TextAlignProps { textAlign?: string | undefined; } const ModalOuter = styled.div` position: fixed; top: 0; bottom: 0; left: 0; right: 0; background-color: rgba(255, 255, 255, 0.7); display: flex; display: ${props => (props.visible ? "flex" : "none")}; justify-content: center; align-items: center; text-align: ${props => props.textAlign || "left"}; z-index: 100001; // to beat wp tools ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` display: block; text-align: center; `} `; interface ModalInnerProps { width?: number; padding?: string; fullScreen?: boolean; } const ModalInner = styled.div` box-shadow: 0px 0px 20px 5px rgba(100, 100, 100, 0.4); max-width: ${(props: ModalInnerProps) => props.width || 400}px; padding: ${(props: ModalInnerProps) => props.padding || "35px 35px 50px 35px"}; background: #fff; ${(props: ModalInnerProps): string => { if (props.fullScreen) { return "max-width: 100%; width: 100%; height: 100%; overflow: auto;"; } return ""; }} ${mediaQueries.MOBILE} { max-height: 100%; max-width: 100%; overflow: auto; padding-top: 15px; padding-right: 10px; padding-left: 10px; ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` max-height: none; padding: 16px; display: inline-block; margin: 32px auto 16px; `} } `; export interface ModalPropsAndState { visible?: boolean; textAlign?: string; width?: number; padding?: string; fullScreen?: boolean; onOuterClicked?(): void; } export class Modal extends React.Component { // tslint:disable-next-line private static getDerivedStateFromProps(props: ModalPropsAndState, state: ModalPropsAndState): any | null { if (typeof props.visible !== "undefined") { const visible = props.visible; return { visible }; } return null; } public bucket: HTMLDivElement = document.createElement("div"); public constructor(props: ModalPropsAndState) { super(props); this.state = { visible: this.props.visible || true, }; } public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( { if (this.props.onOuterClicked) { this.props.onOuterClicked(); } }} > { ev.stopPropagation(); }} > {this.props.children} , this.bucket, ); } } ================================================ FILE: packages/components/src/ModalContent.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { ModalHeading, ModalContent } from "./ModalContent"; const StyledDiv = styled.div` display: flex; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Pattern Library / Modals", module).add("content", () => { return ( I'm a Heading I'm a paragraph of some sorts ); }); ================================================ FILE: packages/components/src/ModalContent.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "./styleConstants"; export const ModalHeading = styled.h2` font-family: ${fonts.SANS_SERIF}; font-weight: 600; font-size: 20px; line-height: 30px; && { margin: 16px 0; } `; export const ModalContent = styled.p` font-family: ${fonts.SANS_SERIF}; color: ${colors.primary.CIVIL_GRAY_2}; font-weight: 200; font-size: 12px; line-height: 24px; ${mediaQueries.MOBILE} { margin-right: 10px; margin-left: 10px; } `; export const ModalContentInsetContainer = styled.div` background: ${colors.accent.CIVIL_GRAY_4}; margin: 24px -35px 32px; padding: 20px 40px; text-align: left; & ${ModalContent} { font-size: 16px; line-height: 26px; } `; export const ModalStepLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; line-height: 17px; margin: 0 0 35px; text-transform: uppercase; `; export const ModalUnorderedList = styled.ol` display: flex; flex-flow: column; font-size: 14px; line-height: 19px; `; export const ModalOrderedList = styled.ol` align-items: center; display: flex; flex-flow: column; font-size: 14px; line-height: 19px; `; export interface ModalListItemProps { type?: string; } export interface ModalListItemColorsProps { [index: string]: [string, string, string]; } export enum ModalListItemTypes { FADED = "faded", STRONG = "strong", } export const StyledModalErrorContainer = styled.div` align-items: center; display: flex; background: ${colors.accent.CIVIL_RED_VERY_FADED}; border-radius: 50%; justify-content: center; height: 100px; margin: 0 auto; text-align: center; width: 100px; `; const ModalListItemStyles: ModalListItemColorsProps = { [ModalListItemTypes.FADED]: [colors.accent.CIVIL_GRAY_3, "italic", "normal"], [ModalListItemTypes.STRONG]: [colors.primary.CIVIL_BLUE_1, "normal", "bold"], }; export const ModalListItem = styled.li` color: ${props => (props.type && ModalListItemStyles[props.type][0]) || colors.primary.CIVIL_GRAY_2}; font-style: ${props => (props.type && ModalListItemStyles[props.type][1]) || "normal"}; font-weight: ${props => (props.type && ModalListItemStyles[props.type][2]) || "normal"}; margin: 0 0 5px; white-space: nowrap; `; ================================================ FILE: packages/components/src/NavBar/__snapshots__/NavBar.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Nav / Nav Bar Global Nav 1`] = `

Common / Nav / Nav Bar

Global Nav

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Common / Nav / Nav Bar Nav Error Bar 1`] = `
Please Switch To Rinkeby Testnet

Common / Nav / Nav Bar

Nav Error Bar

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Notice/Notice.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import styled from "styled-components"; import * as React from "react"; import { Notice, NoticeTypes } from "./index"; import { GrantSubmitIcon } from "../icons"; const Container = styled.div` > div { margin: 20px; } `; storiesOf("Pattern Library / Notices", module) .add("Notice - All types", () => ( This is an info notice This is an error notice This is an alert notice This is an attention notice )) .add("Info", () => { return This is an info notice; }) .add("Error", () => { return This is an error notice; }) .add("Alert", () => { return This is an alert notice; }) .add("Attention", () => { return This is an attention notice; }) .add("foundation action", () => { return ( }> {" "} This is a foundation action notice ); }); ================================================ FILE: packages/components/src/Notice/__snapshots__/Notice.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Notices Alert 1`] = `
This is an alert notice

Pattern Library / Notices

Alert

Story Source

            
< Notice type = { 2 } >
This is an alert notice
</ Notice >

Prop Types

" Notice " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Notices Attention 1`] = `
This is an attention notice

Pattern Library / Notices

Attention

Story Source

            
< Notice type = { 3 } >
This is an attention notice
</ Notice >

Prop Types

" Notice " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Notices Error 1`] = `
This is an error notice

Pattern Library / Notices

Error

Story Source

            
< Notice type = { 1 } >
This is an error notice
</ Notice >

Prop Types

" Notice " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Notices Info 1`] = `
This is an info notice

Pattern Library / Notices

Info

Story Source

            
< Notice type = { 0 } >
This is an info notice
</ Notice >

Prop Types

" Notice " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Notices Notice - All types 1`] = `
This is an info notice
This is an error notice
This is an alert notice
This is an attention notice

Pattern Library / Notices

Notice - All types

Story Source

            
< styled.div >
< Notice type = { 0 } >
This is an info notice
</ Notice >
< Notice type = { 1 } >
This is an error notice
</ Notice >
< Notice type = { 2 } >
This is an alert notice
</ Notice >
< Notice type = { 3 } >
This is an attention notice
</ Notice >
</ styled.div >

Prop Types

" Notice " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Notices foundation action 1`] = `
This is a foundation action notice

Pattern Library / Notices

foundation action

Story Source

            
< Notice type = { 4 } icon = { <function (props) { var width = (props.width || 82).toString(); var height = (props.height || 82).toString(); return (React.createElement("svg", { width: width, height: height, viewBox: "0 0 82 82", xmlns: "http://www.w3.org/2000/svg" }, React.createElement("g", { fill: "none", fillRule: "evenodd" }, React.createElement("circle", { cx: "41", cy: "41", r: "41", fill: "#90E8D3" }), React.createElement("g", { fill: "#000", transform: "translate(11 10)" }, React.createElement("path", { fillRule: "nonzero", d: "M2.86742813,19.5094459 L57.2076375,19.5094459 C57.6222497,19.5093254 57.9875374,19.238741 58.1058429,18.8441062 C58.2241484,18.4494714 58.0673687,18.0245305 57.7203375,17.7992193 L30.5502281,0.151842414 C30.238919,-0.050912319 29.8361467,-0.050912319 29.5248375,0.151842414 L2.3547375,17.7992193 C2.00770626,18.0245305 1.85092658,18.4494714 1.9692321,18.8441062 C2.08753763,19.238741 2.45282526,19.5093254 2.8674375,19.5094459 L2.86742813,19.5094459 Z M30.0375,2.0434531 L54.0609375,17.6473769 L6.0140625,17.6473769 L30.0375,2.0434531 Z" }), React.createElement("path", { fillRule: "nonzero", d: "M30.0375,8.31748034 C28.0624928,8.31785569 26.4616926,9.90808967 26.4619032,11.8694761 C26.4621137,13.8308626 28.0632553,15.4207576 30.0382625,15.4207148 C32.0132697,15.4206719 33.6143413,13.8307075 33.6144656,11.869321 C33.6124137,9.90836017 32.0120789,8.31926622 30.0375,8.31748034 L30.0375,8.31748034 Z M30.0375,13.5586366 C29.097967,13.5582612 28.3366081,12.8016113 28.3369032,11.8685578 C28.3371983,10.9355043 29.0990356,10.1793294 30.0385687,10.1795402 C30.9781017,10.1797509 31.739595,10.9362675 31.7394656,11.869321 C31.7385708,12.8022952 30.9769535,13.55826 30.0375,13.5586552 L30.0375,13.5586366 Z" }), React.createElement("path", { d: "M7.99712813 22.8371679L7.99712813 48.8102369C7.99712813 49.324433 8.41686117 49.7412714 8.93462813 49.7412714 9.45239508 49.7412714 9.87212813 49.324433 9.87212813 48.8102369L9.87212813 22.8371679C9.87212813 22.3229718 9.45239508 21.9061334 8.93462813 21.9061334 8.41686117 21.9061334 7.99712813 22.3229718 7.99712813 22.8371679zM22.4322469 22.8371679L22.4322469 48.8102369C22.4322469 49.324433 22.8519799 49.7412714 23.3697469 49.7412714 23.8875138 49.7412714 24.3072469 49.324433 24.3072469 48.8102369L24.3072469 22.8371679C24.3072469 22.3229718 23.8875138 21.9061334 23.3697469 21.9061334 22.8519799 21.9061334 22.4322469 22.3229718 22.4322469 22.8371679zM36.8664563 22.8371679L36.8664563 48.8102369C36.8664563 49.324433 37.2861893 49.7412714 37.8039563 49.7412714 38.3217232 49.7412714 38.7414563 49.324433 38.7414563 48.8102369L38.7414563 22.8371679C38.7414563 22.3229718 38.3217232 21.9061334 37.8039563 21.9061334 37.2861893 21.9061334 36.8664563 22.3229718 36.8664563 22.8371679zM51.301575 22.8371679L51.301575 48.8102369C51.301575 49.324433 51.721308 49.7412714 52.239075 49.7412714 52.756842 49.7412714 53.176575 49.324433 53.176575 48.8102369L53.176575 22.8371679C53.176575 22.3229718 52.756842 21.9061334 52.239075 21.9061334 51.721308 21.9061334 51.301575 22.3229718 51.301575 22.8371679zM1.50695625 54L58.4930437 54C59.0108107 54 59.4305437 53.5831617 59.4305437 53.0689655 59.4305437 52.5547694 59.0108107 52.137931 58.4930437 52.137931L1.50695625 52.137931C.989189297 52.137931.56945625 52.5547694.56945625 53.0689655.56945625 53.5831617.989189297 54 1.50695625 54z" }))))); } /> } >
This is a foundation action notice
</ Notice >

Prop Types

" Notice " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Notice/index.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { InfoNotification } from "../icons"; export enum NoticeTypes { INFO, ERROR, ALERT, ATTENTION, FOUNDATION_ACTION, } export interface NoticeContainerProps { type: NoticeTypes; } const typeColors = { [NoticeTypes.INFO]: { border: "rgb(208,237,237)", background: "rgb(208,237,237)", color: colors.primary.CIVIL_GRAY_1, weight: "400", }, [NoticeTypes.ERROR]: { border: "rgb(242, 82, 74,1)", background: "rgb(242, 82, 74,0.1)", color: colors.primary.CIVIL_GRAY_1, weight: "400", }, [NoticeTypes.ALERT]: { border: "rgba(94,94,94,0.12)", background: colors.accent.CIVIL_YELLOW_VERY_FADED, color: colors.primary.CIVIL_GRAY_1, weight: "400", }, [NoticeTypes.ATTENTION]: { border: "rgba(255,00,0,1)", background: "#FBF9F6", color: colors.primary.CIVIL_GRAY_1, weight: "400", }, [NoticeTypes.FOUNDATION_ACTION]: { border: colors.accent.CIVIL_GRAY_3, background: colors.basic.WHITE, color: colors.primary.BLACK, weight: "bold", }, }; export const NoticeContainer = styled.div` display: flex; flex-direction: row; color: ${(props: NoticeContainerProps) => typeColors[props.type].color}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 20px; padding: 30px 0; text-align: center; border: 1px solid ${(props: NoticeContainerProps) => typeColors[props.type].border}; border-radius: 4px; background-color: ${(props: NoticeContainerProps) => typeColors[props.type].background}; align-items: center; font-weight: ${(props: NoticeContainerProps) => typeColors[props.type].weight}; `; export const NoticeIconContainer = styled("div")` padding-left: 24px; width: 52px; `; export const NoticeMessageContainer = styled.div` flex-grow: 1; margin-right: 80px; margin-left: 28px; `; export interface NoticeProps { type: NoticeTypes; icon?: any; className?: string; children?: any; } export const Notice = ({ className, children, type, icon }: NoticeProps): JSX.Element => { let displayIcon = null; if (type === NoticeTypes.ERROR) { displayIcon = ; } else if (type === NoticeTypes.FOUNDATION_ACTION) { displayIcon = icon; } return ( {displayIcon} {children} ); }; ================================================ FILE: packages/components/src/Parameterizer/ChallengeProposal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { TransactionButtonNoModal } from "../TransactionButton"; import { StyledCreateProposalOuter, StyledCreateProposalContainer, StyledCreateProposalHeader, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, MetaSingleLine, } from "./ParameterizerStyledComponents"; import { ChallengeProposalHeaderText, ChallengeProposalDescriptionText, CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, CreateProposalTokenDepositText, ChallengeProposalNewValueLabelText, } from "./textComponents"; export interface ChallengeProposalProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterNewValue: string; parameterProposalValue: string; proposalDeposit: string; transactions?: any[]; modalContentComponents?: any; handleClose(): void; postExecuteTransactions?(): any; } export class ChallengeProposal extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( {this.props.parameterDisplayName} {this.props.parameterCurrentValue} {this.props.parameterNewValue} {this.props.proposalDeposit} Confirm With Metamask , this.bucket, ); } } ================================================ FILE: packages/components/src/Parameterizer/ChallengeProposalCommitVote.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { PhaseWithExpiryProps, ChallengePhaseProps, CommitVoteProps } from "../ListingDetailPhaseCard/types"; import { StyledPhaseKicker, StyledPhaseDisplayName, FormHeader, FormCopy, } from "../ListingDetailPhaseCard/styledComponents"; import { ChallengePhaseDetail } from "../ListingDetailPhaseCard/ChallengePhaseDetail"; import { CommitVote } from "../ListingDetailPhaseCard/CommitVote"; import { UnderChallengePhaseDisplayNameText, CommitVoteAlreadyVotedHeaderText, CommitVoteAlreadyVotedCopyText, CommitVoteCalloutHeaderText, CommitVoteCalloutCopyText, } from "../ListingDetailPhaseCard/textComponents"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { StyledCreateProposalOuter, StyledChallengeProposalContainer, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, } from "./ParameterizerStyledComponents"; import { CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, ChallengeProposalNewValueLabelText, } from "./textComponents"; export interface ChallengeProposalCommitVoteProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterProposalValue: string; userHasCommittedVote?: boolean; transactions?: any[]; modalContentComponents?: any; handleClose(): void; } export type TChallengeProposalCommitVoteProps = ChallengeProposalCommitVoteProps & PhaseWithExpiryProps & ChallengePhaseProps & CommitVoteProps; export class ChallengeProposalCommitVote extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { const callout = this.renderCommitVoteCallout(); return ReactDOM.createPortal( Challenge ID {this.props.challengeID} {this.props.parameterDisplayName} {this.props.parameterCurrentValue} {this.props.parameterProposalValue} {callout} Challenge ID {this.props.challengeID} Should this proposal be accepted or rejected from the Civil Registry? , this.bucket, ); } private renderCommitVoteCallout = (): JSX.Element => { if (this.props.userHasCommittedVote) { return ( <> ); } return ( <> ); }; } ================================================ FILE: packages/components/src/Parameterizer/ChallengeProposalRevealVote.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { PhaseWithExpiryProps, ChallengePhaseProps, RevealVoteProps } from "../ListingDetailPhaseCard/types"; import { StyledPhaseKicker, StyledPhaseDisplayName, FormHeader, FormCopy, } from "../ListingDetailPhaseCard/styledComponents"; import { ChallengePhaseDetail } from "../ListingDetailPhaseCard/ChallengePhaseDetail"; import { RevealVote } from "../ListingDetailPhaseCard/RevealVote"; import { UnderChallengePhaseDisplayNameText } from "../ListingDetailPhaseCard/textComponents"; import { TwoPhaseProgressBarCountdownTimer } from "../PhaseCountdown/"; import { StyledCreateProposalOuter, StyledChallengeProposalContainer, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, } from "./ParameterizerStyledComponents"; import { CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, ChallengeProposalNewValueLabelText, } from "./textComponents"; export interface ChallengeProposalRevealVoteProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterProposalValue: string; transactions?: any[]; modalContentComponents?: any; userHasRevealedVote?: boolean; userHasCommittedVote?: boolean; handleClose(): void; postExecuteTransactions?(): any; } export type TChallengeProposalRevealVoteProps = ChallengeProposalRevealVoteProps & PhaseWithExpiryProps & ChallengePhaseProps & RevealVoteProps; export class ChallengeProposalRevealVote extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( Challenge ID {this.props.challengeID} {this.props.parameterDisplayName} {this.props.parameterCurrentValue} {this.props.parameterProposalValue} Challenge ID {this.props.challengeID} {this.renderRevealVote()} , this.bucket, ); } private renderRevealVote = (): JSX.Element => { if (!this.props.userHasCommittedVote) { return ( <> You did not participate in this challenge You did not commit a vote, so there is nothing here for you to reveal ); } else if (this.props.userHasRevealedVote) { return ( <> You have revealed your vote Thank you for participating! Please check back after the challenge ends to see if you have earned a reward{" "} ); } else { return ( <> Should this proposal be accepted or rejected from the Civil Registry? ); } }; } ================================================ FILE: packages/components/src/Parameterizer/ChallengeProposalReviewVote.tsx ================================================ import * as React from "react"; import AddToCalendar from "react-add-to-calendar"; import { EthAddress } from "@joincivil/typescript-types"; import { saltToWords, getFormattedEthAddress, getLocalDateTimeStrings, padString } from "@joincivil/utils"; import { FullScreenModal, FullScreenModalProps } from "../FullscreenModal"; import { buttonSizes, CancelButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { QuestionToolTip } from "../QuestionToolTip"; import { Checkbox, CheckboxSizes } from "../input/Checkbox"; import { MetaMaskLogoButton } from "../"; import { ReviewVoteHeaderTitleText, ReviewVoteCopyText, SaltLabelText, ReviewVoteDepositedCVLLabelText, ReviewVoteMyAddressLabelText, ConfirmVotesLabelText, TransactionButtonText, SaltPhraseToolTipText, TransactionFinePrintText, SaveSaltCheckboxLabelText, } from "../ReviewVote/textComponents"; import { ModalOuter, ModalContent, StyledReviewVoteHeaderTitle, StyledReviewVoteContent, StyledReviewVoteContentCopy, StyledReviewVoteDetails, MetaRow, MetaRowSalt, MetaItemLabel, MetaItemLabelSalt, MetaItemValue, MetaItemValueUser, MetaItemValueSalt, MetaItemValueTwoCol, StyledAddToCalendarContainer, StyledConfirmVoteDateRange, StyledAddToCalendar, StyledButtonContainer, StyledTransactionFinePrint, StyledDidSaveSaltContainer, } from "../ReviewVote/styledComponents"; export interface ChallengeProposalReviewVoteProps extends FullScreenModalProps { parameterName: string | JSX.Element; proposalURL: string; challengeID: string; numTokens?: string; voteOption?: string; salt?: string; userAccount: EthAddress; commitEndDate: number; revealEndDate: number; transactions: any[]; modalContentComponents?: any; handleClose(): void; postExecuteTransactions?(): void; } interface ReviewVoteState { didSaveSalt: boolean; } function printThis(): void { window.print(); } function getSaltyWords(salt?: string): string { if (!salt) { return ""; } return saltToWords(salt).join(" "); } function getReadableRevealDateRange(commitEndDate: number, revealEndDate: number): string { const revealStartDateTime = getLocalDateTimeStrings(commitEndDate + 1); const revealEndDateTime = getLocalDateTimeStrings(revealEndDate); return `From ${revealStartDateTime[0]} at ${revealStartDateTime[1]} to ${revealEndDateTime[0]} at ${revealEndDateTime[1]}`; } function getCalendarEventDateTime(seconds: number | Date): string { const theDate = typeof seconds === "number" ? new Date(seconds * 1000) : seconds; const pad = (num: number | string) => { return padString(num, 2, "0"); }; const hours = pad(theDate.getHours()); const mins = pad(theDate.getMinutes()); const tzOffset = `${pad(theDate.getTimezoneOffset() / 60)}${pad(theDate.getTimezoneOffset() % 60)}`; const dateString = `${theDate.getFullYear()}-${pad(theDate.getMonth() + 1)}-${pad(theDate.getDate())}`; const timeString = `${hours}:${mins}-${tzOffset}`; return `${dateString}T${timeString}`; } const AddRevealPhaseToCalendar: React.FunctionComponent = props => { // @TODO(jon): `textComponents` don't work here b/c these fields are plaintext. Let's // revisit converting JSX.Components to strings via textContent before this goes to mainnet const title = `Reveal My Vote for ${props.parameterName} on The Civil Registry`; const description = ` ${props.proposalURL}\n\n My Secret Phrase\n ${getSaltyWords(props.salt)}\n\n Challenge ID ${props.challengeID}\n I voted for ${props.parameterName} to ${ props.voteOption === "0" ? "remain the same" : "change" } on the Civil Registry\n\n My Deposited CVL\n ${props.numTokens} `; const location = props.proposalURL; const startTime = getCalendarEventDateTime(props.commitEndDate + 1); const endTime = getCalendarEventDateTime(props.revealEndDate); const event = { title, description, location, startTime, endTime, }; return ( ); }; export class ChallengeProposalReviewVote extends React.Component { public state = { didSaveSalt: false, }; public render(): JSX.Element { const { open, challengeID, salt, commitEndDate, revealEndDate, voteOption, parameterName, numTokens, userAccount, transactions, postExecuteTransactions, handleClose, } = this.props; const { didSaveSalt } = this.state; return (
} positionBottom={true} /> {getSaltyWords(salt)} {getReadableRevealDateRange(commitEndDate, revealEndDate)}

Remember to set event to Private

Challenge ID {challengeID} I voted for {parameterName} to {voteOption === "0" ? "remain the same" : "change"} on the Civil Registry\n\n {numTokens} {userAccount && getFormattedEthAddress(userAccount)}
Cancel
); } private toggleHasSavedSalt = (): void => { this.setState({ didSaveSalt: !this.state.didSaveSalt }); }; } ================================================ FILE: packages/components/src/Parameterizer/CreateGovtProposal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { InputGroup } from "../input"; import { TransactionButtonNoModal } from "../TransactionButton"; import { StyledCreateProposalOuter, StyledCreateProposalContainer, StyledCreateProposalHeader, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, } from "./ParameterizerStyledComponents"; import { CreateProposalHeaderText, CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, } from "./textComponents"; export interface CreateGovtProposalProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterDisplayUnits: string; parameterProposalValue: string; transactions?: any[]; handleClose(): void; handleUpdateProposalValue(name: string, value: string): void; postExecuteTransactions?(): any; } export interface CreateGovtProposalState { parameterProposalValue: string; } export class CreateGovtProposal extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( {this.props.parameterDisplayName} {this.props.parameterCurrentValue} } /> Confirm With Metamask , this.bucket, ); } } ================================================ FILE: packages/components/src/Parameterizer/CreateProposal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { InputGroup } from "../input"; import { TransactionButtonNoModal } from "../TransactionButton"; import { StyledCreateProposalOuter, StyledCreateProposalContainer, StyledCreateProposalHeader, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, MetaSingleLine, } from "./ParameterizerStyledComponents"; import { CreateProposalHeaderText, CreateProposalDescriptionText, CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, CreateProposalTokenDepositText, } from "./textComponents"; export interface CreateProposalProps { pApplyLenText: string | JSX.Element; parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterDisplayUnits: string; parameterProposalValue: string; proposalDeposit: string; transactions?: any[]; handleClose(): void; handleUpdateProposalValue(name: string, value: string): void; postExecuteTransactions?(): any; } export interface CreateProposalState { parameterProposalValue: string; } export class CreateProposal extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( {this.props.parameterDisplayName} {this.props.parameterCurrentValue} } /> {this.props.proposalDeposit} Confirm With Metamask , this.bucket, ); } } ================================================ FILE: packages/components/src/Parameterizer/Parameterizer.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { StyledParameterizerContainer } from "./ParameterizerStyledComponents"; import { CreateProposal } from "./CreateProposal"; const StyledDiv = styled.div` display: flex; width: 110px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); const noop = () => { return; }; storiesOf("Registry / Parameterizer", module).add("Create Proposal", () => { return ( {process.env.NODE_ENV !== "test" && ( console.log("Proposed Value is", value)} /> )} ); }); ================================================ FILE: packages/components/src/Parameterizer/ParameterizerStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export const StyledParameterizerContainer = styled.div` margin: 40px 0 0; `; export const StyledCreateProposalContainer = styled.div` background: ${colors.accent.CIVIL_GRAY_4}; bottom: 0; border: 1px solid ${colors.accent.CIVIL_GRAY_3}; font-family: ${fonts.SANS_SERIF}; right: 0; top: 0; width: 634px; `; export const StyledChallengeProposalContainer = styled.div` background: ${colors.basic.WHITE}; bottom: 0; border: 1px solid ${colors.accent.CIVIL_GRAY_3}; font-family: ${fonts.SANS_SERIF}; overflow-y: scroll; right: 0; top: 0; width: 634px; `; export const StyledCreateProposalOuter = styled.div` background: ${colors.basic.WHITE}9a; // 9a is hex for 60^ border: 1px solid ${colors.accent.CIVIL_GRAY_4}; bottom: 0; left: 0; position: fixed; overflow-y: scroll; right: 0; top: 56px; & ${StyledCreateProposalContainer}, & ${StyledChallengeProposalContainer} { position: absolute; } `; export const StyledCreateProposalHeader = styled.div` background-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.basic.WHITE}; font-size: 21px; font-weight: bold; letter-spacing: -0.45px; line-height: 25px; padding: 16px 40px; position: relative; `; export const StyledCreateProposalHeaderClose = styled.div` cursor: pointer; font-size: 21px; font-weight: bold; line-height: 21px; position: absolute; right: 14px; top: 11px; `; export const StyledCreateProposalContent = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 16px; line-height: 20px; padding: 24px 40px 40px; `; export const StyledSection = styled.div` margin: 0 0 19px; `; export const StyledMetaName = styled.div` margin: 0 0 3px; `; export const StyledMetaValue = styled.div` font-weight: bold; `; export const MetaSingleLine = styled.div` display: flex; justify-content: space-between; margin: 0 0 20px; & ${StyledMetaValue} { text-align: right; } `; ================================================ FILE: packages/components/src/Parameterizer/ParameterizerTableCell.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, mediaQueries } from "../styleConstants"; import { Td } from "../Table"; import { StyledTableCell } from "../Table/styledComponents"; import { TableCellProps } from "../Table/types"; const StyledParameterizerTableCell = styled(StyledTableCell)` ${mediaQueries.MOBILE} { display: flex; &:before { display: block; background-color: ${(props: TableCellProps) => props.accent ? colors.accent.CIVIL_GRAY_4 + "7D" : "transparent"}; content: attr(data-mobile-th); text-align: ${(props: TableCellProps) => props.align || "left"}; width: 50%; } } `; const StyledParameterizerTableCellInner = styled.div` ${mediaQueries.MOBILE} { width: 50%; } `; export const ParameterizerTd: React.FunctionComponent = props => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/Parameterizer/ProcessProposal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { TransactionButtonNoModal } from "../TransactionButton"; import { StyledCreateProposalOuter, StyledChallengeProposalContainer, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, } from "./ParameterizerStyledComponents"; import { ProcessProposalDescriptionText, CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, ChallengeProposalNewValueLabelText, } from "./textComponents"; export interface ProcessProposalProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterNewValue: string; parameterProposalValue: string; transactions?: any[]; modalContentComponents?: any; handleClose(): void; postExecuteTransactions?(): any; } export class ProcessProposal extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( {this.props.parameterDisplayName} {this.props.parameterCurrentValue} {this.props.parameterNewValue} Confirm With Metamask , this.bucket, ); } } ================================================ FILE: packages/components/src/Parameterizer/ResolveChallengeProposal.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import { TransactionButtonNoModal } from "../TransactionButton"; import { ChallengeResults, ChallengeResultsProps } from "../ChallengeResultsChart"; import { StyledCreateProposalOuter, StyledChallengeProposalContainer, StyledCreateProposalHeaderClose, StyledCreateProposalContent, StyledSection, StyledMetaName, StyledMetaValue, } from "./ParameterizerStyledComponents"; import { ResolveChallengeProposalDescriptionText, CreateProposalParamNameLabelText, CreateProposalParamCurrentValueLabelText, ChallengeProposalNewValueLabelText, } from "./textComponents"; export interface ResolveChallengeProposalProps { parameterDisplayName: string | JSX.Element; parameterCurrentValue: string; parameterNewValue: string; transactions?: any[]; handleClose(): void; postExecuteTransactions?(): any; } export class ResolveChallengeProposal extends React.Component { public bucket: HTMLDivElement = document.createElement("div"); public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { document.body.removeChild(this.bucket); } public render(): React.ReactPortal { return ReactDOM.createPortal( {this.props.parameterDisplayName} {this.props.parameterCurrentValue} {this.props.parameterNewValue} Confirm With Metamask , this.bucket, ); } } ================================================ FILE: packages/components/src/Parameterizer/__snapshots__/Parameterizer.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Parameterizer Create Proposal 1`] = `

Registry / Parameterizer

Create Proposal

Story Source

            
< Container />

Prop Types

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Parameterizer/index.ts ================================================ export * from "./textComponents"; export * from "./CreateProposal"; export * from "./CreateGovtProposal"; export * from "./ChallengeProposal"; export * from "./ChallengeProposalCommitVote"; export * from "./ChallengeProposalRevealVote"; export * from "./ChallengeProposalReviewVote"; export * from "./ResolveChallengeProposal"; export * from "./ProcessProposal"; export * from "./ParameterizerTableCell"; export { StyledParameterizerContainer } from "./ParameterizerStyledComponents"; ================================================ FILE: packages/components/src/Parameterizer/textComponents.tsx ================================================ import * as React from "react"; export const MinDepositLabelText: React.FunctionComponent = props => <>Application Deposit; export const ParamMinDepositLabelText: React.FunctionComponent = props => <>Parameter Proposal Deposit; export const ApplicationStageLenLabelText: React.FunctionComponent = props => <>Duration for Application Stage; export const ParamApplicationStageLenLabelText: React.FunctionComponent = props => ( <>Duration for Parameter Proposal Application Stage ); export const CommitStageLenLabelText: React.FunctionComponent = props => <>Duration for Commit Vote Stage; export const ParamCommitStageLenLabelText: React.FunctionComponent = props => ( <>Duration for Parameter Commit Vote Stage ); export const RevealStageLenLabelText: React.FunctionComponent = props => <>Duration for Reveal Vote Stage; export const ParamRevealStageLenLabelText: React.FunctionComponent = props => ( <>Duration for Parameter Reveal Vote Stage ); export const DispensationPctLabelText: React.FunctionComponent = props => ( <>Percentage of Stake Distributed To Challenge Winner ); export const ParamDispensationPctLabelText: React.FunctionComponent = props => ( <>Percentage of Stake Distributed To Parameter Proposal Challenge Winner ); export const VoteQuorumLabelText: React.FunctionComponent = props => ( <>Percentage of Votes Needed for Challenge to Succeed ); export const ParamVoteQuorumLabelText: React.FunctionComponent = props => ( <>Percentage of Votes Needed for Parameter Proposal Challenge to Succeed ); export const ChallengeAppealLenLabelText: React.FunctionComponent = props => <>Duration of Challenge Appeal Stage; export const ChallengeAppealCommitStageLenLabelText: React.FunctionComponent = props => ( <>Duration of Challenge Appeal Commit Vote Stage ); export const ChallengeAppealRevealStageLenLabelText: React.FunctionComponent = props => ( <>Duration of Challenge Appeal Reveal Vote Stage ); export const RequestAppealLenLabelText: React.FunctionComponent = props => <>Duration of Request Appeal Stage; export const JudgeAppealLenLabelText: React.FunctionComponent = props => <>Duration of Judge Appeal Stage; export const GovtProposalCommitStageLenLabelText: React.FunctionComponent = props => ( <>Duration of Government Proposal Commit Vote Stage ); export const GovtProposalRevealStageLenLabelText: React.FunctionComponent = props => ( <>Duration of Government Proposal Reveal Vote Stage ); export const AppealFeeLabelText: React.FunctionComponent = props => <>Request Appeal Deposit; export const AppealVotePercentageLabelText: React.FunctionComponent = props => ( <>Percentage of Votes Needed To Overturn a Granted Appeal ); export const AppealVoteDispensationPctLabelText: React.FunctionComponent = props => ( <>Percentage of Stake Distributed To Appeal Challenge Winner ); // Create Proposal export const CreateProposalHeaderText: React.FunctionComponent = props => <>Propose New Value; export interface CreateProposalDescriptionTextProps { applicationLenText: string | JSX.Element; } export const CreateProposalDescriptionText: React.FunctionComponent = props => ( <> Create a new proposal to change a parameter value on The Civil Registry. The CVL token holder community will have{" "} {props.applicationLenText} to challenge the proposal. If there are no challenges, the new value will be automatically approved. ); export const CreateProposalParamNameLabelText: React.FunctionComponent = props => <>Parameter Name; export const CreateProposalParamCurrentValueLabelText: React.FunctionComponent = props => <>Current Value; export const CreateProposalTokenDepositText: React.FunctionComponent = props => <>Total token deposit; // Challenge Proposal export const ChallengeProposalHeaderText: React.FunctionComponent = props => <>Challenge Proposal; export const ChallengeProposalDescriptionText: React.FunctionComponent = props => <>Challenge this proposal.; export const ChallengeProposalNewValueLabelText: React.FunctionComponent = props => <>Proposed Value; export const ResolveChallengeProposalDescriptionText: React.FunctionComponent = props => ( <>Resolve this Proposal Challenge ); export const ProcessProposalDescriptionText: React.FunctionComponent = props => ( <>Process this proposal and update the Registry Parameters with the new value ); ================================================ FILE: packages/components/src/Payments/AvatarLogin.tsx ================================================ import * as React from "react"; import { AvatarGenericIcon, DropdownArrow, colors } from "@joincivil/elements"; import styled from "styled-components"; import { ICivilContext, CivilContext } from "../context"; import { urlConstants as links } from "@joincivil/utils"; const AvatarLoginWrapper = styled.div` position: relative; `; const AvatarImg = styled.img` border-radius: 50%; height: 24px; width: 24px; `; const AvatarLoginAvatarBtn = styled.button` align-items: center; background-color: transparent; border: none; cursor: pointer; display: flex; justify-content: space-between; outline: none; padding: 5px; width: 50px; `; const AvatarLoginDropdown = styled.div` background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 4px; box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); padding: 5px 0; position: absolute; right: 0; top: 30px; width: 120px; `; const AvatarLoginOptionBtn = styled.button` background-color: ${colors.basic.WHITE}; border: none; color: ${colors.accent.CIVIL_GRAY_1}; cursor: pointer; font-size: 13px; line-height: 16px; outline: none; padding: 5px 12px; text-align: left; transition: color 250ms; width: 100%; &:hover { color: ${colors.accent.CIVIL_BLUE}; } `; const AvatarLoginOptionLink = styled.a` color: ${colors.accent.CIVIL_GRAY_1}; cursor: pointer; font-size: 13px; line-height: 16px; padding: 5px 12px; transition: color 250ms; width: 100%; &:hover { color: ${colors.accent.CIVIL_BLUE}; } `; export interface AvatarLoginStates { isOpen: boolean; } export class AvatarLogin extends React.Component<{}, AvatarLoginStates> { public static contextType = CivilContext; public static context: ICivilContext; constructor(props: any) { super(props); this.state = { isOpen: false }; } public render(): JSX.Element { const currentUser = this.context && this.context.currentUser; const showWeb3Login = this.context.auth.showWeb3Login; const logout = this.context.auth.logout.bind(this.context.auth); return ( {currentUser ? ( <> this.setState({ isOpen: !this.state.isOpen })}> {currentUser.userChannel.tiny72AvatarDataUrl ? ( ) : ( )} {this.state.isOpen && ( Your Profile Logout )} ) : ( <> this.setState({ isOpen: !this.state.isOpen })}> {this.state.isOpen && ( Log In / Sign Up )} )} ); } } ================================================ FILE: packages/components/src/Payments/PaymentIntentsStripeForm.tsx ================================================ import * as React from "react"; import { PAYMENTS_STRIPE_MUTATION, SET_EMAIL_MUTATION, GET_STRIPE_PAYMENT_INTENT, CREATE_PAYMENT_METHOD, CLONE_PAYMENT_METHOD, } from "./queries"; import { injectStripe, ReactStripeElements } from "react-stripe-elements"; import styled from "styled-components"; import { PaymentsFormWrapper } from "./PaymentsFormWrapper"; import { CivilContext, ICivilContext } from "../context"; import { isValidEmail } from "@joincivil/utils"; import { RadioInput, RadioButtonStandard } from "@joincivil/elements"; import { PaymentTerms, PaymentBtn, PaymentInputLabel, PaymentError, CheckboxContainer, CheckboxSection, CheckboxLabel, } from "./PaymentsStyledComponents"; import { PayWithCardText, PaymentStripeNoticeText, PaymentTermsText, PaymentErrorText, } from "./PaymentsTextComponents"; import { INPUT_STATE } from "./types"; import { Checkbox, CheckboxSizes } from "../input"; import { PaymentStripeFormSavedCard } from "./PaymentsStripeFormSavedCard"; import ApolloClient from "apollo-client"; import { PaymentsStripeCardComponent } from "./PaymentsStripeCardComponent"; export interface PaymentIntentsStripeFormProps extends ReactStripeElements.InjectedStripeProps { postId: string; newsroomName: string; shouldPublicize: boolean; userEmail?: string; userChannelID?: string; paymentMethods?: any[]; usdToSpend: number; apolloClient: ApolloClient; paymentIntentsEnabled: boolean; stripeApiKey: string; connectedStripeAccountID: string; handlePaymentSuccess(userSubmittedEmail: boolean, didSaveEmail: boolean): void; handleEditPaymentType(): void; } export interface PaymentIntentsStripeFormStates { email: string; emailState: string; name: string; nameState: string; cardInfoState: string; isPaymentError: boolean; paymentProcessing: boolean; wasEmailPrepopulated: boolean; promptSaveEmail: boolean; shouldSaveEmailToAccount: boolean; shouldAddEmailToMailingList: boolean; shouldSaveCCToAccount: boolean; displayStripeErrorMessage: string; payWithNewCard: boolean; paymentMethodId: string; defaultPaymentMethodId: string; hasSavedPaymentMethod: boolean; } class PaymentIntentsStripeForm extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: any) { super(props); const defaultPaymentMethodId = props.paymentMethods && props.paymentMethods.length > 0 ? props.paymentMethods[0].paymentMethodID : ""; this.state = { email: props.userEmail || "", wasEmailPrepopulated: props.userEmail ? true : false, promptSaveEmail: !props.userEmail && props.userChannelID ? true : false, emailState: this.props.userEmail ? INPUT_STATE.VALID : INPUT_STATE.EMPTY, name: "", nameState: INPUT_STATE.EMPTY, cardInfoState: INPUT_STATE.EMPTY, isPaymentError: false, paymentProcessing: false, shouldSaveEmailToAccount: true, shouldAddEmailToMailingList: false, shouldSaveCCToAccount: false, displayStripeErrorMessage: "", payWithNewCard: false, paymentMethodId: defaultPaymentMethodId, defaultPaymentMethodId, hasSavedPaymentMethod: props.paymentMethods && props.paymentMethods.length > 0, }; this.handleSubmit = this.handleSubmit.bind(this); } public render(): JSX.Element { const showCreditCardForm = !this.state.hasSavedPaymentMethod || this.state.payWithNewCard; return ( <> } paymentNoticeText={} showSecureIcon={true} > {this.props.paymentIntentsEnabled && this.state.defaultPaymentMethodId !== "" && ( {this.props.paymentMethods!.map(pm => { return ( ); })} Pay with a new credit card )} {showCreditCardForm && ( <> {this.props.userChannelID && this.props.userChannelID !== "" && ( <> Remember Credit Card )} )} {this.state.promptSaveEmail && this.state.emailState === INPUT_STATE.VALID && ( <> )} this.handleSubmit()} disabled={this.disableBoostBtn()}> {this.state.paymentProcessing ? "Payment processing..." : "Complete Boost"} {this.state.isPaymentError && ( )} ); } private handleStripeChange = (event: any) => { const stripeElements = document.querySelectorAll(".StripeElement"); let displayStripeErrorMessage = ""; if (event.error) { displayStripeErrorMessage = event.error.message; } stripeElements.forEach(element => { const classList = element.classList; if (classList.contains("StripeElement--invalid")) { this.setState({ cardInfoState: INPUT_STATE.INVALID, displayStripeErrorMessage }); } else if (classList.contains("StripeElement--empty")) { this.setState({ cardInfoState: INPUT_STATE.EMPTY, displayStripeErrorMessage }); } else { this.setState({ cardInfoState: INPUT_STATE.VALID, displayStripeErrorMessage }); } }); }; private disableBoostBtn = () => { const disableBoostBtn = this.state.emailState === INPUT_STATE.VALID && this.state.nameState === INPUT_STATE.VALID && this.state.cardInfoState === INPUT_STATE.VALID && this.state.paymentProcessing === false ? false : true; return disableBoostBtn && !this.state.paymentMethodId; }; private toggleShouldSaveCCToAccount = () => { this.setState({ shouldSaveCCToAccount: !this.state.shouldSaveCCToAccount }); }; private toggleShouldSaveEmailToAccount = () => { this.setState({ shouldSaveEmailToAccount: !this.state.shouldSaveEmailToAccount }); }; private toggleShouldAddEmailToMailingList = () => { this.setState({ shouldAddEmailToMailingList: !this.state.shouldAddEmailToMailingList }); }; private handleSavedCreditCard = (name: string, value: any) => { if (value === "new card") { this.setState({ payWithNewCard: true, paymentMethodId: "" }); } else { this.setState({ payWithNewCard: false, paymentMethodId: value }); } }; private handleOnBlur = (event: any) => { const state = event.target.id; const value = event.target.value; switch (state) { case "email": const validEmail = isValidEmail(value); validEmail ? this.setState({ email: value, emailState: INPUT_STATE.VALID }) : this.setState({ emailState: INPUT_STATE.INVALID }); break; case "name": const validName = value !== ""; validName ? this.setState({ name: value, nameState: INPUT_STATE.VALID }) : this.setState({ nameState: INPUT_STATE.INVALID }); break; default: break; } }; private async handleChargePayment(): Promise { try { const token = await this.props.stripe!.createToken({ name: this.state.name, }); await this.props.apolloClient.mutate({ mutation: PAYMENTS_STRIPE_MUTATION, variables: { postID: this.props.postId, input: { // @ts-ignore paymentToken: token.token.id, amount: this.props.usdToSpend, currencyCode: "usd", emailAddress: this.state.email, shouldPublicize: this.props.shouldPublicize, payerChannelID: this.props.userChannelID, }, }, }); return true; } catch (err) { console.error(err); return false; } } private async clonePaymentMethodAndPayViaIntent( paymentMethodID: string, clonePayerChannelID?: string, ): Promise { try { const cloneVariables = { postID: this.props.postId, input: { payerChannelID: clonePayerChannelID, paymentMethodID, amount: 0, currencyCode: "usd", }, }; const cloneResult = await this.props.apolloClient.mutate({ mutation: CLONE_PAYMENT_METHOD, variables: cloneVariables, }); if (cloneResult.error) { console.error(cloneResult.error) } const pamentMethodID2 = (cloneResult as any).data.paymentsClonePaymentMethod.paymentMethodID; const paymentIntentVariables = { postID: this.props.postId, input: { amount: this.props.usdToSpend, currencyCode: "usd", emailAddress: this.state.email, shouldPublicize: this.props.shouldPublicize, payerChannelID: this.props.userChannelID, }, }; const paymentIntent = await this.props.apolloClient.mutate({ mutation: GET_STRIPE_PAYMENT_INTENT, variables: paymentIntentVariables, }); if (paymentIntent.error) { console.error(paymentIntent.error); return false; } const paymentIntentSecret = (paymentIntent as any).data.paymentsCreateStripePaymentIntent.clientSecret; const connectedAccountStripe = window.Stripe(this.props.stripeApiKey, { stripeAccount: this.props.connectedStripeAccountID, }); const piResult = await connectedAccountStripe.confirmCardPayment(paymentIntentSecret, { payment_method: pamentMethodID2, }); if (piResult.error) { console.error(piResult.error); return false; } return true; } catch (err) { console.error(err); return false; } } private async savePaymentMethodThenCloneAndPayViaIntent(): Promise { try { const result = await (this.props.stripe as any).createPaymentMethod({ type: "card", card: (this.props as any).elements.getElement("card"), billing_details: { name: this.state.name, email: this.state.email, }, }); const paymentMethodID = result.paymentMethod.id; const paymentMethodVariables = { input: { paymentMethodID, emailAddress: this.state.email, payerChannelID: this.props.userChannelID, }, }; const paymentMethodResult = await this.props.apolloClient.mutate({ mutation: CREATE_PAYMENT_METHOD, variables: paymentMethodVariables, }); if (paymentMethodResult.error) { console.error(paymentMethodResult.error); return false; } return this.clonePaymentMethodAndPayViaIntent( paymentMethodResult.data.paymentsCreateStripePaymentMethod.paymentMethodID, this.props.userChannelID, ); } catch (err) { console.error(err); return false; } } private async useOneTimePaymentIntent(): Promise { try { const result = await (this.props.stripe as any).createPaymentMethod({ type: "card", card: (this.props as any).elements.getElement("card"), billing_details: { name: this.state.name, email: this.state.email, }, }); const paymentMethodID = result.paymentMethod.id; return this.clonePaymentMethodAndPayViaIntent(paymentMethodID); } catch (err) { console.error(err); return false; } } private async handleSubmit(): Promise { this.context.fireAnalyticsEvent("boost", "Stripe submit clicked", this.props.postId, this.props.usdToSpend); this.setState({ paymentProcessing: true, isPaymentError: false }); let didSaveEmail = false; if (this.state.promptSaveEmail && this.state.email && this.state.shouldSaveEmailToAccount) { didSaveEmail = true; const variables = { input: { emailAddress: this.state.email, channelID: this.props.userChannelID, addToMailing: this.state.shouldAddEmailToMailingList, }, }; await this.props.apolloClient.mutate({ mutation: SET_EMAIL_MUTATION, variables, }); } let success = false; const cardFormVisible = !this.state.hasSavedPaymentMethod || this.state.payWithNewCard; if (this.props.stripe) { if (!this.props.paymentIntentsEnabled) { success = await this.handleChargePayment(); } else if (this.state.paymentMethodId !== "") { success = await this.clonePaymentMethodAndPayViaIntent(this.state.paymentMethodId, this.props.userChannelID); } else if (cardFormVisible && this.state.shouldSaveCCToAccount) { success = await this.savePaymentMethodThenCloneAndPayViaIntent(); } else { success = await this.useOneTimePaymentIntent(); } } if (success) { this.context.fireAnalyticsEvent( "boost", "Stripe transaction confirmed", this.props.postId, this.props.usdToSpend, ); this.props.handlePaymentSuccess(this.state.email !== "" && true, didSaveEmail); } else { this.context.fireAnalyticsEvent("boost", "Stripe transaction rejected", this.props.postId, this.props.usdToSpend); this.setState({ paymentProcessing: false, isPaymentError: true }); } } } export default injectStripe(PaymentIntentsStripeForm); ================================================ FILE: packages/components/src/Payments/Payments.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled, { ThemeProvider } from "styled-components"; import { PaymentsAmount } from "./PaymentsAmount"; import { PaymentsLoginOrGuest } from "./PaymentsLoginOrGuest"; import { PaymentsSuccess } from "./PaymentsSuccess"; import { RENDER_CONTEXT } from "../context"; import { DEFAULT_CHECKBOX_THEME } from "../input"; import { DEFAULT_BUTTON_THEME } from "../Button"; const Container = styled.div` width: 400px; `; const suggestedAmounts = [{ amount: "1" }, { amount: "2" }, { amount: "3" }, { amount: "5" }]; const onClickFunc = () => { console.log("clicked"); }; const theme = { ...DEFAULT_CHECKBOX_THEME, ...DEFAULT_BUTTON_THEME, renderContext: RENDER_CONTEXT.EMBED, }; storiesOf("Boost / Payments", module) .add("Payment Amount", () => { return ( ); }) .add("Payment Login or Guest Selection", () => { return ( ); }) .add("Payment Success", () => { return ( ); }); ================================================ FILE: packages/components/src/Payments/Payments.tsx ================================================ import * as React from "react"; import { ICivilContext, CivilContext } from "../context"; import { PaymentsAmount } from "./PaymentsAmount"; import { PaymentsLoginOrGuest } from "./PaymentsLoginOrGuest"; import { PaymentsSelectType } from "./PaymentsSelectType"; import { PaymentsEth } from "./PaymentsEth"; import { PaymentsStripe } from "./PaymentsStripe"; import { PaymentsApplePay } from "./PaymentsApplePay"; import { PaymentsGooglePay } from "./PaymentsGooglePay"; import { PaymentsWrapper } from "./PaymentsWrapper"; import { SuggestedPaymentAmounts, CreditCardMin, PAYMENT_STATE } from "./types"; import { PaymentsSuccess } from "./PaymentsSuccess"; export interface PaymentsProps { postId: string; usdToSpend?: number; boostType?: string; paymentAddress: string; newsroomName: string; activeChallenge: boolean; isStripeConnected: boolean; stripeAccountID: string; handleClose(): void; } export interface PaymentsStates { usdToSpend: number; etherToSpend?: number; selectedUsdToSpend?: number; paymentAdjustedWarning: boolean; paymentAdjustedStripe: boolean; paymentAdjustedEth: boolean; shouldPublicize: boolean; paymentState: PAYMENT_STATE; resetEthPayments: boolean; userSubmittedEmail: boolean; paymentInProgress: boolean; waitingForConfirmation: boolean; } export class Payments extends React.Component { public static contextType = CivilContext; public static context: ICivilContext; constructor(props: any) { super(props); this.state = { usdToSpend: props.usdToSpend || 0, paymentAdjustedWarning: false, paymentAdjustedStripe: false, paymentAdjustedEth: false, shouldPublicize: true, paymentState: PAYMENT_STATE.SELECT_AMOUNT, resetEthPayments: false, userSubmittedEmail: false, paymentInProgress: false, waitingForConfirmation: false, }; } public componentDidMount(): void { this.context.auth.ensureLoggedInUserEnabled(); if (this.props.boostType === "project") { const paymentAdjustedWarning = this.props.usdToSpend && this.props.usdToSpend <= CreditCardMin ? true : false; this.setState({ paymentState: PAYMENT_STATE.PAYMENT_CHOOSE_LOGIN_OR_GUEST, paymentAdjustedWarning, }); } } public render(): JSX.Element { if (!this.context) { return <>; } const { usdToSpend, etherToSpend, shouldPublicize, paymentState, selectedUsdToSpend, paymentAdjustedWarning, paymentAdjustedStripe, paymentAdjustedEth, userSubmittedEmail, paymentInProgress, waitingForConfirmation, } = this.state; const { postId, paymentAddress, newsroomName, activeChallenge, isStripeConnected, stripeAccountID, boostType, handleClose, } = this.props; const showWeb3Login = this.context.auth.showWeb3Login; // User logged in from PAYMENT_CHOOSE_LOGIN_OR_GUEST state, which will be reflected in context, and we should now show them SELECT_PAYMENT_TYPE state instead. const proceedToPaymentType = paymentState === PAYMENT_STATE.PAYMENT_CHOOSE_LOGIN_OR_GUEST && !!this.context.currentUser; if (paymentState === PAYMENT_STATE.PAYMENT_CHOOSE_LOGIN_OR_GUEST && !proceedToPaymentType) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} handleLogin={showWeb3Login} /> ); } if (proceedToPaymentType || paymentState === PAYMENT_STATE.SELECT_PAYMENT_TYPE) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_AMOUNT)} handleBack={() => this.handleUpdateState(PAYMENT_STATE.SELECT_AMOUNT)} > this.handleUpdateState(PAYMENT_STATE.PAYMENT_SUCCESS)} /> ); } if (paymentState === PAYMENT_STATE.ETH_PAYMENT) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} handleClose={handleClose} > this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} handlePaymentInProgress={this.handlePaymentInProgress} /> ); } if (paymentState === PAYMENT_STATE.STRIPE_PAYMENT) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} > this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} /> ); } if (paymentState === PAYMENT_STATE.APPLE_PAY) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} > this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} newsroomName={newsroomName} usdToSpend={usdToSpend} /> ); } if (paymentState === PAYMENT_STATE.GOOGLE_PAY) { return ( this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} > this.handleUpdateState(PAYMENT_STATE.SELECT_PAYMENT_TYPE)} newsroomName={newsroomName} usdToSpend={usdToSpend} /> ); } if ( paymentState === PAYMENT_STATE.PAYMENT_SUCCESS || paymentState === PAYMENT_STATE.PAYMENT_SUCCESS_WITH_SAVED_EMAIL ) { return ( {paymentState === PAYMENT_STATE.PAYMENT_SUCCESS_WITH_SAVED_EMAIL && (

Please check your email to confirm your email address.

)}
); } return ( ); } private handleShouldPublicize = (shouldPublicize: boolean) => { this.setState({ shouldPublicize }); }; private handlePaymentSuccess = (userSubmittedEmail: boolean, didSaveEmail: boolean, etherToSpend?: number) => { if (didSaveEmail) { this.setState({ paymentState: PAYMENT_STATE.PAYMENT_SUCCESS_WITH_SAVED_EMAIL, userSubmittedEmail, etherToSpend }); } else { this.setState({ paymentState: PAYMENT_STATE.PAYMENT_SUCCESS, userSubmittedEmail, etherToSpend }); } }; private handlePaymentInProgress = (paymentInProgress: boolean, waitingForConfirmation: boolean) => { this.setState({ paymentInProgress, waitingForConfirmation }); }; private handleUpdateState = (paymentState: PAYMENT_STATE) => { if (paymentState === PAYMENT_STATE.STRIPE_PAYMENT && this.state.usdToSpend < CreditCardMin) { this.setState({ paymentState, usdToSpend: CreditCardMin, selectedUsdToSpend: this.state.usdToSpend, paymentAdjustedStripe: true, paymentAdjustedEth: true, }); } else { this.setState({ paymentState, paymentAdjustedStripe: false, paymentAdjustedEth: false }); } }; private handleAmount = (usdToSpend: number) => { const paymentAdjustedWarning = usdToSpend < CreditCardMin ? true : false; if (this.context && this.context.currentUser) { this.setState({ usdToSpend, paymentState: PAYMENT_STATE.SELECT_PAYMENT_TYPE, paymentAdjustedWarning, }); } else { this.setState({ usdToSpend, paymentState: PAYMENT_STATE.PAYMENT_CHOOSE_LOGIN_OR_GUEST, paymentAdjustedWarning, }); } }; private handleUpdateBoostFromEth = (newUsdToSpend: number, selectedUsdToSpend: number, etherToSpend: number) => { this.setState({ usdToSpend: newUsdToSpend, selectedUsdToSpend, etherToSpend, paymentAdjustedEth: true, paymentAdjustedStripe: false, resetEthPayments: true, }); }; } ================================================ FILE: packages/components/src/Payments/PaymentsAmount.tsx ================================================ import * as React from "react"; import { PaymentBtn, PaymentAmountUserInput, PaymentGhostBtn, PaymentDirectionsStyled, } from "./PaymentsStyledComponents"; import { SelectPaymentAmountText, EnterCustomAmountText } from "./PaymentsTextComponents"; import { PaymentsRadio } from "./PaymentsRadio"; import { RENDER_CONTEXT, CivilContext, ICivilContext } from "../context"; import { RadioInput, CurrencyInput } from "@joincivil/elements"; export interface SuggestedAmounts { amount: string; } export interface PaymentsAmountProps { newsroomName: string; suggestedAmounts: SuggestedAmounts[]; handleAmount(usdToSpend: number): void; } export interface PaymentsAmountStates { showInput: boolean; usdToSpend: number; } export class PaymentsAmount extends React.Component { public static contextType = CivilContext; public static context: ICivilContext; constructor(props: any) { super(props); this.state = { showInput: false, usdToSpend: 0, }; } public render(): JSX.Element { const disableNext = this.state.usdToSpend === 0; return ( <> {(!this.context || this.context.renderContext !== RENDER_CONTEXT.EMBED) && ( )} {this.props.suggestedAmounts.map((item, i) => ( ${item.amount} USD ))} {this.state.showInput ? ( $} name="CurrencyInput" onChange={this.handleAmountInput} /> ) : ( )} this.props.handleAmount(this.state.usdToSpend)} disabled={disableNext}> Next ); } private handleShowInput = () => { this.setState({ showInput: true }); }; private handleRadioSelection = (name: string, value: any) => { this.setState({ usdToSpend: value }); }; private handleAmountInput = (name: string, value: any) => { this.setState({ usdToSpend: value }); }; } ================================================ FILE: packages/components/src/Payments/PaymentsApplePay.tsx ================================================ import * as React from "react"; import { PayWithAppleText, PaymentStripeNoticeText, PaymentTermsText } from "./PaymentsTextComponents"; import { PaymentTerms } from "./PaymentsStyledComponents"; import { PaymentsFormWrapper } from "./PaymentsFormWrapper"; export interface PaymentsApplePayProps { newsroomName: string; usdToSpend: number; handleEditPaymentType(): void; } export const PaymentsApplePay: React.FunctionComponent = props => { return ( <> } paymentNoticeText={} /> {/* Apple Pay TKTK */} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsEth.tsx ================================================ import * as React from "react"; import { Mutation, MutationFunc } from "react-apollo"; import { EthAddress } from "@joincivil/typescript-types"; import { ICivilContext, CivilContext } from "../context"; import { PAYMENTS_ETH_MUTATION, SET_EMAIL_MUTATION } from "./queries"; import { UsdEthConverter } from "../"; import { PaymentBtn, PaymentHide } from "./PaymentsStyledComponents"; import { ConnectWalletWarningText } from "./PaymentsTextComponents"; import { PaymentsEthForm } from "./PaymentsEthForm"; import { PaymentsEthUpdateAmount } from "./PaymentsEthUpdateAmount"; import { PaymentsEthWrapper } from "./PaymentsEthWrapper"; export interface PaymentsEthProps { postId: string; newsroomName: string; paymentAddress: EthAddress; shouldPublicize: boolean; etherToSpend?: number; usdToSpend: number; resetEthPayments: boolean; handleBoostUpdate(newUsdToSpend: number, selectedUsdToSpend: number, etherToSpend: number): void; handlePaymentSuccess(userSubmittedEmail: boolean, didSaveEmail: boolean, etherToSpend: number): void; handleEditPaymentType(): void; handlePaymentInProgress(ethPaymentInProgress: boolean, waitingForConfirmation: boolean): void; } export interface PaymentsEthStates { etherToSpend: number; usdToSpend: number; notEnoughEthError: boolean; userAddress?: string; } export class PaymentsEth extends React.Component { public static contextType = CivilContext; public static context: ICivilContext; public static getDerivedStateFromProps(props: PaymentsEthProps, state: PaymentsEthStates): PaymentsEthStates { if (props.resetEthPayments) { return { etherToSpend: props.etherToSpend || 0, usdToSpend: props.usdToSpend, notEnoughEthError: false, }; } return { ...state, }; } public constructor(props: PaymentsEthProps) { super(props); this.state = { etherToSpend: props.etherToSpend || 0, usdToSpend: props.usdToSpend, notEnoughEthError: false, }; } public async componentDidMount(): Promise { // Grab user address after any `currentProviderEnable` call. For users who aren't logged in to Civil but are logged in to metamask, this is the only way we can get their address: this.setState({ userAddress: await this.context.civil.accountStream.first().toPromise(), }); } public render(): JSX.Element { const userChannelID = (this.context && this.context.currentUser && this.context.currentUser.userChannel.id) || ""; const userEmail = this.context && this.context.currentUser && this.context.currentUser.userChannel.EmailAddressRestricted; const userAddress = this.state.userAddress || (this.context && this.context.currentUser && this.context.currentUser.ethAddress); if (!userAddress) { return ( { await this.context.civil.currentProviderEnable(); }} > Select Wallet ); } if (this.state.notEnoughEthError) { return ( ); } if (this.state.etherToSpend === 0) { return ( this.notEnoughEthError(error)} onConversion={(usd: number, eth: number) => this.setConvertedAmount(usd, eth)} /> ); } return ( {(paymentsCreateEtherPayment: MutationFunc) => { return ( {(setEmailMutation: MutationFunc) => { return ( ); }} ); }} ); } private setConvertedAmount(usdToSpend: number, etherToSpend: number): void { const eth = parseFloat(etherToSpend.toFixed(6)); this.setState({ usdToSpend, etherToSpend: eth }); } private notEnoughEthError = (error: boolean) => { this.setState({ notEnoughEthError: error }); }; } ================================================ FILE: packages/components/src/Payments/PaymentsEthForm.tsx ================================================ import * as React from "react"; import { MutationFunc } from "react-apollo"; import { TwoStepEthTransaction } from "@joincivil/core"; import { EthAddress, TxHash } from "@joincivil/typescript-types"; import { isValidEmail } from "@joincivil/utils"; import { PaymentTerms, PaymentInputLabel, CheckboxContainer, CheckboxSection, CheckboxLabel, } from "./PaymentsStyledComponents"; import { TransactionButtonNoModal, CivilContext, ICivilContext } from "../"; import { PaymentsEthWrapper } from "./PaymentsEthWrapper"; import { InputValidationUI } from "./PaymentsInputValidationUI"; import { PaymentErrorText, PaymentTermsText, PaymentEmailConfirmationText, EnoughETHInWalletText, PaymentEmailPrepopulatedText, } from "./PaymentsTextComponents"; import { INPUT_STATE } from "./types"; import { Checkbox, CheckboxSizes } from "../input"; export interface PaymentsEthFormProps { postId: string; etherToSpend: number; usdToSpend: number; shouldPublicize: boolean; newsroomName: string; paymentAddress: EthAddress; userAddress?: EthAddress; userEmail?: string; userChannelID?: string; savePayment: MutationFunc; setEmail: MutationFunc; handlePaymentSuccess(userSubmittedEmail: boolean, didSaveEmail: boolean, etherToSpend: number): void; handleEditPaymentType(): void; handlePaymentInProgress(ethPaymentInProgress: boolean, waitingForConfirmation: boolean): void; } export interface PaymentsEthFormState { email: string; emailState: string; saveEmailState: string; isPaymentError: boolean; wasEmailPrepopulated: boolean; promptSaveEmail: boolean; shouldSaveEmailToAccount: boolean; shouldAddEmailToMailingList: boolean; } export class PaymentsEthForm extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: PaymentsEthFormProps) { super(props); this.state = { email: this.props.userEmail || "", promptSaveEmail: !props.userEmail && props.userChannelID ? true : false, wasEmailPrepopulated: this.props.userEmail ? true : false, emailState: INPUT_STATE.EMPTY, saveEmailState: INPUT_STATE.EMPTY, isPaymentError: false, shouldSaveEmailToAccount: true, shouldAddEmailToMailingList: false, }; } public render(): JSX.Element { return ( <> {this.state.wasEmailPrepopulated && } {!this.state.wasEmailPrepopulated && ( <> Email address (optional) this.handleOnBlur(event)} onChange={() => this.handleOnChange(event)} /> )} {this.state.promptSaveEmail && this.state.saveEmailState === INPUT_STATE.VALID && ( <> )} Complete Boost {this.state.isPaymentError && } ); } private toggleShouldSaveEmailToAccount = () => { this.setState({ shouldSaveEmailToAccount: !this.state.shouldSaveEmailToAccount }); }; private toggleShouldAddEmailToMailingList = () => { this.setState({ shouldAddEmailToMailingList: !this.state.shouldAddEmailToMailingList }); }; private handleOnBlur = (event: any) => { const state = event.target.id; const value = event.target.value; switch (state) { case "email": const validEmail = isValidEmail(event.target.value); validEmail || value === "" ? this.setState({ email: value, emailState: INPUT_STATE.VALID }) : this.setState({ emailState: INPUT_STATE.INVALID }); break; default: break; } }; private handleOnChange = (event: any) => { const state = event.target.id; const value = event.target.value; switch (state) { case "email": const validEmail = isValidEmail(event.target.value); validEmail ? this.setState({ email: value, saveEmailState: INPUT_STATE.VALID, emailState: INPUT_STATE.VALID }) : this.setState({ saveEmailState: INPUT_STATE.INVALID }); if (value === "") { this.setState({ email: value, emailState: INPUT_STATE.VALID }); } break; default: break; } }; private saveEmail = async (): Promise => { if ( this.state.promptSaveEmail && this.state.emailState === INPUT_STATE.VALID && this.state.shouldSaveEmailToAccount ) { const variables = { input: { emailAddress: this.state.email, channelID: this.props.userChannelID, addToMailing: this.state.shouldAddEmailToMailingList, }, }; await this.props.setEmail({ variables, }); } }; private sendPayment = async (): Promise | void> => { this.context.fireAnalyticsEvent("boost", "ETH submit clicked", this.props.postId, this.props.usdToSpend); this.props.handlePaymentInProgress(true, true); if (this.context.civil) { return this.context.civil.simplePayment(this.props.paymentAddress, this.props.etherToSpend.toString()); } }; private handleTransactionHash = async (txHash: TxHash) => { this.context.fireAnalyticsEvent("boost", "ETH transaction submitted", this.props.postId, this.props.usdToSpend); this.props.handlePaymentInProgress(true, false); await this.props.savePayment({ variables: { postID: this.props.postId, input: { transactionID: txHash, paymentAddress: this.props.paymentAddress, fromAddress: this.props.userAddress, amount: this.props.etherToSpend, usdAmount: this.props.usdToSpend.toString(), emailAddress: this.state.email, shouldPublicize: this.props.shouldPublicize, payerChannelID: this.props.userChannelID, }, }, }); }; private onTransactionError = (err: string) => { this.context.fireAnalyticsEvent("boost", "ETH transaction rejected", this.props.postId, this.props.usdToSpend); this.setState({ isPaymentError: true }); this.props.handlePaymentInProgress(false, false); }; private postTransaction = () => { this.context.fireAnalyticsEvent("boost", "ETH transaction confirmed", this.props.postId, this.props.usdToSpend); const didSaveEmail = this.state.promptSaveEmail && this.state.email && this.state.shouldSaveEmailToAccount ? true : false; this.props.handlePaymentSuccess(this.state.email !== "" && true, didSaveEmail, this.props.etherToSpend); }; } ================================================ FILE: packages/components/src/Payments/PaymentsEthUpdateAmount.tsx ================================================ import * as React from "react"; import { UsdEthConverter } from "../"; import { PaymentBtn } from "./PaymentsStyledComponents"; import { NotEnoughETHInWalletText } from "./PaymentsTextComponents"; export interface PaymentsEthUpdateAmountProps { etherToSpend: number; usdToSpend: number; handleBoostUpdate(newUsdToSpend: number, selectedUsdToSpend: number, etherToSpend: number): void; } export interface PaymentsEthUpdateAmountStates { etherToSpend: number; usdToSpend: number; notEnoughEthError: boolean; } export class PaymentsEthUpdateAmount extends React.Component< PaymentsEthUpdateAmountProps, PaymentsEthUpdateAmountStates > { public constructor(props: PaymentsEthUpdateAmountProps) { super(props); this.state = { etherToSpend: this.props.etherToSpend, usdToSpend: this.props.usdToSpend, notEnoughEthError: false, }; } public render(): JSX.Element { return ( <> this.notEnoughEthError(error)} onConversion={(usd: number, eth: number) => this.setConvertedAmount(usd, eth)} /> this.props.handleBoostUpdate(this.state.usdToSpend, this.props.usdToSpend, this.state.etherToSpend) } disabled={this.state.notEnoughEthError} > Update Boost Amount ); } private setConvertedAmount(usdToSpend: number, etherToSpend: number): void { const eth = parseFloat(etherToSpend.toFixed(6)); this.setState({ usdToSpend, etherToSpend: eth }); } private notEnoughEthError = (error: boolean) => { this.setState({ notEnoughEthError: error }); }; } ================================================ FILE: packages/components/src/Payments/PaymentsEthWrapper.tsx ================================================ import * as React from "react"; import { PaymentsFormWrapper } from "./PaymentsFormWrapper"; import { PayWithEthText, PaymentEthNoticeText, WhyEthInfoText, WhatIsEthInfoText, CanUseCVLInfoText, } from "./PaymentsTextComponents"; import { PaymentEthLearnMore, PaymentAmountEth } from "./PaymentsStyledComponents"; import { PaymentsModal } from "./PaymentsModal"; export enum MODEL_CONTENT { WHY_ETH, WHAT_IS_ETH, CAN_USE_CVL, } export interface PaymentsEthWrapperProps { etherToSpend: number; usdToSpend: number; children?: any; handleEditPaymentType(): void; } export interface PaymentsEthWrapperStates { isInfoModalOpen: boolean; modalContent?: MODEL_CONTENT; } export class PaymentsEthWrapper extends React.Component { public constructor(props: PaymentsEthWrapperProps) { super(props); this.state = { isInfoModalOpen: false, }; } public render(): JSX.Element { return ( } paymentNoticeText={} > this.openInfoModal(MODEL_CONTENT.WHAT_IS_ETH)}>What is ETH? this.openInfoModal(MODEL_CONTENT.WHY_ETH)}>Why ETH? this.openInfoModal(MODEL_CONTENT.CAN_USE_CVL)}>Can I use CVL? {this.props.etherToSpend + " ETH"} ≈ {"$" + this.props.usdToSpend} {this.props.children} {this.renderInfoModal()} ); } private renderInfoModal = () => { switch (this.state.modalContent) { case MODEL_CONTENT.WHY_ETH: return ; case MODEL_CONTENT.WHAT_IS_ETH: return ; case MODEL_CONTENT.CAN_USE_CVL: return ; default: return <>; } }; private openInfoModal = (modelContent: any) => { this.setState({ isInfoModalOpen: true, modalContent: modelContent }); }; private handleClose = () => { this.setState({ isInfoModalOpen: false }); }; } ================================================ FILE: packages/components/src/Payments/PaymentsFormWrapper.tsx ================================================ import * as React from "react"; import { SecureLockIcon } from "@joincivil/elements"; import { PaymentFormWrapperStyled, PaymentInfoFlex, PaymentTypeLabel, PaymentSecure, PaymentNotice, } from "./PaymentsStyledComponents"; import { PaymentEditText } from "./PaymentsTextComponents"; export interface PaymentsFormWrapperProps { payWithText: string | JSX.Element; paymentNoticeText: string | JSX.Element; showSecureIcon?: boolean; children?: any; handleEditPaymentType(): void; } export const PaymentsFormWrapper: React.FunctionComponent = props => { return ( <> {props.payWithText} {props.showSecureIcon && ( Secure transaction )} {props.paymentNoticeText} {props.children} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsGooglePay.tsx ================================================ import * as React from "react"; import { PayWithGoogleText, PaymentStripeNoticeText, PaymentTermsText } from "./PaymentsTextComponents"; import { PaymentTerms } from "./PaymentsStyledComponents"; import { PaymentsFormWrapper } from "./PaymentsFormWrapper"; export interface PaymentsGooglePayProps { newsroomName: string; usdToSpend: number; handleEditPaymentType(): void; } export const PaymentsGooglePay: React.FunctionComponent = props => { return ( <> } paymentNoticeText={} /> {/* Google Pay TKTK */} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsInputValidationUI.tsx ================================================ import * as React from "react"; import { INPUT_STATE } from "./types"; import { colors, fonts, ErrorIcon } from "../"; import styled from "styled-components"; export interface InputValidationStyleProps { inputState?: string; } export const StripeElement = styled.div` border: 1px solid ${(props: InputValidationStyleProps) => props.inputState === INPUT_STATE.INVALID ? colors.accent.CIVIL_RED : colors.accent.CIVIL_GRAY_3}; border-radius: 3px; padding: 12px; `; const InputErrorMessageWrapper = styled.div` bottom: -25px; color: ${colors.accent.CIVIL_RED}; font-size: 12px; left: 2px; position: absolute; svg { margin-right: 5px; vertical-align: top; } `; const InputWrapper = styled.div` margin-bottom: 20px; position: relative; width: 100%; p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 13px; line-height: 18px; margin: 5px 0 0; } input { border: 1px solid ${(props: InputValidationStyleProps) => props.inputState === INPUT_STATE.INVALID ? colors.accent.CIVIL_RED : colors.accent.CIVIL_GRAY_3}; border-radius: 3px; font-size: 13px; padding: 10px 35px 10px 12px; width: 100%; &::placeholder { color: ${colors.accent.CIVIL_GRAY_1}; } &:focus { border-color: ${colors.accent.CIVIL_BLUE}; outline: none; } } select { appearance: none; background-color: transparent; border: 1px solid ${(props: InputValidationStyleProps) => props.inputState === INPUT_STATE.INVALID ? colors.accent.CIVIL_RED : colors.accent.CIVIL_GRAY_3}; border-radius: 3px; display: block; font-family: ${fonts.SANS_SERIF}; font-size: 13px; line-height: 16px; margin: 0; padding: 11px 12px 12px; position: relative; width: 100%; z-index: 1; &::-ms-expand { display: none; } &:hover { cursor: pointer; } &:focus { border-color: ${colors.accent.CIVIL_BLUE}; outline: none; } } `; const InputErrorIcon = styled.div` display: ${(props: InputValidationStyleProps) => (props.inputState === INPUT_STATE.INVALID ? "block" : "none")}; position: absolute; right: 5px; top: 10px; `; export interface InputValidationUIProps { children: any; className?: string; inputState?: string; } export const InputValidationUI: React.FunctionComponent = props => { return ( <> {props.children} ); }; export const InputStripeValidationUI: React.FunctionComponent = props => { return ( <> {props.children} ); }; export const InputErrorMessage: React.FunctionComponent = props => { return ( <> {props.children} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsLoadStripePayRequest.tsx ================================================ import * as React from "react"; import { StripeProvider, Elements } from "react-stripe-elements"; import { Mutation, MutationFunc } from "react-apollo"; import { PAYMENTS_STRIPE_MUTATION } from "./queries"; import makeAsyncScriptLoader from "react-async-script"; import PaymentRequestForm from "./PaymentsRequest"; import { CivilContext, ICivilContext } from "../context"; export interface PaymentsStripeProps { postId: string; newsroomName: string; shouldPublicize: boolean; usdToSpend: number; handlePaymentSuccess(): void; } const Loading: React.FunctionComponent = props => <>; export interface PaymentsStripeStates { stripeLoaded: boolean; stripe: any; } export class PaymentsLoadStripePayRequest extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: PaymentsStripeProps) { super(props); this.state = { stripeLoaded: false, stripe: null, }; } public render(): JSX.Element { const userChannelID = (this.context && this.context.currentUser && this.context.currentUser.userChannel.id) || ""; const AsyncScriptLoader = makeAsyncScriptLoader("https://js.stripe.com/v3/")(Loading); if (this.state.stripeLoaded) { return ( {(paymentsCreateStripePayment: MutationFunc) => { return ( ); }} ); } return ( { this.setState({ stripeLoaded: true }); }} /> ); } } ================================================ FILE: packages/components/src/Payments/PaymentsLoginOrGuest.tsx ================================================ import * as React from "react"; import { PaymentLoginOrGuestWrapper, PaymentLoginOrGuestTitle, PaymentLoginOrGuestOption, PaymentLoginOrGuestType, PaymentLoginOrGuestDescription, PaymentBtn, PaymentInvertedBtn, } from "./PaymentsStyledComponents"; export interface PaymentsLoginProps { handleLogin(): void; handleNext(): void; } export const PaymentsLoginOrGuest: React.FunctionComponent = props => { return ( Welcome to Civil! Log in to give a Boost 🚀 Log In / Sign Up You’ll be able to keep track of your contributions and your username may be listed on the Boost leaderboard. Guest Proceed to Boost and become a Civil member later. Continue as a Guest ); }; ================================================ FILE: packages/components/src/Payments/PaymentsModal.tsx ================================================ import * as React from "react"; import { PaymentFullscreenModal, PaymentModalContain, PaymentModalCloseBtn } from "./PaymentsStyledComponents"; import { CloseXIcon } from "../icons"; import { colors } from "../styleConstants"; import { RENDER_CONTEXT, CivilContext, ICivilContext } from "../context"; export interface PaymentsModalProps { open: boolean; children: any; handleClose?(): void; } export const PaymentsModal: React.FunctionComponent = props => { const context = React.useContext(CivilContext); const maxHeight = window.innerHeight - 200; return ( <> {/*iframe resizer used by embed looks for elements with `data-iframe-height` attribute and expands to fit even if they extend outside of `` which this does*/} {props.handleClose && ( props.handleClose && props.handleClose()}> )} {props.children} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsRadio.tsx ================================================ import * as React from "react"; import { PaymentRadioBtnContain, PaymentRadioBtn } from "./PaymentsStyledComponents"; export interface PaymentsRadioProps { onChange?: any; value: any; name?: string; } export const PaymentsRadio: React.FunctionComponent = props => { let input: any; const { onChange, children, value, name } = props; const clickHandler = () => { input.checked = true; if (onChange) { onChange(name, input.value); } }; return ( (input = ref)} /> {children} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsRequest.tsx ================================================ import * as React from "react"; import { MutationFunc } from "react-apollo"; import { injectStripe, ReactStripeElements, PaymentRequestButtonElement } from "react-stripe-elements"; import styled from "styled-components"; import { colors } from "@joincivil/elements"; import { PaymentExpress, PaymentOrBorder } from "./PaymentsStyledComponents"; import { ExpressPayText } from "./PaymentsTextComponents"; const StripePaymentRequest = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_2}; margin-bottom: 10px; padding: 10px 0; `; export interface PaymentRequestProps extends ReactStripeElements.InjectedStripeProps { savePayment: MutationFunc; boostId: string; usdToSpend: number; userChannelID?: string; shouldPublicize: boolean; handlePaymentSuccess(): void; onPayRequestError?(): void; } export interface PaymentRequestStates { canMakePayment: boolean; paymentRequest: any; } class PaymentRequestForm extends React.Component { constructor(props: any) { super(props); const paymentRequest = props.stripe.paymentRequest({ country: "US", currency: "usd", total: { label: "Civil Boost", amount: this.props.usdToSpend * 100, }, requestPayerName: true, requestPayerEmail: true, }); paymentRequest.on("token", async (ev: any) => { if (ev && ev.token && ev.complete && ev.payerEmail) { return this.handlePaymentRequest(ev.token, ev.complete, ev.payerEmail); } else { console.error("Error processing Payment Request"); if (this.props.onPayRequestError) { this.props.onPayRequestError(); } } }); paymentRequest.canMakePayment().then((result: any) => { this.setState({ canMakePayment: !!result }); }); this.state = { canMakePayment: false, paymentRequest, }; } public render(): JSX.Element { return this.state.canMakePayment ? ( ) : ( <> ); } private async handlePaymentRequest(token: any, complete: any, email: string): Promise { try { await this.props.savePayment({ variables: { postID: this.props.boostId, input: { // @ts-ignore paymentToken: token.id, amount: this.props.usdToSpend, currencyCode: "usd", emailAddress: email, shouldPublicize: this.props.shouldPublicize, payerChannelID: this.props.userChannelID, }, }, }); complete("success"); this.props.handlePaymentSuccess(); } catch (err) { console.error(err); complete("fail"); if (this.props.onPayRequestError) { this.props.onPayRequestError(); } } } } export default injectStripe(PaymentRequestForm); ================================================ FILE: packages/components/src/Payments/PaymentsSelectType.tsx ================================================ import * as React from "react"; import { PaymentDirectionsStyled, PaymentTypeSelect, PaymentBtn, PaymentInfoStyled, PayAppleGoogleOnCivilPrompt, PaymentAmountUserOptions, } from "./PaymentsStyledComponents"; import { SelectPaymentMethodText, PayWithCardText, PayWithEthText, PaymentInfoText, PayAppleGoogleOnCivilText, PublicizeUserText, } from "./PaymentsTextComponents"; import { PAYMENT_STATE } from "./types"; import { RENDER_CONTEXT, CivilContext, ICivilContext } from "../context"; import { PaymentsLoadStripePayRequest } from "./PaymentsLoadStripePayRequest"; import { Checkbox, CheckboxSizes } from "../input"; export interface PaymentsSelectTypeProps { postId: string; usdToSpend: number; newsroomName: string; shouldPublicize: boolean; isStripeConnected: boolean; handleShouldPublicize(shouldPublicize: boolean): void; handleNext(paymentState: PAYMENT_STATE): void; handlePaymentSuccess(): void; } export const PaymentsSelectType: React.FunctionComponent = props => { const context = React.useContext(CivilContext); return ( <> {props.isStripeConnected && context.renderContext === RENDER_CONTEXT.DAPP && ( )} {props.isStripeConnected && ( props.handleNext(PAYMENT_STATE.STRIPE_PAYMENT)} backgroundColor={"#26CD41"}> )} props.handleNext(PAYMENT_STATE.ETH_PAYMENT)}> props.handleShouldPublicize(!props.shouldPublicize)} /> {context.renderContext === RENDER_CONTEXT.DAPP && ( )} {props.isStripeConnected && context.renderContext === RENDER_CONTEXT.EMBED && ( )} ); }; ================================================ FILE: packages/components/src/Payments/PaymentsStripe.tsx ================================================ import * as React from "react"; import { StripeProvider, Elements } from "react-stripe-elements"; import { ApolloConsumer, Mutation, MutationFunc } from "react-apollo"; import makeAsyncScriptLoader from "react-async-script"; import PaymentStripeForm from "./PaymentsStripeForm"; import { CivilContext, ICivilContext } from "../context"; import { LoadingMessage } from "../"; import PaymentIntentsStripeForm from "./PaymentIntentsStripeForm"; import { PAYMENTS_STRIPE_MUTATION, SET_EMAIL_MUTATION } from "./queries"; export interface PaymentsStripeProps { postId: string; newsroomName: string; shouldPublicize: boolean; usdToSpend: number; stripeAccountID: string; handlePaymentSuccess(userSubmittedEmail: boolean, didSaveEmail: boolean): void; handleEditPaymentType(): void; } export interface PaymentsStripeStates { stripeLoaded: boolean; stripe: any; } export class PaymentsStripe extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: PaymentsStripeProps) { super(props); this.state = { stripeLoaded: false, stripe: null, }; } public render(): JSX.Element { const { currentUser, features } = this.context; const userChannelID = (currentUser && currentUser.userChannel.id) || ""; const userEmail = currentUser && currentUser.userChannel.EmailAddressRestricted; const paymentMethods = currentUser && currentUser.userChannel.stripeCustomerInfo.paymentMethods; const AsyncScriptLoader = makeAsyncScriptLoader("https://js.stripe.com/v3/")(LoadingMessage); if (this.state.stripeLoaded) { if (!features.featureEnabled("payment-intents")) { return ( {(paymentsCreateStripePayment: MutationFunc) => { return ( {(setEmailMutation: MutationFunc) => { return ( ); }} ); }} ); } else { return ( {client => ( )} ); } } return ( { this.setState({ stripeLoaded: true }); }} /> ); } } ================================================ FILE: packages/components/src/Payments/PaymentsStripeCardComponent.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { PaymentInputLabel } from "./PaymentsStyledComponents"; import { InputValidationUI, InputStripeValidationUI, StripeElement, InputErrorMessage } from "./PaymentsInputValidationUI"; import { PaymentEmailPrepopulatedText, PaymentEmailConfirmationText, AddCardEmailConfirmationText } from "./PaymentsTextComponents"; import { CardElement } from "react-stripe-elements"; const StripeWrapper = styled.div` margin: 20px 0 0; max-width: 500px; width: 100%; `; interface PaymentsStripeCardComponentProps { email: string; wasEmailPrepopulated: boolean; emailState: string; nameState: string; cardInfoState: string; displayStripeErrorMessage: string; showAddCardText?: boolean; handleOnBlur(event: any): void; handleStripeChange(event: any): void; } export const PaymentsStripeCardComponent: React.FunctionComponent = props => { const { email, wasEmailPrepopulated, emailState, nameState, cardInfoState, displayStripeErrorMessage, handleOnBlur, handleStripeChange, showAddCardText } = props; return ( {wasEmailPrepopulated && } {!wasEmailPrepopulated && ( <> Email Address handleOnBlur(event)} /> {showAddCardText && } {!showAddCardText && } )} Name on card handleOnBlur(event)} required /> Card information {displayStripeErrorMessage !== "" && ( {displayStripeErrorMessage} )} ); } ================================================ FILE: packages/components/src/Payments/PaymentsStripeForm.tsx ================================================ import * as React from "react"; import { MutationFunc } from "react-apollo"; import { injectStripe, ReactStripeElements, CardElement } from "react-stripe-elements"; import styled from "styled-components"; import { PaymentsFormWrapper } from "./PaymentsFormWrapper"; import { CivilContext, ICivilContext } from "../context"; import { isValidEmail } from "@joincivil/utils"; import { PaymentTerms, PaymentBtn, PaymentInputLabel, PaymentError, CheckboxContainer, CheckboxSection, CheckboxLabel, } from "./PaymentsStyledComponents"; import { PayWithCardText, PaymentStripeNoticeText, PaymentEmailConfirmationText, PaymentTermsText, PaymentErrorText, PaymentEmailPrepopulatedText, } from "./PaymentsTextComponents"; import { InputValidationUI, InputStripeValidationUI, StripeElement, InputErrorMessage, } from "./PaymentsInputValidationUI"; import { INPUT_STATE } from "./types"; import { Checkbox, CheckboxSizes } from "../input"; const StripeWrapper = styled.div` margin: 20px 0 0; max-width: 500px; width: 100%; `; export interface PaymentStripeFormProps extends ReactStripeElements.InjectedStripeProps { postId: string; newsroomName: string; shouldPublicize: boolean; userEmail?: string; userChannelID?: string; usdToSpend: number; savePayment: MutationFunc; setEmail: MutationFunc; handlePaymentSuccess(userSubmittedEmail: boolean, didSaveEmail: boolean): void; handleEditPaymentType(): void; } export interface PaymentStripeFormStates { email: string; emailState: string; name: string; nameState: string; cardInfoState: string; isPaymentError: boolean; paymentProcessing: boolean; wasEmailPrepopulated: boolean; promptSaveEmail: boolean; shouldSaveEmailToAccount: boolean; shouldAddEmailToMailingList: boolean; displayStripeErrorMessage: string; } class PaymentStripeForm extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: any) { super(props); this.state = { email: props.userEmail || "", wasEmailPrepopulated: props.userEmail ? true : false, promptSaveEmail: !props.userEmail && props.userChannelID ? true : false, emailState: this.props.userEmail ? INPUT_STATE.VALID : INPUT_STATE.EMPTY, name: "", nameState: INPUT_STATE.EMPTY, cardInfoState: INPUT_STATE.EMPTY, isPaymentError: false, paymentProcessing: false, shouldSaveEmailToAccount: true, shouldAddEmailToMailingList: false, displayStripeErrorMessage: "", }; this.handleSubmit = this.handleSubmit.bind(this); } public render(): JSX.Element { return ( <> } paymentNoticeText={} showSecureIcon={true} > {this.state.wasEmailPrepopulated && } {!this.state.wasEmailPrepopulated && ( <> Email this.handleOnBlur(event)} /> )} Name on card this.handleOnBlur(event)} required /> Card information {this.state.displayStripeErrorMessage !== "" && ( {this.state.displayStripeErrorMessage} )} {this.state.promptSaveEmail && this.state.emailState === INPUT_STATE.VALID && ( <> )} this.handleSubmit()} disabled={this.disableBoostBtn()}> {this.state.paymentProcessing ? "Payment processing..." : "Complete Boost"} {this.state.isPaymentError && ( )} ); } private handleStripeChange = (event: any) => { const stripeElements = document.querySelectorAll(".StripeElement"); let displayStripeErrorMessage = ""; if (event.error) { displayStripeErrorMessage = event.error.message; } stripeElements.forEach(element => { const classList = element.classList; if (classList.contains("StripeElement--invalid")) { this.setState({ cardInfoState: INPUT_STATE.INVALID, displayStripeErrorMessage }); } else if (classList.contains("StripeElement--empty")) { this.setState({ cardInfoState: INPUT_STATE.EMPTY, displayStripeErrorMessage }); } else { this.setState({ cardInfoState: INPUT_STATE.VALID, displayStripeErrorMessage }); } }); }; private disableBoostBtn = () => { const disableBoostBtn = this.state.emailState === INPUT_STATE.VALID && this.state.nameState === INPUT_STATE.VALID && this.state.cardInfoState === INPUT_STATE.VALID && this.state.paymentProcessing === false ? false : true; return disableBoostBtn; }; private toggleShouldSaveEmailToAccount = () => { this.setState({ shouldSaveEmailToAccount: !this.state.shouldSaveEmailToAccount }); }; private toggleShouldAddEmailToMailingList = () => { this.setState({ shouldAddEmailToMailingList: !this.state.shouldAddEmailToMailingList }); }; private handleOnBlur = (event: any) => { const state = event.target.id; const value = event.target.value; switch (state) { case "email": const validEmail = isValidEmail(value); validEmail ? this.setState({ email: value, emailState: INPUT_STATE.VALID }) : this.setState({ emailState: INPUT_STATE.INVALID }); break; case "name": const validName = value !== ""; validName ? this.setState({ name: value, nameState: INPUT_STATE.VALID }) : this.setState({ nameState: INPUT_STATE.INVALID }); break; default: break; } }; private async handleSubmit(): Promise { this.context.fireAnalyticsEvent("boost", "Stripe submit clicked", this.props.postId, this.props.usdToSpend); this.setState({ paymentProcessing: true, isPaymentError: false }); if (this.props.stripe) { try { let didSaveEmail = false; if (this.state.promptSaveEmail && this.state.email && this.state.shouldSaveEmailToAccount) { didSaveEmail = true; const variables = { input: { emailAddress: this.state.email, channelID: this.props.userChannelID, addToMailing: this.state.shouldAddEmailToMailingList, }, }; await this.props.setEmail({ variables, }); } const token = await this.props.stripe.createToken({ name: this.state.name, }); await this.props.savePayment({ variables: { postID: this.props.postId, input: { // @ts-ignore paymentToken: token.token.id, amount: this.props.usdToSpend, currencyCode: "usd", emailAddress: this.state.email, shouldPublicize: this.props.shouldPublicize, payerChannelID: this.props.userChannelID, }, }, }); this.context.fireAnalyticsEvent( "boost", "Stripe transaction confirmed", this.props.postId, this.props.usdToSpend, ); this.props.handlePaymentSuccess(this.state.email !== "" && true, didSaveEmail); } catch (err) { console.error(err); this.context.fireAnalyticsEvent( "boost", "Stripe transaction rejected", this.props.postId, this.props.usdToSpend, ); this.setState({ paymentProcessing: false, isPaymentError: true }); } } } } export default injectStripe(PaymentStripeForm); ================================================ FILE: packages/components/src/Payments/PaymentsStripeFormSavedCard.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "@joincivil/elements"; const SavedCardStyled = styled.div` align-items: flex-start; display: flex; > div { margin-right: 10px; } label { color: ${colors.accent.CIVIL_GRAY_3}; font-size: 13px; line-height: 16px; } `; const SavedCardDetails = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; font-weight: 600; line-height: 16px; `; const SavedCardDate = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 13px; line-height: 16px; `; export interface PaymentStripeFormSavedCardProps { cardDetails: string; date: string; } export const PaymentStripeFormSavedCard: React.FunctionComponent = props => { return (
{props.cardDetails} {props.date}
); }; ================================================ FILE: packages/components/src/Payments/PaymentsStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { CurrencyErrorMsg } from "../CurrencyConverter"; import { RENDER_CONTEXT } from "../context"; import { FullScreenModal, ModalInner } from "../FullscreenModal"; import { InputBase, InputIcon, InvertedButton, colors, fonts, mediaQueries } from "@joincivil/elements"; export const PaymentWrapperStyled = styled.div` margin: 0 auto; max-width: 400px; width: 100%; ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` max-width: 100%; `} ${CurrencyErrorMsg} { bottom: 10px; } `; export const PaymentHeader = styled.div` font-family: ${fonts.SANS_SERIF}; margin-bottom: 25px; position: relative; h2 { border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-size: 18px; font-weight: 600; line-height: 22px; margin-bottom: 12px; padding-bottom: 10px; ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && "border-bottom: none; padding-bottom: 0;"} } `; export const PaymentCivilLogo = styled.div` left: calc(50% - 25px); position: absolute; top: 10px; `; export const PaymentHeaderFlex = styled.div` align-items: center; display: flex; justify-content: space-between; margin-bottom: 10px; `; export const PaymentHeaderCenter = styled.div` margin-bottom: 10px; text-align: center; `; export const PaymentHeaderNewsroom = styled.div` font-size: 14px; font-weight: 600; line-height: 17px; svg { vertical-align: bottom; } `; export const PaymentHeaderTip = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 13px; line-height: 16px; `; export const PaymentAdjustedNotice = styled.div` background-color: rgba(255, 204, 0, 0.1); border-radius: 8px; color: ${colors.accent.CIVIL_GRAY_0}; margin-bottom: 25px; padding: 15px 15px 12px; p { font-size: 13px; line-height: 18px; margin-top: 0; span { display: block; font-weight: 700; } } `; export const PaymentAdjustedNoticeFtr = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 17px; padding-top: 10px; text-align: right; span { color: ${colors.primary.BLACK}; font-size: 18px; font-weight: 700; line-height: 22px; } `; export const PaymentFormWrapperStyled = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 3px; font-family: ${fonts.SANS_SERIF}; padding: 20px 15px; margin-bottom: 25px; `; export const PaymentHeaderBoostLabel = styled.span` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 17px; margin-right: 5px; `; export const PaymentHeaderAmount = styled.span` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 18px; line-height: 22px; b { color: ${colors.primary.BLACK}; font-weight: 700; } `; export const PaymentDirectionsStyled = styled.p` font-family: ${fonts.SANS_SERIF}; font-size: 15px; line-height: 20px; margin: 0 0 20px; a:hover { color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } `; export interface PaymentBtnProps { backgroundColor?: string; } export const PaymentBtn = styled.button` background-color: ${(props: PaymentBtnProps) => props.backgroundColor ? props.backgroundColor : colors.accent.CIVIL_BLUE}; border: none; border-radius: 3px; color: ${colors.basic.WHITE}; cursor: pointer; font-size: 14px; font-weight: 700; line-height: 19px; opacity: 1; outline: none; padding: 10px 40px; transition: opacity 250ms; width: 100%; &:hover { opacity: 0.8; } &:disabled { cursor: default; opacity: 0.8; } `; export const PaymentInvertedBtn = styled(InvertedButton)` cursor: pointer; font-size: 14px; font-weight: 700; letter-spacing: 0; line-height: 19px; padding: 10px 40px; text-transform: none; width: 100%; `; export const PaymentTypeSelect = styled.div` padding-bottom: 40px; button { margin-bottom: 8px; } `; export const PaymentNotice = styled.p` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 12px; line-height: 18px; margin: 0 0 15px; `; export const PaymentTerms = styled.p` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 12px; line-height: 18px; margin: 15px 0 10px; a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; &:hover { text-decoration: underline; } } `; export const PaymentInfoFlex = styled.div` align-items: flex-start; display: flex; justify-content: space-between; `; export const PaymentSecure = styled.div` align-items: center; display: flex; color: ${colors.accent.CIVIL_GRAY_1}; font-size: 11px; `; export const PaymentTypeLabel = styled.div` font-size: 15px; font-weight: 700; line-height: 20px; margin-bottom: 10px; `; export const PaymentAmountEth = styled.div` font-size: 14px; line-height: 18px; margin-bottom: 20px; label { color: ${colors.accent.CIVIL_GRAY_1}; display: block; font-size: 11px; font-weight: 600; letter-spacing: 0.92px; margin-bottom: 2px; text-transform: uppercase; } span { color: ${colors.accent.CIVIL_GRAY_1}; } `; export const PaymentError = styled.div` color: ${colors.accent.CIVIL_RED}; font-size: 13px; line-height: 22px; margin-top: 10px; `; export const PaymentInputLabel = styled.label` color: ${colors.accent.CIVIL_GRAY_1}; display: block; font-size: 13px; line-height: 16px; margin-bottom: 5px; `; export interface PaymentWarningProps { redText?: boolean; } export const PaymentWarning = styled.div` color: ${(props: PaymentWarningProps) => (props.redText ? colors.accent.CIVIL_RED : colors.accent.CIVIL_GRAY_1)}; font-size: 13px; line-height: 22px; margin-bottom: 15px; svg { vertical-align: sub; } `; export const PaymentFullscreenModal = styled(FullScreenModal)` ${ModalInner} { ${mediaQueries.MOBILE_SMALL} { ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` top: 0; bottom: auto; `} } } `; export interface PaymentModalProps { maxHeight: number; } export const PaymentModalContain = styled.div` font-family: ${fonts.SANS_SERIF}; overflow: auto; position: relative; max-height: ${(props: PaymentModalProps) => props.maxHeight + "px"}; padding: 20px; width: 400px; ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` padding: 8px 16px 32px; height: 100%; max-height: 100%; width: 100%; `} ${mediaQueries.MOBILE_SMALL} { height: 100%; max-height: 100%; width: 100%; ${props => props.theme.renderContext === RENDER_CONTEXT.EMBED && ` top: 0; height: auto; max-height: none; overflow: visible; `} } `; export const PaymentModalCloseBtn = styled(InvertedButton)` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 50%; height: 32px; padding: 0; position: absolute; right: 15px; top: 15px; width: 32px; svg path { transition: fill 0.2s ease; } &:focus, &:hover { background-color: ${colors.basic.WHITE}; svg path { fill: ${colors.accent.CIVIL_BLUE}; } } `; export const PaymentEthLearnMore = styled.div` background-color: rgba(255, 204, 0, 0.1); border-radius: 5px; display: flex; font-size: 12px; justify-content: center; letter-spacing: -0.07px; line-height: 18px; margin-bottom: 20px; padding: 15px; a { cursor: pointer; margin-right: 30px; ${mediaQueries.MOBILE} { margin-right: 15px; } &:last-of-type { margin-right: 0; } &:hover { color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } } `; export const PaymentRadioBtnContain = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; margin-right: 4%; width: 22%; input { display: none; } input:checked + button { border: 2px solid ${colors.accent.CIVIL_BLUE}; } &:last-of-type { margin-right: 0; } `; export const PaymentRadioBtn = styled.button` background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-radius: 4px; cursor: pointer; font-size: 18px; font-weight: 600; height: 75px; outline: none; padding: 10px; transition: border 0.2s ease; width: 100%; span { display: block; font-size: 12px; font-weight: 400; } &:hover { border: 2px solid ${colors.accent.CIVIL_BLUE}; } `; export const PaymentAmountNewsroom = styled.div` h3 { font-family: ${fonts.SANS_SERIF}; font-size: 18px; font-weight: 600; line-height: 22px; margin: 0 0 10px; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 17px; margin: 0 0 15px; text-align: center; } `; export const PaymentGhostBtn = styled.button` background-color: ${colors.basic.WHITE}; border: none; color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; display: block; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 17px; outline: none; padding: 0; &:hover { text-decoration: underline; } `; export const PaymentAmountUserInput = styled.div` display: flex; justify-content: center; margin: 20px 0 30px; > div { padding: 0; } label { display: none; } ${InputBase} { padding-left: 25px; width: 150px; } ${InputIcon} { left: 9px; top: -40px; width: 18px; } `; export const PaymentAmountUserOptions = styled.div` display: flex; margin: 20px 0; label { color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; margin-right: 8px; } `; export const PaymentLoginOrGuestWrapper = styled.div` padding: 20px; `; export const PaymentLoginOrGuestTitle = styled.div` font-family: ${fonts.SANS_SERIF}; font-size: 18px; font-weight: 600; line-height: 22px; margin-bottom: 40px; text-align: center; `; export const PaymentLoginOrGuestOption = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; margin-bottom: 20px; padding-bottom: 15px; &:last-of-type { border-bottom: none; margin: 0; padding: 0; } button { margin-bottom: 12px; } `; export const PaymentLoginOrGuestType = styled.div` font-family: ${fonts.SANS_SERIF}; font-size: 16px; font-weight: 600; line-height: 19px; margin-bottom: 12px; `; export const PaymentLoginOrGuestDescription = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; font-family: ${fonts.SANS_SERIF}; font-size: 13px; line-height: 16px; margin-bottom: 12px; `; export const PaymentInfoStyled = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 22px; padding: 20px 0; span { color: ${colors.primary.BLACK}; display: block; font-weight: 700; margin: 0; } `; export const PaymentExpress = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_1}; display: block; font-family: ${fonts.SANS_SERIF}; font-size: 12px; padding: 20px 0 15px; text-align: center; width: 100%; label { line-height: 14px; margin-bottom: 10px; } `; export const PaymentOrBorder = styled.div` background-color: ${colors.accent.CIVIL_GRAY_4}; height: 1px; margin: 20px 5%; position: relative; width: 90%; &:after { background-color: ${colors.basic.WHITE}; color: ${colors.accent.CIVIL_GRAY_2}; content: "Or"; font-size: 12px; left: calc(50% - 25px); position: absolute; text-align: center; top: -8px; width: 50px; } `; export const PaymentEdit = styled.div` align-items: center; display: flex; font-size: 15px; justify-content: space-between; margin-bottom: 8px; `; export const PaymentHide = styled.div` visibility: hidden; `; export const PaymentBackBtn = styled.button` align-items: center; background-color: ${colors.basic.WHITE}; border: none; color: ${colors.accent.CIVIL_GRAY_1}; cursor: pointer; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 17px; opacity: 0.5; outline: none; padding: 0; transition: color 250ms, opacity 250ms; svg { margin-right: 5px; transform: rotate(180deg); g { fill: ${colors.accent.CIVIL_GRAY_1}; transition: color 250ms, opacity 250ms; } } &:hover { color: ${colors.accent.CIVIL_BLUE}; opacity: 1; svg g { fill: ${colors.accent.CIVIL_BLUE}; } } `; export const PayAppleGoogleOnCivilPrompt = styled.div` font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 17px; text-align: center; a { font-weight: 700; text-decoration: none; &:hover { text-decoration: underline; } } `; export const CheckboxContainer = styled.ul` list-style: none; padding-left: 0; margin-top: 0; max-width: 400px; `; export const CheckboxSection = styled.li` margin-bottom: 10px; `; export const CheckboxLabel = styled.span` color: ${colors.primary.CIVIL_GRAY_1}; font: 400 14px/24px ${fonts.SANS_SERIF}; padding-left: 7px; vertical-align: middle; `; ================================================ FILE: packages/components/src/Payments/PaymentsSuccess.tsx ================================================ import * as React from "react"; import { PaymentBtn } from "./PaymentsStyledComponents"; import { PaymentSuccessText } from "./PaymentsTextComponents"; import { HollowGreenCheck, fonts, colors } from "@joincivil/elements"; import styled from "styled-components"; const PaymentsSuccessStyled = styled.div` font-family: ${fonts.SANS_SERIF}; text-align: center; svg { margin-bottom: 10px; } h2 { font-size: 18px; font-weight: 600; line-height: 22px; margin: 0 0 5px; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 17px; margin: 0 0 15px; } `; const PaymentSuccessTextStyled = styled.div` margin: 0 auto 30px; width: 280px; `; export interface PaymentsSuccessProps { newsroomName: string; etherToSpend?: number; usdToSpend: number; userSubmittedEmail: boolean; handleClose(): void; } export const PaymentsSuccess: React.FunctionComponent = props => { return ( Done ); }; ================================================ FILE: packages/components/src/Payments/PaymentsTextComponents.tsx ================================================ import * as React from "react"; import { urlConstants as links } from "@joincivil/utils"; import { ErrorIcon, HollowGreenCheck, NorthEastArrow, colors } from "@joincivil/elements"; import { ClipLoader } from "../ClipLoader"; import { PaymentWarning, PaymentGhostBtn, PaymentEdit, PaymentAdjustedNotice, PaymentAdjustedNoticeFtr, PaymentNotice, } from "./PaymentsStyledComponents"; import { CreditCardMin } from "./types"; export const SendPaymentHdrText: React.FunctionComponent = props =>

Send a Boost

; export const SendPaymentHdrEmbedText: React.FunctionComponent = props => (

Send a Boost to {props.newsroomName}

); export const PaymentToNewsroomsTipText: React.FunctionComponent = props => ( <>Your Boost goes directly to the newsroom. ); export const EnterCustomAmountText: React.FunctionComponent = props => <>Or enter a custom amount; export const PublicizeUserText: React.FunctionComponent = props => <>Hide my username from everyone but the newsroom; export const SelectPaymentAmountText: React.FunctionComponent = props => <>Select how much you would like to Boost; export const SelectPaymentMethodText: React.FunctionComponent = props => <>Select how you'd like to pay; export const ExpressPayText: React.FunctionComponent = props => ; export const PaymentInfoText: React.FunctionComponent = props => ( <> Payment Information Boosts procceds are funded using Debit/Credit Cards or ETH. Civil does not collect any fees on Boosts. ); export const PayWithCardText: React.FunctionComponent = props => <>Pay with Card; export const PayWithAppleText: React.FunctionComponent = props => <>Pay with Apple Pay; export const PayWithGoogleText: React.FunctionComponent = props => <>Pay with Google Pay; export interface PayOnCivilTextProps { postId: string; } export const PayAppleGoogleOnCivilText: React.FunctionComponent = props => ( <>

Want to pay with Apple Pay or Google Pay?

Send your Boost on Civil ); export const PaymentStripeNoticeText: React.FunctionComponent = props => ( <>Proceeds of the Boost go directly to the newsroom minus Stripe processing fees. Refunds are not possible. ); export const PayWithEthText: React.FunctionComponent = props => <>Pay with ETH; export const PaymentEthNoticeText: React.FunctionComponent = props => ( <>There are small transaction fees added by the Ethereum network. Refunds are not possible. ); export interface PaymentEmailPrepopulatedTextProps { email: string; } export const PaymentEmailPrepopulatedText: React.FunctionComponent = props => ( Your payment receipt will be sent to {props.email} ); export interface PaymentAmountTextProps { handleEditAmount(): void; } export const PayWithCardMinimumText: React.FunctionComponent = props => (

The Boost minimum for cards is {"$" + CreditCardMin + ".00"}. Boosts amount will be increased to {"$" + CreditCardMin + ".00"} if you pay with a card. Select ETH for smaller amounts. props.handleEditAmount()}>You can edit your Boost amount or continue.

); export const PayWithCardMinimumAdjustedText: React.FunctionComponent = props => (

The Boost minimum for cards is {"$" + CreditCardMin + ".00"}. Your new Boost amount will be increased to {"$" + CreditCardMin + ".00"} when you complete your Boost. This is due to Credit Card processing fees. You can select ETH for smaller amounts.

Adjusted {"$" + CreditCardMin + ".00"}
); export interface PaymentUpdatedTextProps { etherToSpend?: number; usdToSpend?: number; } export const PaymentUpdatedByEthText: React.FunctionComponent = props => (

Your Boost amount was updated. Your new Boost amount will be {props.etherToSpend} ETH ≈ ${props.usdToSpend} when you complete your Boost.

Adjusted ${props.usdToSpend}
); export interface PaymentSelectTextProps { handleEditPaymentType(): void; } export const PaymentEditText: React.FunctionComponent = props => ( Payment Edit ); export const ConnectWalletWarningText: React.FunctionComponent = props => ( You need a digital wallet to continue. ); export const EnoughETHInWalletText: React.FunctionComponent = props => ( You have enough ETH in your connected wallet. ); export const NotEnoughETHInWalletText: React.FunctionComponent = props => ( You don't have enough ETH in your connected wallet. You can update your Boost or purchase more ETH in your wallet. ); export const PaymentEmailConfirmationText: React.FunctionComponent = props => (

We’ll be sending you a confirmation email of your completed transaction.

); export const AddCardEmailConfirmationText: React.FunctionComponent = props => (

We'll send receipts to this email address when you contribute to boosts.

); export const PaymentTermsText: React.FunctionComponent = props => ( <> By sending a Boost, you agree to Civil’s{" "} Terms of Use {" "} and{" "} Privacy Policy . Depending on your selection, your email may be visible to the newsroom. ); export const PaymentInProgressText: React.FunctionComponent = props => ( <>

Your wallet has popped up a new window. Confirm the transaction in your wallet to complete the payment.

); export interface PaymentTextProps { newsroomName: string; etherToSpend?: number; usdToSpend?: number; userSubmittedEmail?: boolean; } export const PaymentSuccessText: React.FunctionComponent = props => ( <>

Boost payment successful!

Thank you for being a contributor.

{props.newsroomName} has received your Boost of{" "} {props.etherToSpend ? ( <> {props.etherToSpend + " ETH"} ≈ {"$" + props.usdToSpend} ) : ( <>${props.usdToSpend} )} . {props.userSubmittedEmail && <>You’ll receive an email with your Boost details.}

); export const PaymentErrorText: React.FunctionComponent = props => <>Your transaction failed. Please try again.; export const WhyEthInfoText: React.FunctionComponent = props => ( <>

Why ETH?

100% of your ETH will go right into the newsroom’s wallet. This way, the Newsroom gets your full support.

You’ll have to use Ethereum cryptocurrency (ETH) in a digital wallet like MetaMask in order to continue. Currently it’s not possible to use other cryptocurrencies, dollars or other fiat currencies.

There is a very small network transaction cost for sending Ethereum out of your wallet, usually it’s a matter of a few cents. This cost goes to the Ethereum miners who perform the computational work for your content to be included on the Ethereum blockchain.

); export const WhatIsEthInfoText: React.FunctionComponent = props => ( <>

What is ETH?

Ether (ETH) is the cryptocurrency for the Ethereum blockchain. You’ll be paying in ETH to tip a newsroom.

You can purchase or exchange for ETH using a cryptocurrency exchange such as Coinbase or Gemini and fund a digital wallet such as MetaMask. Don’t worry, both Coinbase and Gemini are regulated and in compliance with all applicable laws in each jurisdiction in which they operate. Buying ETH with a debit or certain credit cards is instant, once your account is verified.

Each transaction includes a small transaction cost, called gas, which is usually a few cents. These fees go to the Ethereum miners who perform the computational work for your content to be included on the Ethereum blockchain.

); export const CanUseCVLInfoText: React.FunctionComponent = props => ( <>

Can I use CVL to tip a newsroom?

Civil tokens (CVL) are intended as a governance token to be used on the Civil Registry. You can use them to participate in and contribute to Civil’s community. Civil tokens unlock specific activities on the Civil platform, including launching a newsroom on the Registry, challenging and voting for/against Newsrooms for ethics violations or appealing the outcome of a community vote to the Civil Council.

Learn more about Civil tokens

); ================================================ FILE: packages/components/src/Payments/PaymentsWrapper.tsx ================================================ import * as React from "react"; import { PaymentWrapperStyled, PaymentHeader, PaymentHeaderFlex, PaymentHeaderCenter, PaymentHeaderNewsroom, PaymentHeaderBoostLabel, PaymentHeaderAmount, PaymentHeaderTip, PaymentBackBtn, PaymentCivilLogo, } from "./PaymentsStyledComponents"; import { SendPaymentHdrText, SendPaymentHdrEmbedText, PaymentToNewsroomsTipText, PayWithCardMinimumText, PayWithCardMinimumAdjustedText, PaymentUpdatedByEthText, } from "./PaymentsTextComponents"; import { AvatarLogin } from "./AvatarLogin"; import { StoryNewsroomStatus } from "../StoryFeed"; import { CivilLogo, DisclosureArrowIcon, CloseXButton } from "@joincivil/elements"; import { RENDER_CONTEXT, ICivilContext, CivilContext } from "../context"; export interface PaymentsWrapperProps { boostType?: string; newsroomName: string; activeChallenge: boolean; usdToSpend?: number; etherToSpend?: number; selectedUsdToSpend?: number; paymentAdjustedWarning?: boolean; paymentAdjustedEth?: boolean; paymentAdjustedStripe?: boolean; paymentInProgress?: boolean; waitingForConfirmation?: boolean; children: any; handleEditAmount?(): void; handleBack?(): void; handleClose?(): void; } export class PaymentsWrapper extends React.Component { public static contextType = CivilContext; public static context: ICivilContext; public render(): JSX.Element { return ( {this.context.renderContext === RENDER_CONTEXT.EMBED ? this.renderEmbedHeader() : this.renderHeader()} {this.props.paymentAdjustedWarning && this.props.handleEditAmount && ( )} {this.props.paymentAdjustedStripe && } {this.props.paymentAdjustedEth && ( )} {this.props.children} ); } public renderHeader(): JSX.Element { return ( <> {this.props.boostType !== "project" && } {this.props.usdToSpend && this.renderBoostAmount()} ); } public renderEmbedHeader(): JSX.Element { return ( <> {this.props.handleBack ? ( this.props.paymentInProgress ? ( this.props.waitingForConfirmation ? ( Back ) : ( this.props.handleClose && this.props.handleClose()} /> ) ) : ( Back ) ) : (
{/*spacer so flex remains the same with avatarlogin on right*/}
)}
{!this.props.usdToSpend ? ( ) : ( {this.props.usdToSpend && this.renderBoostAmount()} )} ); } public renderBoostAmount(): JSX.Element { return (
{this.props.paymentAdjustedWarning || this.props.paymentAdjustedEth || this.props.paymentAdjustedStripe ? "Selected Boost" : "Boost"} {this.props.paymentAdjustedEth || this.props.paymentAdjustedStripe ? ( "$" + this.props.selectedUsdToSpend ) : ( {"$" + this.props.usdToSpend} )}
); } } ================================================ FILE: packages/components/src/Payments/__snapshots__/Payments.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Boost / Payments Payment Amount 1`] = `

Select how much you would like to Boost

Boost / Payments

Payment Amount

Story Source

            
< styled.div >
< ThemeProvider theme = { {
checkboxInactiveColor
: '#7D7373' ,
checkboxActiveColor
: '#2B56FF' ,
primaryButtonBackground
: '#2B56FF' ,

}
}
>
< PaymentsAmount newsroomName = " Coda Story " suggestedAmounts = { [
{ amount : '1' }
,
{ amount : '2' }
,
{ amount : '3' }
,

]
}
handleAmount = { onClickFunc }
/>
</ ThemeProvider >
</ styled.div >

Prop Types

" PaymentsAmount " Component

No propTypes defined!

" ThemeProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Boost / Payments Payment Login or Guest Selection 1`] = `
Welcome to Civil!
Log in to give a Boost 🚀
You’ll be able to keep track of your contributions and your username may be listed on the Boost leaderboard.
Guest
Proceed to Boost and become a Civil member later.

Boost / Payments

Payment Login or Guest Selection

Story Source

            
< styled.div >
< ThemeProvider theme = { {
checkboxInactiveColor
: '#7D7373' ,
checkboxActiveColor
: '#2B56FF' ,
primaryButtonBackground
: '#2B56FF' ,

}
}
>
< PaymentsLoginOrGuest handleNext = { onClickFunc } handleLogin = { onClickFunc } />
</ ThemeProvider >
</ styled.div >

Prop Types

" PaymentsLoginOrGuest " Component

No propTypes defined!

" ThemeProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Boost / Payments Payment Success 1`] = `

Boost payment successful!

Thank you for being a contributor.

Coda Story has received your Boost of $ 2 . You’ll receive an email with your Boost details.

Boost / Payments

Payment Success

Story Source

            
< styled.div >
< ThemeProvider theme = { {
checkboxInactiveColor
: '#7D7373' ,
checkboxActiveColor
: '#2B56FF' ,
primaryButtonBackground
: '#2B56FF' ,

}
}
>
< PaymentsSuccess newsroomName = " Coda Story " usdToSpend = { 2 } handleClose = { onClickFunc } />
</ ThemeProvider >
</ styled.div >

Prop Types

" PaymentsSuccess " Component

No propTypes defined!

" ThemeProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Boost / Payments Payment Type 1`] = `

Select how you'd like to pay

Want to pay with Apple Pay or Google Pay?

Send your Boost on Civil

Boost / Payments

Payment Type

Story Source

            
< styled.div >
< ThemeProvider theme = { {
checkboxInactiveColor
: '#7D7373' ,
checkboxActiveColor
: '#2B56FF' ,
primaryButtonBackground
: '#2B56FF' ,

}
}
>
< PaymentsOptions
  
postId = " jlasjdfkljsdf "

  
usdToSpend = { 1 }

  
isStripeConnected

  
handleNext = { onClickFunc }

  
renderContext = { 1 }
/>
</ ThemeProvider >
</ styled.div >

Prop Types

" PaymentsOptions " Component

No propTypes defined!

" ThemeProvider " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Payments/index.ts ================================================ export * from "./AvatarLogin"; export * from "./Payments"; export * from "./PaymentsModal"; export * from "./PaymentsStripeCardComponent"; ================================================ FILE: packages/components/src/Payments/queries.ts ================================================ import gql from "graphql-tag"; export const PAYMENTS_ETH_MUTATION = gql` mutation($postID: String!, $input: PaymentsCreateEtherPaymentInput!) { paymentsCreateEtherPayment(postID: $postID, input: $input) { transactionID } } `; export const PAYMENTS_STRIPE_MUTATION = gql` mutation($postID: String!, $input: PaymentsCreateStripePaymentInput!) { paymentsCreateStripePayment(postID: $postID, input: $input) { amount } } `; export const SET_EMAIL_MUTATION = gql` mutation($input: ChannelsSetEmailInput!) { userChannelSetEmail(input: $input) { id } } `; export const GET_STRIPE_PAYMENT_INTENT = gql` mutation($postID: String!, $input: PaymentsCreateStripePaymentInput!) { paymentsCreateStripePaymentIntent(postID: $postID, input: $input) { id clientSecret } } `; export const CREATE_PAYMENT_METHOD = gql` mutation($input: PaymentsCreateStripePaymentMethodInput!) { paymentsCreateStripePaymentMethod(input: $input) { paymentMethodID customerID } } `; export const CLONE_PAYMENT_METHOD = gql` mutation($postID: String!, $input: PaymentsCreateStripePaymentInput!) { paymentsClonePaymentMethod(postID: $postID, input: $input) { payerChannelID paymentMethodID } } `; ================================================ FILE: packages/components/src/Payments/types.ts ================================================ export const SuggestedPaymentAmounts = [{ amount: "1" }, { amount: "2" }, { amount: "3" }, { amount: "5" }]; export const CreditCardMin = 1; export enum PAYMENT_STATE { SELECT_AMOUNT, PAYMENT_CHOOSE_LOGIN_OR_GUEST, SELECT_PAYMENT_TYPE, ETH_PAYMENT, STRIPE_PAYMENT, APPLE_PAY, GOOGLE_PAY, PAYMENT_SUCCESS, PAYMENT_SUCCESS_WITH_SAVED_EMAIL, } export enum INPUT_STATE { EMPTY = "empty", VALID = "valid", INVALID = "invalid", } ================================================ FILE: packages/components/src/PhaseCountdown/PhaseCountdown.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { TextCountdownTimer, ProgressBarCountdownTimer, TwoPhaseProgressBarCountdownTimer } from "./index"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 400px; `; const Container: React.FunctionComponent = ({ children }) => {children}; const now = Date.now() / 1000; const oneDay = 86400; storiesOf("Registry / Application Phase Countdown Timer", module) .add("Text Timers", () => { const eightDaysFromNow = now + oneDay * 8; return ( {process.env.NODE_ENV !== "test" && ( <>

Base style

Warning style

Ended

)}
); }) .add("Progress Bar Timers", () => { const shortTotalSeconds = 60 * 1; const shortEndTime = now + shortTotalSeconds * 0.65; const totalSeconds = oneDay * 8; const endTime = now + oneDay * 3.5; const flavorText = "under community review"; return ( {process.env.NODE_ENV !== "test" && ( <>

A Short Phase

The animation is more visible

A Long Phase

)}
); }) .add("Two Phase Progress Bar Timers", () => { const shortTotalSeconds = 60 * 1; const shortEndTime = now + shortTotalSeconds * 0.65; const flavorText = "under community review"; return ( {process.env.NODE_ENV !== "test" && ( <>

First phase is active

Second phase is active

)}
); }); ================================================ FILE: packages/components/src/PhaseCountdown/ProgressBarCountdownTimer.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings, getReadableDuration } from "@joincivil/utils"; import { InjectedCountdownTimerProps, ProgressBarCountdownProps } from "./types"; import { StyledProgressBarCountdownTimer, ProgressBarCountdownContainer, ProgressBarDisplayLabel, ProgressBarCountdownTotal, ProgressBarCountdownProgress, ProgressBarCopy, MetaItem, MetaItemValueAccent, MetaItemLabel, } from "./styledComponents"; import { QuestionToolTip } from "../QuestionToolTip"; export class ProgressBarCountdownTimerComponent extends React.Component< ProgressBarCountdownProps & InjectedCountdownTimerProps > { public render(): JSX.Element { const progress = this.getProgress(); const style = { width: `${(progress * 100).toString()}%` }; return ( {this.props.displayLabel} {this.renderReadableTimeRemaining()} {this.renderExpiry()} ); } private renderExpiry = (): JSX.Element => { const [expiryDateString, expiryTimeString] = this.props.endTime ? getLocalDateTimeStrings(parseInt(this.props.endTime.toString(), 10)) : ["", ""]; return ( Newsroom listing {this.props.secondsRemaining! > 0 ? "is" : "was"} {this.props.flavorText} until{" "} {expiryDateString} {expiryTimeString} ); }; private renderReadableTimeRemaining = (): JSX.Element => { if (this.props.secondsRemaining! > 0) { return ( {getReadableDuration(this.props.secondsRemaining!, ["second"])} Remaining ); } return ( Ended   ); }; private getProgress = (): number => { if (this.props.secondsRemaining! > 0) { return 1 - this.props.secondsRemaining! / this.props.totalSeconds; } return 1; }; } ================================================ FILE: packages/components/src/PhaseCountdown/SmallProgressBarCountdownTimer.tsx ================================================ import * as React from "react"; import { InjectedCountdownTimerProps, ProgressBarCountdownProps } from "./types"; import { getReadableDuration } from "@joincivil/utils"; import { StyledProgressBarCountdownTimer, ProgressBarCountdownContainer, ProgressBarCountdownTotal, ProgressBarCountdownProgress, MetaItem, CompactProgressBarDisplayLabel, CompactMetaItemValueAccent, } from "./styledComponents"; export class SmallProgressBarCountdownTimerComponent extends React.Component< ProgressBarCountdownProps & InjectedCountdownTimerProps > { public render(): JSX.Element { const progress = this.getProgress(); const style = { width: `${(progress * 100).toString()}%` }; const DisplayLabel = this.props.displayLabel; return ( {this.renderReadableTimeRemaining()} ); } private getProgress = (): number => { if (this.props.secondsRemaining! > 0) { return 1 - this.props.secondsRemaining! / this.props.totalSeconds; } return 1; }; private renderReadableTimeRemaining = (): JSX.Element => { const FlavorText = this.props.flavorText || (() => <>); if (this.props.secondsRemaining! > 0) { return ( {getReadableDuration(this.props.secondsRemaining!)} ); } return ( Ended ); }; } ================================================ FILE: packages/components/src/PhaseCountdown/TextCountdownTimer.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { getLocalDateTimeStrings, getReadableDuration } from "@joincivil/utils"; import { colors, fonts } from "../styleConstants"; import { ClockIcon } from "../icons"; import { CountdownTimerProps, InjectedCountdownTimerProps } from "./types"; const StyledCountdownTimerContainer = styled.div` display: flex; font: normal 14px/17px ${fonts.SANS_SERIF}; margin: 0 0 16px; `; export const StyledDurationContainer = styled.span` color: ${colors.accent.CIVIL_BLUE}; `; const StyledIconContainer = styled.span` margin-right: 12px; `; export const StyledCountdownLabel = styled.span` color: ${colors.accent.CIVIL_BLUE}; `; export const StyledCountdownLabelWarn = styled(StyledCountdownLabel)` color: ${colors.accent.CIVIL_RED}; `; const StyledExpiry = styled.div` font-size: 14px; line-height: 17px; margin: 2px 0 0; `; export class TextCountdownTimerComponent extends React.Component { public render(): JSX.Element { const labelText = this.props.secondsRemaining! > 0 ? "Ends in " : "Ended"; let label; if (this.props.warn) { label = {labelText}; } else { label = {labelText}; } return (
{label} {this.renderReadableTimeRemaining()} {this.renderExpiry()}
); } private renderExpiry = (): JSX.Element => { const [expiryDateString, expiryTimeString] = getLocalDateTimeStrings(this.props.endTime); return ( {expiryDateString} at {expiryTimeString} ); }; private renderReadableTimeRemaining = (): JSX.Element => { if (this.props.warn) { return ( {getReadableDuration(this.props.secondsRemaining!, ["second"])} ); } return {getReadableDuration(this.props.secondsRemaining!, ["second"])}; }; } ================================================ FILE: packages/components/src/PhaseCountdown/TwoPhaseProgressBarCountdownTimer.tsx ================================================ import * as React from "react"; import { getLocalDateTimeStrings, getReadableDuration } from "@joincivil/utils"; import { InjectedCountdownTimerProps, TwoPhaseProgressBarCountdownProps } from "./types"; import { StyledProgressBarCountdownTimer, ProgressBarCountdownContainer, ProgressBarDisplayLabel, ProgressBarCountdownTotal, ProgressBarCountdownProgress, ProgressBarCopy, TwoPhaseProgressBarContainer, MetaItem, MetaItemValueAccent, MetaItemLabel, } from "./styledComponents"; import { QuestionToolTip } from "../QuestionToolTip"; export class TwoPhaseProgressBarCountdownTimerComponent extends React.Component< TwoPhaseProgressBarCountdownProps & InjectedCountdownTimerProps > { public render(): JSX.Element { return ( {this.renderCountdownProgressBars()} {this.renderReadableTimeRemaining()} {this.renderExpiry()} ); } private renderCountdownProgressBars = (): JSX.Element => { const primaryProgressBar = this.renderPrimaryProgressBar(); const secondaryProgressBar = this.renderSecondaryProgressBar(); let progressBars: JSX.Element[]; if (this.props.activePhaseIndex === 0) { progressBars = [primaryProgressBar, secondaryProgressBar]; } else { progressBars = [secondaryProgressBar, primaryProgressBar]; } return {progressBars}; }; private renderPrimaryProgressBar = (): JSX.Element => { const progress = this.getProgress(); const style = { width: `${(progress * 100).toString()}%` }; return ( {this.props.displayLabel} ); }; private renderSecondaryProgressBar = (): JSX.Element => { const progress = this.props.activePhaseIndex === 0 ? 0 : 1; const style = { width: `${(progress * 100).toString()}%` }; return ( {this.props.secondaryDisplayLabel} ); }; private renderExpiry = (): JSX.Element => { const [expiryDateString, expiryTimeString] = getLocalDateTimeStrings(this.props.endTime); return ( Newsroom listing {this.props.secondsRemaining! > 0 ? "is" : "was"} {this.props.flavorText} until{" "} {expiryDateString} {expiryTimeString} ); }; private renderReadableTimeRemaining = (): JSX.Element => { if (this.props.secondsRemaining! > 0) { return ( {getReadableDuration(this.props.secondsRemaining!)} Remaining ); } return ( Ended   ); }; private getProgress = (): number => { if (this.props.secondsRemaining! > 0) { return 1 - this.props.secondsRemaining! / this.props.totalSeconds; } return 1; }; } ================================================ FILE: packages/components/src/PhaseCountdown/__snapshots__/PhaseCountdown.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Application Phase Countdown Timer Progress Bar Timers 1`] = `

Registry / Application Phase Countdown Timer

Progress Bar Timers

Story Source

            
< Container />

Prop Types

" Container " Component

No propTypes defined!
`; exports[`Storyshots Registry / Application Phase Countdown Timer Text Timers 1`] = `

Registry / Application Phase Countdown Timer

Text Timers

Story Source

            
< Container />

Prop Types

" Container " Component

No propTypes defined!
`; exports[`Storyshots Registry / Application Phase Countdown Timer Two Phase Progress Bar Timers 1`] = `

Registry / Application Phase Countdown Timer

Two Phase Progress Bar Timers

Story Source

            
< Container />

Prop Types

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/PhaseCountdown/constants.ts ================================================ import * as React from "react"; import { InApplicationPhaseLabelText, ChallengeCommitVotePhaseLabelText, ChallengeRevealVotePhaseLabelText, ChallengeAwaitingAppealRequestPhaseLabelText, ChallengeAwaitingAppealJudgementPhaseLabelText, InApplicationFlavorText, ChallengeCommitVoteFlavorText, ChallengeRevealVoteFlavorText, ChallengeAwaitingAppealRequestFlavorText, ChallengeAwaitingAppealJudgementFlavorText, ChallengeAwaitingAppealChallengePhaseLabelText, ChallengeAwaitingAppealChallengeFlavorText, } from "./textComponents"; export enum PHASE_TYPE_NAMES { IN_APPLICATION = "IN_APPLICATION", CHALLENGE_COMMIT_VOTE = "CHALLENGE_COMMIT_VOTE", CHALLENGE_REVEAL_VOTE = "CHALLENGE_REVEAL_VOTE", CHALLENGE_AWAITING_APPEAL_REQUEST = "CHALLENGE_AWAITING_APPEAL_REQUEST", CHALLENGE_AWAITING_APPEAL_JUDGEMENT = "CHALLENGE_AWAITING_APPEAL_JUDGEMENT", CHALLENGE_AWAITING_APPEAL_CHALLENGE = "CHALLENGE_AWAITING_APPEAL_CHALLENGE", APPEAL_CHALLENGE_COMMIT_VOTE = "APPEAL_CHALLENGE_COMMIT_VOTE", APPEAL_CHALLENGE_REVEAL_VOTE = "APPEAL_CHALLENGE_REVEAL_VOTE", } export const PHASE_TYPE_LABEL: { [index: string]: React.FunctionComponent } = { IN_APPLICATION: InApplicationPhaseLabelText, CHALLENGE_COMMIT_VOTE: ChallengeCommitVotePhaseLabelText, CHALLENGE_REVEAL_VOTE: ChallengeRevealVotePhaseLabelText, CHALLENGE_AWAITING_APPEAL_REQUEST: ChallengeAwaitingAppealRequestPhaseLabelText, CHALLENGE_AWAITING_APPEAL_JUDGEMENT: ChallengeAwaitingAppealJudgementPhaseLabelText, CHALLENGE_AWAITING_APPEAL_CHALLENGE: ChallengeAwaitingAppealChallengePhaseLabelText, APPEAL_CHALLENGE_COMMIT_VOTE: ChallengeCommitVotePhaseLabelText, APPEAL_CHALLENGE_REVEAL_VOTE: ChallengeRevealVotePhaseLabelText, }; export const PHASE_TYPE_FLAVOR_TEXT: { [index: string]: React.FunctionComponent } = { IN_APPLICATION: InApplicationFlavorText, CHALLENGE_COMMIT_VOTE: ChallengeCommitVoteFlavorText, CHALLENGE_REVEAL_VOTE: ChallengeRevealVoteFlavorText, CHALLENGE_AWAITING_APPEAL_REQUEST: ChallengeAwaitingAppealRequestFlavorText, CHALLENGE_AWAITING_APPEAL_JUDGEMENT: ChallengeAwaitingAppealJudgementFlavorText, CHALLENGE_AWAITING_APPEAL_CHALLENGE: ChallengeAwaitingAppealChallengeFlavorText, APPEAL_CHALLENGE_COMMIT_VOTE: ChallengeCommitVoteFlavorText, APPEAL_CHALLENGE_REVEAL_VOTE: ChallengeRevealVoteFlavorText, }; ================================================ FILE: packages/components/src/PhaseCountdown/index.tsx ================================================ import { CountdownTimerProps, InjectedCountdownTimerProps, CountdownTimerState, ProgressBarCountdownProps, TwoPhaseProgressBarCountdownProps, } from "./types"; import { TextCountdownTimerComponent } from "./TextCountdownTimer"; import { ProgressBarCountdownTimerComponent } from "./ProgressBarCountdownTimer"; import { TwoPhaseProgressBarCountdownTimerComponent } from "./TwoPhaseProgressBarCountdownTimer"; import { SmallProgressBarCountdownTimerComponent } from "./SmallProgressBarCountdownTimer"; import * as React from "react"; const connectCountdownTimer = () => ( CountdownTimerComponent: | React.ComponentClass | React.FunctionComponent, ) => { return class HOCountdownTimerContainer extends React.Component { public timer?: number; constructor(props: TCountdownTimerProps) { super(props); this.state = { secondsRemaining: 0, }; } public render(): JSX.Element { return ; } public async componentDidMount(): Promise { return this.initCountdown(); } public componentWillUnmount(): void { if (this.timer) { window.clearInterval(this.timer); } } public updateTimeRemaining = () => { const expiry = this.props.endTime; const currentTime = parseInt((Date.now() / 1000).toString(), 10); // convert from milliseconds const secondsRemaining = expiry - currentTime; this.setState({ secondsRemaining }); return secondsRemaining; }; public initCountdown = async () => { const timeRemaining = this.updateTimeRemaining(); if (timeRemaining > 0) { this.timer = window.setInterval(this.updateTimeRemaining, 1000); } else { window.clearInterval(this.timer); } }; }; }; export const TextCountdownTimer = connectCountdownTimer()(TextCountdownTimerComponent); export const ProgressBarCountdownTimer: React.ComponentClass = connectCountdownTimer()( ProgressBarCountdownTimerComponent, ); export const SmallProgressBarCountdownTimer: React.ComponentClass = connectCountdownTimer()( SmallProgressBarCountdownTimerComponent, ); export const TwoPhaseProgressBarCountdownTimer: React.ComponentClass< TwoPhaseProgressBarCountdownProps > = connectCountdownTimer()(TwoPhaseProgressBarCountdownTimerComponent); export * from "./types"; export * from "./constants"; ================================================ FILE: packages/components/src/PhaseCountdown/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export const ProgressBarCountdownContainer = styled.div` margin-bottom: 24px; `; export const ProgressBarDisplayLabel = styled.h4` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 12px; font-weight: 600; line-height: 15px; margin: 0 0 7px; text-transform: uppercase; `; export const ProgressBarBase = styled.div` height: 12px; border-radius: 7.5px; `; export const ProgressBarCountdownTotal = styled(ProgressBarBase)` background-color: ${colors.accent.CIVIL_GRAY_4}; box-sizing: border-box; position: relative; width: 100%; `; export const ProgressBarCountdownProgress = styled(ProgressBarBase)` display: inline-block; background-color: ${colors.accent.CIVIL_BLUE}; left: 0; top: 0; position: absolute; transition: width 500ms ease; `; export const StyledProgressBarCountdownTimer = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; text-align: left; `; export const TwoPhaseProgressBarContainer = styled.div` display: flex; justify-content: space-between; ${ProgressBarCountdownContainer}${ProgressBarCountdownContainer} { width: 46%; margin-left: 4%; } ${ProgressBarCountdownContainer}${ProgressBarCountdownContainer}:first-of-type { border-right: 1px solid ${colors.accent.CIVIL_GRAY_4}; margin-left: 0; padding-right: 4%; } `; export const MetaItem = styled.div` margin: 0 0 16px; `; export const MetaItemValue = styled.div` font-size: 22px; line-height: 27px; `; export const MetaItemValueAccent = styled(MetaItemValue)` color: ${colors.primary.CIVIL_BLUE_1}; `; export const MetaItemLabel = styled.div` font-size: 14px; line-height: 17px; `; export const ProgressBarCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; letter-spacing: 0.68px; line-height: 20px; `; export const CompactProgressBarDisplayLabel = styled.h4` font-size: 12px; line-height: 15px; margin: 0 0 7px; text-transform: uppercase; `; export const CompactMetaItemValueAccent = styled.div` color: ${colors.accent.CIVIL_RED}; font-size: 14px; line-height: 17px; `; ================================================ FILE: packages/components/src/PhaseCountdown/textComponents.tsx ================================================ import * as React from "react"; export const InApplicationPhaseLabelText: React.FunctionComponent = props => <>Awaiting Approval; export const ChallengeCommitVotePhaseLabelText: React.FunctionComponent = props => <>Commit Vote; export const ChallengeRevealVotePhaseLabelText: React.FunctionComponent = props => <>Reveal Vote; export const ChallengeAwaitingAppealRequestPhaseLabelText: React.FunctionComponent = props => ( <>Awaiting Appeal Request ); export const ChallengeAwaitingAppealJudgementPhaseLabelText: React.FunctionComponent = props => ( <>Awaiting Appeal Decision ); export const ChallengeAwaitingAppealChallengePhaseLabelText: React.FunctionComponent = props => ( <>Awaiting Appeal Challenge ); export const InApplicationFlavorText: React.FunctionComponent = props => <>until approval; export const ChallengeCommitVoteFlavorText: React.FunctionComponent = props => <>to commit votes; export const ChallengeRevealVoteFlavorText: React.FunctionComponent = props => <>to reveal votes; export const ChallengeAwaitingAppealRequestFlavorText: React.FunctionComponent = props => <>to request an appeal; export const ChallengeAwaitingAppealJudgementFlavorText: React.FunctionComponent = props => ( <>until Council's decision ); export const ChallengeAwaitingAppealChallengeFlavorText: React.FunctionComponent = props => ( <>to challenge the granted appeal ); ================================================ FILE: packages/components/src/PhaseCountdown/types.ts ================================================ import * as React from "react"; export interface CountdownTimerProps { warn?: boolean | undefined; endTime: number; } export interface InjectedCountdownTimerProps { secondsRemaining?: number; } export interface CountdownTimerState { secondsRemaining: number; } export interface ProgressBarCountdownProps extends CountdownTimerProps { displayLabel: string | React.FunctionComponent | React.ComponentClass; totalSeconds: number; flavorText?: string | React.FunctionComponent | React.ComponentClass; toolTipText?: string | React.ReactNode; } export interface TwoPhaseProgressBarCountdownProps extends ProgressBarCountdownProps { activePhaseIndex: number; secondaryDisplayLabel: string | React.FunctionComponent | React.ComponentClass; secondaryToolTipText?: string | React.ReactNode; } ================================================ FILE: packages/components/src/ProgressModalContent.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { LoadingIndicator } from "./LoadingIndicator"; import { ModalHeading, ModalContent, ModalContentInsetContainer, StyledModalErrorContainer } from "./ModalContent"; import { Button, buttonSizes } from "./Button"; import { OctopusErrorIcon } from "./icons"; export interface ProgressModalContentProps { hideModal?(): void; } export const ProgressModalContentInProgress: React.FunctionComponent = props => { const content = props.children || Your transaction is in progress.; return ( <> {content} Your transaction is processing. This can take several minutes. Please don't close the tab. How about taking a little breather and standing for a bit? Maybe even stretching? ); }; export const ProgressModalContentSuccess: React.FunctionComponent = props => { const handleOnClick = (event: any): void => { if (props.hideModal) { props.hideModal(); } }; return ( <> Success! Transaction processed. ); }; export const ProgressModalContentError: React.FunctionComponent = props => { const handleOnClick = (event: any): void => { if (props.hideModal) { props.hideModal(); } }; if (props.children) { return ( <> {props.children} ); } return ( <> Uh oh! Your transaction failed. Please try again. ); }; export const ProgressModalContentMobileUnsupported: React.FunctionComponent = props => { const handleOnClick = (event: any): void => { if (props.hideModal) { props.hideModal(); } }; return ( <> We're sorry, this action is only available on desktop. Transactions requiring MetaMask on mobile are not available yet, but they're coming. In the meantime, you can still browse newsroom listings on our site. ); }; ================================================ FILE: packages/components/src/QuestionToolTip.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { QuestionToolTip } from "./QuestionToolTip"; import styled from "styled-components"; const Wrapper = styled.div` display: flex; justify-content: center; align-items: center; width: 100vw; height: 100vh; `; storiesOf("Pattern Library / Tooltips / QuestionToolTip", module).add("tooltip", () => { return ( ); }); ================================================ FILE: packages/components/src/QuestionToolTip.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { ToolTip, ToolTipProps } from "./ToolTip"; import { colors } from "./styleConstants"; const Outer = styled.div` display: inline-block; vertical-align: top; `; const Wrapper = styled.div` width: 18px; height: 18px; position: relative; margin-left: 5px; margin-top: -1px; `; export class QuestionToolTip extends React.Component { public render(): JSX.Element { const colorEnabled = (this.props.theme && this.props.theme.toolTipColorEnabled) || colors.primary.BLACK; const colorDisabled = (this.props.theme && this.props.theme.toolTipColorDisabled) || colors.accent.CIVIL_GRAY_4; const color = this.props.disabled ? colorDisabled : colorEnabled; return ( ); } } ================================================ FILE: packages/components/src/RegistryEmpty/index.ts ================================================ export * from "./styledComponents"; ================================================ FILE: packages/components/src/RegistryEmpty/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { Button } from "../Button"; export const StyledRegistryEmpty = styled.div` font-family: ${fonts.SANS_SERIF}; padding: 50px 0 221px; text-align: center; `; export const StyledEmptyHeader = styled.div` font-size: 21px; line-height: 33px; letter-spacing: -0.2px; margin: 0 0 60px; `; export const StyledEmptyCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 18px; line-height: 33px; letter-spacing: -0.12px; margin: 40px 0; ${Button} { margin-top: 12px; } `; ================================================ FILE: packages/components/src/RescueTokens.tsx ================================================ import * as React from "react"; import { TextInput } from "./input/"; import { TransactionButton } from "./TransactionButton"; import { FormCopy, FormHeader } from "./ListingDetailPhaseCard/styledComponents"; export interface RescueTokensProps { challengeID: string; transactions: any[]; modalContentComponents?: any; } export class RescueTokens extends React.Component { public render(): JSX.Element { return ( <> Rescue Tokens You did not reveal your vote. Please use the below button to rescue your unrevealed voting tokens. Rescue Tokens ); } } ================================================ FILE: packages/components/src/ReviewVote/ReviewVote.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { ReviewVote, ReviewVoteProps } from "./ReviewVoteModal"; const StyledDiv = styled.div` display: flex; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Registry / Review Vote", module).add("Review Vote Modal", () => { const handleClose = () => { console.log("Closed the modal"); }; const props: ReviewVoteProps = { newsroomName: "Taco Tuesdays", listingDetailURL: "https://civil.co/#taco-tuesdays", challengeID: "420", open: true, numTokens: "1000", voteOption: "1", salt: "9635457449074", userAccount: "0xa441d0e2b078f13e8c45e221b81f6aa103c48a45", commitEndDate: 1533916728, revealEndDate: 1533917128, transactions: [], handleClose, }; return (

Some good stuff was already on the page which is pretty exciting

{process.env.NODE_ENV !== "test" && }
); }); ================================================ FILE: packages/components/src/ReviewVote/ReviewVoteModal.tsx ================================================ import * as React from "react"; import AddToCalendar from "react-add-to-calendar"; import { EthAddress } from "@joincivil/typescript-types"; import { saltToWords, getFormattedEthAddress, getLocalDateTimeStrings, padString } from "@joincivil/utils"; import { FullScreenModal, FullScreenModalProps } from "../FullscreenModal"; import { buttonSizes, CancelButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { QuestionToolTip } from "../QuestionToolTip"; import { Checkbox, CheckboxSizes } from "../input/Checkbox"; import { MetaMaskLogoButton } from "../"; import { ReviewVoteHeaderTitleText, ReviewVoteCopyText, SaltLabelText, ReviewVoteDecisionText, AppealChallengeReviewVoteDecisionText, ReviewVoteDepositedCVLLabelText, ReviewVoteMyAddressLabelText, ConfirmVotesLabelText, TransactionButtonText, SaltPhraseToolTipText, TransactionFinePrintText, SaveSaltCheckboxLabelText, } from "./textComponents"; import { ModalOuter, ModalContent, StyledReviewVoteHeaderTitle, StyledReviewVoteContent, StyledReviewVoteContentCopy, StyledReviewVoteDetails, MetaRow, MetaRowSalt, MetaItemLabel, MetaItemLabelSalt, MetaItemValue, MetaItemValueUser, MetaItemValueSalt, MetaItemValueTwoCol, StyledAddToCalendarContainer, StyledConfirmVoteDateRange, StyledAddToCalendar, StyledButtonContainer, StyledTransactionFinePrint, StyledDidSaveSaltContainer, } from "./styledComponents"; export interface ReviewVoteProps extends FullScreenModalProps { newsroomName: string; listingDetailURL: string; challengeID: string; isAppealChallenge?: boolean; numTokens?: string; voteOption?: string; salt?: string; userAccount: EthAddress; commitEndDate: number; revealEndDate: number; transactions: any[]; modalContentComponents?: any; handleClose(): void; postExecuteTransactions?(): void; } interface ReviewVoteState { didSaveSalt: boolean; } function printThis(): void { window.print(); } function getSaltyWords(salt?: string): string { if (!salt) { return ""; } return saltToWords(salt).join(" "); } function getReadableRevealDateRange(commitEndDate: number, revealEndDate: number): string { const revealStartDateTime = getLocalDateTimeStrings(commitEndDate + 1); const revealEndDateTime = getLocalDateTimeStrings(revealEndDate); return `From ${revealStartDateTime[0]} at ${revealStartDateTime[1]} to ${revealEndDateTime[0]} at ${revealEndDateTime[1]}`; } function getCalendarEventDateTime(seconds: number | Date): string { const theDate = typeof seconds === "number" ? new Date(seconds * 1000) : seconds; const pad = (num: number | string) => { return padString(num, 2, "0"); }; const hours = pad(theDate.getHours()); const mins = pad(theDate.getMinutes()); const tzOffset = `${pad(theDate.getTimezoneOffset() / 60)}${pad(theDate.getTimezoneOffset() % 60)}`; const dateString = `${theDate.getFullYear()}-${pad(theDate.getMonth() + 1)}-${pad(theDate.getDate())}`; const timeString = `${hours}:${mins}-${tzOffset}`; return `${dateString}T${timeString}`; } const AddRevealPhaseToCalendar: React.FunctionComponent = props => { // @TODO(jon): `textComponents` don't work here b/c these fields are plaintext. Let's // revisit converting JSX.Components to strings via textContent before this goes to mainnet const title = `Reveal My Vote for ${props.newsroomName} on The Civil Registry`; const description = ` ${props.listingDetailURL}\n\n My Secret Phrase\n ${getSaltyWords(props.salt)}\n\n Challenge ID ${props.challengeID}\n I voted for ${props.newsroomName} to be ${ props.voteOption === "0" ? "rejected from" : "accepted to" } the Civil Registry\n\n My Deposited CVL\n ${props.numTokens} `; const location = props.listingDetailURL; const startTime = getCalendarEventDateTime(props.commitEndDate + 1); const endTime = getCalendarEventDateTime(props.revealEndDate); const event = { title, description, location, startTime, endTime, }; return ( ); }; export class ReviewVote extends React.Component { public state = { didSaveSalt: false, }; public render(): JSX.Element { const { open, challengeID, salt, commitEndDate, revealEndDate, isAppealChallenge, voteOption, newsroomName, numTokens, userAccount, transactions, postExecuteTransactions, handleClose, } = this.props; const { didSaveSalt } = this.state; return (
} positionBottom={true} /> {getSaltyWords(salt)} {getReadableRevealDateRange(commitEndDate, revealEndDate)}

Remember to set event to Private

Challenge ID {challengeID} {isAppealChallenge ? ( ) : ( )} {numTokens} {userAccount && getFormattedEthAddress(userAccount)}
Cancel
); } private toggleHasSavedSalt = (): void => { this.setState({ didSaveSalt: !this.state.didSaveSalt }); }; } ================================================ FILE: packages/components/src/ReviewVote/__snapshots__/ReviewVote.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Review Vote Review Vote Modal 1`] = `

Some good stuff was already on the page which is pretty exciting

Registry / Review Vote

Review Vote Modal

Story Source

            
< Container >
< p >
Some good stuff was already on the page which is pretty exciting
</ p >
</ Container >

Prop Types

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/ReviewVote/index.ts ================================================ export * from "./ReviewVoteModal"; export { StyledAddToCalendar } from "./styledComponents"; ================================================ FILE: packages/components/src/ReviewVote/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; export const ModalOuter = styled.div` display: flex; height: 100vh; justify-content: center; overflow: hidden scroll; width: 100vw; `; export const ModalContent = styled.div` padding: 100px 0 156px; max-width: 800px; a { border-bottom: transparent 1px solid; color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; text-decoration: none; } a:hover { border-bottom-color: ${colors.accent.CIVIL_BLUE}; } ${mediaQueries.MOBILE} { margin-right: 10px; margin-left: 10px; } `; export const StyledReviewVoteHeaderTitle = styled.h2` font-size: 24px; line-height: 30px; letter-spacing: -0.17px; margin: 0 0 2px; `; export const StyledReviewVoteContent = styled.div` max-width: 790px; `; export const StyledReviewVoteContentCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 16px; line-height: 26px; margin: 12px 0 30px; span { border-bottom: transparent 1px solid; color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; text-decoration: none; } span:hover { border-bottom-color: ${colors.accent.CIVIL_BLUE}; } `; export const StyledReviewVoteDetails = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 3px; padding: 33px 30px; `; export const MetaRowSalt = styled.div` background: ${colors.accent.CIVIL_TEAL_FADED}; margin: -33px -30px 24px; padding: 33px 30px; `; export const MetaRow = styled.div` margin: 0 0 18px; & ~ & { border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding: 19px 0 0; } `; export const MetaItemLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 12px; font-weight: bold; line-height: 15px; margin-bottom: 8px; text-transform: uppercase; `; export const MetaItemLabelSalt = styled(MetaItemLabel)` color: ${colors.primary.BLACK}; font-size: 18px; line-height: 21px; margin-bottom: 10px; `; export const MetaItemValue = styled.div` line-height: 33px; `; export const MetaItemValueTwoCol = styled(MetaItemValue)` display: flex; font-size: 18px; justify-content: space-between; `; export const StyledConfirmVoteDateRange = styled.div` width: 50%; `; export const StyledAddToCalendarContainer = styled.div` width: 207px; p { color: ${colors.primary.CIVIL_GRAY_1}; font-size: 12px; line-height: 15px; margin: 6px 0 0; } `; export const MetaItemValueUser = styled(MetaItemValue)` font-family: ${fonts.MONOSPACE}; `; export const MetaItemValueSalt = styled.div` background: ${colors.basic.WHITE}; font-family: ${fonts.MONOSPACE}; font-size: 21px; line-height: 14px; padding: 10px 27px; text-align: center; `; export const StyledAddToCalendar = styled.div` .react-add-to-calendar { -webkit-font-smoothing: antialiased; text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004); position: relative; display: inline-block; margin: 0 auto 6px; white-space: nowrap; } .react-add-to-calendar__wrapper { zoom: 1; cursor: pointer; } .react-add-to-calendar__button { background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.accent.CIVIL_BLUE_VERY_FADED}; border-radius: 0px; font-weight: bold; color: ${colors.accent.CIVIL_BLUE}; font-size: 14px; line-height: 17px; padding: 15px 35px; .react-add-to-calendar--light { background-color: ${colors.basic.WHITE}; } } .react-add-to-calendar__icon { .react-add-to-calendar--right { padding-left: 5px; } .react-add-to-calendar--left { padding-right: 5px; } } .react-add-to-calendar__dropdown { position: absolute; top: 42px; left: 1px; width: 93%; padding: 5px 0 5px 8px; box-shadow: 1px 3px 6px rgba(0, 0, 0, 0.15); border: 1px solid ${colors.accent.CIVIL_GRAY_4}; background-color: ${colors.basic.WHITE}; text-align: left; ul { list-style: none; margin: 0; padding: 0; li { padding: 0 0 5px; a { font-size: 14px; text-decoration: none; &:hover { color: ${colors.accent.CIVIL_BLUE}; } i { padding-right: 10px; } } } } } `; export const StyledButtonContainer = styled.div` display: flex; flex-direction: row-reverse; justify-content: flex-start; margin-bottom: 16px; text-align: right; & > button { margin-left: 10px; } `; export const StyledDidSaveSaltContainer = styled.div` display: flex; font-size: 15px; letter-spacing: -0.1px; line-height: 26px; padding: 0 30px; margin: 58px 0 51px; & > div + div { margin: -8px 0 0 8px; } `; export const StyledTransactionFinePrint = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 13px; line-height: 16px; margin-bottom: 150px; text-align: right; `; ================================================ FILE: packages/components/src/ReviewVote/textComponents.tsx ================================================ import * as React from "react"; import { urlConstants as links } from "@joincivil/utils"; import { WhitelistActionText, RemoveActionText, OverturnActionText, UpholdActionText, } from "../ListingDetailPhaseCard/textComponents"; // Review Vote modal export const ReviewVoteHeaderTitleText: React.FunctionComponent = props => { return <>Review and Save Your Voting Information; }; export interface ReviewVoteCopyTextProps { handlePrintClick(): void; } export const ReviewVoteCopyText: React.FunctionComponent = props => { return ( <>

Civil does not store your voting information; it is stored in a{" "} voting smart contract .

You need to carefully save your unique 4-word voting code for the next voting stage. If you forget this voting code when you confirm your vote in the next voting stage, your vote will not be counted.

We recommend writing your voting code down and emailing it to yourself, taking a screenshot of this page, or{" "} print this out. Or, add a reminder to your calendar so you don’t forget to confirm your vote.

); }; export const ReviewVoteDepositedCVLLabelText: React.FunctionComponent = props => { return <>Amount of Voting Tokens Submitted; }; export const ReviewVoteMyAddressLabelText: React.FunctionComponent = props => { return <>My Public Address; }; export interface SaltLabelTextProps { challengeID: string; } export const SaltLabelText: React.FunctionComponent = props => { return <>Unique 4-word Voting Code for Challenge #{props.challengeID}; }; export interface ReviewVoteDecisionTextProps { newsroomName?: string; voteOption?: string; } export const ReviewVoteDecisionText: React.FunctionComponent = props => { if (!props.voteOption) { return <>; } const voteText = props.voteOption === "0" ? : ; return ( <> I voted to {voteText} {props.newsroomName || "this newsroom"} {props.voteOption === "0" ? "from" : "in"}{" "} the Civil Registry ); }; export const AppealChallengeReviewVoteDecisionText: React.FunctionComponent = props => { if (!props.voteOption) { return <>; } const voteText = props.voteOption === "1" ? : ; return ( <> I voted for the Granted Appeal for {props.newsroomName || "this newsroom"} to be {voteText} ); }; export const ConfirmVotesLabelText: React.FunctionComponent = props => { return <>Confirm Vote Dates; }; export const TransactionButtonText: React.FunctionComponent = props => { return <>Open MetaMask to Approve; }; export const SaltPhraseToolTipText: React.FunctionComponent = props => { return ( <>

Your vote will be hidden, using this secret phrase. You will need to enter this secret phrase when you confirm your vote during the reveal phase of this challenge.

Be sure to record your secret phrase for safekeeping. If you lose your secret phrase, your vote is lost. Unfortunately, we can not recover it for you.

); }; export const TransactionFinePrintText: React.FunctionComponent = props => { return ( <> This will open a new window asking to confirm and process your transaction. A small transaction fee will be added for all votes. This fee does not go to the Civil Media Company.{" "} Learn more . ); }; export const SaveSaltCheckboxLabelText: React.FunctionComponent = props => { return ( <> I have saved my voting information by one of the following ways: Added to My Calendar, wrote down the voting code, took a screenshot or printed this page.{" "} ); }; ================================================ FILE: packages/components/src/Share/Share.stories.tsx ================================================ import * as React from "react"; import { storiesOf } from "@storybook/react"; import styled from "styled-components"; import { ShareStory } from "@joincivil/elements"; const Container = styled.div` width: 400px; `; storiesOf("Common / Share", module).add("Share Story", () => { return ( ); }); ================================================ FILE: packages/components/src/Share/__snapshots__/Share.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Share Share Story 1`] = `

Share

Memes and Satire on Hong Kong’s Front Lines https://civil.co

Common / Share

Share Story

Story Source

            
< styled.div >
< ShareStory title = " Memes and Satire on Hong Kong’s Front Lines " url = " https://civil.co " />
</ styled.div >

Prop Types

" ShareStory " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/SignConstitutionButton.stories.tsx ================================================ // import { storiesOf } from "@storybook/react"; // import * as React from "react"; // import styled from "styled-components"; // import { SignConstitutionButton } from "./SignConstitutionButton"; // import { Civil } from "@joincivil/core"; // let civil: Civil | undefined; // try { // civil = new Civil(); // } catch (error) { // civil = undefined; // } // const signConstitution = async (): Promise => { // console.log("Signing the Constituion!"); // }; // const Wrapper = styled.div` // margin: 50px; // max-width: 500px; // `; // TODO: Fix these when we build constitution // storiesOf("Sign Constitution Button", module) // .add("User can sign", () => { // return ( // // // Create Newsroom // // // ); // }) // .add("Metamask is not installed", () => { // return ( // // // Create Newsroom // // // ); // }) // .add("Metamask is locked", () => { // const fakeCivil = {}; // return ( // // // Create Newsroom // // // ); // }) // .add("Metamask connected to wrong network", () => { // const fakeCivil = { userAccount: "0x0", networkName: "fakenet" }; // return ( // // // Create Newsroom // // // ); // }) // .add("User is not an Owner of the Newsroom", () => { // return ( // // // Create Newsroom // // // ); // }); ================================================ FILE: packages/components/src/SignConstitutionButton.tsx ================================================ import { EthAddress } from "@joincivil/core"; import * as React from "react"; import styled from "styled-components"; import { Button } from "./Button"; import { DetailsButtonComponent } from "./DetailsButtonComponent"; import { colors, fonts } from "./styleConstants"; export interface SignConstitutionButtonProps { currentNetwork?: string; currentAccount?: EthAddress; requiredNetwork: string; isNewsroomOwner: boolean | undefined; signConstitution(): Promise; } const SmallHeader = styled.h4` font-family: ${fonts.SANS_SERIF}; font-weight: 600; font-size: 14px; margin-bottom: 10px; `; const SmallText = styled.p` font-family: ${fonts.SANS_SERIF}; font-size: 11px; line-height: 18px; `; const Link = styled.a` font-family: ${fonts.SANS_SERIF}; font-size: 11px; text-decoration: none; font-weight: 600; color: ${colors.primary.CIVIL_BLUE_1}; `; export class SignConstitutionButton extends React.Component { constructor(props: SignConstitutionButtonProps) { super(props); } public render(): JSX.Element { const detailsComponent = this.renderDetails(); const buttonComponent = this.renderButtonComponent(); return ; } public isDisabled(): boolean { return ( !this.props.currentAccount || this.props.requiredNetwork !== this.props.currentNetwork || !this.props.isNewsroomOwner ); } public renderNoMetaMask(): JSX.Element { return ( <> Set up your MetaMask wallet Download the MetaMask browser plugin and follow the instructions to set up your wallet. Get MetaMask > ); } public renderMetaMaskLocked(): JSX.Element { return ( <> MetaMask is locked Please unlock MetaMask to create a newsroom contract ); } public renderWrongNetwork(): JSX.Element { return ( <> MetaMask is on the wrong network Please change your network to the {this.props.requiredNetwork.replace(/^\w/, c => c.toUpperCase())} Network before proceeding ); } public renderTransactionDetails(): JSX.Element { return ( <> Wallet Connected Signing the Civil Constitution does not incur a gas cost. ); } public renderIsNotOwner(): JSX.Element { return ( <> Your current wallet address is not an owner of this contract Please switch to the wallet associated with this newsroom contract on Metamask. ); } public renderDetails(): JSX.Element { if (!this.props.currentNetwork) { return this.renderNoMetaMask(); } else if (!this.props.currentAccount) { return this.renderMetaMaskLocked(); } else if (this.props.requiredNetwork !== this.props.currentNetwork) { return this.renderWrongNetwork(); } else if (!this.props.isNewsroomOwner) { return this.renderIsNotOwner(); } else { return this.renderTransactionDetails(); } } private handleOnClick = async (event: any): Promise => { return this.props.signConstitution(); }; private renderButtonComponent = (): JSX.Element => { return ( ); }; } ================================================ FILE: packages/components/src/SnackBar/SnackBar.tsx ================================================ import * as React from "react"; import { StyledSnackBar, StyledSnackBarContent } from "./styledComponents"; export const SnackBar: React.FunctionComponent = props => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/SnackBar/index.ts ================================================ export * from "./SnackBar"; ================================================ FILE: packages/components/src/SnackBar/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export const StyledSnackBar = styled.div` justify-content: center; display: flex; background: ${colors.basic.WHITE}; box-shadow: 0 2px 10px 0 ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; padding: 30px 0; position: fixed; top: 62px; width: 100%; z-index: 99; `; export const StyledSnackBarContent = styled.div` width: 708px; `; ================================================ FILE: packages/components/src/StepProcess/StepHeader.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import styled from "styled-components"; import { fonts, colors } from "../styleConstants"; export interface ComponentProps { disabled?: boolean; active?: boolean; } export const SectionHeader = styled.h4` font-family: ${props => props.theme.sansSerifFont}; font-weight: ${props => (props.active ? props.theme.stepHeaderWeightHeavy : props.theme.stepHeaderWeightLight)}; font-size: 20px; font-weight: 600; margin-top: 0; margin-bottom: 15px; color: ${props => (props.disabled ? colors.accent.CIVIL_GRAY_3 : "#000")}; `; SectionHeader.defaultProps = { theme: { sansSerifFont: fonts.SANS_SERIF, stepHeaderWeightHeavy: 600, stepHeaderWeightLight: 400, }, }; export interface StepHeaderTheme { stepHeaderWeight: number; stepHeaderWeightHeavy: number; } export interface StepHeaderProps { children: React.ReactNode | React.ReactNode[]; disabled?: boolean; active?: boolean; } export const StepHeader = (props: StepHeaderProps): JSX.Element => { return {props.children}; }; ================================================ FILE: packages/components/src/StepProcess/StepProcess.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { StepProcess, StepProps } from "./StepProcess"; import { StepHeader } from "./StepHeader"; import { StepStyled } from "./StepStyled"; const Step1 = (props: StepProps): JSX.Element => { return ( Step 1

this is a step

); }; const Step2 = (props: StepProps): JSX.Element => { return ( Step 2

this is another step

); }; const Step3 = (props: StepProps): JSX.Element => { return ( Step 3

this is another step

); }; storiesOf("Common / Steps / Step Process (deprecated?)", module).add("Step Process", () => { return (
); }); ================================================ FILE: packages/components/src/StepProcess/StepProcess.tsx ================================================ import * as React from "react"; import styled from "styled-components"; export interface StepProcessProps { disabled?: boolean; activeIndex?: number; stepIsDisabled?(index: number): boolean; } export interface StepProps { index?: number; active?: boolean; disabled?: boolean; } const Container = styled.div` display: flex; flex-direction: column; align-items: flex-start; `; export class StepProcess extends React.Component { public render(): JSX.Element { const childrenWithDisabled = React.Children.map(this.props.children, (child, index) => { let disabled = this.props.stepIsDisabled ? this.props.stepIsDisabled(index) : false; if (this.props.disabled) { disabled = this.props.disabled; } return React.cloneElement(child as JSX.Element, { index, active: this.props.activeIndex === index, disabled, }); }); return {childrenWithDisabled}; } } ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNav/Step.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { fonts } from "../../styleConstants"; import * as ReactDom from "react-dom"; export interface RenderButtonsArgs { stepsLength: number; index: number; goNext(): void; goPrevious(): void; } export interface StepTopNavProps { title: string | JSX.Element; isActive?: boolean; isCurrent?: boolean; startPosition?: number; complete?: boolean; disabled?: boolean; index?: number; children: React.ReactChild; renderButtons?(args: RenderButtonsArgs): JSX.Element; onClick?(index: number): void; setStartPosition?(position: number): void; } export interface StepState { dotPosition?: number; } export interface DotProps { isActive?: boolean; isCurrent?: boolean; tailLength?: number; } export interface StyledLiProps { isActive?: boolean; isCurrent?: boolean; disabled?: boolean; } const StyledLi = styled.li` cursor: ${props => (props.disabled ? "default" : "pointer")}; box-sizing: border-box; font-family: ${props => props.theme.sansSerifFont}; font-weight: ${props => (props.isCurrent ? 500 : 300)}; margin-bottom: 0; padding: 3px 0 18px; text-align: center; display: flex; flex-direction: column; justify-content: space-between; align-items: center; color: ${props => { if (props.isCurrent) { return props.theme.stepProccessTopNavCurrentColor; } else if (props.isActive) { return props.theme.stepProccessTopNavActiveColor; } else { return props.theme.stepProccessTopNavFutureColor; } }}; `; const Dot = styled.div` width: 10px; height: 10px; border-radius: 50%; background-color: ${(props): string => props.isActive ? props.theme.stepProcessDotActiveColor : props.theme.stepProcessDotFutureColor}; margin: 0; margin-bottom: 8px; box-sizing: border-box; ${(props): string => props.isCurrent ? `margin-left: -${props.tailLength}px; width: ${props.tailLength! + 10 || 10}px; border-radius: 10px; ` : ""}; `; const CompleteDot = styled(Dot)` position: relative; width: 21px; height: 21px; z-index: 10; margin-top: -5px; margin-left: -2px; margin-bottom: 2px; background-color: ${props => props.theme.stepProcessDotActiveColor}; border: 2px solid ${props => props.theme.stepProccessCompleteDotBorderColor}; ${(props): string => props.isCurrent ? `margin-left: ${props.tailLength ? props.tailLength! - 2 : -2}px;` : ""} &:after { content: ""; position: absolute; left: 6px; top: 2.5px; width: 3px; height: 7px; border: solid white; border-width: 0 1.5px 1.5px 0; transform: rotate(45deg); } `; StyledLi.defaultProps = { theme: { sansSerifFont: fonts.SANS_SERIF, stepProccessTopNavCurrentColor: "blue", stepProccessTopNavActiveColor: "#404040", stepProccessTopNavFutureColor: "#bbb", }, }; Dot.defaultProps = { theme: { stepProcessDotActiveColor: "blue", stepProcessDotFutureColor: "#ddd", }, }; CompleteDot.defaultProps = { theme: { stepProccessCompleteDotBorderColor: "#fff", stepProcessDotActiveColor: "blue", }, }; export interface StepProcessTopNavTheme { stepProccessTopNavCurrentColor: string; stepProccessTopNavActiveColor: string; stepProccessTopNavFutureColor: string; stepProcessDotActiveColor: string; stepProcessDotFutureColor: string; stepProccessCompleteDotBorderColor: string; } export class Step extends React.Component { public dot?: HTMLDivElement; constructor(props: StepTopNavProps) { super(props); this.state = {}; } public componentDidMount(): void { if (this.props.setStartPosition) { this.props.setStartPosition(this.dot ? this.dot!.offsetLeft : 0); } this.setState({ dotPosition: this.dot ? this.dot!.offsetLeft : 0 }); } public render(): JSX.Element { const tailLength = this.state.dotPosition! - this.props.startPosition!; return ( !this.props.disabled && this.props.onClick!(this.props.index!)} isActive={this.props.isActive} isCurrent={this.props.isCurrent} disabled={this.props.disabled} > (this.dot = el)} isActive={this.props.isActive} isCurrent={this.props.isCurrent} tailLength={tailLength} > {this.props.complete && } {" "} {this.props.title} ); } } ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNav/StepProcessTopNav.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Button, SecondaryButton } from "../../Button"; import { StepProcessTopNav } from "./StepProcessTopNav"; import { Step, RenderButtonsArgs } from "./Step"; storiesOf("Common / Steps / Step Process (with buttons)", module) .add("StepProcessTopNav step 1", () => { return ( { return ( <> ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

); }) .add("StepProcessTopNav complete step 1", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("step 2", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("step 3", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("step 3 2 complete", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("scrolls to top", () => { return ( { return ( <> ); }} >

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

{ return ( <> args.goPrevious()}>got to previous ); }} >

Content

); }); ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNav/StepProcessTopNav.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StepTopNavProps } from "./Step"; export interface StepsProps { activeIndex?: number; children: Array>; startPosition?: number; contentPrepend?: JSX.Element; onActiveTabChange?(activeIndex: number): void; } export interface StepProcessTopNavState { activeIndex: number; startPosition?: number; } const StyledNav = styled.div` position: relative; height: 76px; margin: 0 auto; width: 100%; & > ul { justify-content: space-between; } `; const StyledContainer = styled.ul` display: flex; list-style: none; margin: 0 auto; padding: 0; `; const MainSection = styled.div` background-color: #fff; padding: 45px 115px; `; const ButtonSection = styled.div` border-top: 1px solid rgb(233, 233, 234); display: flex; flex-direction: row; justify-content: flex-end; padding: 25px; & > button { margin-left: 15px; } `; export class StepProcessTopNav extends React.Component { public buttonContainer?: HTMLDivElement; public navContainer?: HTMLDivElement; constructor(props: StepsProps) { super(props); this.state = { activeIndex: props.activeIndex || 0, }; } public componentDidUpdate(prevProps: StepsProps, prevState: StepProcessTopNavState): void { if (typeof this.props.activeIndex === "undefined") { return; } if (this.state.activeIndex !== prevState.activeIndex) { return; } if (this.props.activeIndex !== prevProps.activeIndex) { this.setState({ activeIndex: this.props.activeIndex }); } else if (prevProps.activeIndex !== prevState.activeIndex && this.props.activeIndex !== this.state.activeIndex) { this.setState({ activeIndex: this.props.activeIndex }); } } public renderTabs(): Array> { return React.Children.map(this.props.children, (child, index) => { return React.cloneElement(child as React.ReactElement, { index, startPosition: this.state.startPosition, isCurrent: this.state.activeIndex === index, isActive: this.state.activeIndex >= index, onClick: this.handleClick, setStartPosition: index === 0 ? this.setStartPosition : undefined, }); }); } public renderContent(): React.ReactNode | undefined { const children = this.props.children; const { activeIndex } = this.state; if (children[activeIndex]) { return children[activeIndex].props.children; } } public renderButtons(): JSX.Element | undefined { const children = this.props.children; const { activeIndex } = this.state; if (children[activeIndex] && children[activeIndex].props.renderButtons) { return children[activeIndex].props.renderButtons!({ goNext: this.goNext, goPrevious: this.goPrevious, index: this.state.activeIndex, stepsLength: children.length, }); } } public render(): JSX.Element { return (
(this.navContainer = el)}> {this.renderTabs()} {this.renderContent()} {this.renderButtons()}
); } private setStartPosition = (position: number): void => { this.setState({ startPosition: position }); }; private scrollToTop = (): void => { if (this.navContainer) { this.navContainer.scrollIntoView(true); } }; private goNext = (): void => { this.scrollToTop(); const newIndex = this.state.activeIndex + 1; if (this.props.onActiveTabChange) { this.props.onActiveTabChange(newIndex); } this.setState({ activeIndex: newIndex }); }; private goPrevious = (): void => { this.scrollToTop(); const newIndex = this.state.activeIndex - 1; if (this.props.onActiveTabChange) { this.props.onActiveTabChange(newIndex); } this.setState({ activeIndex: newIndex }); }; private handleClick = (index: number): void => { if (this.props.onActiveTabChange) { this.props.onActiveTabChange(index); } this.setState({ activeIndex: index }); }; } ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNav/__snapshots__/StepProcessTopNav.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Steps / Step Process (with buttons) StepProcessTopNav complete step 1 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Common / Steps / Step Process (with buttons)

StepProcessTopNav complete step 1

Story Source

            
< StepProcessTopNav >
< Step complete title = " Step 1 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 2 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 3 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (with buttons) StepProcessTopNav step 1 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Common / Steps / Step Process (with buttons)

StepProcessTopNav step 1

Story Source

            
< StepProcessTopNav >
< Step title = " Step 1 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 2 " disabled renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 3 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (with buttons) scrolls to top 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Common / Steps / Step Process (with buttons)

scrolls to top

Story Source

            
< StepProcessTopNav >
< Step title = " Step 1 " renderButtons = { renderButtons } >
< div >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
</ div >
</ Step >
< Step title = " Step 2 " disabled renderButtons = { renderButtons } >
< div >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
</ div >
</ Step >
< Step title = " Step 3 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " renderButtons = { renderButtons } >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (with buttons) step 2 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Common / Steps / Step Process (with buttons)

step 2

Story Source

            
< StepProcessTopNav activeIndex = { 1 } >
< Step complete title = " Step 1 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 2 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 3 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (with buttons) step 3 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Common / Steps / Step Process (with buttons)

step 3

Story Source

            
< StepProcessTopNav activeIndex = { 2 } >
< Step complete title = " Step 1 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 2 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 3 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (with buttons) step 3 2 complete 1`] = `
  • Step 1
  • Step 2
  • Step 3
  • Step 4
  • Step 5
  • Step 6
  • Step 7

Content

Common / Steps / Step Process (with buttons)

step 3 2 complete

Story Source

            
< StepProcessTopNav activeIndex = { 2 } >
< Step complete title = " Step 1 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 2 " complete >
< p >
Content
</ p >
</ Step >
< Step title = " Step 3 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 4 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 5 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 6 " >
< p >
Content
</ p >
</ Step >
< Step title = " Step 7 " >
< p >
Content
</ p >
</ Step >
</ StepProcessTopNav >

Prop Types

" Step " Component

No propTypes defined!

" StepProcessTopNav " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNav/index.ts ================================================ export * from "./Step"; export * from "./StepProcessTopNav"; ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNavNoButtons/Step.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../../styleConstants"; import { StyledLiProps, StepState } from "../StepProcessTopNav"; export interface StepTopNavNoButtonsProps { title: string | JSX.Element; isActive?: boolean; isCurrent?: boolean; startPosition?: number; complete?: boolean; disabled?: boolean; index?: number; children: React.ReactChild; onClick?(index: number): void; setStartPosition?(position: number): void; } const StyledLi = styled.li` cursor: ${props => (props.disabled ? "default" : "pointer")}; box-sizing: border-box; font-family: ${props => props.theme.sansSerifFont}; font-weight: 500; margin-bottom: 0; padding: 3px 0 18px; display: flex; flex-direction: column; justify-content: space-between; align-items: center; color: ${props => { if (props.isCurrent) { return colors.primary.CIVIL_BLUE_1; } else if (props.isActive) { return colors.primary.BLACK; } else { return colors.accent.CIVIL_GRAY_3; } }}; `; export class StepNoButtons extends React.Component { public render(): JSX.Element { return ( !this.props.disabled && this.props.onClick!(this.props.index!)} isActive={this.props.isActive} isCurrent={this.props.isCurrent} disabled={this.props.disabled} > {this.props.title} ); } } ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNavNoButtons/StepProcessTopNav.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { StepProcessTopNavNoButtons, ContentProps } from "./StepProcessTopNavNoButtons"; import { StepNoButtons } from "./Step"; export interface StepThingProps extends ContentProps { children: string; } const StepThing = (props: StepThingProps): JSX.Element => { return (
{props.children}
); }; storiesOf("Common / Steps / Step Process (no buttons)", module) .add("StepProcessTopNavNoButtons StepNoButtons 1", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("StepProcessTopNavNoButtons complete StepNoButtons 1", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("StepNoButtons 2", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("StepNoButtons 3", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("StepNoButtons 3 2 complete", () => { return (

Content

Content

Content

Content

Content

Content

Content

); }) .add("scrolls to top", () => { return (

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

); }) .add("passes go next to content", () => { return ( Content Content Content Content Content Content Content ); }); ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNavNoButtons/StepProcessTopNavNoButtons.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StepTopNavNoButtonsProps } from "./Step"; import { StepProcessTopNavState, StepsProps } from "../StepProcessTopNav"; import { colors } from "../../styleConstants"; export interface StepsNoButtonsProps extends StepsProps { fullyControlledIndex?: boolean /** If true, step nav won't update activeIndex, it will simply call onActiveTabChange and rely on parent component to update index. */; } export interface ContentProps { goNext?(): void; goPrevious?(): void; } export interface ProgressBarInnerProps { percent: number; } const StyledNav = styled.div` position: relative; margin: 0 auto; width: 100%; & > ul { justify-content: space-around; } `; const StyledContainer = styled.ul` display: flex; list-style: none; margin: 27px auto 0 auto; padding: 0; `; const MainSection = styled.div` background-color: #fff; padding: 45px 10px; `; const ProgressBar = styled.div` width: 100%; height: 6px; display: block; border-radius: 2px; background-color: ${colors.accent.CIVIL_GRAY_3}; `; const ProgressBarInner = styled.div` width: ${props => `${Math.ceil(props.percent * 100)}%`}; height: 6px; border-radius: 2px; background-color: ${colors.accent.CIVIL_BLUE_FADED}; `; export class StepProcessTopNavNoButtons extends React.Component { public buttonContainer?: HTMLDivElement; public navContainer?: HTMLDivElement; constructor(props: StepsNoButtonsProps) { super(props); this.state = { activeIndex: props.activeIndex || 0, }; } public componentDidUpdate(prevProps: StepsNoButtonsProps, prevState: StepProcessTopNavState): void { if (typeof this.props.activeIndex === "undefined") { return; } if (this.state.activeIndex !== prevState.activeIndex) { return; } if (this.props.activeIndex !== prevProps.activeIndex) { this.setState({ activeIndex: this.props.activeIndex }); } else if (prevProps.activeIndex !== prevState.activeIndex && this.props.activeIndex !== this.state.activeIndex) { this.setState({ activeIndex: this.props.activeIndex }); } } public renderTabs(): Array> { return React.Children.map(this.props.children, (child, index) => { return React.cloneElement(child as React.ReactElement, { index, startPosition: this.state.startPosition, isCurrent: this.state.activeIndex === index, isActive: this.state.activeIndex >= index, onClick: this.handleClick, setStartPosition: index === 0 ? this.setStartPosition : undefined, }); }); } public renderContent(): React.ReactNode | undefined { const children = this.props.children; const { activeIndex } = this.state; if (children[activeIndex]) { return React.cloneElement(children[activeIndex].props.children as React.ReactElement, { goNext: this.goNext, goPrevious: this.goPrevious, }); } } public render(): JSX.Element { const progress = (this.state.activeIndex + 1) / this.props.children.length; return (
(this.navContainer = el)}> {this.renderTabs()} {this.props.contentPrepend} {this.renderContent()}
); } private setStartPosition = (position: number): void => { this.setState({ startPosition: position }); }; private scrollToTop = (): void => { if (this.navContainer) { this.navContainer.scrollIntoView(true); } }; private goNext = (): void => { this.scrollToTop(); const newIndex = this.state.activeIndex + 1; if (this.props.onActiveTabChange) { this.props.onActiveTabChange(newIndex); } if (!this.props.fullyControlledIndex) { this.setState({ activeIndex: newIndex }); } }; private goPrevious = (): void => { this.scrollToTop(); const newIndex = this.state.activeIndex - 1; if (this.props.onActiveTabChange) { this.props.onActiveTabChange(newIndex); } if (!this.props.fullyControlledIndex) { this.setState({ activeIndex: newIndex }); } }; private handleClick = (index: number): void => { if (this.props.onActiveTabChange) { this.props.onActiveTabChange(index); } if (!this.props.fullyControlledIndex) { this.setState({ activeIndex: index }); } }; } ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNavNoButtons/__snapshots__/StepProcessTopNav.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Steps / Step Process (no buttons) StepNoButtons 2 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Common / Steps / Step Process (no buttons)

StepNoButtons 2

Story Source

            
< StepProcessTopNavNoButtons activeIndex = { 1 } >
< StepNoButtons complete title = " StepNoButtons 1 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) StepNoButtons 3 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Common / Steps / Step Process (no buttons)

StepNoButtons 3

Story Source

            
< StepProcessTopNavNoButtons activeIndex = { 2 } >
< StepNoButtons complete title = " StepNoButtons 1 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) StepNoButtons 3 2 complete 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Common / Steps / Step Process (no buttons)

StepNoButtons 3 2 complete

Story Source

            
< StepProcessTopNavNoButtons activeIndex = { 2 } >
< StepNoButtons complete title = " StepNoButtons 1 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " complete >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) StepProcessTopNavNoButtons StepNoButtons 1 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Common / Steps / Step Process (no buttons)

StepProcessTopNavNoButtons StepNoButtons 1

Story Source

            
< StepProcessTopNavNoButtons >
< StepNoButtons title = " StepNoButtons 1 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " disabled >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) StepProcessTopNavNoButtons complete StepNoButtons 1 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Common / Steps / Step Process (no buttons)

StepProcessTopNavNoButtons complete StepNoButtons 1

Story Source

            
< StepProcessTopNavNoButtons >
< StepNoButtons complete title = " StepNoButtons 1 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) passes go next to content 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7
Content

Common / Steps / Step Process (no buttons)

passes go next to content

Story Source

            
< StepProcessTopNavNoButtons activeIndex = { 2 } >
< StepNoButtons complete title = " StepNoButtons 1 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " complete >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< StepThing >
Content
</ StepThing >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!

" StepThing " Component

No propTypes defined!
`; exports[`Storyshots Common / Steps / Step Process (no buttons) scrolls to top 1`] = `
  • StepNoButtons 1
  • StepNoButtons 2
  • StepNoButtons 3
  • StepNoButtons 4
  • StepNoButtons 5
  • StepNoButtons 6
  • StepNoButtons 7

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Content

Common / Steps / Step Process (no buttons)

scrolls to top

Story Source

            
< StepProcessTopNavNoButtons >
< StepNoButtons title = " StepNoButtons 1 " >
< div >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
</ div >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 2 " disabled >
< div >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
< p >
Content
</ p >
</ div >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 3 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 4 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 5 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 6 " >
< p >
Content
</ p >
</ StepNoButtons >
< StepNoButtons title = " StepNoButtons 7 " >
< p >
Content
</ p >
</ StepNoButtons >
</ StepProcessTopNavNoButtons >

Prop Types

" StepNoButtons " Component

No propTypes defined!

" StepProcessTopNavNoButtons " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/StepProcess/StepProcessTopNavNoButtons/index.ts ================================================ export * from "./Step"; export * from "./StepProcessTopNavNoButtons"; ================================================ FILE: packages/components/src/StepProcess/StepStyled.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; export interface StepStyledProps { index: number; disabled?: boolean; } export interface StepDescriptionProps { disabled?: boolean; } export const StepStyled = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding: 23px 4px 37px 75px; width: 645px; position: relative; display: flex; flex-direction: row; align-items: flex-start; justify-content: space-between; &:after{ content: "${(props: StepStyledProps) => props.index + 1}"; color: ${(props: StepStyledProps) => (props.disabled ? colors.accent.CIVIL_GRAY_3 : "#000")}; position: absolute; left: 3px; top: 23px; height: 10px; font-family: ${props => props.theme.sansSerifFont}; font-size: 20px; font-weight: 600; } `; StepStyled.defaultProps = { theme: { sansSerifFont: fonts.SANS_SERIF, }, }; export const StepStyledFluid = styled(StepStyled)` padding-left: 0; padding-right: 0; width: 100%; // Step counter marker is position "outside" for Fluid sections &:after { background: ${colors.accent.CIVIL_GRAY_4}; border-radius: 50%; box-sizing: border-box; left: -52px; height: 34px; padding-top: 8px; text-align: center; width: 34px; } `; export const StepDescription = styled.p` color: ${props => (props.disabled ? colors.accent.CIVIL_GRAY_3 : colors.accent.CIVIL_GRAY_2)}; margin-bottom: 23px; margin-top: 0; `; export const StepFormSection = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding-top: 10px; padding-bottom: 40px; `; ================================================ FILE: packages/components/src/StepProcess/__snapshots__/StepProcess.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Steps / Step Process (deprecated?) Step Process 1`] = `

Step 1

this is a step

Step 2

this is another step

Step 3

this is another step

Common / Steps / Step Process (deprecated?)

Step Process

Story Source

            
< div >
< StepProcess >
< Step1 />
< Step2 />
< Step3 />
</ StepProcess >
</ div >

Prop Types

" Step1 " Component

No propTypes defined!

" Step2 " Component

No propTypes defined!

" Step3 " Component

No propTypes defined!

" StepProcess " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/StepProcess/index.ts ================================================ export * from "./StepHeader"; export * from "./StepProcess"; export * from "./StepStyled"; export * from "./StepProcessTopNav"; export * from "./StepProcessTopNavNoButtons"; ================================================ FILE: packages/components/src/StoryFeed/StoryNewsroomStatus.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { ChallengeMarkIcon, TrustMarkIcon, colors, fonts } from "@joincivil/elements"; export const StoryNewsroomStatusStyled = styled.div` font-family: ${fonts.SANS_SERIF}; font-size: 13px; font-weight: 600; line-height: 16px; margin-bottom: 7px; a { align-items: center; color: ${colors.primary.BLACK}; cursor: pointer; display: flex; transition: color 0.2s ease; &:hover { color: ${colors.accent.CIVIL_BLUE}; } } svg { margin-left: 5px; } `; export interface StoryNewsroomStatusProps { newsroomName: string; activeChallenge: boolean; handleOpenNewsroom?(): void; } export const StoryNewsroomStatus: React.FunctionComponent = props => { if (props.handleOpenNewsroom) { return ( {props.newsroomName} {props.activeChallenge ? ( ) : ( )} ); } return ( {props.newsroomName} {props.activeChallenge ? : } ); }; ================================================ FILE: packages/components/src/StoryFeed/index.ts ================================================ export * from "./StoryNewsroomStatus"; ================================================ FILE: packages/components/src/TCRUserDashboard/Dashboard.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; const StyledDashboardHeaderOuter = styled.div` display: flex; padding: 62px 0 38px; justify-content: center; width: 400px; min-width: 400px; ${mediaQueries.MOBILE} { width: 100%; min-width: 0; } `; const StyledDashboardHeader = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-family: ${fonts.SERIF}; `; export const UserDashboardHeader: React.FunctionComponent = props => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivity.tsx ================================================ import * as React from "react"; import { Tabs, Tab } from "../Tabs"; import { StyledUserActivity, StyledDashboardTabsContainer, StyledDashboardTab, StyledUserActivityContent, } from "./DashboardStyledComponents"; import { MyVotingTabText, MyNewsroomsTabText, MyChallengesTabText } from "./DashboardTextComponents"; export interface DashboardActivityProps { userVotes: JSX.Element; numUserVotes: number; userNewsrooms: JSX.Element; numUserNewsrooms: number; userChallenges: JSX.Element; activeIndex: number; preventStartingTabOverride: boolean; onTabChange(activeIndex: number): void; onTabsLoadChange(activeIndex: number): void; } export const DashboardActivity: React.FunctionComponent = props => { const [hasSetStartingTab, setStartingTab] = React.useState(false); React.useEffect(() => { if (!hasSetStartingTab && !props.preventStartingTabOverride) { setStartingTab(true); if (props.numUserVotes > 0) { props.onTabsLoadChange(0); } else if (props.numUserNewsrooms > 0) { props.onTabsLoadChange(1); } } }); return ( } badgeNum={props.numUserVotes}> {props.userVotes} }> {props.userNewsrooms} }> {props.userChallenges} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityItem.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { buttonSizes, InvertedButton } from "../Button"; import { CharterData } from "@joincivil/typescript-types"; import { SmallNewsroomIcon } from "../ListingSummary/styledComponents"; import defaultNewsroomImgUrl from "../images/img-default-newsroom@2x.png"; import { StyledDashboardActivityItem, StyledDashboardActivityItemDetails, StyledNewsroomName, } from "./DashboardStyledComponents"; const StyledDashboardActivityItemIcon = styled.div` margin-right: 16px; width: 50px; `; const StyledDashboardActivityItemAction = styled.div` text-align: right; `; const StyledButtonHelperText = styled.div` font-weight: normal; font-size: 14px; line-height: 18px; margin: 0 0 10px; `; export interface DashboardActivityItemProps { newsroomName: string; charter?: CharterData; listingDetailURL: string; buttonText: string; buttonHelperText?: string | JSX.Element; challengeID?: string; salt?: any; toggleSelect?(challengeID: string, isSelected: boolean, salt: any): void; } export const DashboardActivityItem: React.FunctionComponent = props => { return ( {props.charter && props.charter.logoUrl && ( { (e.target as any).src = defaultNewsroomImgUrl; }} /> )} {props.newsroomName} {props.children} {props.buttonHelperText} {props.buttonText} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityItemCTAButton.tsx ================================================ import * as React from "react"; import { buttonSizes, InvertedButton } from "../Button"; import { DashboardActivityItemCTAButtonProps } from "./DashboardTypes"; export const DashboardActivityItemCTAButton: React.FunctionComponent = props => { const { listingDetailURL, inCommitPhase, inRevealPhase, canRequestAppeal, canResolveChallenge, isAwaitingAppealChallenge, canListingAppealBeResolved, isAppealChallengeInCommitStage, isAppealChallengeInRevealStage, canListingAppealChallengeBeResolved, didUserCommit, didUserReveal, canUserCollect, canUserRescue, onClick, } = props; let buttonText; if (inCommitPhase) { buttonText = "Change Vote"; } else if (isAppealChallengeInCommitStage && didUserCommit) { buttonText = "Commit Vote"; } else if ((!didUserReveal && inRevealPhase) || isAppealChallengeInRevealStage) { buttonText = "Reveal Vote"; } else if (canRequestAppeal) { buttonText = "Request Appeal"; } else if (canResolveChallenge || canListingAppealChallengeBeResolved) { buttonText = "Resolve"; } else if (isAwaitingAppealChallenge) { buttonText = "Challenge Appeal"; } else if (canListingAppealBeResolved) { buttonText = "Resolve"; } else if (canUserCollect) { buttonText = "Claim Rewards"; } else if (canUserRescue) { buttonText = "Rescue Tokens"; } if ((!listingDetailURL && !onClick) || !buttonText) { return <>; } let actionProp = {}; if (onClick) { actionProp = { onClick }; } else if (listingDetailURL) { actionProp = { to: listingDetailURL }; } return ( {buttonText} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityItemTask.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { SmallNewsroomIcon } from "../ListingSummary/styledComponents"; import defaultNewsroomImgUrl from "../images/img-default-newsroom@2x.png"; import { DashboardActivityItemProps } from "./DashboardTypes"; import { StyledDashboardActivityItem, StyledDashboardActivityItemIcon, StyledDashboardActivityItemDetails, } from "./DashboardStyledComponents"; import DashboardActivityItemTitle from "./DashboardActivityItemTitle"; export const DashboardActivityItemTask: React.FunctionComponent = props => { const { logoUrl } = props; return ( {logoUrl && ( { (e.target as any).src = defaultNewsroomImgUrl; }} /> )} {props.children} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityItemTitle.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { DashboardActivityItemBaseProps, DashboardActivityItemTitleProps } from "./DashboardTypes"; import { StyledDashboardActivityItemTitle } from "./DashboardStyledComponents"; const DashboardActivityItemTitle: React.FunctionComponent< DashboardActivityItemBaseProps & DashboardActivityItemTitleProps > = props => { const titleChild = props.viewDetailURL ? {props.title} : props.title; return {titleChild}; }; export default React.memo(DashboardActivityItemTitle); ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityProposalItemCTAButton.tsx ================================================ import * as React from "react"; import { buttonSizes, InvertedButton } from "../Button"; import { DashboardActivityItemProposalCTAButtonProps } from "./DashboardTypes"; export const DashboardActivityProposalItemCTAButton: React.FunctionComponent< DashboardActivityItemProposalCTAButtonProps > = props => { const { propDetailURL, canUserReveal, canUserCollect, canUserRescue, canResolveChallenge, onClick } = props; let buttonText; if (canUserReveal) { buttonText = "Reveal Vote"; } else if (canUserCollect) { buttonText = "Claim Rewards"; } else if (canUserRescue) { buttonText = "Rescue Tokens"; } else if (canResolveChallenge) { buttonText = "Resolve"; } else { buttonText = "Change Vote"; } if ((!propDetailURL && !onClick) || !buttonText) { return <>; } let actionProp = {}; if (onClick) { actionProp = { onClick }; } else if (propDetailURL) { actionProp = { to: propDetailURL }; } return ( {buttonText} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivitySelectableItem.tsx ================================================ import * as React from "react"; import { DashboardActivitySelectableItemProps } from "./DashboardTypes"; import DashboardActivityItemTitle from "./DashboardActivityItemTitle"; import { StyledDashboardActivityItem, StyledChallengeIDKicker, StyledItemCheckboxContainer, StyledDashboardActivityItemDetails, StyledNumTokensContainer, } from "./DashboardStyledComponents"; const ItemCheckbox: React.FunctionComponent = props => { const challengeID = props.appealChallengeID || props.challengeID; const handleChange = (event: any) => { props.toggleSelect!(challengeID!, event.target.checked, props.salt); }; return ; }; export const DashboardActivitySelectableItem: React.FunctionComponent = props => { if (props.challengeID && props.appealChallengeID) { throw new Error("DashboardActivitySelectableItem: cannot have both challengeID and appealChallengeID props"); } let challengeIDDisplay = "Challenge"; if (props.challengeID) { challengeIDDisplay = `Challenge #${props.challengeID}`; } else if (props.appealChallengeID) { challengeIDDisplay = `Appeal Challenge #${props.appealChallengeID}`; } return ( {props.toggleSelect && ItemCheckbox(props)} {challengeIDDisplay} {props.children} {props.numTokens && +{props.numTokens}} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardActivityTabTitle.tsx ================================================ import * as React from "react"; import { StyledSubTabCount } from "./DashboardStyledComponents"; import { SubTabAllChallengesVotedText, SubTabRevealVoteText, SubTabClaimRewardsText, SubTabRescueTokensText, SubTabChallengesCompletedText, SubTabChallengesStakedText, } from "./DashboardTextComponents"; export interface DashboardActivityTabTitleProps { count?: number; } const DashboardActivityTabTitle: React.FunctionComponent = props => { return ( <> {props.children} {props.count || "0"} ); }; export const AllChallengesDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; export const RevealVoteDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; export const ClaimRewardsDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; export const RescueTokensDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; export const ChallengesCompletedDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; export const ChallengesStakedDashboardTabTitle: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardNewsroom.tsx ================================================ import * as React from "react"; import { Link } from "react-router-dom"; import { urlConstants, copyToClipboard } from "@joincivil/utils"; import { EthAddressViewer } from "../EthAddressViewer"; import gql from "graphql-tag"; import { Query } from "react-apollo"; import { ChevronAnchor } from "../ChevronAnchor"; import { InvertedButton, buttonSizes } from "../Button"; import { FeatureFlag } from "../features"; import { StyledDashboardNewsroom, StyledDashboardNewsroomName, StyledDashboardNewsroomSection, StyledDashboardNewsroomSectionContentRow, StyledDashboardNewsroomHdr, StyledDashboardNewsroomSubHdr, StyledDashboardNewsroomTerHdr, StyledDashboardNewsroomBorder, StyledChallengeIDKicker, StyledDashboardNewsroomLinks, StyledDashboardNewsroomTokensContainer, StyledDashboardNewsroomTokensLabel, StyledCVLLabel, StyledEmbedCode, } from "./DashboardStyledComponents"; import { DashboardNewsroomStripeConnect } from "./DashboardNewsroomStripeConnect"; import { DashboardNewsroomSubmitLink } from "./DashboardNewsroomSubmitLink"; import { NewsroomProceeds } from "./DashboardNewsroomProceeds"; export interface DashboardNewsroomProps { newsroomName: string; newsroomAddress: string; listingDetailURL: string; manageNewsroomURL: string; newsroomDeposit: string; etherscanBaseURL: string; newsroomMultiSigBalance: string; newsroomMultiSigAddress?: string; isAccepted?: boolean; isInProgress?: boolean; isUnderChallenge?: boolean; isRejected?: boolean; acceptedDate?: string; inProgressPhaseDisplayName?: string; inProgressPhaseCountdown?: JSX.Element; inProgressPhaseDetails?: string | JSX.Element; boostProceeds?: JSX.Element; rejectedDate?: string; } const CHANNEL_ID_FROM_NEWSROOM_ADDRESS_QUERY = gql` query($contractAddress: String!) { channelsGetByNewsroomAddress(contractAddress: $contractAddress) { id } } `; const DashboardNewsroomRegistryStatusBase: React.FunctionComponent = props => { let statusDisplay; let statusDetails: string | JSX.Element = <>; const { isAccepted, isInProgress, isRejected, acceptedDate, inProgressPhaseDisplayName, inProgressPhaseCountdown, inProgressPhaseDetails, rejectedDate, } = props; if (isInProgress) { statusDisplay = inProgressPhaseDisplayName; if (inProgressPhaseCountdown) { statusDetails = inProgressPhaseCountdown; } else if (inProgressPhaseDetails) { statusDetails = inProgressPhaseDetails; } } else if (isAccepted) { statusDisplay = "Accepted"; if (acceptedDate) { statusDisplay = "Accepted Date"; statusDetails = <>{acceptedDate}; } } else if (isRejected) { statusDisplay = "Rejected"; if (rejectedDate) { statusDisplay = "Rejected Date"; statusDetails = <>{rejectedDate}; } } return ( <> {statusDisplay} {statusDetails} ); }; const DashboardNewsroomRegistryStatus = React.memo(DashboardNewsroomRegistryStatusBase); const DashboardNewsroomBase: React.FunctionComponent = props => { const [copied, setCopied] = React.useState(false); const storyBoostEmbed = ''; return ( {props.newsroomName} Manage Newsroom View on Registry Newsroom Token Balance {props.newsroomMultiSigBalance} CVL Tokens in Newsroom Wallet Status on the Registry
{props.newsroomDeposit} CVL Newsroom Token Deposit
{props.newsroomMultiSigAddress && ( )} Boosts Story Boosts

Story Boosts allow supporters to give you small, incremental proceeds using ETH or credit cards. When you add the Story Boost embed, your stories will be included on the Civil storyfeed and you will be able to collect proceeds from the feed as well as your own site.

Place the following code in your CMS where you'd like a Story Boost to be displayed on your site. You can add it to each story or your CMS template.

{storyBoostEmbed} setCopied(copyToClipboard(storyBoostEmbed))}> Copy {" "} {copied && "Copied!"}

Use WordPress? You can download and install the Story Boost plugin to automatically embed Story Boosts on your site.

Download this zip file, navigate to the Plugins page in your admin dashboard, select Add New, then Upload Plugin.

Download Story Boost Plugin query={CHANNEL_ID_FROM_NEWSROOM_ADDRESS_QUERY} variables={{ contractAddress: props.newsroomAddress }} > {({ loading, error, data }) => { if (loading || error) { return <>; } return ( <> Submit a Story ); }} Proceeds collected from Story Boosts Project Boosts

Project Boosts lets your newsroom host one-off fundraisers anywhere on your website to fund and produce larger journalism projects. Share your vision and how the money will be used so your readers can get behind it.

You can embed Projects Boosts on your site as well. You just need to copy the embed from each Project Boost.{" "} Learn more

{/*@TODO Because we're in components we can't access dapp routes so we have to hard code the route*/}

Launch a New Project Boost

View your Project Boosts

Proceeds collected from Project Boosts
Payments {/*@HACK We need to include `NewsroomWithdraw` from `sdk` package, but this component is in `components` package which `sdk` uses so we'd have a circular dependency. @TODO/tobek all these TCR dashboard components should be moved into `dapp` package.*/} {props.boostProceeds} Set Up Credit Card Payments

Connect a Stripe account to accept Credit Cards payments for your Boosts. You can link your existing Stripe account or start a new one. Any payments sent with credit cards with automatically be deposited into your Stripe account.

); }; export const DashboardNewsroom = React.memo(DashboardNewsroomBase); ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardNewsroomProceeds.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Query } from "react-apollo"; import { LoadingIndicator } from "../LoadingIndicator"; import { withNewsroomChannel, NewsroomChannelInjectedProps } from "../WithNewsroomChannelHOC"; import { colors, fonts, mediaQueries } from "@joincivil/elements"; import gql from "graphql-tag"; const boostTypeProceedsQuery = gql` query proceeds($channelID: String!, $boostType: String!) { getChannelTotalProceedsByBoostType(channelID: $channelID, boostType: $boostType) { totalAmount usd ethUsdAmount ether } } `; const Wrapper = styled.div` display: flex; font-size: 14px; justify-content: space-between; margin: 0 0 20px; ${mediaQueries.MOBILE} { display: block; } `; const Proceed = styled.div` flex: 1; padding: 15px; `; const TotalProceeds = styled(Proceed)` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; `; const Amount = styled.span` color: ${colors.primary.BLACK}; font-size: 16px; `; const TotalAmount = styled(Amount)` font-size: 20px; `; interface CurrencyLabelProps { secondary?: boolean; } const CurrencyLabel = styled.span` color: ${colors.primary.CIVIL_GRAY_0}; font-size: 12px; font-weight: ${(props: CurrencyLabelProps) => (props.secondary ? 500 : 600)}; `; export interface NewsroomProceedsProps { newsroomAddress: string; boostType: string; } class NewsroomProceedsComponent extends React.Component { public constructor(props: NewsroomProceedsProps & NewsroomChannelInjectedProps) { super(props); } public render(): JSX.Element { return ( query={boostTypeProceedsQuery} variables={{ channelID: this.props.channelData.id, boostType: this.props.boostType }} > {({ loading, error, data }) => { if (loading) { return ; } else if (error || !data || !data.getChannelTotalProceedsByBoostType) { console.error("Error loading boost proceeds query:", error || "no data returned"); return Error loading proceed amounts: {JSON.stringify(error || "no data returned")}; } let { totalAmount, ether, ethUsdAmount, usd } = data.getChannelTotalProceedsByBoostType; totalAmount = parseFloat(totalAmount || 0).toFixed(2); ether = parseFloat(ether || 0).toFixed(5); ethUsdAmount = parseFloat(ethUsdAmount || 0).toFixed(2); usd = parseFloat(usd || 0).toFixed(2); return (
${totalAmount} USD
Total Collected
{ether} ETH ≈ ${ethUsdAmount}{" "} USD
ETH Proceeds
${usd} USD
Credit Card Proceeds
); }} ); } } export const NewsroomProceeds: React.ComponentType = withNewsroomChannel( NewsroomProceedsComponent, ) as any; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardNewsroomStripeConnect.tsx ================================================ import * as React from "react"; import * as qs from "querystring"; import { withApollo, WithApolloClient } from "react-apollo"; import gql from "graphql-tag"; import styled from "styled-components"; import { CivilContext, ICivilContext } from "../context/CivilContext"; import { withNewsroomChannel, NewsroomChannelInjectedProps, CHANNEL_BY_NEWSROOM_QUERY, } from "../WithNewsroomChannelHOC"; import { StyledDashboardLoadingMessage } from "./DashboardStyledComponents"; import { ErrorIcon, NorthEastArrow } from "../icons"; import { colors } from "../styleConstants"; import { InvertedButton, buttonSizes } from "../Button"; import stripeLogo from "../images/stripe-logo-blue.png"; import stripeConnectButtonLight from "../images/stripe-connect-blue-on-light.png"; import stripeConnectButtonDark from "../images/stripe-connect-blue-on-dark.png"; export const StripeContainer = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding: 20px 16px 24px; `; const StripeLogo = styled.img` display: block; height: 24px; margin-bottom: 10px; width: auto; `; const StripeConnectButtonLink = styled.a` background-size: contain; display: inline-block; height: 33px; width: 190px; background-image: url("${stripeConnectButtonLight}"); &:hover { background-image: url("${stripeConnectButtonDark}"); } // Preload image to prevent flash on hover: &:after { content: url("${stripeConnectButtonDark}"); position: absolute; left: -50000px; } `; export interface StripeOauthParams { code?: string; error?: string; error_description?: string; } export interface DashboardNewsroomStripeConnectOwnProps { newsroomAddress: string; } export interface DashboardNewsroomStripeConnectState { connectingStripe?: boolean; connectStripeError?: any; } export type DashboardNewsroomStripeConnectProps = WithApolloClient< DashboardNewsroomStripeConnectOwnProps & NewsroomChannelInjectedProps >; export const CHANNEL_CONNECT_STRIPE_MUTATION = gql` mutation($input: ChannelsConnectStripeInput!) { channelsConnectStripe(input: $input) { id } } `; export class DashboardNewsroomStripeConnectComponent extends React.Component< DashboardNewsroomStripeConnectProps, DashboardNewsroomStripeConnectState > { public static contextType = CivilContext; public context!: ICivilContext; private qsParams: StripeOauthParams; constructor(props: DashboardNewsroomStripeConnectProps) { super(props); this.state = {}; this.qsParams = qs.parse(document.location.search.substr(1)); } public async componentDidMount(): Promise { if (this.qsParams.code) { try { this.setState({ connectingStripe: true }); await this.props.client.mutate({ mutation: CHANNEL_CONNECT_STRIPE_MUTATION, variables: { input: { channelID: this.props.channelData.id, oauthCode: this.qsParams.code } }, refetchQueries: [ { query: CHANNEL_BY_NEWSROOM_QUERY, variables: { contractAddress: this.props.newsroomAddress, }, }, ], }); this.setState({ connectingStripe: false }); } catch (err) { console.error("error running channelsConnectStripe mutation:", err); this.setState({ connectStripeError: err }); } } } public render(): JSX.Element { return ( <> {this.renderBody()} ); } private renderBody(): JSX.Element { if (!this.props.channelData.currentUserIsAdmin) { return ( <> {/*@TODO/tobek When we have a flow for updating newsroom channel admins, add it here*/} You are not an admin for this Newsroom, so you cannot edit its Stripe settings. Please contact an admin to be added. ); } else if (!this.state.connectingStripe && this.props.channelData.isStripeConnected) { const justConnected = this.qsParams.code; return ( <>

{justConnected ? "Connection successful! You are now" : "You are currently"} accepting credit cards through your connected Stripe account.

Go to Your Stripe Dashboard

{!justConnected && this.renderStripeConnectButton("Connect a different Stripe account")} ); } else if (this.state.connectStripeError) { return ( <>

Sorry, there was an error connecting your Newsroom to your Stripe account:{" "} {JSON.stringify(this.state.connectStripeError.message || this.state.connectStripeError)}. Please try again.

{this.renderStripeConnectButton()} ); } else if (this.state.connectingStripe || this.qsParams.code) { return Connecting your Stripe account; } else if (this.qsParams.error) { return ( <>

Error connecting your Stripe account: {this.qsParams.error}:{" "} {this.qsParams.error_description}. Please try again.

{this.renderStripeConnectButton()} ); } else { return ( <>

Allows you to accept credit card payments for your Boosts. Stripe fees will apply. The Boost amounts sent by supporters will go directly into your connected Stripe account. Civil will not keep or hold any of your proceeds.

{this.renderStripeConnectButton()} ); } } private renderStripeConnectButton(linkText?: string): JSX.Element { const redirectUrl = `${document.location.origin}/dashboard/newsrooms`; const oauthUrl = `https://connect.stripe.com/oauth/authorize?response_type=code&client_id=${ this.context.config.STRIPE_CLIENT_ID }&scope=read_write&redirect_uri=${encodeURIComponent(redirectUrl)}`; return

{linkText ? {linkText} : }

; } } export const DashboardNewsroomStripeConnect = withNewsroomChannel(withApollo(DashboardNewsroomStripeConnectComponent)); ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardNewsroomSubmitLink.tsx ================================================ import * as React from "react"; import { SubmitLink } from "../input"; import gql from "graphql-tag"; import { Mutation, MutationFunc } from "react-apollo"; const EXTERNAL_LINK_MUTATION = gql` mutation($input: PostCreateExternalLinkInput!) { postsCreateExternalLink(input: $input) { url channelID } } `; export interface DashboardNewsroomSubmitLinkProps { channelID: string; } export interface DashboardNewsroomSubmitLinkState { url: string; submitting: boolean; success: boolean; error: boolean; } export class DashboardNewsroomSubmitLink extends React.Component< DashboardNewsroomSubmitLinkProps, DashboardNewsroomSubmitLinkState > { constructor(props: any) { super(props); this.state = { url: "", submitting: false, success: false, error: false, }; } public render(): JSX.Element { return ( mutation={EXTERNAL_LINK_MUTATION}> {mutation => { return ( this.handleSubmit(mutation)} /> ); }} ); } private setURL = (name: string, value: string) => { this.setState({ url: value }); }; private async handleSubmit(mutation: MutationFunc): Promise { this.setState({ submitting: true, error: false, success: false }); try { const response = await mutation({ variables: { input: { channelID: this.props.channelID, url: this.state.url, }, }, }); if (response && response.data && response.data.postsCreateExternalLink) { this.setState({ success: true }); } else { this.setState({ error: true }); } } catch (error) { console.log(error); this.setState({ error: true }); } this.setState({ submitting: false }); } } ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { StyledTab, TabComponentProps } from "../Tabs"; import { LoadingMessage } from "../LoadingMessage"; import { Button, InvertedButton } from "../Button"; import { Dropdown, DropdownGroup, InputBase, InputIcon, DropdownItem } from "../input"; import { colors, fonts, mediaQueries } from "@joincivil/elements"; export const DashboardStylesNoticeContainer = styled.div` padding: 24px; border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; `; export const StyledUserActivity = styled.div` background-color: transparent; flex-grow: 1; max-width: 800px; padding-right: 50px; ${mediaQueries.MOBILE} { padding: 0; max-width: 100%; } `; export const StyledUserActivityContent = styled.div` background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-top: none; `; export const StyledDashboardTabsContainer = styled.div` background: ${colors.accent.CIVIL_GRAY_4}; `; export const StyledDashboardTab = styled.li` color: ${(props: TabComponentProps) => (props.isActive ? colors.primary.CIVIL_BLUE_1 : colors.primary.CIVIL_GRAY_1)}; border-bottom: ${(props: TabComponentProps) => props.isActive ? "3px solid " + colors.primary.CIVIL_BLUE_1 : "none"}; cursor: pointer; font-size: 18px; font-weight: ${(props: TabComponentProps) => (props.isActive ? "bold" : "normal")}; line-height: 21px; white-space: nowrap; flex-grow: 1; display: flex; flex-direction: column; justify-content: space-around; align-items: center; height: 62px; `; export const StyledSubTabCount = styled.span` display: inline-block; border-radius: 31px; font-size: 12px; line-height: 15px; margin-left: 6px; padding: 3px 10px; `; export const StyledDashboardSubTab = styled(StyledTab)` white-space: nowrap; & ${StyledSubTabCount} { background-color: ${(props: TabComponentProps) => props.isActive ? colors.accent.CIVIL_TEAL : colors.accent.CIVIL_GRAY_3}; } `; export interface StyledDashboardActivityDescriptionProps { noBorder?: boolean; } export const StyledDashboardActivityDescription = styled.div` ${props => props.noBorder ? "" : ` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; `} font-size: 21px; font-weight: 300; line-height: 28px; letter-spacing: -0.14px; padding: 36px 24px; `; export const StyledUserInfo = styled.div` width: 333px; ${mediaQueries.MOBILE} { width: 100%; } `; export const StyledUserProfile = styled.div` width: 333px; ${mediaQueries.MOBILE} { width: 100%; } display: flex; flex-direction: row; justify-content: flex-start; margin-bottom: 22px; `; export const StyledAvatarContainer = styled.div` width: 76px; height: 76px; margin-right: 15px; position: relative; clip-path: circle(38px at center); `; export const StyledUserAvatar = styled.img` width: 76px; height: 76px; position: absolute; z-index: 999; `; export const StyledEditAvatar = styled.figure` width: 76px; height: 20px; position: absolute; top: 40px; left: -40px; background-color: #3e3e3e; opacity: 0.5; z-index: 10000; `; export const StyledEditSpan = styled.span` display: flex; flex-direction: row; align-items: center; justify-content: space-around; width: 76px; height: 20px; position: absolute; top: 55px; left: 0px; font-size: 14px; line-height: 17px; font-family: ${fonts.SANS_SERIF_BOLD}; font-weight: 700; letter-spacing: 0.22px; color: ${colors.basic.WHITE}; z-index: 20000; cursor: pointer; `; export const StyledUserNoAvatar = styled.div` display: flex; justify-content: space-around; width: 76px; height: 76px; align-items: center; background-color: #ef6b4a; font-family: ${fonts.SANS_SERIF}; color: ${colors.basic.WHITE}; text-transform: uppercase; font-size: 50px; `; export const StyledUserHandleText = styled.span` font-size: 19px; font-weight: 600; height: 23px; letter-spacing: -0.04px; line-height: 23px; max-width: 242px; text-overflow: ellipsis; `; export const StyledUserEmailText = styled.span` font-size: 16px; font-weight: 400; height: 23px; letter-spacing: -0.04px; line-height: 23px; `; export const StyledUserSetEmailText = styled.span` font-size: 12px; font-weight: 300; height: 23px; letter-spacing: -0.04px; line-height: 23px; color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; `; export const StyledChangeUserEmailText = styled.span` font-size: 12px; font-weight: 300; height: 23px; letter-spacing: -0.04px; line-height: 23px; margin-left: 2px; color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; `; export const StyledChangeUserAvatarText = styled.span` font-size: 12px; font-weight: 300; height: 23px; letter-spacing: -0.04px; line-height: 23px; color: ${colors.accent.CIVIL_BLUE}; `; export const StyledUserEmailContainer = styled.div` flex-direction: row; `; export const StyledUserHandleAndEmailContainer = styled.div` display: flex; flex-direction: column; justify-content: center; height: 76px; `; export const StyledUserInfoSectionLabel = styled.div` color: ${colors.accent.CIVIL_GRAY_2}; font-size: 12px; font-weight: 800; letter-spacing: 0.93px; line-height: 15px; text-transform: uppercase; `; export const StyledUserInfoSectionValue = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 12px; font-weight: 600; line-height: 15px; text-align: right; & strong { display: block; font-size: 18px; font-weight: bold; line-height: 21px; } `; export const StyledUserInfoSection = styled.div` display: flex; margin: 24px 0; min-height: 30px; justify-content: space-between; ${StyledUserInfoSectionLabel} { width: 40%; } `; export const StyledUserInfoButtonSection = styled.div` margin: 24px 0; & ${Button}, & ${InvertedButton} { margin: 0 0 19px; padding: 14px 0; text-align: center; text-transform: none; width: 100%; } `; // '32' == 20% in hexadecimal export const StyledUserAddress = styled.div` border-bottom: 1px solid ${colors.basic.WHITE}32; font-size: 16px; font-family: ${fonts.MONOSPACE}; line-height: 26px; padding: 0 0 24px; margin: 15px 0; `; // Activity Items export const StyledDashboardActivityItem = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; box-sizing: border-box; display: flex; padding: 25px 0; margin: 0 25px; justify-content: space-between; `; export const StyledItemCheckboxContainer = styled.div` margin: 0 23px 0 0; padding: 15px 0 0; width: 20px; `; export const StyledDashboardActivityItemIcon = styled.div` margin-right: 16px; width: 50px; `; export const StyledDashboardActivityItemDetails = styled.div` flex-grow: 1; font-size: 14px; line-height: 22px; margin-right: 30px; `; export const StyledDashboardActivityItemAction = styled.div` align-items: flex-end; display: flex; flex-direction: column; padding-left: 10px; text-align: right; min-width: 30%; ${InvertedButton} { display: block; margin: 0 0 27px; white-space: nowrap; } a { color: ${colors.accent.CIVIL_BLUE}; font-weight: bold; font-size: 14px; line-height: 14px; white-space: nowrap; } `; export const StyledDashboardActivityItemTitle = styled.h4` color: ${colors.primary.CIVIL_GRAY_1}; font-weight: 800; font-size: 18px; line-height: 21px; margin: 0 0 10px; `; export const StyledDashboardActivityItemSubTitle = styled.h4` color: ${colors.primary.CIVIL_GRAY_1}; font-weight: 800; font-size: 18px; line-height: 21px; margin: 10px 0; `; export const StyledDashbaordActvityItemSectionOuter = styled.div` display: flex; justify-content: space-between; `; export const StyledChallengeSummarySection = styled.div` flex-grow: 1; `; export const StyledDashbaordActvityItemSection = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; background: ${colors.accent.CIVIL_GRAY_5}; box-shadow: inset 0 -1px 0 0 ${colors.accent.CIVIL_GRAY_4}; padding: 10px 24px 21px; `; export const StyledDashbaordActvityItemHeader = styled.div` font-size: 16px; font-weight: 500; line-height: 33px; margin: 0 0 8px; `; export const StyledDashbaordActvityItemSectionInner = styled.div` padding-left: 23px; `; export const StyledChallengeIDKicker = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 12px; font-weight: 600; line-height: 15px; margin: 0 0 3px; text-transform: uppercase; `; export const StyledNewsroomName = styled.div` font-size: 18px; font-weight: 600; line-height: 33px; margin: 0; `; export const StyledNumTokensContainer = styled.div` color: ${colors.accent.CIVIL_BLUE}; font-size: 18px; font-weight: 600; line-height: 18px; padding: 15px 0 0; text-align: right; `; // Transfer Tokens export const StyledTransferTokenTitle = styled.div` font-family: ${fonts.SANS_SERIF}; text-align: center; margin: 0 0 40px; padding: 20px; flex-grow: 1; h3 { font-size: 20px; font-weight: bold; line-height: 32px; margin: 0 0 10px; } p { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 16px; line-height: 26px; margin: 0; } `; export const StyledTransferTokenForm = styled.div` font-family: ${fonts.SANS_SERIF}; font-weight: 400; margin: 0 auto 45px; padding: 35px; `; export const StyledTransferTokenFormGroup = styled.div` margin: 0 auto; max-width: 460px; ${Dropdown} { border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-radius: 3px; font-size: 15px; margin-top: 5px; & > div:nth-child(2) > div { border-top: none; box-shadow: none; left: -1px; top: -1px; width: calc(100% + 2px); max-width: unset; :before, :after { display: none; } } ${DropdownGroup} { li { border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; display: flex; justify-content: space-between; } } ${DropdownItem} { padding: 0; button { background-color: transparent; border: none; cursor: pointer; padding: 17px 50px 17px 15px; width: 100%; } } } ${InputBase} { margin-bottom: 3px; position: relative; > input, > textarea { border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-radius: 3px; padding: 15px; } > input:focus, > textarea:focus { border: 1px solid ${colors.accent.CIVIL_BLUE}; } } label { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; } ${InputIcon} { background-color: ${colors.basic.WHITE}; left: calc(100% - 50px); position: absolute; top: 42px; z-index: 2; } `; export const StyledTransferTokenFormElement = styled.div` margin-bottom: 25px; `; export const StyledInputLabel = styled.label` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; `; export const StyledTransferTokenTip = styled.div` color: ${colors.accent.CIVIL_GRAY_1}; font-size: 13px; line-height: 18px; `; export const StyledTransferTokenDropdown = styled.div` padding: 17px 50px 17px 15px; position: relative; `; export const StyledTransferTokenBalance = styled.div` display: flex; font-size: 15px; justify-content: space-between; width: 100%; `; export const StyledDropdownArrow = styled.div` align-items: center; border-left: 1px solid ${colors.accent.CIVIL_GRAY_3}; display: flex; justify-content: center; padding: 12px 15px 12px 14px; position: absolute; right: 0; top: calc(50% - 14px); `; export const StyledFromBalance = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_3}; border-radius: 3px; margin-top: 5px; padding: 17px 15px; `; // Newsroom tab export const StyledDashboardNewsroom = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; box-sizing: border-box; padding: 25px 0; margin: 0 25px; p { font-size: 14px; line-height: 20px; } `; export const StyledDashboardNewsroomName = styled.div` color: ${colors.primary.BLACK}; font-size: 24px; line-height: 29px; `; export const StyledDashboardNewsroomSection = styled.div` margin: 0 0 26px; & ~ & { border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; padding: 14px 0 0; } `; export const StyledDashboardNewsroomHdr = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 18px; line-height: 33px; margin-bottom: 15px; `; export const StyledDashboardNewsroomSubHdr = styled.div` font-size: 16px; font-weight: 700; letter-spacing: 0.2px; line-height: 25px; `; export const StyledDashboardNewsroomTerHdr = styled.p` font-size: 14px; font-weight: 700; line-height: 20px; margin: 30px 0 10px; `; export const StyledDashboardNewsroomSectionContentRow = styled.div` display: flex; justify-content: space-between; `; export const StyledDashboardNewsroomLinks = styled.div` text-align: right; a { display: block; font-size: 13px; letter-spacing: 0.2px; line-height: 14px; margin: 0 0 20px; } `; export const StyledDashboardNewsroomBorder = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; margin: 10px 0 20px; `; export const StyledWarningText = styled.span` color: ${colors.accent.CIVIL_RED}; & svg { margin: 0 2px -3px 0; } `; export const StyledDashboardNewsroomTokensContainer = styled.div` text-align: left; width: 30%; `; export const StyledDashboardNewsroomTokensLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; margin: 7px 0 0; `; export const StyledCVLLabel = styled.span` color: ${colors.accent.CIVIL_GRAY_0}; font-size: 12px; font-weight: bold; letter-spacing: -0.07px; line-height: 15px; `; // No Content export const StyledDashboardNoContent = styled.div` margin: 0 auto; padding: 60px 0 60px; text-align: center; flex-grow: 1; width: 740px; ${mediaQueries.MOBILE} { width: 100%; } `; export const StyledDashboardNoContentHdr = styled.div` color: ${colors.primary.CIVIL_GRAY_0}; font-size: 21px; font-weight: 500; letter-spacing: -0.14px; line-height: 33px; margin: 17px 0 2px; `; export const StyledDashboardNoContentCopy = styled.div` color: ${colors.primary.CIVIL_GRAY_0}; font-size: 16px; line-height: 30px; margin: 0 0 24px; `; export const StyledDashboardNoContentButtonContainer = styled.div` ${InvertedButton} { font-size: 13px; font-weight: bold; letter-spacing: 0.2px; line-height: 14px; padding: 14px 0; text-transform: none; width: 236px; } `; // @ts-ignore: Looks like `React.FunctionComponent` type (which `LoadingMessage` is) doesn't play nicely with `styled` typings export const StyledDashboardLoadingMessage = styled(LoadingMessage)` padding-top: 0; p { margin-top: 18px; } `; export const StyledEmbedCode = styled.pre` background: ${colors.accent.CIVIL_GRAY_5}; margin-bottom: 10px; padding: 8px; white-space: pre-wrap; width: 100%; word-break: break-word; `; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardTextComponents.tsx ================================================ import * as React from "react"; import { StyledTransferTokenTitle, StyledTransferTokenTip } from "./DashboardStyledComponents"; export const SubTabAllChallengesVotedText: React.FunctionComponent = props => <>All; export const SubTabRevealVoteText: React.FunctionComponent = props => <>Reveal Vote; export const SubTabClaimRewardsText: React.FunctionComponent = props => <>Claim Rewards; export const SubTabRescueTokensText: React.FunctionComponent = props => <>Rescue Tokens; export const SubTabReclaimTokensText: React.FunctionComponent = props => <>Transfer Voting Tokens; export const SubTabChallengesCompletedText: React.FunctionComponent = props => <>Completed; export const SubTabChallengesStakedText: React.FunctionComponent = props => <>Staked; export const MyVotingTabText: React.FunctionComponent = props => <>Tasks; export const MyNewsroomsTabText: React.FunctionComponent = props => <>Newsrooms; export const MyChallengesTabText: React.FunctionComponent = props => <>Challenges; export const ClaimRewardsDescriptionText: React.FunctionComponent = props => <>Claim rewards from your winning votes; export const RescueTokensDescriptionText: React.FunctionComponent = props => ( <>Reclaim your voting tokens from votes that you did not reveal ); export const YourPublicAddressLabelText: React.FunctionComponent = props => <>Your Public Address; export const BalanceLabelText: React.FunctionComponent = props => <>Available Balance; export const VotingBalanceLabelText: React.FunctionComponent = props => <>Voting Tokens; export const ChallengesWonLabelText: React.FunctionComponent = props => <>Challenges Won; export const RewardsClaimedLabelText: React.FunctionComponent = props => <>Rewards Claimed; export const NoTasks: React.FunctionComponent = props => (

No Tasks

You don't have any tasks right now. Tasks represent actions you need to take (or have taken) related to Civil's governance. Action items will appear here if you participate in a Newsroom Challenge.

); export const NoVotesToReveal: React.FunctionComponent = props => (

No Votes to Reveal

You don't have any votes to reveal right now.

); export const NoRewardsToClaim: React.FunctionComponent = props => (

No Rewards to Claim

You don't have any rewards to claim right now.

); export const NoTokensToRescue: React.FunctionComponent = props => (

No Tokens to Rescue

You don't have any tokens to rescue right now.

); export const NoChallenges: React.FunctionComponent = props => (

No Challenges

You haven't participated in any challenges yet.

); export const TransferTokenText: React.FunctionComponent = props => (

Transfer Tokens

Transfer tokens between your Available Balance and Voting Balance. Use tokens in your Available Balance to apply, challenge, send or sell. Use tokens in your Voting Balance to vote in challenges. You may transfer any inactive voting tokens to your Available Balance.

); export const TransferTokenTipsText: React.FunctionComponent = props => ( Tip: We recommend reserving some tokens in your available balance if you plan on applying, challenging, or tipping newsrooms. ); export const MetaMaskPopUpText: React.FunctionComponent = props => ( This will pop-up MetaMask window to confirm your transactions ); ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardTransferTokenForm.tsx ================================================ import * as React from "react"; import { StyledTransferTokenForm, StyledTransferTokenFormGroup, StyledTransferTokenFormElement, StyledTransferTokenDropdown, StyledDropdownArrow, StyledTransferTokenBalance, StyledFromBalance, } from "./DashboardStyledComponents"; import { BalanceLabelText, VotingBalanceLabelText, TransferTokenText, MetaMaskPopUpText, } from "./DashboardTextComponents"; import { Dropdown, DropdownGroup, DropdownItem } from "../input"; import { DropdownArrow } from "../icons"; export enum BalanceType { AVAILABLE_BALANCE = 0, TOKEN_VOTING_BALANCE = 1, } export interface TransferTokenDropdownOptionProps { label: string | JSX.Element; cvl: string; } export const TransferTokenBalance: React.FunctionComponent = props => { return ( {props.label} {props.cvl} ); }; export interface TransferTokenDropdownSelectedProps { label: string | JSX.Element; } export const TransferTokenDropdownSelected: React.FunctionComponent = props => { return ( {props.label} ); }; export interface DashboardTransferTokenFormProps { cvlAvailableBalance: string; cvlVotingBalance: string; renderTransferBalance(value: number): void; } export interface DashboardTransferTokenFormStates { dropdownValue: string | JSX.Element; fromValue: string | JSX.Element; } export class DashboardTransferTokenForm extends React.Component< DashboardTransferTokenFormProps, DashboardTransferTokenFormStates > { constructor(props: DashboardTransferTokenFormProps) { super(props); this.state = { dropdownValue: } />, fromValue: } />, }; } public render(): JSX.Element { return ( }> {this.state.fromValue} {this.props.children} ); } private onClick = (value: number) => { if (value === BalanceType.AVAILABLE_BALANCE) { this.setState({ dropdownValue: } />, fromValue: } />, }); } else { this.setState({ dropdownValue: } />, fromValue: } />, }); } this.props.renderTransferBalance(value); }; } ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardTypes.ts ================================================ export interface DashboardActivityItemBaseProps { viewDetailURL?: string; } export interface DashboardActivityItemLogo { logoUrl?: string; } export interface DashboardActivityItemTitleProps { title: string; } export interface DashboardActivityItemCTAButtonProps { listingDetailURL?: string; inCommitPhase: boolean; inRevealPhase: boolean; canRequestAppeal: boolean; canResolveChallenge: boolean; isAwaitingAppealChallenge: boolean; canListingAppealBeResolved: boolean; isAppealChallengeInCommitStage: boolean; isAppealChallengeInRevealStage: boolean; canListingAppealChallengeBeResolved: boolean; didUserCommit?: boolean; didUserReveal?: boolean; canUserCollect?: boolean; canUserRescue?: boolean; onClick?(): void; } export interface DashboardActivityItemProposalCTAButtonProps { propDetailURL?: string; canUserReveal?: boolean; didUserCommit?: boolean; didUserReveal?: boolean; canUserCollect?: boolean; canUserRescue?: boolean; canResolveChallenge?: boolean; onClick?(): void; } export interface DashboardActivityItemProps extends DashboardActivityItemBaseProps, DashboardActivityItemLogo, DashboardActivityItemTitleProps {} export interface DashboardActivityProposalItemProps extends DashboardActivityItemBaseProps, DashboardActivityItemLogo, DashboardActivityItemTitleProps {} export interface DashboardActivitySelectableItemProps extends DashboardActivityItemBaseProps, DashboardActivityItemTitleProps { numTokens?: string; challengeID?: string; appealChallengeID?: string; salt?: any; toggleSelect?(challengeID: string, isSelected: boolean, salt: any): void; } ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardUserInfoSummary.tsx ================================================ import * as React from "react"; import { StyledUserInfo, StyledUserInfoSection, StyledUserInfoButtonSection, StyledUserInfoSectionLabel, StyledUserInfoSectionValue, StyledUserAddress, } from "./DashboardStyledComponents"; import { YourPublicAddressLabelText, BalanceLabelText, VotingBalanceLabelText, ChallengesWonLabelText, RewardsClaimedLabelText, } from "./DashboardTextComponents"; import { Button, buttonSizes } from "../Button"; export interface DashboardUserInfoSummaryProps { userAccount: string; balance: string; votingBalance: string; challengesWonTotalCvl?: string; rewardsEarned?: string; buyCvlUrl: string; } export const DashboardUserInfoSummary = (props: DashboardUserInfoSummaryProps) => { const { buyCvlUrl, challengesWonTotalCvl, rewardsEarned } = props; let buyBtnProps: any = { href: buyCvlUrl }; if (buyCvlUrl.charAt(0) === "/") { buyBtnProps = { to: buyCvlUrl }; } return ( {props.userAccount} {props.balance} {props.votingBalance} {challengesWonTotalCvl && ( <> {challengesWonTotalCvl} )} {rewardsEarned && ( <> {rewardsEarned} )} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/DashboardUserProfileSummary.tsx ================================================ import * as React from "react"; import { StyledUserProfile, StyledUserHandleAndEmailContainer, StyledUserAvatar, StyledUserHandleText, StyledUserEmailText, StyledUserNoAvatar, StyledAvatarContainer, } from "./DashboardStyledComponents"; export interface DashboardUserProfileSummaryProps { userAvatarImgDataURL: string; userHandle: string; userEmailAddress: string; } export const DashboardUserProfileSummary = (props: DashboardUserProfileSummaryProps) => { const { userAvatarImgDataURL, userHandle, userEmailAddress, } = props; const initial = userHandle ? userHandle.charAt(0) : "?"; return ( {userAvatarImgDataURL && ( )} {!userAvatarImgDataURL && ( {initial} )} {userHandle} {userEmailAddress && {userEmailAddress}} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/NoNewsrooms.tsx ================================================ import * as React from "react"; import { urlConstants as links } from "@joincivil/utils"; import { DashboardNewsroomApplicationIcon } from "../icons"; import { InvertedButton } from "../Button"; import { StyledDashboardNoContent, StyledDashboardNoContentHdr, StyledDashboardNoContentCopy, StyledDashboardNoContentButtonContainer, } from "./DashboardStyledComponents"; export interface NoNewsroomsProps { hasInProgressApplication?: boolean; applyToRegistryURL: string; } export const NoNewsrooms: React.FunctionComponent = props => { const { hasInProgressApplication, applyToRegistryURL } = props; let hdrText = "You don't have any Newsrooms on the Registry"; let copy = ( <> Learn how to join as a Newsroom {" "} or apply to our network of community-approved Newsrooms on Civil. ); let buttonText = "Apply to the Registry"; if (hasInProgressApplication) { hdrText = "You have an application in progress"; copy = <>; buttonText = "Continue your application"; } return ( {hdrText} {copy} {buttonText} ); }; ================================================ FILE: packages/components/src/TCRUserDashboard/index.ts ================================================ export * from "./Dashboard"; export * from "./DashboardUserInfoSummary"; export * from "./DashboardUserProfileSummary"; export * from "./DashboardActivity"; export * from "./DashboardActivityItem"; export * from "./DashboardActivityItemTask"; export * from "./DashboardActivityItemCTAButton"; export * from "./DashboardActivityProposalItemCTAButton"; export * from "./DashboardActivitySelectableItem"; export * from "./DashboardActivityTabTitle"; export * from "./DashboardNewsroomStripeConnect"; export * from "./DashboardStyledComponents"; export * from "./DashboardTextComponents"; export * from "./DashboardTransferTokenForm"; export * from "./DashboardNewsroom"; export * from "./NoNewsrooms"; ================================================ FILE: packages/components/src/Table/Table.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import styled from "styled-components"; import { Table } from "./Table"; import { Tr } from "./Tr"; import { Th } from "./TableHeader"; import { Td } from "./TableCell"; const StyledDiv = styled.div` display: flex; flex-direction: column; align-items: center; width: 600px; `; const Container: React.FunctionComponent = ({ children }) => {children}; storiesOf("Pattern Library / Table", module).add("Default", () => { return (
Default Header Right aligned Accent Col spanned header
Default cell Default cell Pasta Pho
Pizza is delicious Ramen is tasty too Pasta Pho
); }); ================================================ FILE: packages/components/src/Table/Table.tsx ================================================ import * as React from "react"; import { TableProps } from "./types"; import { StyledTable } from "./styledComponents"; export const Table: React.FunctionComponent = props => ( {props.children} ); ================================================ FILE: packages/components/src/Table/TableCell.tsx ================================================ import * as React from "react"; import { TableCellProps } from "./types"; import { StyledTableCell } from "./styledComponents"; export const Td: React.FunctionComponent = props => { const StyledTableCellComponent = props.StyledTableCellComponent || StyledTableCell; return {props.children}; }; ================================================ FILE: packages/components/src/Table/TableHeader.tsx ================================================ import * as React from "react"; import { TableCellProps } from "./types"; import { StyledTableHeader } from "./styledComponents"; export const Th: React.FunctionComponent = props => ( {props.children} ); ================================================ FILE: packages/components/src/Table/Tr.tsx ================================================ import * as React from "react"; import { StyledTableRow } from "./styledComponents"; export const Tr: React.FunctionComponent = props => {props.children}; ================================================ FILE: packages/components/src/Table/__snapshots__/Table.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Table Default 1`] = `
Default Header Right aligned Accent Col spanned header
Default cell Default cell Pasta Pho
Pizza is delicious Ramen is tasty too Pasta Pho

Pattern Library / Table

Default

Story Source

            
< Container >
< Table width = " 100% " >
< Tr >
< Th >
Default Header
</ Th >
< Th align = " right " >
Right aligned
</ Th >
< Th accent colSpan = { 2 } >
Accent Col spanned header
</ Th >
</ Tr >
< Tr >
< Td >
Default cell
</ Td >
< Td align = " right " >
Default cell
</ Td >
< Td accent >
Pasta
</ Td >
< Td accent >
Pho
</ Td >
</ Tr >
< Tr >
< Td >
Pizza is delicious
</ Td >
< Td align = " right " >
Ramen is tasty too
</ Td >
< Td accent >
Pasta
</ Td >
< Td accent >
Pho
</ Td >
</ Tr >
</ Table >
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" Table " Component

No propTypes defined!

" Td " Component

No propTypes defined!

" Th " Component

No propTypes defined!

" Tr " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Table/index.ts ================================================ export * from "./Table"; export * from "./Tr"; export * from "./TableHeader"; export * from "./TableCell"; export { StyledTableAccentText } from "./styledComponents"; ================================================ FILE: packages/components/src/Table/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { StyledDurationContainer, StyledCountdownLabel, StyledCountdownLabelWarn, } from "../PhaseCountdown/TextCountdownTimer"; import { TableProps, TableCellProps } from "./types"; export const StyledTableCell = styled.td` background-color: ${(props: TableCellProps) => (props.accent ? colors.accent.CIVIL_GRAY_4 + "7D" : "transparent")}; border: solid ${colors.accent.CIVIL_GRAY_4}; border-width: ${(props: TableCellProps) => props.borderWidth || "1px 0"}; padding: ${(props: TableCellProps) => (props.padding !== undefined ? props.padding : "20px 16px")}; text-align: ${(props: TableCellProps) => props.align || "left"}; `; export const StyledTable = styled.table` border: solid ${colors.accent.CIVIL_GRAY_4}; border-width: ${(props: TableProps) => props.borderWidth || "1px"}; border-collapse: collapse; font-family: ${fonts.SANS_SERIF}; font-size: 16px; line-height: 19px; & ${StyledTableCell} { border-width: ${(props: TableProps) => props.borderWidth || "1px 0"}; } ${mediaQueries.MOBILE} { font-size: 14px; letter-spacing: -0.09px; line-height: 17px; } `; export const StyledTableHeader = styled.th` background-color: ${(props: TableCellProps) => props.accent ? colors.accent.CIVIL_BLUE_VERY_FADED : colors.accent.CIVIL_GRAY_4}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.primary.CIVIL_GRAY_1}; font-weight: 600; letter-spacing: -0.11px; padding: 20px 16px; text-align: ${(props: TableCellProps) => props.align || "left"}; ${mediaQueries.MOBILE} { display: none; } `; export interface StyledTabAccentTextProps { strong?: boolean; } export const StyledTableAccentText = styled.span` color: ${colors.accent.CIVIL_BLUE}; cursor: pointer; font-weight: ${(props: StyledTabAccentTextProps) => (props.strong ? "bold" : "normal")}; `; export const StyledTableRow = styled.tr` ${mediaQueries.HOVER} { &:hover ${StyledTableCell} { background-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.basic.WHITE} !important; } // prettier-ignore &:hover ${StyledTableAccentText}, &:hover ${StyledDurationContainer}, &:hover ${StyledCountdownLabel}, &:hover ${StyledCountdownLabelWarn} { color: ${colors.basic.WHITE} !important; } &:hover svg g { fill: ${colors.basic.WHITE} !important; } } `; ================================================ FILE: packages/components/src/Table/types.ts ================================================ export interface TableProps { borderWidth?: string; width?: string; } export interface TableCellProps { accent?: boolean; align?: any; // not sure why `string` was causing compiler issues, but it was. TODO(nickreynolds): investigate borderWidth?: string; colSpan?: number; padding?: number; rowSpan?: number; StyledTableCellComponent?: any; width?: string; } ================================================ FILE: packages/components/src/Tabs/Tab.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { fonts, colors } from "../styleConstants"; export interface TabProps { title: string | JSX.Element; isActive?: boolean; isResponsiveAndVisible?: boolean; index?: number; children: React.ReactChild; TabComponent?: any; badgeNum?: number; onClick?(index: number): void; } export interface TabComponentProps { isActive?: boolean; isResponsiveAndVisible?: boolean; onClick?(e: any): void; } const StyledLi = styled.li` border-bottom: ${(props: TabComponentProps) => (props.isActive ? "3px solid #01a0d2" : "none")}; box-sizing: border-box; font-family: ${props => props.theme.sansSerifFont}; font-weight: ${(props: TabComponentProps) => (props.isActive ? "600" : "400")}; margin-bottom: 0; padding: 3px 0 18px; text-align: center; cursor: ${(props: TabComponentProps) => (props.isActive ? "default" : "pointer")}; & a { color: inherit; } flex-grow: 1; `; StyledLi.defaultProps = { theme: { sansSerifFont: fonts.SANS_SERIF, }, }; export const Count = styled.span` font-weight: 400; `; const StyledBadge = styled.figure` position: absolute; top: -20px; right: -60px; border-radius: 10px; background: ${colors.accent.CIVIL_RED_2}; color: white; font-size: 10px; font-weight: 400; width: 20px; height: 20px; display: flex; flex-direction: column; align-items: center; justify-content: space-around; `; const StyledTabTitle = styled.div` position: relative; display: inline-block; `; export class Tab extends React.Component { public render(): JSX.Element { const { badgeNum } = this.props; const TabComponent = this.props.TabComponent || StyledLi; const displayBadge = badgeNum && badgeNum > 0; let badgeCount = ""; if (displayBadge) { if (badgeNum! > 99) { badgeCount = "99+"; } else { badgeCount = badgeNum + ""; } } return ( {this.props.title} {displayBadge && {badgeCount}} ); } private onClick = () => { this.props.onClick!(this.props.index!); }; } ================================================ FILE: packages/components/src/Tabs/TabTitles.tsx ================================================ import * as React from "react"; import { StyledTabCount } from "./TabsStyled"; import { TabNewApplicationsText, TabUnderChallengeText, TabAppealToCouncilText, TabChallengeCouncilAppealText, TabReadyToUpdateText, } from "./textComponents"; export interface TabTitleProps { count?: number; } const TabTitle: React.FunctionComponent = props => { return ( <> {props.children} {props.count || "0"} ); }; export const NewApplicationsTabTitle: React.FunctionComponent = props => { return ( ); }; export const UnderChallengeTabTitle: React.FunctionComponent = props => { return ( ); }; export const AppealToCouncilTabTitle: React.FunctionComponent = props => { return ( ); }; export const ChallengeCouncilAppealTabTitle: React.FunctionComponent = props => { return ( ); }; export const ReadyToUpdateTabTitle: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/Tabs/Tabs.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Tabs } from "./Tabs"; import { Tab } from "./Tab"; import { StyledTabNav, StyledTabLarge, StyledSquarePillTabNav, StyledSquarePillTab, StyledRoundPillTabNav, StyledRoundPillTab, StyledTab, } from "./TabsStyled"; import { ApprovedNewsroomsTabText, ApplicationsInProgressTabText, RejectedNewsroomsTabText } from "./textComponents"; storiesOf("Common / Tabs", module) .add("Default Tabs", () => { return (

Some Content

Some other Content

); }) .add("Styled Large Tab", () => { return ( }>

Some Content

}>

Some other Content

}>

Some other Content

); }) .add("Square Pill Tab", () => { return (

Some Content

Some other Content

Some other Content

Some other Content

); }) .add("Round Pill Tab", () => { return (

Some Content

Some other Content

Some other Content

Some other Content

Some other Content

); }) .add("Styled Tab", () => { return (

Some Content

Some other Content

Some other Content

); }) .add("Tabs with before/after elements in nav", () => { const before = before!; const after = after!; return (

Some Content

Some other Content

); }); ================================================ FILE: packages/components/src/Tabs/Tabs.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../styleConstants"; import { ExpandDownArrow } from "../icons"; import { TabProps } from "./Tab"; import { StyledTabsContainer, StyledNav, StyledResponsiveTabsToggleButton, TabContainer } from "./TabsStyled"; export interface TabsProps { activeIndex?: number; flex?: boolean; children: Array>; TabComponent?: any; TabsNavComponent?: any; TabsNavBefore?: React.ReactElement; TabsNavAfter?: React.ReactElement; /** Set to `true` to prevent tab change silently. If set to a string, on tab change attempt string will be passed to `window.confirm`: if user hits "cancel" tab change will be prevented. */ preventTabChange?: boolean | string; onActiveTabChange?(activeIndex: number): void; } export interface TabsState { activeIndex: number; isResponsiveTabsetVisible: boolean; } export class Tabs extends React.Component { public static getDerivedStateFromProps(nextProps: TabsProps, prevState: TabsState): TabsState { return { ...prevState, activeIndex: typeof nextProps.activeIndex === "number" ? nextProps.activeIndex : prevState.activeIndex, }; } constructor(props: TabsProps) { super(props); this.state = { activeIndex: props.activeIndex || 0, isResponsiveTabsetVisible: false, }; } public renderTabs(): Array> { return React.Children.map(this.props.children, (child, index) => { return React.cloneElement(child as React.ReactElement, { index, isActive: this.state.activeIndex === index, isResponsiveAndVisible: this.state.isResponsiveTabsetVisible, onClick: this.handleClick, TabComponent: this.props.TabComponent, }); }); } public renderContent(): React.ReactNode | undefined { const children = this.props.children; const { activeIndex } = this.state; if (children[activeIndex]) { return children[activeIndex].props.children; } } public render(): JSX.Element { const TabsNavComponent = this.props.TabsNavComponent || StyledNav; const TabComponentOrnamental = styled(this.props.TabComponent || "span")` cursor: default; `; const arrowColor = this.state.isResponsiveTabsetVisible ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_2; return ( {this.props.TabsNavBefore && {this.props.TabsNavBefore}} {this.renderTabs()} {this.props.TabsNavAfter && {this.props.TabsNavAfter}}
{this.renderContent()}
); } private handleClick = (index: number) => { if ( this.props.preventTabChange && (this.props.preventTabChange === true || !window.confirm(this.props.preventTabChange)) ) { return; } this.setState({ activeIndex: index }); if (this.props.onActiveTabChange) { this.props.onActiveTabChange(index); } }; private toggleResponsiveVisible = () => { this.setState({ isResponsiveTabsetVisible: !this.state.isResponsiveTabsetVisible }); }; } ================================================ FILE: packages/components/src/Tabs/TabsStyled.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { TabComponentProps } from "./Tab"; import { colors, fonts, mediaQueries } from "../styleConstants"; export interface StyledTabsContainerProps { flex?: boolean; } export const StyledTabsContainer = styled.span` display: ${(props: StyledTabsContainerProps) => (props.flex ? "flex" : "block")}; `; export const StyledTabCount = styled.span` display: inline-block; border-radius: 31px; font-size: 12px; line-height: 15px; margin-left: 6px; padding: 3px 10px; `; /* Primary Tab styles used on the Registry page */ export const StyledTabNav = styled.div` background-color: ${colors.accent.CIVIL_GRAY_4}; height: 76px; margin: 0 auto 50px; width: 100%; & > ul { justify-content: center; } ${mediaQueries.MOBILE} { height: auto; margin-bottom: 30px; position: relative; & > ul { display: block; justify-content: left; } } `; export const StyledNav = styled.nav` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_3}; `; export interface StyledResponsiveTabsToggleButtonProps { isExpanded: boolean; } export const StyledResponsiveTabsToggleButton = styled.div` display: none; ${mediaQueries.MOBILE} { display: block; position: absolute; right: 16px; top: 16px; transform: ${(props: StyledResponsiveTabsToggleButtonProps) => (props.isExpanded ? "rotate(180deg)" : "rotate(0)")}; z-index: 2; } & svg { ${mediaQueries.MOBILE} { width: 16px; height: 26px; } } `; export const TabContainer = styled.ul` display: flex; list-style: none; margin: 0 auto; padding: 0; `; export const StyledTabLarge = styled.li` align-items: center; border-bottom: ${(props: TabComponentProps) => props.isActive ? "8px solid " + colors.accent.CIVIL_BLUE : "8px solid transparent"}; color: ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_2)}; cursor: pointer; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 19px; font-weight: 800; margin: 39px 40px 0 0; padding: 0 0 10px; &:last-of-type { margin: 39px 0 0 0; } ${mediaQueries.HOVER} { &:hover { border-bottom: ${(props: TabComponentProps) => props.isActive ? "8px solid " + colors.accent.CIVIL_BLUE : "8px solid " + colors.accent.CIVIL_GRAY_2}; } } & a { color: inherit; } & svg { margin-right: 5px; & circle { stroke: ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_2)}; } & path { fill: ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_2)}; } } ${mediaQueries.MOBILE} { border-bottom-width: 0; display: ${(props: TabComponentProps) => (props.isActive || props.isResponsiveAndVisible ? "block" : "none")}; padding: 20px 16px; margin: 0; & svg { ${(props: TabComponentProps) => props.isResponsiveAndVisible ? "box-shadow: inset 0 -1px 0 0 " + colors.accent.CIVIL_GRAY_3 + ", inset 0 1px 0 0 " + colors.accent.CIVIL_GRAY_3 + ", 0 -1px 0 0 " + colors.accent.CIVIL_GRAY_0 : ""}; &:last-of-type { margin: 0; ${(props: TabComponentProps) => props.isResponsiveAndVisible ? "box-shadow: inset 0 -3px 0 0 " + colors.accent.CIVIL_BLUE + ", 0 -1px 0 0 " + colors.accent.CIVIL_GRAY_0 : ""}; } } } `; /* Secondary Tab styles used on the Registry page */ export const StyledSquarePillTabNav = styled.div` display: flex; justify-content: center; margin: 30px auto 50px; width: 100%; ${mediaQueries.MOBILE} { height: auto; margin: 30px 22px 20px; width: auto; position: relative; & > ul { display: block; width: 100%; } } `; /* Secondary Tab styles used on the Registry page */ export const StyledSquarePillTab = styled.li` background-color: ${(props: TabComponentProps) => props.isActive ? colors.accent.CIVIL_BLUE_FADED_2 : "transparent"}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-right: none; color: ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_BLUE : colors.primary.BLACK)}; cursor: pointer; font-family: ${fonts.SANS_SERIF}; font-size: 14px; font-weight: 600; line-height: 17px; padding: 20px 44px; white-space: nowrap; &:last-of-type { border-right: 1px solid ${colors.accent.CIVIL_GRAY_4}; } ${mediaQueries.HOVER} { &:hover { color: ${colors.accent.CIVIL_BLUE}; background-color: ${colors.accent.CIVIL_BLUE_FADED_2}; } } & ${StyledTabCount} { background-color: ${(props: TabComponentProps) => props.isActive ? colors.accent.CIVIL_TEAL : colors.accent.CIVIL_GRAY_3}; } ${mediaQueries.MOBILE} { border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-width: 1px 1px 0; border-collapse: collapse; display: ${(props: TabComponentProps) => (props.isActive || props.isResponsiveAndVisible ? "block" : "none")}; padding: 20px 16px; margin: 0; text-align: center; &:last-of-type { border-bottom-width: 1px; } } `; export const StyledRoundPillTabNav = styled.div` margin: 0 auto 50px; max-width: 1200px; width: 100%; `; export const StyledRoundPillTab = styled.li` background-color: ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_GRAY_4 : "transparent")}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 23px; color: ${colors.primary.BLACK}; cursor: pointer; font-family: ${fonts.SANS_SERIF}; font-size: 14px; letter-spacing: -0.12px; list-style: none; margin-right: 10px; padding: 8px 15px; ${mediaQueries.HOVER} { &:hover { background-color: ${colors.accent.CIVIL_GRAY_4}; } } `; export const StyledTab = styled.li` border-bottom: ${(props: TabComponentProps) => props.isActive ? "2px solid " + colors.accent.CIVIL_BLUE : "2px solid transparent"}; color: ${(props: TabComponentProps) => (props.isActive ? colors.primary.BLACK : colors.accent.CIVIL_GRAY_2)}; cursor: pointer; font-family: ${fonts.SANS_SERIF}; font-size: 14px; letter-spacing: -0.12px; margin-right: 30px; padding: 25px 0 15px; text-align: center; text-decoration: none; transition: background-color 500ms, border 500ms, color 500ms; ${mediaQueries.HOVER} { &:hover { border-bottom: 2px solid ${colors.accent.CIVIL_BLUE}; color: ${colors.primary.BLACK}; } } &.active { border-bottom: 2px solid ${colors.accent.CIVIL_BLUE}; color: ${colors.primary.BLACK}; } `; ================================================ FILE: packages/components/src/Tabs/__snapshots__/Tabs.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Tabs Default Tabs 1`] = `

Some Content

Common / Tabs

Default Tabs

Story Source

            
< Tabs >
< Tab title = " Index " >
< p >
Some Content
</ p >
</ Tab >
< Tab title = " Sign " >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; exports[`Storyshots Common / Tabs Round Pill Tab 1`] = `
  • All
  • Accepting Votes
  • Verifying Votes
  • Request Appeal
  • Ready to Complete

Some Content

Common / Tabs

Round Pill Tab

Story Source

            
< Tabs TabsNavComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
TabComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
>
< Tab title = " All " >
< p >
Some Content
</ p >
</ Tab >
< Tab title = " Accepting Votes " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " Verifying Votes " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " Request Appeal " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " Ready to Complete " >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; exports[`Storyshots Common / Tabs Square Pill Tab 1`] = `
  • New Applications
  • Under Challenge
  • Appeal to Council
  • Challenge Council Appeal

Some Content

Common / Tabs

Square Pill Tab

Story Source

            
< Tabs TabsNavComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
TabComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
>
< Tab title = " New Applications " >
< p >
Some Content
</ p >
</ Tab >
< Tab title = " Under Challenge " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " Appeal to Council " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " Challenge Council Appeal " >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; exports[`Storyshots Common / Tabs Styled Large Tab 1`] = `
  • Approved Newsrooms
  • Newsrooms In Progress
  • Rejected Newsrooms

Some Content

Common / Tabs

Styled Large Tab

Story Source

            
< Tabs TabsNavComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
TabComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
>
< Tab title = { <ApprovedNewsroomsTabText /> } >
< p >
Some Content
</ p >
</ Tab >
< Tab title = { <ApplicationsInProgressTabText /> } >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = { <RejectedNewsroomsTabText /> } >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; exports[`Storyshots Common / Tabs Styled Tab 1`] = `

Some Content

Common / Tabs

Styled Tab

Story Source

            
< Tabs TabComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
>
< Tab title = " About " >
< p >
Some Content
</ p >
</ Tab >
< Tab title = " Discussions " >
< p >
Some other Content
</ p >
</ Tab >
< Tab title = " History " >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; exports[`Storyshots Common / Tabs Tabs with before/after elements in nav 1`] = `

Some Content

Common / Tabs

Tabs with before/after elements in nav

Story Source

            
< Tabs TabsNavBefore = { <span /> } TabsNavAfter = { <span /> } >
< Tab title = " Index " >
< p >
Some Content
</ p >
</ Tab >
< Tab title = " Sign " >
< p >
Some other Content
</ p >
</ Tab >
</ Tabs >

Prop Types

" Tab " Component

No propTypes defined!

" Tabs " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Tabs/index.ts ================================================ export * from "./Tab"; export * from "./Tabs"; export * from "./TabsStyled"; export * from "./TabTitles"; export * from "./textComponents"; ================================================ FILE: packages/components/src/Tabs/textComponents.tsx ================================================ import * as React from "react"; import { ApplicationInProgressIcon, ApprovedNewsroomsIcon, RejectedNewsroomsIcon } from "@joincivil/elements"; // Text for listings approved newsrooms tab export const ApprovedNewsroomsTabText: React.FunctionComponent = props => { return ( <> Approved Newsrooms ); }; // Text for listings applicaitons in progress tab export const ApplicationsInProgressTabText: React.FunctionComponent = props => { return ( <> Newsrooms In Progress ); }; // Text for listings rejected newsrooms tab export const RejectedNewsroomsTabText: React.FunctionComponent = props => { return ( <> Rejected Newsrooms ); }; export const TabNewApplicationsText: React.FunctionComponent = props => { return <>New Applications; }; export const TabUnderChallengeText: React.FunctionComponent = props => { return <>Under Challenge; }; export const TabAppealToCouncilText: React.FunctionComponent = props => { return <>Under Appeal; }; export const TabChallengeCouncilAppealText: React.FunctionComponent = props => { return <>Decision Challenged; }; export const TabReadyToUpdateText: React.FunctionComponent = props => { return <>Ready to Update; }; ================================================ FILE: packages/components/src/Tokens/EthereumTransactionButton.tsx ================================================ import * as React from "react"; import { MetaMaskLogoButton } from "../MetaMaskLogoButton"; import { MetaMaskModal } from "../MetaMaskModal"; import { ModalHeading } from "../ModalContent"; import { CivilContext, ICivilContext } from "../context"; export interface EthereumTransactionInfo { hash: string; } export interface EthereumTransactionButtonProps { disabled: boolean; modalHeading: string; execute(): Promise; onComplete(): any; } export interface EthereumTransactionButtonState { inProgress: boolean; waiting: boolean; rejected: boolean; complete: boolean; } export class EthereumTransactionButton extends React.Component< EthereumTransactionButtonProps, EthereumTransactionButtonState > { public static contextType = CivilContext; public context!: ICivilContext; public constructor(props: EthereumTransactionButtonProps) { super(props); this.state = { inProgress: false, waiting: false, rejected: false, complete: false }; } public render(): JSX.Element { return ( <> this.handleTransaction()}> {this.props.children} {this.state.inProgress ? ( this.cancelTransaction()} > {this.props.modalHeading} ) : null} ); } private async handleTransaction(): Promise { this.setState({ inProgress: true, waiting: true, rejected: false }); try { const tx = await this.props.execute(); await this.context.waitForTx((tx as any).hash); this.setState({ inProgress: false, waiting: false, rejected: false }); this.props.onComplete(); } catch (err) { console.log("error in transaction", err); this.setState({ inProgress: true, waiting: false, rejected: true }); } } private cancelTransaction(): void { this.setState({ inProgress: false, waiting: false, rejected: true }); } } ================================================ FILE: packages/components/src/Tokens/TokenPurchaseSummary.tsx ================================================ import * as React from "react"; import { CurrencyCalcCVL } from "../CurrencyConverter"; export interface TokenPurchaseSummaryProps { mode: "buy" | "sell"; currencyCode: string; pricePer: number; totalTokens: number; totalPrice?: number; zeroValue?: string; } function round(amount: number | undefined): number | string { return amount ? Math.round(amount * 1000) / 1000 : 0; } export const TokenPurchaseSummary = (props: TokenPurchaseSummaryProps) => { const { mode, currencyCode, totalPrice, totalTokens, pricePer } = props; return ( You are {mode === "buy" ? "buying" : "selling"}

{round(totalTokens)} {currencyCode}

{totalTokens > 0 ? (

approx. ${round(totalPrice)} @ ${round(pricePer)} per {currencyCode}

) : null}
); }; ================================================ FILE: packages/components/src/Tokens/Tokens.tsx ================================================ import * as React from "react"; import { TokenAccountOuter, TokenAccountInner, FlexColumns, FlexColumnsPrimary, FlexColumnsPrimaryModule, FlexColumnsSecondary, TokenHeader, } from "./TokensStyledComponents"; import { TokenWelcomeHeaderText, TokenBuySellHeaderText } from "./TokensTextComponents"; import { UserTokenAccountSignup } from "./TokensAccountSignup"; import { UserTokenAccountBuy } from "./TokensAccountBuy"; import { UserTokenAccountHelp } from "./TokensAccountHelp"; import { UserTokenAccountProgress } from "./TokensAccountProgress"; import { UserTokenAccountFaq } from "./TokensAccountFaq"; import { getFormattedEthAddress, isBrowserCompatible } from "@joincivil/utils"; import { UserTokenAccountPaypal } from "./TokensAccountPaypal"; import { BrowserCompatible } from "../BrowserCompatible"; export enum TOKEN_PROGRESS { ACTIVE = "active", COMPLETED = "completed", DISABLED = "disabled", } export interface UserTokenAccountProps { foundationAddress: string; network: string; user?: any; addWalletPath: string; signupPath: string; } export class UserTokenAccount extends React.Component { public render(): JSX.Element | null { const { user } = this.props; const accountSignupComplete = this.getAccountComplete(user); const userAccount = this.getUserAccount(user); const loggedInState = accountSignupComplete ? TOKEN_PROGRESS.COMPLETED : TOKEN_PROGRESS.ACTIVE; const buyState = accountSignupComplete ? TOKEN_PROGRESS.ACTIVE : TOKEN_PROGRESS.DISABLED; return ( {buyState === TOKEN_PROGRESS.ACTIVE ? : } {!isBrowserCompatible() ? this.renderBrowserIncompatible() : this.renderTokenSteps(loggedInState, buyState)} ); } private renderBrowserIncompatible = () => { return ( ); }; private renderTokenSteps = (loggedInState: any, buyState: any) => { return ( <> ); }; private getAccountComplete = (user: any) => { if (user && user.ethAddress) { return true; } return false; }; private getUserAccount = (user: any) => { if (user && user.ethAddress) { return getFormattedEthAddress(user.ethAddress); } return ""; }; } ================================================ FILE: packages/components/src/Tokens/TokensAccount.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import StoryRouter from "storybook-react-router"; import * as React from "react"; import Web3HttpProvider from "web3-providers-http"; import apolloStorybookDecorator from "apollo-storybook-react"; import { UserTokenAccountSignup } from "./TokensAccountSignup"; import { UserTokenAccountBuy } from "./TokensAccountBuy"; import { CivilContext, buildCivilContext } from "../context"; import Web3 from "web3"; const web3Provider = new Web3HttpProvider("http://localhost:8045"); const web3 = new Web3(web3Provider); const civilContext = buildCivilContext({ web3, featureFlags: ["uniswap"], config: { DEFAULT_ETHEREUM_NETWORK: 4 } }); const typeDefs = ` type Query { storefrontEthPrice: Float storefrontCvlPrice: Float storefrontCvlQuoteUsd(usdToSpend: Float!): Float } schema { query: Query } `; const mocks = { Query: () => { return { storefrontEthPrice: () => { return 102.98; }, storefrontCvlPrice: () => { return 0.2; }, storefrontCvlQuoteUsd: () => { return 500.48635; }, }; }, }; export interface UserTokenAccountProgressProps { userAccount: string; } storiesOf("Storefront / User Token Account", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("Signup Section", () => { return ( ); }) .add("Buy Section", () => { return ( ); }); ================================================ FILE: packages/components/src/Tokens/TokensAccountBuy.tsx ================================================ import * as React from "react"; import { FlexColumnsPrimaryModule, TokenBtns, TokenBuySection, TokenBuySellTab, TokenBuySellTabsNav, } from "./TokensStyledComponents"; import { TokenBuyTextDisabled, TokenBuyBtnDisabledText } from "./TokensTextComponents"; import { TOKEN_PROGRESS } from "./Tokens"; import { Tabs, Tab } from "../Tabs"; import { TokensTabBuy } from "./buy/TokensTabBuy"; import { TokensTabSell } from "./sell/TokensTabSell"; export interface TokenAccountBuyProps { foundationAddress: string; network: string; step: string; } export const UserTokenAccountBuy: React.FunctionComponent = props => { const { foundationAddress, network, step } = props; if (step === TOKEN_PROGRESS.DISABLED) { return ( ); } return ( ); }; ================================================ FILE: packages/components/src/Tokens/TokensAccountFaq.tsx ================================================ import * as React from "react"; import { TokenFAQCollapse, FlexColumnsPrimaryModule, TokenFAQImg } from "./TokensStyledComponents"; import { TokenETHFAQQuestion1Text, TokenETHFAQQuestion2Text, TokenETHFAQQuestion3Text, TokenETHFAQQuestion4Text, TokenETHFAQQuestion5Text, } from "./TokensTextComponents"; import { Collapsable } from "../Collapsable"; import metamaskEthAmount from "../images/img-metamask-eth-amount@2x.png"; export const UserTokenAccountFaq: React.FunctionComponent = props => { return ( } open={false}>

Ether (ETH) is the cryptocurrency for the Ethereum blockchain. Gas is the transaction cost of performing actions like adding content, or buying Civil tokens. Gas costs are variable. Like any currency, Ether (ETH) fluctuates in value with the market.

You will have to pay gas in Ether (ETH), which you can purchase via MetaMask and a cryptocurrency exchange such as Coinbase.

} open={false}>

When you perform actions like buying or selling tokens, you need to pay the cost of that computing effort. That payment is calculated in gas. Think about it like paying for a stamp on an envelope or paying for the shipping costs of sending a package. Gas can only be paid for with ETH.

ETH is used to also purchase Civil tokens (CVL) from an exchange or from Civil.

} open={false}>

To complete your membership contribution and receive Civil tokens (CVL), you must buy Ether (ETH). Then you will be able to exchange ETH for CVL. Unfortunately at this time, you can’t use USD or local currencies to directly buy Civil tokens. You must first convert local currencies into ETH using an exchange like Coinbase or Gemini. You will need to have your debit card or bank account details handy, as well as your passport to{" "} verify your identity Don't worry, both Coinbase and Gemini are regulated and in compliance with all applicable laws in each jurisdiction in which they operate. Once you fund your token wallet via{" "} Coinbase {" "} or{" "} Gemini{" "} {" "} (), you can return to Civil where we will walk you through how to complete your membership contribution. We know this can be confusing. For more information, read this blog post or contact us at{" "} support@civil.co.

} open={false}>

If you purchase Ether (ETH) in Coinbase using your Bank Account, Coinbase uses a ACH (Automated Clearing House, which is governed by the Federal Reserve) bank transfer system for U.S. customers, and it can take 3-5 business days for funds to transfer from your bank.

Buying ETH with a debit or certain credit cards is instant, once your account is verified on Coinbase.

It can possibly take up 30 days with your first transaction for the Ether (ETH) to appear in your wallet.

} open={false}>

AirSwap is a secure decentralized, peer-to-peer token trading network built on the Ethereum blockchain. It is an independent entity. Airswap does not charge any of its own fees on each trade. You only have to pay a Gas fee for each transaction on Ethereum. You can learn more about Airswap{" "} here .

You’ll be able to purchase Civil tokens (CVL) using Ethereum (ETH) in Airswap. Airswap will open its own interface to allow you to use ETH to buy CVL. You will need to use a wallet such as Metamask to connect and buy those tokens. Since Airswap is based on a trading network, the prices of Civil tokens (CVL) are based on the current market rate and can fluctuate.

); }; ================================================ FILE: packages/components/src/Tokens/TokensAccountHelp.tsx ================================================ import * as React from "react"; import { TokenQuestionsHeaderText, TokenFAQText } from "./TokensTextComponents"; import { FlexColumnsSecondaryModule } from "./TokensStyledComponents"; import { Collapsable } from "../Collapsable"; export const UserTokenAccountHelp: React.FunctionComponent = props => { return ( } open={true}> ); }; ================================================ FILE: packages/components/src/Tokens/TokensAccountPaypal.tsx ================================================ import * as React from "react"; import { TokenDonateToCivilFoundationText } from "./TokensTextComponents"; import { PaypalDonate, FlexColumnsSecondaryModule } from "./TokensStyledComponents"; export const UserTokenAccountPaypal: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/Tokens/TokensAccountProgress.tsx ================================================ import * as React from "react"; import { FlexColumnsSecondaryModule, TokenProgressContain } from "./TokensStyledComponents"; import { TokenConnectWalletCompletedText, TokenWalletAddressText } from "./TokensTextComponents"; import { EthAddressViewer } from "../EthAddressViewer"; export interface UserTokenAccountProgressProps { userAccount: string; logInComplete: boolean; } export const UserTokenAccountProgress: React.FunctionComponent = props => { if (props.logInComplete) { return ( } /> ); } return <>; }; ================================================ FILE: packages/components/src/Tokens/TokensAccountRequirement.tsx ================================================ import * as React from "react"; import { TokenRequirement } from "./TokensStyledComponents"; export interface TokenAccountRequirementProps { step?: string; } export const UserTokenAccountRequirement: React.FunctionComponent = props => { return {props.children}; }; ================================================ FILE: packages/components/src/Tokens/TokensAccountSignup.tsx ================================================ import * as React from "react"; import { UserTokenAccountRequirement } from "./TokensAccountRequirement"; import { FlexColumnsPrimaryModule, TokenBtns, TokenRequirementIcon } from "./TokensStyledComponents"; import { TokenConnectWalletText, TokenConnectWalletBtnText, TokenAuthText } from "./TokensTextComponents"; import { TokenWalletIcon } from "@joincivil/elements"; import { TOKEN_PROGRESS } from "./Tokens"; export interface TokenRequirementProps { step?: string; user: any; addWalletPath: string; signupPath: string; } // TODO(jorgelo) This should take into account whether the currentUser.ethAddress is same as MM address. They should have to reconnect if that is true. (Thanks Toby!) export const UserTokenAccountSignup: React.FunctionComponent = props => { const { addWalletPath, step, user } = props; const renderConnectWallet = (): JSX.Element => ( <> ); const renderNotLoggedIn = (): JSX.Element => ( <> ); const renderAuthCard = (): JSX.Element => { if (!user) { return renderNotLoggedIn(); } return renderConnectWallet(); }; if (step === TOKEN_PROGRESS.ACTIVE) { return ( {renderAuthCard()} ); } return <>; }; ================================================ FILE: packages/components/src/Tokens/TokensStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts, mediaQueries } from "../styleConstants"; import { Button, InvertedButton } from "../Button"; import { TOKEN_PROGRESS } from "./Tokens"; import { TabComponentProps } from "../Tabs"; import { PaypalLogoIcon } from "../icons/logos"; export interface TokenRequirementStyleProps { step?: string; padding?: boolean; } export const TokenAccountOuter = styled.div` background-color: ${colors.accent.CIVIL_BLUE_FADED_2}; display: flex; height: 100%; justify-content: center; padding: 20px 20px 50px; width: 100%; `; export const TokenSection = styled.div` margin-bottom: 30px; `; const PAYPAL_BLUE = "rgba(43,86,255,0.5)"; const PAYPAL_BLUE_DARK = "#2b56ff"; export const PaypalDonateContainer = styled.div` display: flex; flex-direction: row; border: 1px solid ${PAYPAL_BLUE}; `; export const PaypalDonateIconContainer = styled.div` padding: 18px 12px; border-right: 1px solid ${PAYPAL_BLUE}; `; export const PaypalDonateIconButtonContainer = styled.div` flex-grow: 1; `; export const PaypalLogoContainer = styled.div` padding: 18px; `; export const PaypalDonateIconButton = styled.input` background: #fff; box-shadow: 0px 0px 0px transparent; border: 0px solid transparent; text-shadow: 0px 0px 0px transparent; color: ${PAYPAL_BLUE_DARK}; padding: 20px; border-left: 1px solid ${PAYPAL_BLUE}; flex-grow: 1; width: 100%; height: 100%; outline: none; font-weight: bold; &:hover { background: ${PAYPAL_BLUE_DARK}; color: #fff; box-shadow: 0px 0px 0px transparent; border: 0px solid transparent; text-shadow: 0px 0px 0px transparent; } `; export const PaypalDonate: React.FunctionComponent = () => (
); export const TokenAccountInner = styled.div` max-width: 1200px; `; export const TokenBtns = styled(Button)` border-radius: 1px; font-size: 13px; font-weight: 700; letter-spacing: 0.3px; text-transform: none; `; export const TokenBtnsInverted = styled(InvertedButton)` border-radius: 1px; font-size: 13px; font-weight: 700; letter-spacing: 0.3px; text-transform: none; `; export const FlexColumns = styled.div` display: flex; ${mediaQueries.MOBILE} { display: block; } `; export const FlexColumnsPrimary = styled.div` margin-right: 30px; width: calc(100% - 380px); ${mediaQueries.MOBILE} { margin-right: 0; width: auto; } `; export const FlexColumnsPrimaryModule = styled.div` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; background-color: ${colors.basic.WHITE}; margin-bottom: 30px; ${(props: TokenRequirementStyleProps) => (props.padding ? "padding: 30px 0" : "")}; `; export const FlexColumnsSecondary = styled.div` width: 350px; ${mediaQueries.MOBILE} { width: auto; } `; export const FlexColumnsSecondaryModule = styled.div` background-color: ${colors.basic.WHITE}; border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; margin-bottom: 30px; padding: 20px 30px; h3 { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 18px; line-height: 28px; margin: 0 0 25px; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 16px; line-height: 26px; a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; &:hover { text-decoration: underline; } } } `; export const TokenHeader = styled.div` color: ${colors.primary.BLACK}; font-family: ${fonts.SANS_SERIF}; padding: 30px 30px 40px; text-align: center; h2 { font-size: 27px; line-height: 39px; margin-bottom: 25px; } p { font-size: 24px; line-height: 29px; margin-bottom: 60px; } `; export const TokenAccountSectionHeader = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; margin: 0 0 30px; padding: 0 25px 30px; text-align: center; h3 { color: ${colors.primary.BLACK}; font-size: 20px; font-weight: 700; line-height: 32px; margin: 0 0 8px; } p { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 18px; letter-spacing: -0.12px; line-height: 33px; margin: 0; } `; export const TokenRequirement = styled.div` margin: 0 30px 0 50px; padding: ${(props: TokenRequirementStyleProps) => props.step === "completed" ? "0 20px 0 35px" : "5px 20px 20px 35px"}; position: relative; h3 { color: ${(props: TokenRequirementStyleProps) => props.step === "completed" ? colors.primary.BLACK : colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 18px; font-weight: ${(props: TokenRequirementStyleProps) => (props.step === "completed" ? "400" : "600")}; ${(props: TokenRequirementStyleProps) => (props.step === "completed" ? "letter-spacing: -0.12px;" : "")}; line-height: 33px; margin: ${(props: TokenRequirementStyleProps) => (props.step === "completed" ? "0" : "0 0 5px")}; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 16px; line-height: 26px; margin: 0 0 30px; } `; export const TokenRequirementIcon = styled.div` align-items: center; background-color: ${colors.basic.WHITE}; border: ${(props: TokenRequirementStyleProps) => props.step === TOKEN_PROGRESS.DISABLED ? "1px solid" + colors.accent.CIVIL_GRAY_3 : "1px solid" + colors.accent.CIVIL_BLUE}; border-radius: 50%; display: flex; height: 38px; justify-content: center; left: -21px; position: absolute; top: 0; width: 38px; z-index: 1; `; export const TokenCheckIcon = styled.div` left: -21px; position: absolute; top: 0; z-index: 1; `; export const TokenBuySection = styled.div` font-family: ${fonts.SANS_SERIF}; padding: 0 30px 5px; h4 { font-size: 16px; font-weight: 700; line-height: 26px; margin: 0; } h3 { font-size: 20px; font-weight: 700; line-height: 32px; margin: 0; } p { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 16px; line-height: 24px; margin: 0 0 15px; } button { border-radius: 1px; font-size: 13px; font-weight: 700; letter-spacing: 0.3px; text-transform: none; } `; export const TokenBuyIntro = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_2}; padding: 0 0 15px; margin: 0 0 25px; span { color: ${colors.accent.CIVIL_GRAY_0}; display: block; font-size: 14px; line-height: 24px; margin: 0 0 15px; } `; export const TokenAirswapSection = styled.div` padding: 15px 30px 0 30px; text-align: center; ${mediaQueries.MOBILE} { padding-right: 10px; padding-left: 10px; } button { display: block; width: 100%; } `; export const TokenSellSection = styled.div` margin: 0 auto; max-width: 450px; button { margin-top: 50px; } `; export const TokenOrBreak = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; margin: 50px 0; position: relative; p { background-color: ${colors.basic.WHITE}; color: ${colors.accent.CIVIL_GRAY_3}; font-size: 14px; left: calc(50% - 50px); letter-spacing: 0.88px; line-height: 1; margin: 0; position: absolute; text-transform: uppercase; top: -5px; width: 100px; } `; export const TokenProgressContain = styled.div` margin-bottom: 10px; h3 { color: ${colors.primary.BLACK}; font-size: 16px; font-weight: bold; line-height: 26px; margin: 0 0 8px; svg { margin-right: 8px; vertical-align: text-bottom; } } p { color: ${colors.accent.CIVIL_GRAY_2}; font-size: 13px; font-weight: 500; letter-spacing: -0.14px; line-height: 21px; } span { margin-right: 15px; } a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; } div { align-items: flex-start; } button { margin: 0 0 0 10px; } `; export const TokenFAQCollapse = styled.div` border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 21px; padding: 20px 30px; h3 { font-size: 14px; font-weight: bold; line-height: 32px; margin: 0; } li { margin-bottom: 15px; } `; export const TokenFAQImg = styled.div` align-items: flex-start; display: flex; img { margin-left: 50px; max-width: 250px; width: 50%; } `; export const TokenFAQLineBreak = styled.hr` background-color: ${colors.accent.CIVIL_GRAY_4}; margin: 20px 0; width: 15px; `; export const CloseBtn = styled(InvertedButton)` border: none; padding: 0; height: 40px; position: absolute; right: 50px; top: 45px; width: 40px; svg path { transition: fill 0.2s ease; } &:focus, &:hover { background-color: transparent; svg path { fill: ${colors.accent.CIVIL_BLUE}; } } `; export const TokenExchangeSection = styled.div` button { background-color: transparent; border: 1px solid ${colors.accent.CIVIL_BLUE}; color: ${colors.accent.CIVIL_BLUE}; transition: all 0.2s ease; &:hover, &:focus { background-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.basic.WHITE}; } } `; export const TokenCalcCVL = styled.div` color: ${colors.accent.CIVIL_GRAY_0}; margin: 70px 0 0; text-align: center; span { font-size: 14px; font-weight: 600; line-height: 22px; } h4 { font-size: 28px; font-weight: 500; letter-spacing: -0.58px; line-height: 39px; } p { font-size: 14px; line-height: 22px; } `; export const TokenBuySellComplete = styled.div` margin-bottom: 35px; text-align: center; & > svg { margin: 0 auto 5px; } h3 { font-size: 20px; font-weight: bold; line-height: 32px; margin-bottom: 14px; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; margin-bottom: 17px; } a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; &:hover, &:focus { color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } } `; export const TokenUnlock = styled.div` background-color: #fff7f8; border: 1px solid ${colors.accent.CIVIL_RED_FADED}; border-radius: 4px; padding: 20px; h4 { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 16px; font-weight: 600; line-height: 26px; margin-bottom: 10px; svg { margin-right: 8px; } } p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; b { font-weight: 700; } } a { border: 1px solid ${colors.accent.CIVIL_BLUE}; border-radius: 2px; padding: 16px 40px; } `; export const TokenBuySellTab = styled.li` background-color: ${(props: TabComponentProps) => (props.isActive ? "transparent" : colors.accent.CIVIL_GRAY_4)}; border-top: 1px solid ${(props: TabComponentProps) => (props.isActive ? colors.accent.CIVIL_BLUE : "transparent")}; color: ${colors.primary.CIVIL_GRAY_1}; cursor: pointer; font-family: ${fonts.SANS_SERIF}; font-size: 18px; font-weight: 600; letter-spacing: -0.12px; line-height: 33px; padding: 20px 0; text-align: center; text-decoration: none; transition: border-color 500ms; width: 50%; ${mediaQueries.HOVER} { &:hover { border-color: ${(props: TabComponentProps) => props.isActive ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_3}; } } `; export const TokenBuySellTabsNav = styled.div` height: 80px; margin: -31px 0 50px; `; export const ComingSoon = styled.div` text-align: center; h3 { margin-bottom: 10px; } p { color: ${colors.accent.CIVIL_GRAY_1}; font-size: 14px; line-height: 20px; a { color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; &:hover { text-decoration: underline; } } } `; ================================================ FILE: packages/components/src/Tokens/TokensTextComponents.tsx ================================================ import styled from "styled-components"; import * as React from "react"; import { Link } from "react-router-dom"; import { HollowGreenCheck, NorthEastArrow } from "../icons"; import { colors } from "../styleConstants"; import { urlConstants as links } from "@joincivil/utils"; // Signup/Connect wallet section export const TokenWelcomeHeaderText: React.FunctionComponent = props => ( <>

Hello, you’re about to become a Civil member

Let’s get you set up to use, buy or sell Civil tokens

); export const TokenBuySellHeaderText: React.FunctionComponent = props =>

Buy or Sell Civil Tokens

; export const TokenConnectWalletText: React.FunctionComponent = props => ( <>

Connect your cryptocurrency wallet

Use your wallet to safely store your cryptocurrencies like Ether (ETH) and Civil tokens (CVL)

); export const TokenConnectWalletCompletedText: React.FunctionComponent = props => (

Wallet Connected

); export const TokenWalletAddressText: React.FunctionComponent = props => ( <> Public Address{" "} What's this? ); export const TokenMustBuyEth: React.FunctionComponent = props => ( <> To complete your membership contribution and receive Civil tokens (CVL), you must use Ether (ETH). Then you will be able to exchange ETH for CVL.{" "} Learn how to buy ETH here. ); // TODO(jorgelo): Is this text okay? export const TokenConnectWalletBtnText: React.FunctionComponent = props => <>Connect your wallet; // TODO(jorgelo): Find the real text here. export const TokenAuthText: React.FunctionComponent = props => ( <>

Sign up or Log in to your Civil account

); // TODO(jorgelo): Is this text okay? export const TokenAuthBtnText: React.FunctionComponent = props => <>Sign up or Log in; // Buy section export const TokenBuyTextDisabled: React.FunctionComponent = props => (

Sign up or Log in to use, share or buy Civil tokens.

); export const TokenBuyBtnDisabledText: React.FunctionComponent = props => <>Buy CVL; export const TokenBuyFoundationBtnText: React.FunctionComponent = props => ( <>Buy CVL from Civil Media Company in Airswap ); export const TokenBuyExchangeBtnText: React.FunctionComponent = props => <>Buy CVL on the open market in Airswap; export const TokenBuyText: React.FunctionComponent = props => ( <>

To buy Civil tokens (CVL), you must have Ether (ETH). Then, you will be able to exchange ETH for CVL. If you don't have enough ETH, you can buy ETH on Coinbase or{" "} Gemini or{" "} learn how. Please note, if you are a first-time purchaser, it may take a few days to get ETH in your wallet.

); export const TokenAirswapFoundationText: React.FunctionComponent = props => ( <>

Contribute to the Civil Foundation

Buy Civil tokens from The Civil Media Company and 100% of net proceeds go to the Civil Foundation for supporting worthy journalism.{" "} Learn about our transparent pricing.

); export const TokenUniswapExchangeText: React.FunctionComponent = props => ( <>

Buy Civil tokens on the open market

The Civil community can buy and sell Civil tokens between each other without a middle man, sometimes resulting in a lower price than offered by The Civil Media Company. Tokens bought on the open market perform the exact same utility as those purchased directly from The Civil Media Company, however none of the proceeds go to the Civil Foundation. Instead, the funds go to a third-party buyer.

); export const TokenAirswapExchangeTermsOfSaleTextContainer = styled.div` margin-top: 12px; font-size: 13px; color: ${colors.primary.CIVIL_GRAY_2}; `; export const TokenAirswapExchangeTermsOfSaleText: React.FunctionComponent = props => ( By clicking buy to purchase Civil tokens, you agree to the{" "} Terms of Sale. ); export const TokenOrText: React.FunctionComponent = props =>

or

; export const TokenBuyCompleteText: React.FunctionComponent = props => ( <>

Thanks for your purchase!

Your CVL will be deposited to your wallet address.

Please check the{" "} Dashboard {" "} to see your purchased CVL in the Available Balance.
To learn how to add Civil tokens in your MetaMask wallet,{" "} go to our FAQ

); // Sell section export const TokenSellInstructionsText: React.FunctionComponent = props => (

To sell Civil tokens (CVL), you must first exchange them for Ether (ETH). Then, you will be able to exchange ETH for USD or local currencies at an exchange like{" "} Coinbase {" "} or{" "} Gemini

); export const TokenSellAirswapText: React.FunctionComponent = props =>

Sell Civil tokens in Airswap

; export const TokenSellCompleteText: React.FunctionComponent = props => ( <>

Your sell was successful!

Your ETH will be deposited to your wallet address.

Please check the{" "} Dashboard {" "} to see your CVL balance in the Available Balance. To learn how to sell ETH for USD,{" "} go to our FAQ .

); // FAQ section export const TokenETHFAQQuestion1Text: React.FunctionComponent = props =>

What is Ethereum, ETH and gas?

; export const TokenETHFAQQuestion2Text: React.FunctionComponent = props =>

Why do I need ETH?

; export const TokenETHFAQQuestion3Text: React.FunctionComponent = props =>

How do I buy ETH?

; export const TokenETHFAQQuestion4Text: React.FunctionComponent = props =>

How long does it take to buy ETH?

; export const TokenETHFAQQuestion5Text: React.FunctionComponent = props =>

What is Airswap?

; export const TokenDonateToCivilFoundationText: React.FunctionComponent = () => ( <>

Donate to the Civil Foundation

Want to support this project, but don’t want to buy Civil tokens?

); export const TokenQuestionsHeaderText: React.FunctionComponent = props =>

Ask Questions

; export const TokenFAQText: React.FunctionComponent = props => ( <>

For support inquiries, send email to {links.EMAIL_SUPPORT}

Read our{" "} Frequently Asked Questions (FAQ) {" "} for general help

); export const SellFeeNotice = (props: any) => ( A small transaction fee will be added for all sales. This fee does not go to the Civil Media Company. Learn more ); export const ApproveNoticeText = ({ cvlToSell }: { cvlToSell: any }) => ( Almost there! You need to authorize the exchange to sell {cvlToSell} CVL on your behalf. After you approve you can complete the sale. ); ================================================ FILE: packages/components/src/Tokens/__snapshots__/TokensAccount.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Storefront / User Token Account Buy Section 1`] = `
  • Buy
  • Sell

To buy Civil tokens (CVL), you must have Ether (ETH). Then, you will be able to exchange ETH for CVL. If you don't have enough ETH, you can buy ETH on Coinbase or Gemini or learn how . Please note, if you are a first-time purchaser, it may take a few days to get ETH in your wallet.

Contribute to the Civil Foundation

Buy Civil tokens from The Civil Media Company and 100% of net proceeds go to the Civil Foundation for supporting worthy journalism. Learn about our transparent pricing.

You are buying

0 CVL

By clicking buy to purchase Civil tokens, you agree to the Terms of Sale.

or

Buy Civil tokens on the open market

The Civil community can buy and sell Civil tokens between each other without a middle man, sometimes resulting in a lower price than offered by The Civil Media Company. Tokens bought on the open market perform the exact same utility as those purchased directly from The Civil Media Company, however none of the proceeds go to the Civil Foundation. Instead, the funds go to a third-party buyer.

By clicking buy to purchase Civil tokens, you agree to the Terms of Sale.

Storefront / User Token Account

Buy Section

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / User Token Account Signup Section 1`] = `

Connect your cryptocurrency wallet

Use your wallet to safely store your cryptocurrencies like Ether (ETH) and Civil tokens (CVL)

Connect your wallet

Storefront / User Token Account

Signup Section

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / User Token Account Tutorial Verify 1`] = `

Take the Civil Tutorial

Before you can use, buy or sell Civil tokens, you must complete a tutorial to ensure you understand how to use Civil tokens and how the Civil Registry works.

Civil Tutorial

Complete a walkthrough and answer a series of questions about Civil and how to use Civil tokens (CVL). This is a standard procedure to help inform you of best practices with purchasing and using tokens.

It will take about 30 minutes to complete if you're a novice. If at any point you answer incorrectly, don’t worry. You will be able to answer the questions again.

Storefront / User Token Account

Tutorial Verify

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Tokens/buy/AirswapBuyCVL.tsx ================================================ import * as React from "react"; import makeAsyncScriptLoader from "react-async-script"; import { airswapScript, getAirswapCvlAddress, getAirswapEnv } from "@joincivil/utils"; import { Button } from "../../Button"; export interface BuyCVLProps { buyFromAddress?: string; buyCVLBtnText?: string | JSX.Element; network: string; amount?: number; onClick?(index: number): void; onComplete(): void; } class BuyCVLBase extends React.Component { public render(): JSX.Element { return ; } private displayAirswap(): void { const environment = getAirswapEnv(this.props.network); const tokenAddress = getAirswapCvlAddress(this.props.network); const buyFromAddress = this.props.buyFromAddress || ""; const amount = this.props.amount || 0; // this is pretty hacky, would probably be better off making this a bignumber and converting to wei // however, this doesn't display properly in Airswap if its more than 3 digits const amountString = Math.ceil(amount).toString() + "000000000000000000"; console.log("amountString", amountString); // @ts-ignore window.AirSwap.Trader.render( { mode: "buy", env: environment, token: tokenAddress, address: buyFromAddress, // amount: amountString, onComplete: () => { this.props.onComplete(); }, onCancel: () => { console.info("Trade cancelled"); }, }, "body", ); } } export const AirswapBuyCVL = makeAsyncScriptLoader(airswapScript)(BuyCVLBase); ================================================ FILE: packages/components/src/Tokens/buy/AirswapBuySection.tsx ================================================ import * as React from "react"; import { Query } from "react-apollo"; import gql from "graphql-tag"; import { TokenBuyFoundationBtnText, TokenAirswapExchangeTermsOfSaleText } from "../TokensTextComponents"; import { AirswapBuyCVL } from "./AirswapBuyCVL"; import { TokenPurchaseSummary } from "../TokenPurchaseSummary"; const cvlPriceQuery = gql` query($usdToSpend: Float!) { storefrontEthPrice storefrontCvlPrice storefrontCvlQuoteUsd(usdToSpend: $usdToSpend) } `; export interface AirswapBuySectionProps { usdToSpend: number; ethToSpend: number; foundationAddress: string; network: string; onBuyComplete(): void; } export const AirswapBuySection = (props: AirswapBuySectionProps) => { const { usdToSpend, onBuyComplete, foundationAddress, network } = props; return ( <> query={cvlPriceQuery} variables={{ usdToSpend }}> {({ loading, error, data }) => { if (error) { return
error loading data
; } const totalTokens = data.storefrontCvlQuoteUsd; const pricePer = usdToSpend / data.storefrontCvlQuoteUsd; return ( <> } buyFromAddress={foundationAddress} onComplete={onBuyComplete} amount={totalTokens} /> ); }} ); }; ================================================ FILE: packages/components/src/Tokens/buy/TokensTabBuy.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import StoryRouter from "storybook-react-router"; import apolloStorybookDecorator from "apollo-storybook-react"; import styled from "styled-components"; import Web3HttpProvider from "web3-providers-http"; import { TokensTabBuy } from "./TokensTabBuy"; import { CivilContext, buildCivilContext } from "../../context/CivilContext"; import { UniswapBuy } from "./UniswapBuy"; import { AirswapBuyCVL } from "./AirswapBuyCVL"; import { TokensTabBuyComplete } from "./TokensTabBuyComplete"; import Web3 from "web3"; export const Container = styled.div` align-items: center; display: flex; height: 250px; justify-content: center; width: 100%; max-width: 720px; `; const typeDefs = ` type Query { storefrontEthPrice: Float storefrontCvlPrice: Float storefrontCvlQuoteUsd(usdToSpend: Float!): Float } schema { query: Query } `; const mocks = { Query: () => { return { storefrontEthPrice: () => { return 102.98; }, storefrontCvlPrice: () => { return 0.2; }, storefrontCvlQuoteUsd: () => { return 500.48635; }, }; }, }; const web3Provider = new Web3HttpProvider("http://localhost:8045"); const web3 = new Web3(web3Provider); const civilContext = buildCivilContext({ web3, featureFlags: ["uniswap"], config: { DEFAULT_ETHEREUM_NETWORK: 4 } }); const foundationAddress = "hello!"; storiesOf("Storefront / Buy Tab", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("Buy Tab", () => { return ( ); }) .add("Buy from Uniswap", () => { return ( alert("buy complete")} /> ); }) .add("Buy from Airswap", () => { return ( ); }) .add("Buy Complete", () => { return ( ); }); ================================================ FILE: packages/components/src/Tokens/buy/TokensTabBuy.tsx ================================================ import * as React from "react"; import * as qs from "querystring"; import { Redirect } from "react-router-dom"; import { TokensTabBuyActive } from "./TokensTabBuyActive"; import { TokensTabBuyComplete } from "./TokensTabBuyComplete"; export interface TokensTabBuyProps { foundationAddress: string; network: string; } export interface TokensTabBuyStates { isBuyComplete: boolean; } export class TokensTabBuy extends React.Component { public constructor(props: TokensTabBuyProps) { super(props); this.state = { isBuyComplete: false, }; } public render(): JSX.Element | null { const { foundationAddress, network } = this.props; const { isBuyComplete } = this.state; if (isBuyComplete) { const redirect = qs.parse(document.location.search.substr(1)).redirect as string; if (redirect) { return ; } return ; } return ( ); } private onBuyComplete = () => { this.setState({ isBuyComplete: true }); }; } ================================================ FILE: packages/components/src/Tokens/buy/TokensTabBuyActive.tsx ================================================ import * as React from "react"; import { TokenAirswapSection, TokenOrBreak } from "../TokensStyledComponents"; import { TokenBuyText, TokenOrText, TokenAirswapExchangeTermsOfSaleText, TokenAirswapFoundationText, TokenUniswapExchangeText, } from "../TokensTextComponents"; import { UniswapBuySection } from "./UniswapBuySection"; import { AirswapBuySection } from "./AirswapBuySection"; import { UsdEthConverter } from "../../CurrencyConverter/UsdEthConverter"; import { FeatureFlag } from "../../features/FeatureFlag"; import { PaddedSection } from "../../containers"; import { Notice, NoticeTypes } from "../../Notice"; export interface TokensTabBuyActiveProps { foundationAddress: string; network: string; onBuyComplete(): void; } export class TokensTabBuyActive extends React.Component { constructor(props: TokensTabBuyActiveProps) { super(props); this.state = { etherToSpend: 0, usdToSpend: 0 }; } public render(): JSX.Element { const { foundationAddress, network, onBuyComplete } = this.props; return ( <> this.setConvertedAmount(usd, eth)} /> ); } private setConvertedAmount(usdToSpend: number, etherToSpend: number): void { this.setState({ ...this.state, usdToSpend, etherToSpend }); } } ================================================ FILE: packages/components/src/Tokens/buy/TokensTabBuyComplete.tsx ================================================ import * as React from "react"; import { TokenBuySellComplete } from "../TokensStyledComponents"; import { TokenBuyCompleteText } from "../TokensTextComponents"; import { HollowGreenCheck } from "../../icons"; export const TokensTabBuyComplete = () => { return ( <> ); }; ================================================ FILE: packages/components/src/Tokens/buy/UniswapBuy.tsx ================================================ import * as React from "react"; import { CurrencyConverterSection } from "../../CurrencyConverter"; import { CivilContext, ICivilContext } from "../../context"; import { TokenPurchaseSummary } from "../TokenPurchaseSummary"; import { EthereumTransactionButton } from "../EthereumTransactionButton"; import { BigNumber } from "@joincivil/typescript-types"; export interface UniswapBuyProps { usdToSpend: number; ethToSpend: number; ethExchangeRate: number; onBuyComplete(): void; } export const UniswapBuy: React.FunctionComponent = ({ ethToSpend, ethExchangeRate, usdToSpend, onBuyComplete, }) => { const context = React.useContext(CivilContext); const uniswap = context.uniswap; const [cvlToReceive, setCvlToReceive] = React.useState(null); React.useEffect(() => { async function updatePrice(): Promise { await context.civil!.currentProviderEnable(); const weiToSpend = uniswap.parseEther(ethToSpend.toString()); const result = await uniswap.quoteETHToCVL(weiToSpend); setCvlToReceive(result); } updatePrice().catch(err => { // TODO(dankins): commenting out this error to prevent storyshots from complaining. // this was silently failing before due to the way the component was set up // there are definitely more components that suffer the same fate // see UnhandledPromiseRejectionWarning: Error: Invalid JSON RPC response: "" at the end of the test run // console.log("error updating price", err); }); }, [context, ethToSpend]); async function buyCVL(): Promise { const weiToSpend = uniswap.parseEther(ethToSpend.toString()); return uniswap.executeETHToCVL(weiToSpend, cvlToReceive!); } if (!cvlToReceive) { return
loading price...
; } const cvl = uniswap.weiToEtherNumber(cvlToReceive); let pricePerCVL; if (ethToSpend === 0) { pricePerCVL = 0; } else { pricePerCVL = (ethExchangeRate * ethToSpend) / cvl; } return (
buyCVL()} disabled={usdToSpend === 0} onComplete={onBuyComplete} > Buy CVL on the open market from Uniswap
); }; ================================================ FILE: packages/components/src/Tokens/buy/UniswapBuySection.tsx ================================================ import * as React from "react"; import { Query } from "react-apollo"; import gql from "graphql-tag"; import { UniswapBuy } from "../buy/UniswapBuy"; const ethPriceQuery = gql` query { storefrontEthPrice } `; export interface UniswapBuySectionProps { ethToSpend: number; usdToSpend: number; onBuyComplete(): void; } export const UniswapBuySection = (props: UniswapBuySectionProps) => { return ( query={ethPriceQuery}> {({ loading, error, data }) => { if (loading) { return
; } return ( <>
); }} ); }; ================================================ FILE: packages/components/src/Tokens/buy/__snapshots__/TokensTabBuy.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Storefront / Buy Tab Buy Complete 1`] = `

Thanks for your purchase!

Your CVL will be deposited to your wallet address.

Please check the Dashboard to see your purchased CVL in the Available Balance.
To learn how to add Civil tokens in your MetaMask wallet, go to our FAQ

Storefront / Buy Tab

Buy Complete

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Buy Tab Buy Tab 1`] = `

To buy Civil tokens (CVL), you must have Ether (ETH). Then, you will be able to exchange ETH for CVL. If you don't have enough ETH, you can buy ETH on Coinbase or Gemini or learn how . Please note, if you are a first-time purchaser, it may take a few days to get ETH in your wallet.

Contribute to the Civil Foundation

Buy Civil tokens from The Civil Media Company and 100% of net proceeds go to the Civil Foundation for supporting worthy journalism. Learn about our transparent pricing.

You are buying

0 CVL

By clicking buy to purchase Civil tokens, you agree to the Terms of Sale.

or

Buy Civil tokens on the open market

The Civil community can buy and sell Civil tokens between each other without a middle man, sometimes resulting in a lower price than offered by The Civil Media Company. Tokens bought on the open market perform the exact same utility as those purchased directly from The Civil Media Company, however none of the proceeds go to the Civil Foundation. Instead, the funds go to a third-party buyer.

By clicking buy to purchase Civil tokens, you agree to the Terms of Sale.

Storefront / Buy Tab

Buy Tab

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Buy Tab Buy from Airswap 1`] = `

Storefront / Buy Tab

Buy from Airswap

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Buy Tab Buy from Uniswap 1`] = `
loading price...

Storefront / Buy Tab

Buy from Uniswap

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/Tokens/index.ts ================================================ export * from "./Tokens"; export * from "./TokensAccountHelp"; export * from "./TokensAccountRequirement"; export * from "./TokensAccountSignup"; export * from "./TokensAccountBuy"; export * from "./TokensAccountFaq"; export * from "./TokensAccountProgress"; export * from "./TokensStyledComponents"; export * from "./TokensTextComponents"; export * from "./TokensAccountPaypal"; ================================================ FILE: packages/components/src/Tokens/sell/TokensTabSell.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import StoryRouter from "storybook-react-router"; import apolloStorybookDecorator from "apollo-storybook-react"; import styled from "styled-components"; import Web3HttpProvider from "web3-providers-http"; import { TokensTabSell } from "./TokensTabSell"; import { CivilContext, buildCivilContext } from "../../context/CivilContext"; import { UniswapSell } from "./UniswapSell"; import { Notice, NoticeTypes } from "../../Notice"; import Web3 from "web3"; export const Container = styled.div` align-items: center; display: flex; height: 250px; justify-content: center; width: 100%; max-width: 720px; `; const typeDefs = ` type Query { storefrontEthPrice: Float storefrontCvlPrice: Float storefrontCvlQuoteUsd(usdToSpend: Float!): Float } schema { query: Query } `; const mocks = { Query: () => { return { storefrontEthPrice: () => { return 137.23; }, storefrontCvlPrice: () => { return 0.2; }, storefrontCvlQuoteUsd: () => { return 500.48635; }, }; }, }; const web3Provider = new Web3HttpProvider("http://localhost:8045"); const web3 = new Web3(web3Provider); const civilContext = buildCivilContext({ web3, featureFlags: ["uniswap"], config: { DEFAULT_ETHEREUM_NETWORK: 4 } }); const civilContextNoUniswap = buildCivilContext({ web3, featureFlags: [], config: { DEFAULT_ETHEREUM_NETWORK: 4 } }); storiesOf("Storefront / Sell Tab", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .addDecorator(StoryRouter()) .add("Sell Tab", () => { return ( notes for storybooks: if you are actually trying to buy you might have troubles. make sure the storefrontEthPrice graphql mock gets updated to the current price. ); }) .add("Coming Soon", () => { return ( ); }) .add("Uniswap", () => { return (
ethExchangeRate: 0.5
cvlToSell: 100
etherToReceive: 50
({})} />
); }); ================================================ FILE: packages/components/src/Tokens/sell/TokensTabSell.tsx ================================================ import * as React from "react"; import { getFormattedTokenBalance } from "@joincivil/utils"; import { TokensTabSellActive } from "./TokensTabSellActive"; import { TokensTabSellComplete } from "./TokensTabSellComplete"; import { ICivilContext, CivilContext } from "../../context"; import { FeatureFlag } from "../../features/FeatureFlag"; import { ComingSoon } from "../TokensStyledComponents"; export interface TokensTabSellProps { network: string; } export interface TokensTabSellStates { isSellComplete: boolean; balance: any | null; } export class TokensTabSell extends React.Component { public static contextType = CivilContext; public static context: ICivilContext; public constructor(props: TokensTabSellProps) { super(props); this.state = { isSellComplete: false, balance: null, }; } public async componentDidMount(): Promise { await this.setTokenBalance(); } public render(): JSX.Element | null { const { isSellComplete, balance } = this.state; const comingSoon = (

Coming Soon...

We appreciate your patience while we are testing this feature.
If you need help or have questions, please contact our support team at{" "} support@civil.co.

); let content: JSX.Element; if (balance === null) { return null; } else if (isSellComplete) { content = ; } else { content = ( ); } return ( {content} ); } private async setTokenBalance(): Promise { const civil = this.context.civil; const account = await civil.accountStream.first().toPromise(); if (account) { const tcr = await civil.tcrSingletonTrusted(); const token = await tcr.getToken(); const balance = await token.instance.balanceOf.callAsync(account); this.setState({ ...this.state, balance }); } } private onSellComplete = () => { this.setState({ isSellComplete: true }); }; } ================================================ FILE: packages/components/src/Tokens/sell/TokensTabSellActive.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { TokenBuyIntro } from "../TokensStyledComponents"; import { TokenSellInstructionsText } from "../TokensTextComponents"; import { UniswapSellSection } from "./UniswapSellSection"; import { Heading } from "../../Heading"; import { FullScreenModal } from "../../FullscreenModal"; import { ModalHeading, ModalContent } from "../../ModalContent"; import { Link } from "react-router-dom"; export interface TokensTabSellActiveProps { balance: string; onSellComplete(): void; } const BalanceContainer = styled.div` display: flex; flex-direction: row; > :first-child { flex-grow: 1; } `; const TokenInfoContainer = styled.div` margin: 20px; font-size: 16px; align-items: start; > p { font-size: 16px; } `; class CVLBalanceHeader extends React.Component { public constructor(props: any) { super(props); this.state = {}; } public render(): JSX.Element { const { balance } = this.props; return (
Available CVL to Sell {balance} this.hideModal()}> Don't see all of your tokens? Check the amount of CVL in your voting balance. If your voting tokens are not used for any challenges, or votes, transfer them to your Available Balance in order to sell. You can do this within the{" "} Dashboard section .
); } private showModal(e: any): void { e.preventDefault(); this.setState({ showModal: true }); } private hideModal(): void { this.setState({ showModal: false }); } } export const TokensTabSellActive: React.FunctionComponent = props => { const { onSellComplete, balance } = props; return ( <> ); }; ================================================ FILE: packages/components/src/Tokens/sell/TokensTabSellComplete.tsx ================================================ import * as React from "react"; import { TokenBuySellComplete } from "../TokensStyledComponents"; import { TokenSellCompleteText } from "../TokensTextComponents"; import { HollowGreenCheck } from "../../icons"; export const TokensTabSellComplete: React.FunctionComponent = props => { return ( ); }; ================================================ FILE: packages/components/src/Tokens/sell/UniswapCvlEthConverter.tsx ================================================ import * as React from "react"; import { CivilContext, ICivilContext } from "../../context/CivilContext"; import { CurrencyConverter } from "../../CurrencyConverter/CurrencyConverter"; export interface UniswapCvlEthConverterProps { onConversion(cvlValue: number, ethValue: number): void; } export class UniswapCvlEthConverter extends React.Component { public static contextType: React.Context = CivilContext; public constructor(props: UniswapCvlEthConverterProps) { super(props); } public render(): JSX.Element { return ( this.convertToETH(cvlAmount)} onConversion={(cvlValue, ethValue) => this.props.onConversion(cvlValue, ethValue)} /> ); } private async convertToETH(cvlAmount: number): Promise { const uniswap = this.context.uniswap; const bn = uniswap.parseEther(cvlAmount.toString()); const result = await uniswap.quoteCVLToETH(bn); return uniswap.weiToEtherNumber(result); } } ================================================ FILE: packages/components/src/Tokens/sell/UniswapSell.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { CivilContext, ICivilContext } from "../../context/CivilContext"; import { TokenPurchaseSummary } from "../TokenPurchaseSummary"; import { MetaMaskLogoButton } from "../../MetaMaskLogoButton"; import { Notice, NoticeTypes } from "../../Notice"; import { EthereumTransactionButton } from "../EthereumTransactionButton"; import { SellFeeNotice, ApproveNoticeText } from "../TokensTextComponents"; import { BigNumber } from "@joincivil/typescript-types"; const SellContainer = styled.div` padding: 0; > button { margin-top: 25px; width: 100%; } `; const ApproveNotice = styled(Notice)` margin-top: 20px; padding-bottom: 10px; font-size: 14px; > div { display: flex; flex-direction: column; align-items: center; } > div > button { margin: 20px; } `; export interface UniswapSellProps { ethExchangeRate: number; cvlToSell: number; onSellComplete(): void; } export interface UniswapSellState { approvedTokens?: any; weiToReceive?: BigNumber; } export class UniswapSell extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: UniswapSellProps) { super(props); this.state = {}; } public async componentDidUpdate(prevProps: UniswapSellProps): Promise { if (prevProps.cvlToSell !== this.props.cvlToSell) { const uniswap = this.context.uniswap; const weiToReceive = await uniswap.quoteCVLToETH(uniswap.parseEther(this.props.cvlToSell.toString())); this.setState({ ...this.state, weiToReceive }); } } public async componentDidMount(): Promise { const uniswap = this.context.uniswap; const approvedTokens = await uniswap.getApprovedSellAmount(); const weiToReceive = await uniswap.quoteCVLToETH( uniswap.parseEther(this.props.cvlToSell ? this.props.cvlToSell.toString() : "0"), ); this.setState({ ...this.state, approvedTokens, weiToReceive }); } public render(): JSX.Element { if (!this.state.approvedTokens || !this.state.weiToReceive) { return
; } const uniswap = this.context.uniswap; const { ethExchangeRate } = this.props; const cvlWei = uniswap.parseEther((this.props.cvlToSell || "0").toString()); const weiToReceive = this.state.weiToReceive; const etherToReceive = uniswap.weiToEtherNumber(this.state.weiToReceive); const usdAmount = etherToReceive * ethExchangeRate; let usdPerCVL: number = 0; let usdTotal: number = 0; if (this.props.cvlToSell === 0) { return ( null} disabled> Estimate Proceeds ); } if (this.props.cvlToSell > 0) { usdPerCVL = usdAmount / this.props.cvlToSell!; usdTotal = this.props.cvlToSell * usdPerCVL; } const summary = ( ); if (this.state.approvedTokens.lt(cvlWei)) { return ( {summary} this.approve(cvlWei)} disabled={this.props.cvlToSell === 0} onComplete={async () => this.updateApprovedSellAmount()} > Open MetaMask to approve ); } return ( {summary} this.sellCVL(cvlWei, weiToReceive)} disabled={this.props.cvlToSell === 0} onComplete={() => this.props.onSellComplete()} > Complete Sale ); } private async sellCVL(cvlWei: any, weiToReceive: any): Promise { const uniswap = this.context.uniswap; return uniswap.executeCVLToETH(cvlWei, weiToReceive); } private async approve(cvlWei: BigNumber): Promise { const uniswap = this.context.uniswap; return uniswap.setApprovedSellAmount(cvlWei); } private async updateApprovedSellAmount(): Promise { const uniswap = this.context.uniswap; const approvedTokens = await uniswap.getApprovedSellAmount(); this.setState({ ...this.state, approvedTokens }); } } ================================================ FILE: packages/components/src/Tokens/sell/UniswapSellSection.tsx ================================================ import * as React from "react"; import { UniswapSell } from "./UniswapSell"; import { Query } from "react-apollo"; import gql from "graphql-tag"; import { UniswapCvlEthConverter } from "./UniswapCvlEthConverter"; const ethPriceQuery = gql` query { storefrontEthPrice } `; export interface UniswapSellSectionProps { onComplete(): void; } export interface UniswapSellSectionState { cvlToSell: number; etherToReceive: number; } export class UniswapSellSection extends React.Component { constructor(props: UniswapSellSectionProps) { super(props); this.state = { cvlToSell: 0, etherToReceive: 0 }; } public render(): JSX.Element { const updatePrice = this.updatePrice.bind(this); return ( query={ethPriceQuery}> {({ loading, error, data }) => { if (loading) { return null; } return ( <> ); }} ); } private async updatePrice(cvlToSell: number, etherToReceive: number): Promise { this.setState({ cvlToSell, etherToReceive }); } } ================================================ FILE: packages/components/src/Tokens/sell/__snapshots__/TokensTabSell.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Storefront / Sell Tab Coming Soon 1`] = `

Storefront / Sell Tab

Coming Soon

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Sell Tab Need to Unlock 1`] = `

You must unlock your tokens to remove the restrictions to sell. Once your tokens are unlocked, you will be eligible to sell them here.

Unlock Tokens

All first-time token purchasers must unlock their tokens by participating in community votes and the general oversight of Civil. This is to prevent speculators from affecting the price of Civil tokens. Learn more in the FAQ below.

Unlocking your tokens is straightforward, and you only have to do this once. Simply transfer at least 50 percent of your purchased tokens into the voting balance . And that’s it.

Unlock My Tokens

Storefront / Sell Tab

Need to Unlock

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Sell Tab Sell Tab 1`] = `
notes for storybooks: if you are actually trying to buy you might have troubles. make sure the storefrontEthPrice graphql mock gets updated to the current price.

Storefront / Sell Tab

Sell Tab

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Storefront / Sell Tab Uniswap 1`] = `
ethExchangeRate: 0.5
cvlToSell: 100
etherToReceive: 50

Storefront / Sell Tab

Uniswap

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/ToolTip.tsx ================================================ import * as React from "react"; import * as ReactDOM from "react-dom"; import styled from "styled-components"; import { colors, fonts } from "./styleConstants"; export interface ToolTipTheme { toolTipDefaultWidth?: number; toolTipTextAlign?: string; toolTipColorEnabled?: string; toolTipColorDisabled?: string; } export interface ToolTipProps { explainerText: React.ReactNode; disabled?: boolean; positionBottom?: boolean; verticalOffset?: number; className?: string; // for use as styled component width?: number; theme?: ToolTipTheme; onClick?(e: React.MouseEvent): void; } export interface ToolTipState { open: boolean; } export interface TipContainerProps { top?: number; left?: number; } const TipContainer = styled.div` position: absolute; top: ${(props: TipContainerProps) => props.top || 0}px; left: ${(props: TipContainerProps) => props.left || 0}px; height: 0px; `; const Tip = styled.div` position: absolute; ${(props: ToolTipProps) => (props.positionBottom ? "top: 30px" : "bottom: 10px")}; left: 7px; ${(props: ToolTipProps) => props.verticalOffset ? `margin-${props.positionBottom ? "top" : "bottom"}: ${props.verticalOffset}px` : ""}; transform: translateX(-50%); width: ${(props: ToolTipProps) => props.width || (props.theme && props.theme.toolTipDefaultWidth) || 260}px; color: ${colors.basic.WHITE}; background: rgba(21, 21, 21, 0.9); border-radius: 3px; padding: 15px; ${(props: ToolTipProps) => props.theme && props.theme.toolTipTextAlign ? `text-align: ${props.theme.toolTipTextAlign}` : ""}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; font-weight: 400; line-height: 15px; text-transform: none; z-index: 100001; &:after { content: ""; position: absolute; left: calc(50% - 5px); top: ${(props: ToolTipProps) => (props.positionBottom ? "-6px" : "100%")}; width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-top: 6px solid rgba(21, 21, 21, 0.9); transform: ${(props: ToolTipProps) => (props.positionBottom ? "rotate(180deg)" : "rotate(0)")}; } `; // z-index to compete with wp const Wrapper = styled.div` display: inline-block; position: relative; `; const HitBox = styled.div` background-color: transparent; position: absolute; width: 100%; height: 100%; min-width: 30px; min-height: 30px; top: 0; left: 0; z-index: 100001; `; export class ToolTip extends React.Component { public divEl: HTMLDivElement | null; public bucket: HTMLDivElement = document.createElement("div"); constructor(props: ToolTipProps) { super(props); this.divEl = null; this.state = { open: false, }; } public componentDidMount(): void { document.body.appendChild(this.bucket); } public componentWillUnmount(): void { this.bucket.remove(); } public render(): JSX.Element { let tip = null; let hitBox = null; if (this.state.open) { tip = ReactDOM.createPortal( {this.props.explainerText} , this.bucket, ); hitBox = ; } return ( (this.divEl = el)} onMouseLeave={this.onMouseLeave} onMouseEnter={this.onMouseEnter} onClick={this.props.onClick} className={this.props.className} > {tip} {hitBox} {this.props.children} ); } private getLeft = (): number => { const box = this.divEl!.getBoundingClientRect(); return box.left - 5 + box.width / 2; }; private getTop = (): number => { const box = this.divEl!.getBoundingClientRect(); const scrollDist = (document.documentElement || document.body.parentNode || document.body).scrollTop; return scrollDist + box.top; }; private onMouseEnter = (): void => { this.setState({ open: true }); }; private onMouseLeave = (): void => { this.setState({ open: false }); }; } ================================================ FILE: packages/components/src/TransactionButton.tsx ================================================ import * as React from "react"; import { TwoStepEthTransaction } from "@joincivil/core"; import { EthSignedMessage, EthAddress, TxHash } from "@joincivil/typescript-types"; import { Button, InvertedButton, DarkButton, buttonSizes } from "./Button"; import { CivilContext, ICivilContext } from "./context"; import { Modal } from "./Modal"; import { ProgressModalContentInProgress, ProgressModalContentSuccess, ProgressModalContentError, } from "./ProgressModalContent"; import { Subscription } from "rxjs"; export interface TransactionButtonState { name: string; error: string; step: number; disableButton: boolean; currentAccount?: EthAddress; ethereumUpdates?: Subscription; } export interface TransactionButtonModalFlowState { modalOpen?: boolean; isPreTransactionModalOpen?: boolean; isWaitingTransactionModalOpen?: boolean; metaMaskRejectionModal?: boolean; metaMaskErrorModal?: boolean; completeModalOpen?: boolean; startTransaction?(): any; cancelTransaction?(): any; } export interface Transaction { progressEventName?: string; transaction(): Promise | EthSignedMessage | void>; preTransaction?(): any; requireBeforeTransaction?(): Promise; postTransaction?(result: any, txHash?: TxHash): any; handleTransactionError?(err: any, txHash?: TxHash): any; handleTransactionHash?(txhash?: TxHash): void; onTransactionError?(err: any, txHash?: TxHash): any; // function passed in here does not "handle" the tx error, but might do something extra with it (such as log an error) } export interface TransactionButtonProps { transactions: Transaction[]; disabled?: boolean; Button?: React.FunctionComponent; preExecuteTransactions?(): any; postExecuteTransactions?(): any; onMobileClick?(): any; } export enum progressModalStates { IN_PROGRESS = "IN_PROGRESS", SUCCESS = "SUCCESS", ERROR = "ERROR", } export interface TransactionButtonModalContentComponentsProps { [index: string]: JSX.Element | undefined; [progressModalStates.IN_PROGRESS]?: JSX.Element | undefined; [progressModalStates.SUCCESS]?: JSX.Element | undefined; [progressModalStates.ERROR]?: JSX.Element | undefined; } export interface TransactionButtonModalProps { modalComponent?: JSX.Element; modalContentComponents?: TransactionButtonModalContentComponentsProps; } export interface TransitionButtonModalState { isProgressModalVisible: boolean; progressModalState?: string; } const DEFAULT_MODAL_COMPONENTS: TransactionButtonModalContentComponentsProps = { [progressModalStates.IN_PROGRESS]: , [progressModalStates.SUCCESS]: , [progressModalStates.ERROR]: , }; export interface TransactionButtonInnerProps { disabled?: boolean; step?: number; children?: React.ReactNode | React.ReactNode[]; onClick(event?: any): void; } export const PrimaryTransactionButton: React.FunctionComponent = ( props: TransactionButtonInnerProps, ): JSX.Element => { return ( ); }; export const InvertedTransactionButton: React.FunctionComponent = ( props: TransactionButtonInnerProps, ): JSX.Element => { return ( props.onClick(e)} disabled={props.disabled} size={buttonSizes.MEDIUM}> {props.step === 1 && "Waiting for confirmation..."} {props.step === 2 && "Processing..."} {props.step === 0 && props.children} ); }; export const DarkTransactionButton: React.FunctionComponent = ( props: TransactionButtonInnerProps, ): JSX.Element => { return ( props.onClick(e)} disabled={props.disabled} size={buttonSizes.MEDIUM}> {props.step === 1 && "Waiting for confirmation..."} {props.step === 2 && "Processing..."} {props.step === 0 && props.children} ); }; export class TransactionButtonNoModal extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; constructor(props: TransactionButtonProps) { super(props); this.state = { name: "", error: "", step: 0, disableButton: !!props.disabled, }; } public componentDidUpdate(prevProps: TransactionButtonProps): void { if (prevProps.disabled !== this.props.disabled) { this.setState({ disableButton: !!this.props.disabled }); } } public render(): JSX.Element { const ButtonComponent = this.props.Button || PrimaryTransactionButton; // Some responsive css trickery to return ( <> {this.state.error} {this.props.children} ); } private onClick = async () => { const { civil } = this.context; if (civil && civil.currentProvider) { await civil.currentProviderEnable(); const currentAccount = await civil.accountStream.first().toPromise(); if (currentAccount) { this.setState({ currentAccount }); if (this.props.preExecuteTransactions) { setImmediate(() => this.props.preExecuteTransactions!()); } return this.executeTransactions(this.props.transactions.slice().reverse()); } else { this.setState({ error: "No Ethereum Account Found. You may need to install MetaMask and grant account access for this app.", }); } } else { this.setState({ error: "No Ethereum Provider Found. You may need to install MetaMask or another Web3 wallet and grant account access for this app.", }); } }; private executeTransactions = async (transactions: Transaction[]): Promise => { const currTransaction = transactions.pop(); if (currTransaction) { if (currTransaction.preTransaction) { setImmediate(() => currTransaction.preTransaction!()); } let txHash: TxHash | undefined; try { if (currTransaction.requireBeforeTransaction) { await currTransaction.requireBeforeTransaction(); } this.setState({ step: 1, disableButton: true }); const pending = await currTransaction.transaction(); txHash = pending && "txHash" in pending ? pending.txHash : undefined; this.setState({ step: 2 }); if (currTransaction.handleTransactionHash && pending) { if ("txHash" in pending) { currTransaction.handleTransactionHash(txHash); } else { currTransaction.handleTransactionHash(); } } if (pending) { let receipt = pending; if ("awaitReceipt" in pending) { receipt = await pending.awaitReceipt(); } if (!transactions.length) { this.setState({ step: 0, disableButton: false }); } if (currTransaction.postTransaction) { currTransaction.postTransaction(receipt, txHash); } } return this.executeTransactions(transactions); } catch (err) { console.log("error executing transaction", err); this.setState({ step: 0, disableButton: false }); if (currTransaction.handleTransactionError) { setImmediate(() => currTransaction.handleTransactionError!(err, txHash)); } if (currTransaction.onTransactionError) { setImmediate(() => currTransaction.onTransactionError!(err, txHash)); } } } else if (this.props.postExecuteTransactions) { setImmediate(() => this.props.postExecuteTransactions!()); } }; } export class TransactionButton extends React.Component< TransactionButtonProps & TransactionButtonModalProps, TransitionButtonModalState > { constructor(props: TransactionButtonProps & TransactionButtonModalProps) { super(props); this.state = { isProgressModalVisible: false, }; } public render(): JSX.Element { const { modalComponent, modalContentComponents, transactions, preExecuteTransactions, postExecuteTransactions, ...other } = this.props; const progressModal = this.getProgressModalEl(modalComponent, modalContentComponents); const extendedTransactions = this.extendTransactionsHandlers(transactions); let extendedPreExecuteTransactions = this.showProgressModal; let extendedPostExecuteTransactions = this.showProgressModalSuccess; if (!!preExecuteTransactions) { extendedPreExecuteTransactions = (): void => { this.showProgressModal(); preExecuteTransactions(); }; } if (!!postExecuteTransactions) { extendedPostExecuteTransactions = (): void => { this.showProgressModalSuccess(); postExecuteTransactions(); }; } return ( <> {progressModal} ); } private extendTransactionsHandlers = (transactions: Transaction[]): Transaction[] => { return transactions.map(transaction => { if (!transaction.handleTransactionError) { transaction.handleTransactionError = this.showProgressModalError; } if (transaction.progressEventName) { const preTransaction = transaction.preTransaction; transaction.preTransaction = () => { if (preTransaction) { preTransaction(); } this.showProgressModal(transaction.progressEventName); }; } return transaction; }); }; private getProgressModalEl = ( modalComponent: JSX.Element | undefined, modalContentComponents?: any, ): JSX.Element | undefined => { const modalContentSource = (modalContentComponents && modalContentComponents[this.state.progressModalState!]) || DEFAULT_MODAL_COMPONENTS[this.state.progressModalState!]; let modalContent: JSX.Element | undefined; if (modalContentSource) { modalContent = React.cloneElement(modalContentSource as React.ReactElement, { hideModal: this.hideProgressModal, }); } if (modalComponent) { return React.cloneElement( modalComponent as React.ReactElement, { visible: this.state.isProgressModalVisible, }, modalContent, ); } return ( {modalContent} ); }; private showProgressModalSuccess = (): void => { this.setState({ progressModalState: progressModalStates.SUCCESS }); }; private showProgressModalError = (): void => { this.setState({ progressModalState: progressModalStates.ERROR }); }; private showProgressModal = (progressModalState: string = progressModalStates.IN_PROGRESS): void => { this.setState({ isProgressModalVisible: true, progressModalState }); }; private hideProgressModal = (): void => { this.setState({ isProgressModalVisible: false }); }; } export class TransactionDarkButton extends React.Component< TransactionButtonProps & TransactionButtonModalProps, TransitionButtonModalState > { public render(): JSX.Element { return ; } } export class TransactionInvertedButton extends React.Component< TransactionButtonProps & TransactionButtonModalProps, TransitionButtonModalState > { public render(): JSX.Element { return ; } } ================================================ FILE: packages/components/src/Tutorial/Tutorial.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { TutorialInfo } from "./TutorialInfo"; import { TutorialQuestion } from "./TutorialQuestion"; import { TutorialTopicIntro } from "./TutorialTopicIntro"; import { TutorialTopicCompleted } from "./TutorialTopicCompleted"; const TopicTutorial: React.FunctionComponent = props => ( <>

What is Civil?

Civil is a decentralized network for trustworthy and sustainable journalism. It is founded on the principle that a free press is essential to a fair and just society.

Our community-run model providing members a say and share in the project’s operations and long-term evolution.

More than 125 journalists representing 18 independent newsrooms, from Chicago to Singapore, are already part of the Civil community. And we’re just getting started!

); const TopicIntro: React.FunctionComponent = props => ( <>

You’ll learn

What is Civil, and what makes us different?

How does a Newsroom join the Civil network?

What are Civil tokens (CVL)?

What is the Civil Registry?

); const onClickFunc = () => { console.log("clicked!"); }; const tutorial = { tutorialTopicIntroHeader: "Topic 1: How to use Civil tokens", tutorialTopicIntroInfo: , tutorialContent: , quizName: "Quiz: Considerations before buying tokens", question: "Which of the following is important to you when purchasing a token?", options: [{ text: "Option 1" }, { text: "Option 2" }, { text: "Option 3" }], answer: "Option 1", completedHeader: "Nice! You’ve completed Topic 1", completedText: "Buying tokens, like any financial decision, is a risk. The price of tokens can fluctuate depending on various factors. It’ a good rule of thumb to look at the team behind the token – the founders, the advisors – as well as the token design and its supply. It’s also important to diversify your portfolio across many investment vehicles – crypto assets and non-crypto assets.", continueBtnText: "Continue to topic 2", }; storiesOf("Common / Tutorial", module) .add("Tutorial Topic Intro", () => { return ( ); }) .add("Tutorial Info", () => { return ( ); }) .add("Tutorial Question", () => { return ( ); }) .add("Tutorial Topic Completed", () => { return ( ); }); ================================================ FILE: packages/components/src/Tutorial/TutorialFooter.tsx ================================================ import * as React from "react"; import { TutorialFooterFull, TutorialFooterWrap } from "./TutorialStyledComponents"; export interface TutorialFooterProps { questionResult?: string; floatRight?: boolean; } export const TutorialFooter: React.FunctionComponent = props => { return ( {props.children} ); }; ================================================ FILE: packages/components/src/Tutorial/TutorialInfo.tsx ================================================ import * as React from "react"; import { TutorialContentWrap, TutorialSlideContent, TutorialInvertedBtn, TutorialBtn, } from "./TutorialStyledComponents"; import { TutorialFooter } from "./TutorialFooter"; import { TutorialProgress } from "./TutorialProgress"; export interface TutorialInfoProps { activeSlide: number; totalSlides: number; content: string | JSX.Element; onClickPrev(e: any): void; onClickNext(e: any): void; } export const TutorialInfo: React.FunctionComponent = props => { return ( <> {props.content} Back Continue ); }; ================================================ FILE: packages/components/src/Tutorial/TutorialProgress.tsx ================================================ import * as React from "react"; import { TutorialProgressContain, TutorialProgressBar, TutorialProgressBarActive, TutorialProgressBarSlideCount, } from "./TutorialStyledComponents"; export interface TutorialProgressProps { activeSlide: number; totalSlides: number; showSlideCount?: boolean; } export const TutorialProgress: React.FunctionComponent = props => { return ( <> {props.showSlideCount && ( {props.activeSlide} of {props.totalSlides} )} ); }; ================================================ FILE: packages/components/src/Tutorial/TutorialQuestion.tsx ================================================ import * as React from "react"; import { TutorialQuizName, TutorialQuizQuestion, TutorialContentWrap, TutorialInvertedBtn, TutorialBtn, TutorialFooterLeft, } from "./TutorialStyledComponents"; import { IncorrectText, SelectCorrectText, CorrectText } from "./TutorialTextComponents"; import { TutorialFooter } from "./TutorialFooter"; import { TutorialProgress } from "./TutorialProgress"; import { TutorialRadio } from "./TutorialRadio"; import { RadioInput } from "../input"; import { HollowGreenCheck, HollowRedNoGood } from "@joincivil/elements"; export interface Options { text: string; } export interface TutorialQuestionProps { activeSlide: number; totalSlides: number; quizName: string | JSX.Element; quizId: string; question: string; options: Options[]; answer: string; onClickPrev(e: any): void; onClickNext(e: any): void; } export interface TutorialQuestionStates { checkAnswerDisabled: boolean; usersAnswerValue: string; usersAnswerResult: string; resetQuestion: boolean; } export class TutorialQuestion extends React.Component { public static getDerivedStateFromProps( props: TutorialQuestionProps, state: TutorialQuestionStates, ): TutorialQuestionStates { if (state.resetQuestion) { return { checkAnswerDisabled: true, usersAnswerValue: "", usersAnswerResult: "", resetQuestion: false, }; } return { ...state, }; } public constructor(props: any) { super(props); this.state = { checkAnswerDisabled: true, usersAnswerValue: "", usersAnswerResult: "", resetQuestion: false, }; } public render(): JSX.Element { return ( <> Quiz: {this.props.quizName} {this.props.activeSlide}. {this.props.question}
{this.props.options.map((option, idx) => ( {option.text} ))}
{this.state.usersAnswerResult === "correct" ? ( <>

Continue ) : this.state.usersAnswerResult === "incorrect" ? ( <>

{this.props.answer}

this.checkAnswer()}> Check ) : ( <> Back to Tutorial this.checkAnswer()}> Check )}
); } private enableCheckAnswerBtn = (name: string, value: any) => { this.setState({ checkAnswerDisabled: false, usersAnswerValue: value }); }; private checkAnswer = () => { if (this.state.usersAnswerValue === this.props.answer) { this.setState({ usersAnswerResult: "correct" }); } else { this.setState({ usersAnswerResult: "incorrect", checkAnswerDisabled: true }); } }; private resetQuestion = (event: any) => { const radioButtons = Array.from(document.querySelectorAll("input[type=radio]")); radioButtons.forEach(radio => { const radioInput = radio as HTMLInputElement; radioInput.checked = false; }); this.props.onClickNext(event); this.setState({ resetQuestion: true }); }; } ================================================ FILE: packages/components/src/Tutorial/TutorialRadio.tsx ================================================ import * as React from "react"; import { TutorialRadioBtnCircle, TutorialRadioBtnContain, TutorialRadioBtn } from "./TutorialStyledComponents"; export interface TutorialOptionProps { onChange?: any; value: any; name?: string; } export const TutorialRadio: React.FunctionComponent = props => { let input: any; const { onChange, children, value, name } = props; const clickHandler = () => { input.checked = true; if (onChange) { onChange(name, input.value); } }; return ( (input = ref)} /> {children} ); }; ================================================ FILE: packages/components/src/Tutorial/TutorialStyledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { Button, InvertedButton, SecondaryButton } from "../Button"; export interface TutorialProgressBarProps { activeSlide: number; totalSlides: number; } export const TutorialProgressContain = styled.div` padding: 20px 0 50px; width: 100%; `; export const TutorialProgressBar = styled.div` background-color: ${colors.accent.CIVIL_GRAY_4}; border-radius: 3px; height: 6px; margin: 0 auto; max-width: 900px; position: relative; width: 100%; `; export const TutorialProgressBarActive = styled.div` background-color: ${colors.accent.CIVIL_BLUE}; border-radius: 3px; height: 6px; width: ${(props: TutorialProgressBarProps) => ((props.activeSlide / props.totalSlides) * 100).toString()}%; `; export const TutorialProgressBarSlideCount = styled.div` color: ${colors.accent.CIVIL_BLUE}; font-family: ${fonts.SANS_SERIF}; font-size: 12px; font-weight: bold; left: ${(props: TutorialProgressBarProps) => "calc(" + ((props.activeSlide / props.totalSlides) * 100).toString() + "% - 25px)"}; position: absolute; text-align: center; top: -20px; width: 50px; `; export interface TutorialStyleProps { centerContent?: boolean; } export const TutorialContentWrap = styled.div` font-family: ${fonts.SANS_SERIF}; margin: 0 auto 50px; max-width: 710px; min-height: 500px; position: relative; text-align: ${(props: TutorialStyleProps) => (props.centerContent ? "center" : "left")}; svg { display: block; margin: 0 auto; } button { padding: 14px 30px; width: auto; } `; export const TutorialSlideContent = styled.div` margin: 0 auto; max-width: 540px; h2 { font-size: 24px; line-height: 29px; } p, li { font-size: 18px; line-height: 33px; } `; export const TutorialTopicTitle = styled.div` font-size: 32px; font-weight: 300; letter-spacing: -0.87px; line-height: 39px; margin-bottom: 50px; b { font-weight: 800; } `; export const TutorialTopicInfo = styled.div` font-size: 21px; font-weight: 300; letter-spacing: -0.11px; line-height: 31px; margin-bottom: 30px; `; export interface TutorialFooterFullProps { questionResult?: string; floatRight?: boolean; } export const TutorialFooterFull = styled.div` background-color: ${(props: TutorialFooterFullProps) => props.questionResult === "correct" ? "rgba(41,203,66,0.2)" : props.questionResult === "incorrect" ? "#FFE6E8" : colors.accent.CIVIL_GRAY_4}; bottom: 0; display: flex; justify-content: center; padding: 40px 20px 50px; position: fixed; width: 100%; `; export const TutorialFooterWrap = styled.div` align-items: center; display: flex; justify-content: ${(props: TutorialFooterFullProps) => (props.floatRight ? "flex-end" : "space-between")}; max-width: 900px; width: 100%; `; export const TutorialFooterLeft = styled.div` align-items: flex-start; display: flex; font-family: ${fonts.SANS_SERIF}; svg { margin-right: 15px; } h3 { font-size: 18px; font-weight: 700; line-height: 28px; margin: 0 0 5px; } p { color: ${colors.accent.CIVIL_GRAY_0}; font-size: 14px; line-height: 22px; margin: 0 0 25px; } span { color: ${colors.accent.CIVIL_RED}; display: block; font-size: 14px; font-weight: 500; line-height: 17px; } `; export const TutorialBtn = styled(Button)` border-radius: 1px; font-size: 14px; font-weight: 700; letter-spacing: 0; padding: 14px; text-transform: none; width: 160px; `; export const TutorialInvertedBtn = styled(InvertedButton)` background-color: transparent; border-radius: 1px; font-size: 14px; font-weight: 700; letter-spacing: 0; padding: 12px; text-transform: none; width: 160px; `; export const TutorialTextBtn = styled(InvertedButton)` background-color: transparent; border: none; font-size: 13px; font-weight: bold; letter-spacing: 0.3px; line-height: 14px; padding: 12px; text-transform: none; width: 160px; &:hover, &:focus { background-color: transparent; color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } `; export const TutorialQuizName = styled.h2` font-family: ${fonts.SANS_SERIF}; font-size: 27px; font-weight: 300; letter-spacing: -0.14px; line-height: 30px; margin: 10px 0 40px -65px; `; export const TutorialQuizQuestion = styled.h3` font-family: ${fonts.SANS_SERIF}; font-size: 24px; font-weight: bold; line-height: 29px; position: relative; span { font-size: 18px; left: -20px; line-height: 28px; position: absolute; text-align: right; top: 0; } `; export const TutorialCompletedHeader = styled.p` color: ${colors.accent.CIVIL_GRAY_0}; font-family: ${fonts.SANS_SERIF}; font-size: 28px; font-weight: 700; letter-spacing: -0.58px; line-height: 39px; margin: 30px 0; text-align: center; `; export const TutorialCompletedP = styled.p` color: ${colors.accent.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 18px; letter-spacing: -0.12px; line-height: 33px; margin: 30px 0 70px; `; export const TutorialRadioBtnCircle = styled.div` background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.basic.WHITE}; border-radius: 50%; box-shadow: 0 0 0 1px ${colors.accent.CIVIL_GRAY_2}; height: 16px; left: 22px; position: absolute; top: 16px; width: 16px; `; export const TutorialRadioBtnContain = styled.div` width: 100%; input { display: none; } input:checked + button { background-color: ${colors.basic.WHITE}; border: 1px solid ${colors.accent.CIVIL_BLUE}; color: ${colors.accent.CIVIL_GRAY_0}; ${TutorialRadioBtnCircle} { background-color: ${colors.accent.CIVIL_BLUE}; border: 1px solid ${colors.basic.WHITE}; box-shadow: 0 0 0 1px ${colors.accent.CIVIL_BLUE}; } } `; export const TutorialRadioBtn = styled(SecondaryButton)` border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 3px; color: ${colors.accent.CIVIL_GRAY_0}; cursor: pointer; display: block; font-family: ${fonts.SANS_SERIF}; font-size: 16px; letter-spacing: 0; line-height: 26px; margin-bottom: 15px; padding: 12px 15px 12px 55px !important; position: relative; text-align: left; text-transform: none; transition: border-color 0.2s ease; width: 100% !important; &:hover { background-color: ${colors.basic.WHITE}; border-color: ${colors.accent.CIVIL_BLUE}; color: ${colors.accent.CIVIL_GRAY_0}; } `; ================================================ FILE: packages/components/src/Tutorial/TutorialTextComponents.tsx ================================================ import * as React from "react"; export const SkipToQuizBtnText: React.FunctionComponent = props => <>Skip to the quiz; export const LetsGoBtnText: React.FunctionComponent = props => <>Let’s go; export const IncorrectText: React.FunctionComponent = props => <>Sorry, the correct answer is; export const SelectCorrectText: React.FunctionComponent = props => <>Select the correct answer to continue; export const CorrectText: React.FunctionComponent = props => <>You are correct; ================================================ FILE: packages/components/src/Tutorial/TutorialTopicCompleted.tsx ================================================ import * as React from "react"; import { TutorialCompletedHeader, TutorialCompletedP, TutorialContentWrap, TutorialBtn, } from "./TutorialStyledComponents"; import { HollowGreenCheck } from "@joincivil/elements"; export interface TutorialTopicCompletedProps { completedHeader: string | JSX.Element; completedText: string | JSX.Element; continueBtnText: string; lastTopic: boolean; onClickNextTopic(e: any): void; handleClose(): void; } export const TutorialTopicCompleted: React.FunctionComponent = props => { const buttonNext = props.lastTopic ? ( {props.continueBtnText} ) : ( {props.continueBtnText} ); return ( {props.completedHeader} {props.completedText} {buttonNext} ); }; ================================================ FILE: packages/components/src/Tutorial/TutorialTopicIntro.tsx ================================================ import * as React from "react"; import { TutorialTopicTitle, TutorialTopicInfo, TutorialBtn, TutorialTextBtn, TutorialContentWrap, } from "./TutorialStyledComponents"; import { SkipToQuizBtnText } from "./TutorialTextComponents"; import { TutorialFooter } from "./TutorialFooter"; import { TutorialProgress } from "./TutorialProgress"; export interface TutorialTopicIntroProps { activeSlide: number; totalSlides: number; headerText: string | JSX.Element; infoText: string | JSX.Element; onClickNext(e: any): void; onClickSkipTutorial(e: any): void; } export const TutorialTopicIntro: React.FunctionComponent = props => { return ( <> {props.headerText} {props.infoText}
Let’s go
); }; ================================================ FILE: packages/components/src/Tutorial/__snapshots__/Tutorial.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Tutorial Tutorial Info 1`] = `

What is Civil?

Civil is a decentralized network for trustworthy and sustainable journalism. It is founded on the principle that a free press is essential to a fair and just society.

Our community-run model providing members a say and share in the project’s operations and long-term evolution.

More than 125 journalists representing 18 independent newsrooms, from Chicago to Singapore, are already part of the Civil community. And we’re just getting started!

Common / Tutorial

Tutorial Info

Story Source

            
< TutorialInfo
  
content = { <TopicTutorial /> }

  
activeSlide = { 1 }

  
totalSlides = { 3 }

  
onClickPrev = { onClickFunc }

  
onClickNext = { onClickFunc }
/>

Prop Types

" TutorialInfo " Component

No propTypes defined!
`; exports[`Storyshots Common / Tutorial Tutorial Question 1`] = `
1 of 3

Quiz: Quiz: Considerations before buying tokens

1 . Which of the following is important to you when purchasing a token?

Common / Tutorial

Tutorial Question

Story Source

            
< TutorialQuestion
  
quizId = " topic1 "

  
quizName = " Quiz: Considerations before buying tokens "

  
question = " Which of the following is important to you when pu… "

  
answer = " Option 1 "

  
options = { [ { text : 'Option 1' } , { text : 'Option 2' } , { text : 'Option 3' } ] }

  
activeSlide = { 1 }

  
totalSlides = { 3 }

  
onClickPrev = { onClickFunc }

  
onClickNext = { onClickFunc }
/>

Prop Types

" TutorialQuestion " Component

No propTypes defined!
`; exports[`Storyshots Common / Tutorial Tutorial Topic Completed 1`] = `

Nice! You’ve completed Topic 1

Buying tokens, like any financial decision, is a risk. The price of tokens can fluctuate depending on various factors. It’ a good rule of thumb to look at the team behind the token – the founders, the advisors – as well as the token design and its supply. It’s also important to diversify your portfolio across many investment vehicles – crypto assets and non-crypto assets.

Common / Tutorial

Tutorial Topic Completed

Story Source

            
< TutorialTopicCompleted
  
completedHeader = " Nice! You’ve completed Topic 1 "

  
completedText = " Buying tokens, like any financial decision, is a r… "

  
continueBtnText = " Continue to topic 2 "

  
lastTopic = { false }

  
onClickNextTopic = { onClickFunc }

  
handleClose = { onClickFunc }
/>

Prop Types

" TutorialTopicCompleted " Component

No propTypes defined!
`; exports[`Storyshots Common / Tutorial Tutorial Topic Intro 1`] = `
Topic 1: How to use Civil tokens

You’ll learn

What is Civil, and what makes us different?

How does a Newsroom join the Civil network?

What are Civil tokens (CVL)?

What is the Civil Registry?

Common / Tutorial

Tutorial Topic Intro

Story Source

            
< TutorialTopicIntro
  
headerText = " Topic 1: How to use Civil tokens "

  
infoText = { <TopicIntro /> }

  
activeSlide = { 0 }

  
totalSlides = { 0 }

  
onClickNext = { onClickFunc }

  
onClickSkipTutorial = { onClickFunc }
/>

Prop Types

" TutorialTopicIntro " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/Tutorial/index.ts ================================================ export * from "./TutorialFooter"; export * from "./TutorialInfo"; export * from "./TutorialQuestion"; export * from "./TutorialStyledComponents"; export * from "./TutorialTextComponents"; export * from "./TutorialTopicCompleted"; export * from "./TutorialTopicIntro"; export * from "./TutorialProgress"; export * from "./TutorialRadio"; ================================================ FILE: packages/components/src/UserStatement/RequestAppealStatement.tsx ================================================ import * as React from "react"; import RichTextEditor from "react-rte"; import { TextareaInput } from "../input"; import { buttonSizes, CancelButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { MetaMaskLogoButton } from "../"; import { StyledErrorMessage, StyledUserStatementHeaderOuter, StyledUserStatementHeader, StatementHeaderHeading, StatementHeaderNewsroomName, StyledUserStatementBodyOuter, StyledUserStatementBody, CopyLarge, StyledLi, StyledLiContent, StyledOl, CopySmall, StyledLink, BodyHeader, BodyCopyHelper, SectionForm, SectionFormHeader, SectionFormCopyHelper, StyledTextareaContainer, SectionDeposit, StyledDepositLabel, StyledDepositAmount, SectionActions, } from "./styledComponents"; export interface RequestAppealStatementProps { constitutionURI: string; governanceGuideURI: string; listingURI: string; appealFee: string; judgeAppealLen: string; newsroomName: string; transactions: any[]; modalContentComponents?: { [index: string]: JSX.Element }; updateStatementValue(key: string, value: any): void; postExecuteTransactions?(): void; } export interface RequestAppealStatementState { summaryValue: string; detailsValue: any; } const SUMMARY_MAX_LENGTH = 120; export class RequestAppealStatement extends React.Component { constructor(props: RequestAppealStatementProps) { super(props); this.state = { summaryValue: "", detailsValue: RichTextEditor.createEmptyValue(), }; } public render(): JSX.Element { return ( <> Request Appeal {this.props.newsroomName} A deposit of {this.props.appealFee} tokens is required to request an appeal. Read our{" "} governance guide before you begin. State reasons for your request to appeal Deposit CVL tokens to request to appeal After a request is submitted, the Civil Council will have {this.props.judgeAppealLen} to rule on the appeal. State reasons for your appeal request Enter a summary of the reasons for your appeal request (Max 120 characters) Write 1-2 sentences about why you’re appealing this challenge (required) Max character limit: {SUMMARY_MAX_LENGTH.toString()} Add details and evidence to support your statements. (required) Help the Civil Council consider your request by providing as much information as possible to support your case Total Token Deposit {this.props.appealFee}
Confirm and Deposit CVL {this.renderHelperMessage()}
Cancel
); } private isFormInvalid = (): boolean => { const { summaryValue, detailsValue } = this.state; const details = document.createElement("div"); details.innerHTML = detailsValue.toString("html"); return !summaryValue || !summaryValue.length || !details.innerText.length; }; private renderHelperMessage = (): JSX.Element => { if (this.isFormInvalid()) { return Please check that all fields have been filled out; } return <>This will pop up a separate MetaMask window to confirm your transactions.; }; private handleSummaryValueChange = (name: string, summaryValue: string) => { this.setState({ summaryValue }); this.props.updateStatementValue("summary", summaryValue); }; private handleDetailsValueChange = (detailsValue: any) => { this.setState({ detailsValue }); this.props.updateStatementValue("details", detailsValue); }; } ================================================ FILE: packages/components/src/UserStatement/SubmitAppealChallengeStatement.tsx ================================================ import * as React from "react"; import RichTextEditor from "react-rte"; import { TextareaInput } from "../input"; import { buttonSizes, CancelButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { MetaMaskLogoButton } from "../"; import { StyledUserStatementHeaderOuter, StyledUserStatementHeader, StatementHeaderHeading, StatementHeaderNewsroomName, StyledUserStatementBodyOuter, StyledUserStatementBody, CopyLarge, StyledLi, StyledLiContent, StyledOl, CopySmall, StyledLink, BodyHeader, BodyCopyHelper, SectionForm, SectionFormHeader, SectionFormCopyHelper, StyledTextareaContainer, SectionDeposit, StyledDepositLabel, StyledDepositAmount, SectionActions, } from "./styledComponents"; export interface SubmitAppealChallengeStatementProps { constitutionURI?: string; governanceGuideURI?: string; listingURI?: string; appealFee?: string; challengeAppealCommitLen?: string; challengeAppealRevealLen?: string; appealVotePercentage?: string; newsroomName?: string; transactions: any[]; modalContentComponents?: { [index: string]: JSX.Element }; updateStatementValue(key: string, value: any): void; postExecuteTransactions?(): void; } export interface SubmitAppealChallengeStatementState { summaryValue: string; detailsValue: any; } const SUMMARY_MAX_LENGTH = 120; export class SubmitAppealChallengeStatement extends React.Component< SubmitAppealChallengeStatementProps, SubmitAppealChallengeStatementState > { constructor(props: SubmitAppealChallengeStatementProps) { super(props); this.state = { summaryValue: "", detailsValue: RichTextEditor.createEmptyValue(), }; } public render(): JSX.Element { return ( <> Challenge Granted Appeal {this.props.newsroomName} A deposit of {this.props.appealFee} tokens is required to challenge a granted appeal. Read our governance guide before you begin. State reasons for your challenge of the granted appeal Deposit CVL tokens to challenge After a challenge is submitted, the CVL token-holding community will have have{" "} {this.props.challengeAppealCommitLen} to commit their votes, followed by{" "} {this.props.challengeAppealRevealLen} to confirm their votes. Only a supermajority ( {this.props.appealVotePercentage}) from the community can overturn the Civil Council's decision. State reasons for your challenge Enter a summary of the reasons for your challenge (Max 120 characters) Write 1-2 sentences about why you’re challenging this granted appeal (required) Max character limit: {SUMMARY_MAX_LENGTH.toString()} Add details and evidence to support your statements. (required) Help inform the Civil community to vote accordingly by providing as much information as possible to support your case. Total Token Deposit {this.props.appealFee}
Confirm and Deposit CVL This will pop up a separate MetaMask window to confirm your transactions.
Cancel
); } private isFormInvalid = (): boolean => { const { summaryValue, detailsValue } = this.state; const details = document.createElement("div"); details.innerHTML = detailsValue.toString("html"); return !summaryValue || !summaryValue.length || !details.innerText.length; }; private handleSummaryValueChange = (name: string, summaryValue: string) => { this.setState({ summaryValue }); this.props.updateStatementValue("summary", summaryValue); }; private handleDetailsValueChange = (detailsValue: any) => { this.setState({ detailsValue }); this.props.updateStatementValue("details", detailsValue); }; } ================================================ FILE: packages/components/src/UserStatement/SubmitChallengeStatement.tsx ================================================ import * as React from "react"; import RichTextEditor from "react-rte"; import { TextareaInput } from "../input"; import { buttonSizes, CancelButton } from "../Button"; import { TransactionButtonNoModal } from "../TransactionButton"; import { MetaMaskLogoButton } from "../"; import { Checkbox, CheckboxSizes } from "../input/Checkbox"; import { StyledErrorMessage, StyledUserStatementHeaderOuter, StyledUserStatementHeader, StatementHeaderHeading, StatementHeaderNewsroomName, StyledUserStatementBodyOuter, StyledUserStatementBody, CopyLarge, StyledLi, StyledLiContent, StyledOl, CopySmall, StyledLink, BodyHeader, BodyCopyHelper, SectionForm, SectionFormHeader, SectionFormCopyHelper, SectionConfirmChallenge, StyledTextareaContainer, SectionDeposit, StyledDepositLabel, StyledDepositAmount, SectionActions, } from "./styledComponents"; export interface SubmitChallengeStatementProps { constitutionURI?: string; governanceGuideURI?: string; listingURI?: string; minDeposit?: string; commitStageLen?: string; revealStageLen?: string; newsroomName?: string; transactions: any[]; modalContentComponents?: { [index: string]: JSX.Element }; updateStatementValue(key: string, value: any): void; postExecuteTransactions?(): void; } export interface SubmitChallengeStatementState { summaryValue: string; citeConstitutionValue: any; detailsValue: any; didConfirmChallenge: boolean; } const SUMMARY_MAX_LENGTH = 120; export class SubmitChallengeStatement extends React.Component< SubmitChallengeStatementProps, SubmitChallengeStatementState > { public state = { summaryValue: "", citeConstitutionValue: RichTextEditor.createEmptyValue(), detailsValue: RichTextEditor.createEmptyValue(), didConfirmChallenge: false, }; public render(): JSX.Element { return ( <> Challenge Newsroom {this.props.newsroomName} A deposit of {this.props.minDeposit} tokens is required to challenge a newsroom. Read our{" "} governance guide before you begin. State reasons for your challenge Deposit CVL tokens to challenge After a challenge is submitted, the CVL token-holding community will have have{" "} {this.props.commitStageLen} to commit their votes, followed by{" "} {this.props.revealStageLen} to confirm their votes. State reasons for your challenge Enter a summary of the reasons for your challenge (Max 120 characters) Write 1-2 sentences about why you’re challenging this newsroom (required) Max character limit: {SUMMARY_MAX_LENGTH.toString()} Please cite the section or principles of the Civil Constitution that you believe the Newsroom has violated. (required) See Civil Constitution Add details and evidence to support your statements. (required) Help inform the Civil community to vote accordingly by providing as much information as possible to support your case. Total Token Deposit {this.props.minDeposit}
I understand that once I confirm this challenge, I can not withdraw it, and that I communicated my concerns with Newsroom.
Confirm and Deposit CVL {this.renderHelperMessage()}
Cancel
); } private isFormInvalid = (): boolean => { const { summaryValue, citeConstitutionValue, detailsValue, didConfirmChallenge } = this.state; const citeConstitution = document.createElement("div"); citeConstitution.innerHTML = citeConstitutionValue.toString("html"); const details = document.createElement("div"); details.innerHTML = detailsValue.toString("html"); return ( !summaryValue || !summaryValue.length || !citeConstitution.innerText.length || !details.innerText.length || !didConfirmChallenge ); }; private renderHelperMessage = (): JSX.Element => { if (this.isFormInvalid()) { return Please check that all fields have been filled out; } return <>This will pop up a separate MetaMask window to confirm your transactions.; }; private handleSummaryValueChange = (name: string, summaryValue: string) => { this.setState({ summaryValue }); this.props.updateStatementValue("summary", summaryValue); }; private handleCiteConstitutionValueChange = (citeConstitutionValue: any) => { this.setState({ citeConstitutionValue }); this.props.updateStatementValue("citeConstitution", citeConstitutionValue); }; private handleDetailsValueChange = (detailsValue: any) => { this.setState({ detailsValue }); this.props.updateStatementValue("details", detailsValue); }; private toggleDidConfirmChallenge = (): void => { this.setState({ didConfirmChallenge: !this.state.didConfirmChallenge }); }; } ================================================ FILE: packages/components/src/UserStatement/UserStatement.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import StoryRouter from "storybook-react-router"; import * as React from "react"; import styled from "styled-components"; import { SubmitChallengeStatement, SubmitChallengeStatementProps } from "./SubmitChallengeStatement"; import { RequestAppealStatement, RequestAppealStatementProps } from "./RequestAppealStatement"; import { SubmitAppealChallengeStatement, SubmitAppealChallengeStatementProps } from "./SubmitAppealChallengeStatement"; const StyledDiv = styled.div` display: flex; width: 100vh; height: 100vw; background-color: #fff; `; const Container: React.FunctionComponent = ({ children }) => (
{children}
); storiesOf("Registry / User Statement Forms", module) .addDecorator(StoryRouter()) .add("Submit Challenge Statement", () => { const updateStatementValue = (name: string, value: any) => { console.log("update statement", name, value); }; const props: SubmitChallengeStatementProps = { constitutionURI: "https://civil.co", governanceGuideURI: "https://civil.co", listingURI: "https://civil.co", newsroomName: "The Sleeper Reporters", minDeposit: "100,000 CVL", commitStageLen: "10 days", revealStageLen: "7 days", transactions: [], updateStatementValue, }; return {process.env.NODE_ENV !== "test" && }; }) .add("Submit Appeal Statement", () => { const updateStatementValue = (name: string, value: any) => { console.log("update statement", name, value); }; const props: RequestAppealStatementProps = { constitutionURI: "https://civil.co", governanceGuideURI: "https://civil.co", listingURI: "https://civil.co", newsroomName: "The Sleeper Reporters", appealFee: "100,000 CVL", judgeAppealLen: "5 days", transactions: [], updateStatementValue, }; return {process.env.NODE_ENV !== "test" && }; }) .add("Submit Appeal Challenge Statement", () => { const updateStatementValue = (name: string, value: any) => { console.log("update statement", name, value); }; const props: SubmitAppealChallengeStatementProps = { constitutionURI: "https://civil.co", governanceGuideURI: "https://civil.co", listingURI: "https://civil.co", newsroomName: "The Sleeper Reporters", appealFee: "100,000 CVL", appealVotePercentage: "60%", challengeAppealCommitLen: "10 days", challengeAppealRevealLen: "7 days", transactions: [], updateStatementValue, }; return {process.env.NODE_ENV !== "test" && }; }); ================================================ FILE: packages/components/src/UserStatement/__snapshots__/UserStatement.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / User Statement Forms Submit Appeal Challenge Statement 1`] = `

Registry / User Statement Forms

Submit Appeal Challenge Statement

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / User Statement Forms Submit Appeal Statement 1`] = `

Registry / User Statement Forms

Submit Appeal Statement

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Registry / User Statement Forms Submit Challenge Statement 1`] = `

Registry / User Statement Forms

Submit Challenge Statement

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/UserStatement/index.ts ================================================ export * from "./SubmitChallengeStatement"; export * from "./SubmitAppealChallengeStatement"; export * from "./RequestAppealStatement"; ================================================ FILE: packages/components/src/UserStatement/styledComponents.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { CancelButton } from "../Button"; import { colors, fonts, mediaQueries } from "../styleConstants"; export const StyledUserStatementHeaderOuter = styled.div` background: ${colors.primary.BLACK}; display: flex; justify-content: center; padding: 67px 0 0; margin: 0 0 52px; width: 100%; `; export const StyledUserStatementHeader = styled.div` background: ${colors.accent.CIVIL_YELLOW}; box-sizing: content-box; font-family: ${fonts.SANS_SERIF}; padding: 36px 123px; max-width: 675px; ${mediaQueries.MOBILE} { padding-right: 10px; padding-left: 10px; } `; export const StatementHeaderHeading = styled.h2` color: ${colors.primary.BLACK}; font-family: ${fonts.SERIF}; font-size: 32px; line-height: 40px; margin: 0 0 23px; `; export const StatementHeaderNewsroomName = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 24px; line-height: 29px; margin: 0 0 11px; `; export const CopyLarge = styled.p` font: normal 18px/33px ${fonts.SANS_SERIF}; margin: 0 0 24px; `; export const StyledLi = styled.li` font-size: 21px; line-height: 25px; padding: 0; margin: 0 0 17px; `; export const StyledLiContent = styled.span` font-size: 18px; line-height: 33px; `; export const StyledOl = styled.ol` margin: 13px 0 21px; padding: 0 0 0 39px; `; export const CopySmall = styled.p` font-size: 14px; line-height: 20px; margin: 0 0 30px; `; export const StyledLink = styled.a` border-bottom: 1px solid transparent; color: ${colors.accent.CIVIL_BLUE}; text-decoration: none; &:hover { border-bottom-color: ${colors.accent.CIVIL_BLUE}; } `; export const StyledUserStatementBodyOuter = styled.div` display: flex; justify-content: center; ${mediaQueries.MOBILE} { margin-right: 10px; margin-left: 10px; } `; export const StyledUserStatementBody = styled.div` font-family: ${fonts.SANS_SERIF}; width: 675px; `; export const BodyHeader = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 24px; font-weight: bold; letter-spacing: -0.12px; margin: 0 0 9px; line-height: 33px; `; export const BodyCopyHelper = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; margin: 0 0 9px; line-height: 20px; `; export const SectionForm = styled.div` margin: 32px 0; `; export const SectionFormHeader = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 18px; letter-spacing: -0.1px; line-height: 21px; margin: 0 0 12px; `; export const SectionFormCopyHelper = styled.div` color: ${colors.primary.CIVIL_GRAY_2}; font-size: 14px; letter-spacing: -0.1px; line-height: 17px; margin: 0 0 5px; `; export const StyledTextareaContainer = styled.div` min-height: 110px; & textarea, & .public-DraftEditor-content { min-height: 110px; } `; export const SectionDeposit = styled.div` box-shadow: inset 0 -1px 0 0 ${colors.accent.CIVIL_GRAY_4}; display: flex; justify-content: space-between; padding: 26px; `; export const StyledDepositLabel = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-size: 18px; font-weight: bold; letter-spacing: -0.1px; line-height: 21px; `; export const StyledDepositAmount = styled(StyledDepositLabel)` text-align: right; `; export const SectionActions = styled.div` display: flex; flex-direction: row-reverse; justify-content: flex-start; padding: 50px 0 120px; ${CancelButton} { font-size: 13px; line-height: 14px; margin: 6px 27px 0 0; text-transform: none; } & ${SectionFormCopyHelper} { margin-top: 18px; max-width: 305px; text-align: left; } `; export const SectionConfirmChallenge = styled.div` display: flex; font-size: 15px; letter-spacing: -0.1px; line-height: 26px; padding: 32px 0 0; margin: 0 0 56px; & > div + div { margin: -8px 0 0 12px; } ${mediaQueries.MOBILE} { padding-right: 10px; padding-left: 10px; } `; export const StyledErrorMessage = styled.span` color: ${colors.accent.CIVIL_RED}; `; export const PullRight = styled.div` text-align: right; `; ================================================ FILE: packages/components/src/ViewTransactionLink.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { ViewTransactionLink } from "./ViewTransactionLink"; storiesOf("Common / Ethereum / viewTransactionLink", module).add("link", () => { return ( ); }); ================================================ FILE: packages/components/src/ViewTransactionLink.tsx ================================================ import * as React from "react"; import { TxHash } from "@joincivil/typescript-types"; import styled from "styled-components"; import { colors, fonts } from "./styleConstants"; import { NorthEastArrow } from "./icons"; export interface ViewTransactionLinkProps { txHash: TxHash; network: string; text?: string; } export interface LinkTheme { linkColorHover: string; linkColor: string; } const defaultProps = { theme: { linkColor: colors.accent.CIVIL_BLUE, linkColorHover: colors.accent.CIVIL_BLUE_FADED, sansSerifFont: fonts.SANS_SERIF, }, }; const StyledLink = styled.a` text-decoration: none; font-family: ${props => props.theme.sansSerifFont}; color: ${props => props.theme.linkColor}; &:hover { color: ${props => props.theme.linkColorHover}; } & path { fill: ${props => props.theme.linkColor}; } &:hover path { fill: ${props => props.theme.linkColorHover}; } `; StyledLink.defaultProps = defaultProps; export const ViewTransactionLink = (props: ViewTransactionLinkProps) => { const baseUrl = props.network === "rinkeby" ? "https://rinkeby.etherscan.io/tx/" : "https://etherscan.io/tx/"; return ( {props.text || "view transaction"} ); }; ================================================ FILE: packages/components/src/WalletOnboarding.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import apolloStorybookDecorator from "apollo-storybook-react"; import { EthSignedMessage } from "@joincivil/typescript-types"; import { WalletOnboarding } from "."; const typeDefs = ` type User { ethAddress: String } type Query { currentUser: User } input UserSignatureInput { message: String! messageHash: String! signature: String! signer: String! r: String! s: String! v: String! } type Mutation { userSetEthAddress( input: UserSignatureInput! ): String } schema { query: Query mutation: Mutation } `; const mocks = { Query: () => { return { currentUser: () => { return "ok"; }, }; }, Mutation: () => { return { userSetEthAddress: (sig: EthSignedMessage) => { return "ok"; }, }; }, }; storiesOf("Common / Wallet Onboarding", module) .addDecorator( apolloStorybookDecorator({ typeDefs, mocks, }), ) .add("No Provider", () => { return undefined} noProvider={true} />; }) .add("Not Enabled", () => { return undefined} notEnabled={true} />; }) .add("Locked", () => { return undefined} walletLocked={true} />; }) .add("Wrong Network", () => { return ( undefined} wrongNetwork={true} requiredNetworkNiceName="Main Ethereum Network" /> ); }) .add("Save address to CMS profile", () => { return ( undefined} metamaskWalletAddress="0xabc1230000000000000000000000000000abc123" saveAddressToProfile={async () => undefined} /> ); }) .add("CMS profile vs. MetaMask address mismatch", () => { return ( undefined} metamaskWalletAddress="0xabc1230000000000000000000000000000abc123" profileWalletAddress="0x123abc00000000000000000000000000000x123abc" saveAddressToProfile={async () => undefined} /> ); }) .add("Connected", () => { return ( undefined} metamaskWalletAddress="0xabc1230000000000000000000000000000abc123" /> ); }); ================================================ FILE: packages/components/src/WalletOnboarding.tsx ================================================ import * as React from "react"; import { Civil } from "@joincivil/core"; import { EthAddress } from "@joincivil/typescript-types"; import { AddressWithMetaMaskIcon, NorthEastArrow, Button, buttonSizes, MetaMaskSideIcon, fonts, ManagerSectionHeading, } from "./"; import styled from "styled-components"; import metaMaskNetworkSwitchUrl from "./images/img-metamask-networkswitch@2x.png"; import metaMaskLoginUrl from "./images/img-metamask-login@2x.png"; export interface WalletOnboardingProps { civil?: Civil; noProvider?: boolean; walletLocked?: boolean; wrongNetwork?: boolean; requiredNetworkNiceName?: string; metamaskWalletAddress?: EthAddress; profileWalletAddress?: EthAddress; profileUrl?: string; profileAddressSaving?: boolean; helpUrl?: string; helpUrlBase?: string; notEnabled?: boolean; enable(): void; saveAddressToProfile?(): Promise; onContinue?(): void; } export interface WalletOnboardingState { justSaved?: boolean; } const Wrapper = styled.div` margin: 32px 0; padding: 6px 24px 12px; background: white; border: solid 1px #e5e5e5; color: #5f5f5f; &:after { content: ""; display: table; clear: both; } `; const LargeishButton = styled(Button)` box-sizing: border-box; height: 42px; `; const WalletAddress = styled(AddressWithMetaMaskIcon)` margin-bottom: 28px; `; const ProfileWalletAddress = styled.span` font-family: ${fonts.MONOSPACE}; `; const ArrowWrap = styled.span` margin-left: 1px; path { fill: white; } `; const WalletAction = styled.div` display: inline-block; margin-left: 12px; padding-left: 15px; border-left: 1px solid #dddddd; `; const WalletLabel = styled.p` font-weight: bold; margin-bottom: 10px; `; const MetaMaskIcon = styled(MetaMaskSideIcon)` position: relative; top: 3px; `; const MetaMaskMockImage = styled.img` float: right; max-width: 255px; margin-bottom: -12px; `; export class WalletOnboarding extends React.Component { constructor(props: WalletOnboardingProps) { super(props); this.state = {}; } public render(): JSX.Element | null { if (this.props.noProvider) { return ( It looks like you aren’t logged in to your wallet

New to using a digital wallet? Having a wallet is mandatory and we recommend{" "} MetaMask {" "} to manage your transactions.{" "} Read this FAQ .

Once the extension is installed,{" "} window.location.reload()}> refresh this page .

After you've set up MetaMask, you'll receive a wallet address and you'll be able to buy ETH with your bank or credit card. We recommend purchasing USD$50 of ETH to start. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

You will use your MetaMask wallet to set up and manage your smart contract, as well as sign, index, and archive posts to the Ethereum blockchain. Make sure you've saved your{" "} seed phrase {" "} from MetaMask in a safe place.

Already have a wallet? Make sure it's unlocked and connected to the {this.props.requiredNetworkNiceName}, and then{" "} window.location.reload()}> refresh this page .

); } else if (this.props.notEnabled) { return ( MetaMask not enabled

Press this button to enable MetaMask for this domain.

this.props.enable()}> Enable

If you do not see the MetaMask popup, please click the icon in your browser address bar.

); } else if (this.props.walletLocked) { return ( Not logged in to wallet

Please open the MetaMask extension and follow the instructions to log in to your wallet. After you are logged in, you can continue with your newsroom smart contract.{" "} Need help?

Once you are on logged in, refresh this page.

window.location.reload()}> Refresh

); } else if (this.props.wrongNetwork) { return ( Change your network

Looks like you’re using an unsupported Ethereum network. Make sure you're using the{" "} {this.props.requiredNetworkNiceName}.{" "} Read this tutorial {" "} to switch networks in MetaMask

Once you are on the correct network, refresh this page.

window.location.reload()}> Refresh

); } else if (this.props.metamaskWalletAddress) { if (this.props.saveAddressToProfile && !this.props.profileWalletAddress) { return ( Wallet Connected

Your wallet is connected. Now you can add your public wallet address to your WordPress user profile.

Your wallet address {" "}
); } else if ( this.props.saveAddressToProfile && this.props.metamaskWalletAddress !== this.props.profileWalletAddress ) { return ( Wallet Connected

Your WordPress user profile wallet address does not match your MetaMask wallet address

Profile wallet address {this.props.profileWalletAddress}{" "} Connected wallet address {" "}
); } else { return ( Wallet Connected Your wallet address {" "} {this.props.onContinue && (
)}
); } } else { return null; } } private saveAddress = async () => { if (!this.props.saveAddressToProfile) { return; } await this.props.saveAddressToProfile(); this.setState({ justSaved: true }); }; } ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.connected.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2/Connected", module).add("Connected", () => { return ( ); }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.decorator.stories.tsx ================================================ import apolloStorybookDecorator from "apollo-storybook-react"; import { EthSignedMessage } from "@joincivil/typescript-types"; const typeDefs = ` type User { ethAddress: String } type Query { currentUser: User } input UserSignatureInput { message: String! messageHash: String! signature: String! signer: String! r: String! s: String! v: String! } type Mutation { userSetEthAddress( input: UserSignatureInput! ): String } schema { query: Query mutation: Mutation } `; const mocks = { Query: () => { return { currentUser: () => { return "ok"; }, }; }, Mutation: () => { return { userSetEthAddress: (sig: EthSignedMessage) => { return "ok"; }, }; }, }; export const apolloDecorator = apolloStorybookDecorator({ typeDefs, mocks, }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.disabled.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2/Not Enabled", module).add("Not Enabled", () => { return ( NOTE: To see this state you must view this story with metamask from a browser where you haven't enabled MetaMask for this domain, or if you already have, you can go into MetaMask settings, enable privacy mode, and hit Clear Privacy Data and refresh. ); }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.locked.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2/Locked", module).add("Locked", () => { return ; }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.mismatch.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; import { apolloDecorator } from "./WalletOnboardingV2.decorator.stories"; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2/Mismatch", module) .addDecorator(apolloDecorator) .add("Civil account vs. MetaMask address mismatch", () => { return ( ); }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.network.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { WalletOnboardingV2 } from "."; storiesOf("Common / Wallet Onboarding V2/ Wrong Network", module).add("Wrong Network", () => { return ; }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.provider.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2/No Provider", module).add("No Provider", () => { return ( NOTE: To see this state you must view this story with MetaMask disabled or from a browser without it installed. ); }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.save.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Civil } from "@joincivil/core"; import { WalletOnboardingV2 } from "."; import { apolloDecorator } from "./WalletOnboardingV2.decorator.stories"; let civil: Civil | undefined; try { civil = new Civil(); } catch (error) { civil = undefined; } storiesOf("Common / Wallet Onboarding V2 / Save Address", module) .addDecorator(apolloDecorator) .add("Save address to Civil account", () => { return ; }); ================================================ FILE: packages/components/src/WalletOnboardingV2/WalletOnboardingV2.tsx ================================================ import * as React from "react"; import gql from "graphql-tag"; import styled from "styled-components"; import { hasInjectedProvider } from "@joincivil/ethapi"; import { isWalletOnboarded, getApolloClient, isBrowserCompatible, urlConstants as links } from "@joincivil/utils"; import { Civil } from "@joincivil/core"; import { EthAddress } from "@joincivil/typescript-types"; import { colors, AddressWithMetaMaskIcon, NorthEastArrow, Button, buttonSizes, MetaMaskSideIcon, MetaMaskLogoButton, fonts, metaMaskNetworkSwitchImgUrl, metaMaskLoginImgUrl, metaMaskFrontLargeImgUrl, metaMaskConnectImgUrl, metaMaskSignImgUrl, HollowGreenCheck, OBSectionTitle, OBSectionDescription, OBSmallParagraph, OBSmallestParagraph, OBBorderedSection, OBBorderedSectionActive, OBCollapsableHeader, OBCollapsable, OBNoteContainer, OBNoteHeading, OBNoteText, AuthApplicationEnum, } from "../"; import { AccountEthAuth } from "../Account/"; import { BrowserCompatible } from "../BrowserCompatible"; export interface WalletOnboardingV2Props { civil?: Civil; wrongNetwork?: boolean; requiredNetworkNiceName?: string; metamaskWalletAddress?: EthAddress; profileWalletAddress?: EthAddress; authApplicationType?: AuthApplicationEnum; onOnboardingComplete?(): void; } export interface WalletOnboardingV2State { metamaskEnabled?: boolean; showWalletConnected?: boolean; onboarded?: boolean; } const sendNewsroomWelcomeEmailMutation = gql` mutation sendNewsroomWelcomeMutation { nrsignupSendWelcomeEmail } `; const Wrapper = styled.div` text-align: center; margin: 63px 0 32px; padding: 6px 24px 12px; background: white; color: #5f5f5f; &:after { content: ""; display: table; clear: both; } a { color: ${colors.accent.CIVIL_BLUE}; } `; const WalletAddress = styled(AddressWithMetaMaskIcon)` margin-bottom: 28px; `; const ProfileWalletAddress = styled.div` font-family: ${fonts.MONOSPACE}; margin-bottom: 12px; `; const ArrowWrap = styled.span` margin-left: 1px; path { fill: ${colors.accent.CIVIL_BLUE}; } `; const WalletLabel = styled.p` font-weight: bold; font-size: 14px; line-height: 24px; margin-bottom: 10px; `; const MetaMaskIcon = styled(MetaMaskSideIcon)` position: relative; top: 3px; `; const IntroText = styled(OBSectionDescription)` max-width: 600px; margin-left: auto; margin-right: auto; `; const InstructionsWrapper = styled(OBBorderedSection)` display: flex; justify-content: space-between; margin: 32px auto 18px; max-width: 550px; padding: 24px 12px 0 24px; `; const InstructionsText = styled.div` color: ${colors.primary.CIVIL_GRAY_1}; font-family: ${fonts.SANS_SERIF}; font-size: 15px; line-height: 18px; margin-top: 20px; text-align: left; `; const InstructionsImage = styled.img` height: 240px; width: auto; `; const InstructionsButtonWrap = styled.div` margin-top: 24px; `; const GetMetaMaskBox = styled(OBBorderedSectionActive)` margin: 24px auto 12px; max-width: 550px; padding: 24px; `; const GetMetaMaskImg = styled.img` width: 85px; height: auto; margin-bottom: 16px; `; const GetMetaMaskText = styled.div` color: ${colors.accent.CIVIL_BLUE}; font-family: ${fonts.SANS_SERIF}; font-size: 17px; font-weight: bold; line-height: 22px; `; const GetMetaMaskMoreHelp = styled(OBSmallParagraph)` text-align: left; `; const ContinueButtonWrap = styled.div` margin-top: 48px; margin-bottom: 80px; `; const ConnectedCheck = styled(HollowGreenCheck)` margin-right: 5px; vertical-align: bottom; `; const ConnectedWalletAddressWrap = styled.div` display: inline-block; margin: 24px auto 12px; text-align: left; `; const ConnectedWalletAddress = styled.div` background-color: ${colors.accent.CIVIL_GRAY_6}; border: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-radius: 3px; font-family: ${fonts.MONOSPACE}; font-size: 18px; line-height: 24px; margin-bottom: 12px; padding: 16px; `; const WarningWrap = styled.p` background-color: ${colors.accent.CIVIL_RED_ULTRA_FADED}; border: 1px solid ${colors.accent.CIVIL_RED_FADED}; border-radius: 4px; padding: 12px; ${OBNoteText} { display: inline-block; max-width: 520px; } `; export class WalletOnboardingV2 extends React.Component { public static getDerivedStateFromProps( props: WalletOnboardingV2Props, state: WalletOnboardingV2State, ): WalletOnboardingV2State { return { ...state, onboarded: isWalletOnboarded( !!props.civil, props.metamaskWalletAddress, props.profileWalletAddress, props.wrongNetwork, ), }; } constructor(props: WalletOnboardingV2Props) { super(props); this.state = {}; } public async componentDidMount(): Promise { await this.enableEthereum(); } public render(): JSX.Element | null { if (this.state.onboarded) { if (this.state.showWalletConnected || !this.props.children) { return this.renderConnected(); } else { return <>{this.props.children}; } } if (!isBrowserCompatible()) { return this.renderBrowserIncompatible(); } else if (!hasInjectedProvider()) { return this.renderNoProvider(); } else if (!this.state.metamaskEnabled) { return this.renderNotEnabled(); } else if (this.props.civil && this.state.metamaskEnabled && !this.props.metamaskWalletAddress) { return this.renderLocked(); } else if (this.props.wrongNetwork) { return this.renderWrongNetwork(); } else if (this.props.metamaskWalletAddress) { if (!this.props.profileWalletAddress) { return this.renderSaveAddress(); } else if (this.props.metamaskWalletAddress.toLowerCase() !== this.props.profileWalletAddress.toLowerCase()) { return this.renderAddressMismatch(); } } return null; } private renderBrowserIncompatible(): JSX.Element { return ( ); } private renderNoProvider(): JSX.Element { return ( Connect your crypto wallet To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask. Get the MetaMask Browser Extension Once the extension is installed,{" "} window.location.reload()}> refresh this page . {this.renderFaqEtc()} ); } private renderNotEnabled(): JSX.Element { return ( Connect your crypto wallet Civil uses MetaMask to view your public wallet address and prompt you with Ethereum transactions, but first we need to connect with MetaMask. Please grant permission to Civil to view your wallet address.

MetaMask will open a new window, and will ask you connect Civil to MetaMask to grant access.

Open MetaMask
If you do not see the MetaMask popup, please click the icon in your browser address bar. {this.renderFaqEtc()}
); } private renderLocked(): JSX.Element { return ( Log in to your crypto wallet Please open the MetaMask extension and follow the instructions to log in to your crypto wallet. After you are logged in, you can continue.

Open the MetaMask extension in your browser and follow the instructions to unlock and log into your wallet.

{this.renderFaqEtc()}
); } private renderWrongNetwork(): JSX.Element { return ( Log in to your crypto wallet Please open the MetaMask extension and follow the instructions to log in to your crypto wallet. After you are logged in, you can continue.

Looks like you’re using an unsupported Ethereum network. Make sure you have the{" "} {this.props.requiredNetworkNiceName} selected.

{this.renderFaqEtc()}
); } private renderSaveAddress(): JSX.Element { return ( Log in to Civil with your crypto wallet Almost there! To set up your Civil account, you need to authenticate your account with a signature. This is similar to signing in with a password. It verifies your account with your crypto wallet.

MetaMask will open a new window, and will require you to sign a message.

this.ethAddressSaved(true)} buttonOnly={true} />
{this.renderFaqEtc()}
); } private renderAddressMismatch(): JSX.Element { return ( Log in to Civil with your crypto wallet The wallet address saved in your profile does not match your current MetaMask wallet address. Please update your profile, or switch MetaMask to use the wallet that is saved to your profile. Profile wallet address {this.props.profileWalletAddress}{" "} Connected MetaMask wallet address {" "}

Open MetaMask to sign a message to authenticate your MetaMask address and save it to your profile.

this.ethAddressSaved()} buttonOnly={true} buttonText={"Update Profile"} />
{this.renderFaqEtc()}
); } private renderConnected(): JSX.Element { return ( Wallet Connected Your crypto wallet is connected. Your public wallet address will be linked to your email address on the Civil network so you can log in using your wallet. Public Wallet Address {this.props.metamaskWalletAddress} Make sure you've backed up and saved your MetaMask login and account details, such as your seed phrase, username and password in a safe place. We can’t help you restore or regain access if you lose it. {this.renderFaqEtc(false)} ); } private renderFaqEtc = (showDisabledButton = true): JSX.Element => { return ( <> {showDisabledButton && ( )} Using a different wallet? Make sure it's unlocked {this.props.requiredNetworkNiceName && " and connected to the " + this.props.requiredNetworkNiceName}. You may need to refresh. What is a cryptocurrency wallet?} > A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin. Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain. Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin. Why do I need a cryptocurrency wallet?} > Having a wallet is required. We recommend{" "} MetaMask {" "} to log in and manage your transactions. You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain. After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges.{" "} Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet. Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it. Need help setting up your wallet?} > Head over to our{" "} FAQ guide {" "} on how to install a MetaMask wallet. Need more info before you start using a crypto wallet?{" "} Learn more in our support area{" "} ); }; private ethAddressSaved = async (firstAddressSave?: boolean) => { this.setState({ showWalletConnected: true }); if (firstAddressSave && this.props.authApplicationType === AuthApplicationEnum.NEWSROOM) { const client = getApolloClient(); const { error } = await client.mutate({ mutation: sendNewsroomWelcomeEmailMutation, }); if (error) { console.error("Failed to send welcome email:", error); } } }; private enableEthereum = async (): Promise => { const { civil } = this.props; let isEthereumEnabled = false; if (civil && civil.currentProvider) { isEthereumEnabled = !!(await civil.currentProviderEnable()); } this.setState({ metamaskEnabled: isEthereumEnabled }); }; private onboardingComplete = () => { this.setState({ showWalletConnected: false }); if (this.props.onOnboardingComplete) { this.props.onOnboardingComplete(); } }; } ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.connected.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/Connected Connected 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/Connected

Connected

Story Source

            
< WalletOnboardingV2 metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " profileWalletAddress = " 0xabc1230000000000000000000000000000abc123 " civil = { null } />

Prop Types

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.disabled.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/Not Enabled Not Enabled 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/Not Enabled

Not Enabled

Story Source

            
< WalletOnboardingV2 metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " profileWalletAddress = " 0xabc1230000000000000000000000000000abc123 " civil = { null } >
< b >
NOTE:
</ b >
To see this state you must view this story with metamask from a browser where you haven't enabled MetaMask for this domain, or if you already have, you can go into MetaMask settings, enable privacy mode, and hit Clear Privacy Data and refresh.
</ WalletOnboardingV2 >

Prop Types

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.locked.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/Locked Locked 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/Locked

Locked

Story Source

            
< WalletOnboardingV2 civil = { null } />

Prop Types

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.mismatch.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/Mismatch Civil account vs. MetaMask address mismatch 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/Mismatch

Civil account vs. MetaMask address mismatch

Story Source

            
< StorybookProvider >
< WalletOnboardingV2 metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " profileWalletAddress = " 0x123abc00000000000000000000000000000x123abc " civil = { null } />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.network.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/ Wrong Network Wrong Network 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked and connected to the Main Ethereum Network . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/ Wrong Network

Wrong Network

Story Source

            
< WalletOnboardingV2 wrongNetwork requiredNetworkNiceName = " Main Ethereum Network " />

Prop Types

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.provider.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2/No Provider No Provider 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2/No Provider

No Provider

Story Source

            
< WalletOnboardingV2 metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " profileWalletAddress = " 0xabc1230000000000000000000000000000abc123 " civil = { null } >
< b >
NOTE:
</ b >
To see this state you must view this story with MetaMask disabled or from a browser without it installed.
</ WalletOnboardingV2 >

Prop Types

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/__snapshots__/WalletOnboardingV2.save.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding V2 / Save Address Save address to Civil account 1`] = `

Connect your crypto wallet

To log in to your Civil account and continue, you’ll need to use a secure crypto wallet. We recommend using MetaMask.

Once the extension is installed, refresh this page .

Using a different wallet? Make sure it's unlocked . You may need to refresh.

What is a cryptocurrency wallet?

A cryptocurrency wallet is where you will store your CVL tokens and other crypto assets. It is also one of the main tools you'll need to log in to the Civil Registry and use the Civil plugin.

Cryptocurrency wallets don’t store any actual money – they store the Public and Private Keys that provide access to those assets. You keep your cryptocurrency including ETH and CVL tokens in a wallet. When using your wallet on Civil, you use your wallet to pay for fees or transactions. Your wallet address also acts as your identity on the Ethereum blockchain.

Consider it like your passport to the Civil economy. With your MetaMask wallet you will be able to store CVL tokens, apply, vote, engage on the Registry, and sign, index, archive content using the Publisher plugin.

Why do I need a cryptocurrency wallet?

Having a wallet is required. We recommend MetaMask to log in and manage your transactions.

You will also use your MetaMask wallet to set up and manage your Newsroom Smart Contract, manage your tokens, as well as sign and index posts to the Ethereum blockchain.

After you've set up MetaMask, you'll receive a public wallet address. You'll need to fund your wallet with ETH. You can buy ETH with your bank or credit card on a variety of cryptocurrency exchanges. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

Make sure you've backed up and saved your MetaMask login and seed phrase in a safe place. We can’t help you regain access if you lose it.

Need help setting up your wallet?

Head over to our FAQ guide on how to install a MetaMask wallet.

Need more info before you start using a crypto wallet? Learn more in our support area

Common / Wallet Onboarding V2 / Save Address

Save address to Civil account

Story Source

            
< StorybookProvider >
< WalletOnboardingV2 metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " civil = { null } />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboardingV2 " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/WalletOnboardingV2/index.ts ================================================ export * from "./WalletOnboardingV2"; ================================================ FILE: packages/components/src/WithNewsroomChannelHOC.tsx ================================================ import * as React from "react"; import { Query, Mutation } from "react-apollo"; import gql from "graphql-tag"; import { ErrorIcon } from "./icons"; import { LoadingMessage } from "./LoadingMessage"; export interface NewsroomChannelData { id: string; currentUserIsAdmin: boolean; isStripeConnected: boolean; newsroom: { multisigAddress: string; charter: { name: string; tagline: string; logoUrl: string; newsroomUrl: string; }; }; } export interface WithNewsroomChannelOuterProps { newsroomAddress?: string; newsroomContractAddress?: string; } export interface WithNewsroomChannelState { newsroomAddress: string; } export interface NewsroomChannelInjectedProps { channelData: NewsroomChannelData; } export const CHANNEL_BY_NEWSROOM_QUERY = gql` query Channel($contractAddress: String!) { channelsGetByNewsroomAddress(contractAddress: $contractAddress) { id currentUserIsAdmin isStripeConnected newsroom { multisigAddress charter { name tagline logoUrl newsroomUrl } } } } `; export const CREATE_NEWSROOM_CHANNEL_MUTATION = gql` mutation($newsroomContractAddress: String!) { channelsCreateNewsroomChannel(newsroomContractAddress: $newsroomContractAddress) { id currentUserIsAdmin } } `; export const NRSIGNUP_DELETE = gql` mutation { nrsignupDelete } `; /** Usage: The component returned by this HOC will require the `newsroomAddress` or `newsroomContractAddress` prop and will pass `channelData` to the wrapped component, or instead will show loading or error states as necessary. If the newsroom channel does not yet exist, it will attempt to create it. */ export const withNewsroomChannel = ( WrappedComponent: React.ComponentType, ) => { type TOriginalProps = Omit; return class ComponentWithNewsroomChannel extends React.Component< WithNewsroomChannelOuterProps & TOriginalProps, WithNewsroomChannelState > { constructor(props: WithNewsroomChannelOuterProps & TOriginalProps) { super(props); const newsroomAddress = this.props.newsroomAddress || this.props.newsroomContractAddress; if (!newsroomAddress || typeof newsroomAddress !== "string") { throw Error("Must supply `newsroomAddress` or `newsroomContractAddress` prop."); } this.state = { newsroomAddress, }; } public render(): JSX.Element { return ( query={CHANNEL_BY_NEWSROOM_QUERY} variables={{ contractAddress: this.state.newsroomAddress }}> {({ loading, error, data }) => { if (loading) { return Loading; } else if (error && error.message.indexOf("record not found") !== -1) { return this.renderNoChannel(); } else if (error || !data || !data.channelsGetByNewsroomAddress) { console.error( "error loading channel data for", this.state.newsroomAddress, " error:", error, "data:", data, ); return this.renderError( "Sorry, there was an error loading your newsroom information. Please try again later.", ); } return ; }} ); } public renderNoChannel(): JSX.Element { return ( mutation={CREATE_NEWSROOM_CHANNEL_MUTATION} variables={{ newsroomContractAddress: this.state.newsroomAddress }} refetchQueries={[ { query: CHANNEL_BY_NEWSROOM_QUERY, variables: { contractAddress: this.state.newsroomAddress } }, ]} > {(createChannel, { data, error, called }) => { if (!called && !error) { console.warn("Channel doesn't exist for newsroom", this.state.newsroomAddress, "attempting to create..."); createChannel().catch(() => {}); } if (error || !data || !data.channelsCreateNewsroomChannel) { console.error("Error creating new channel for newsroom with channelsCreateNewsroomChannel", error, data); return this.renderError( "Sorry, there was an error initializing your newsroom information. Please try again later.", ); } if (!data.channelsCreateNewsroomChannel.currentUserIsAdmin) { console.error( "Error using channelsCreateNewsroomChannel, created channel doesn't have user as admin", data, ); return this.renderError( "Sorry, there was an error assigning admin rights to your newsroom. Please try again later.", ); } return Loading; }} ); } public renderError(message: string): JSX.Element { return ( <> {message} ); } }; }; ================================================ FILE: packages/components/src/__mocks__/fileMock.js ================================================ module.exports = 'test-file-stub'; ================================================ FILE: packages/components/src/__snapshots__/ApplicationPhaseStatusLabels.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Registry / Application Status Labels Labels 1`] = `
Awaiting Approval

Awaiting Request to Appeal

Awaiting Council Decision

Challenge Council Decision

Submit Vote

Confirm Vote

Ready To Update

Registry / Application Status Labels

Labels

Story Source

            
< Container >
< AwaitingApprovalStatusLabel />
< br />
< AwaitingAppealRequestLabel />
< br />
< AwaitingDecisionStatusLabel />
< br />
< AwaitingAppealChallengeStatusLabel />
< br />
< CommitVoteStatusLabel />
< br />
< RevealVoteStatusLabel />
< br />
< ReadyToCompleteStatusLabel />
</ Container >

Prop Types

" AwaitingAppealChallengeStatusLabel " Component

No propTypes defined!

" AwaitingAppealRequestLabel " Component

No propTypes defined!

" AwaitingApprovalStatusLabel " Component

No propTypes defined!

" AwaitingDecisionStatusLabel " Component

No propTypes defined!

" CommitVoteStatusLabel " Component

No propTypes defined!

" Container " Component

No propTypes defined!

" ReadyToCompleteStatusLabel " Component

No propTypes defined!

" RevealVoteStatusLabel " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/Button.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Buttons Button 1`] = `


Link Button

Pattern Library / Buttons

Button

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons CardTransactionButton 1`] = `

This is a Transaction Button styled as a Card, and can contain any markup

Transaction

Pattern Library / Buttons

CardTransactionButton

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons DarkButton 1`] = `

Pattern Library / Buttons

DarkButton

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons InvertedButton 1`] = `

Pattern Library / Buttons

InvertedButton

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons MetaMaskLogoButton 1`] = `

Pattern Library / Buttons

MetaMaskLogoButton

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons SecondaryButton 1`] = `

Pattern Library / Buttons

SecondaryButton

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; exports[`Storyshots Pattern Library / Buttons sizes 1`] = `





Pattern Library / Buttons

sizes

Story Source

            
< StoryRouter story = { anonymous } links = { null } routerProps = { null } />

Prop Types

" StoryRouter " Component

property propType required default description
story other yes -
links other - -
routerProps other - -
`; ================================================ FILE: packages/components/src/__snapshots__/ChevronAnchor.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Typography / Chevron Anchor Civil Themed 1`] = `

Pattern Library / Typography / Chevron Anchor

Civil Themed

Story Source

            
< styled.div >
< ChevronAnchor href = " # " >
Check this out
</ ChevronAnchor >
</ styled.div >

Prop Types

" ChevronAnchor " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Typography / Chevron Anchor Civil Themed, Left 1`] = `

Pattern Library / Typography / Chevron Anchor

Civil Themed, Left

Story Source

            
< styled.div >
< ChevronAnchorLeft href = " # " >
Go back to that thing
</ ChevronAnchorLeft >
</ styled.div >

Prop Types

" ChevronAnchorLeft " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Typography / Chevron Anchor Default 1`] = `

Pattern Library / Typography / Chevron Anchor

Default

Story Source

            
< ChevronAnchor href = " # " >
Check this out
</ ChevronAnchor >

Prop Types

" ChevronAnchor " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/ClipLoader.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Loading / Clip Loader Default Size (32px x 32px) 1`] = `

Pattern Library / Loading / Clip Loader

Default Size (32px x 32px)

Story Source

            
< Container >
< styled.div />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" styled.div " Component

property propType required default description
size unknown - 35
theme unknown - { clipLoaderColor : '#7D7373' }
`; exports[`Storyshots Pattern Library / Loading / Clip Loader Prop-defined size (100px x 100px) 1`] = `

Pattern Library / Loading / Clip Loader

Prop-defined size (100px x 100px)

Story Source

            
< Container >
< styled.div size = { 100 } />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" styled.div " Component

property propType required default description
size unknown - 35
theme unknown - { clipLoaderColor : '#7D7373' }
`; ================================================ FILE: packages/components/src/__snapshots__/Collapsable.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Collapsable closed 1`] = `

Hello

Some Content

Pattern Library / Collapsable

closed

Story Source

            
< styled.div >
< Collapsable header = { <h3 /> } open = { false } >
< p >
Some Content
</ p >
</ Collapsable >
</ styled.div >

Prop Types

" Collapsable " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Collapsable disabled 1`] = `

Hello

Some Content

Pattern Library / Collapsable

disabled

Story Source

            
< styled.div >
< Collapsable disabled header = { <h3 /> } open = { false } >
< p >
Some Content
</ p >
</ Collapsable >
</ styled.div >

Prop Types

" Collapsable " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Collapsable open 1`] = `

Hello

Some Content

Pattern Library / Collapsable

open

Story Source

            
< styled.div >
< Collapsable header = { <h3 /> } open >
< p >
Some Content
</ p >
</ Collapsable >
</ styled.div >

Prop Types

" Collapsable " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Collapsable with custom arrow 1`] = `
Hello

Some Content

Pattern Library / Collapsable

with custom arrow

Story Source

            
< styled.div >
< Collapsable header = " Hello " ArrowComponent = { {
$$typeof
: ,
render
: forwardRef ,
attrs
: [ ] ,

}
}
open = { false }
>
< p >
Some Content
</ p >
</ Collapsable >
</ styled.div >

Prop Types

" Collapsable " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Collapsable with open text 1`] = `
Hello

Some Content

Pattern Library / Collapsable

with open text

Story Source

            
< styled.div >
< Collapsable header = " Hello " headerOpen = " goodbye " open = { false } >
< p >
Some Content
</ p >
</ Collapsable >
</ styled.div >

Prop Types

" Collapsable " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/DetailTransactionButton.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Ethereum / DetailTransactionButton detail transaction button 1`] = `

Common / Ethereum / DetailTransactionButton

detail transaction button

Story Source

            
< styled.div />

Prop Types

" styled.div " Component

No propTypes defined!
`; exports[`Storyshots Common / Ethereum / DetailTransactionButton detail transaction button with visible progress modal 1`] = `

Common / Ethereum / DetailTransactionButton

detail transaction button with visible progress modal

Story Source

            
< styled.div />

Prop Types

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/Heading.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Typography / Headings Headings 1`] = `

Heading

Sub Heading

Section Heading

Block Heading

Pattern Library / Typography / Headings

Headings

Story Source

            
< Container >
< styled.h1 >
Heading
</ styled.h1 >
< styled.h2 >
Sub Heading
</ styled.h2 >
< styled.h1 >
Section Heading
</ styled.h1 >
< styled.h3 >
Block Heading
</ styled.h3 >
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" styled.h1 " Component

property propType required default description
theme unknown - { sansSerifFont : '"Libre Franklin", sans-serif' , serifFont : '"Spectral", serif' }

" styled.h1 " Component

property propType required default description
theme unknown - { sansSerifFont : '"Libre Franklin", sans-serif' , serifFont : '"Spectral", serif' }

" styled.h2 " Component

property propType required default description
theme unknown - { sansSerifFont : '"Libre Franklin", sans-serif' , serifFont : '"Spectral", serif' }

" styled.h3 " Component

property propType required default description
theme unknown - { sansSerifFont : '"Libre Franklin", sans-serif' , serifFont : '"Spectral", serif' }
`; ================================================ FILE: packages/components/src/__snapshots__/LoadingIndicator.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Loading / Loading Indicator Default Size (32px x 32px) 1`] = `

Pattern Library / Loading / Loading Indicator

Default Size (32px x 32px)

Story Source

            
< Container >
< LoadingIndicator />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LoadingIndicator " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Loading / Loading Indicator Prop-defined size (100px x 100px) 1`] = `

Pattern Library / Loading / Loading Indicator

Prop-defined size (100px x 100px)

Story Source

            
< Container >
< LoadingIndicator height = { 100 } />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LoadingIndicator " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/LoadingMessage.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Loading / Loading Message Default size (32px x 32px), custom text 1`] = `

Please wait while we load all the stuff.

Pattern Library / Loading / Loading Message

Default size (32px x 32px), custom text

Story Source

            
< Container >
< LoadingMessage >
Please wait while we load all the stuff.
</ LoadingMessage >
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LoadingMessage " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Loading / Loading Message Default size (32px x 32px), default text 1`] = `

Loading

Pattern Library / Loading / Loading Message

Default size (32px x 32px), default text

Story Source

            
< Container >
< LoadingMessage />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LoadingMessage " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Loading / Loading Message Prop-defined size (100px x 100px), default text 1`] = `

Loading

Pattern Library / Loading / Loading Message

Prop-defined size (100px x 100px), default text

Story Source

            
< Container >
< LoadingMessage height = { 100 } />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LoadingMessage " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/Message.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Notices / Messages (deprecate this?) Info Message 1`] = `
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Pattern Library / Notices / Messages (deprecate this?)

Info Message

Story Source

            
< Container >
< Styled(Styled(MessageBase)) >
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</ Styled(Styled(MessageBase)) >
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" Styled(Styled(MessageBase)) " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/MetaMaskModal.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Ethereum / MetaMaskModal SignatureMetaMaskModal 1`] = `
test

Common / Ethereum / MetaMaskModal

SignatureMetaMaskModal

Story Source

            
< div >
test
</ div >
`; exports[`Storyshots Common / Ethereum / MetaMaskModal SignatureMetaMaskModal waiting 1`] = `
test

Common / Ethereum / MetaMaskModal

SignatureMetaMaskModal waiting

Story Source

            
< div >
test
</ div >
`; exports[`Storyshots Common / Ethereum / MetaMaskModal deniedMetaMaskModal 1`] = `
test

Common / Ethereum / MetaMaskModal

deniedMetaMaskModal

Story Source

            
< div >
test
</ div >
`; exports[`Storyshots Common / Ethereum / MetaMaskModal preMetaMaskModal 1`] = `
test

Common / Ethereum / MetaMaskModal

preMetaMaskModal

Story Source

            
< div >
test
</ div >
`; exports[`Storyshots Common / Ethereum / MetaMaskModal waitingMetaMaskModal 1`] = `
test

Common / Ethereum / MetaMaskModal

waitingMetaMaskModal

Story Source

            
< div >
test
</ div >
`; ================================================ FILE: packages/components/src/__snapshots__/Modal.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Modals Fullscreen Modal 1`] = `

Some good stuff was already on the page which is pretty exciting

Pattern Library / Modals

Fullscreen Modal

Story Source

            
< Container >
< p >
Some good stuff was already on the page which is pretty exciting
</ p >
</ Container >

Prop Types

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / Modals Modal 1`] = `

Some good stuff was already on the page which is pretty exciting

Pattern Library / Modals

Modal

Story Source

            
< Container >
< p >
Some good stuff was already on the page which is pretty exciting
</ p >
</ Container >

Prop Types

" Container " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/ModalContent.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Modals content 1`] = `

I'm a Heading

I'm a paragraph of some sorts

Pattern Library / Modals

content

Story Source

            
< Container >
< styled.h2 >
I'm a Heading
</ styled.h2 >
< styled.p >
I'm a paragraph of some sorts
</ styled.p >
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" styled.h2 " Component

No propTypes defined!

" styled.p " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/QuestionToolTip.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Tooltips / QuestionToolTip tooltip 1`] = `

Pattern Library / Tooltips / QuestionToolTip

tooltip

Story Source

            
< styled.div >
< QuestionToolTip explainerText = " this is a tool tip " />
</ styled.div >

Prop Types

" QuestionToolTip " Component

No propTypes defined!

" styled.div " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/ViewTransactionLink.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Ethereum / viewTransactionLink link 1`] = `

Common / Ethereum / viewTransactionLink

link

Story Source

            
< ViewTransactionLink txHash = " 0x90cf2411cac2a4d4873332bcf60bed49e62d7d4021120c3d… " network = " rinkeby " />

Prop Types

" ViewTransactionLink " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__snapshots__/WalletOnboarding.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Common / Wallet Onboarding CMS profile vs. MetaMask address mismatch 1`] = `

Wallet Connected

Your WordPress user profile wallet address does not match your MetaMask wallet address

Profile wallet address

0x123abc00000000000000000000000000000x123abc

Connected wallet address

0xabc1230000000000000000000000000000abc123

Common / Wallet Onboarding

CMS profile vs. MetaMask address mismatch

Story Source

            
< StorybookProvider >
< WalletOnboarding
  
enable = { enable }

  
metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 "

  
profileWalletAddress = " 0x123abc00000000000000000000000000000x123abc "

  
saveAddressToProfile = { saveAddressToProfile }
/>
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding Connected 1`] = `

Wallet Connected

Your wallet address

0xabc1230000000000000000000000000000abc123

Common / Wallet Onboarding

Connected

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding Locked 1`] = `

Not logged in to wallet

Please open the MetaMask extension and follow the instructions to log in to your wallet. After you are logged in, you can continue with your newsroom smart contract. Need help?

Once you are on logged in, refresh this page.

Common / Wallet Onboarding

Locked

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } walletLocked />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding No Provider 1`] = `

It looks like you aren’t logged in to your wallet

New to using a digital wallet? Having a wallet is mandatory and we recommend MetaMask to manage your transactions. Read this FAQ .

Open MetaMask.io Once the extension is installed, refresh this page .

After you've set up MetaMask, you'll receive a wallet address and you'll be able to buy ETH with your bank or credit card. We recommend purchasing USD$50 of ETH to start. Note: Processing times can vary, and it can take up to 7 days for the ETH to be deposited in your wallet.

You will use your MetaMask wallet to set up and manage your smart contract, as well as sign, index, and archive posts to the Ethereum blockchain. Make sure you've saved your seed phrase from MetaMask in a safe place.

Already have a wallet? Make sure it's unlocked and connected to the , and then refresh this page .

Common / Wallet Onboarding

No Provider

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } noProvider />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding Not Enabled 1`] = `

MetaMask not enabled

Press this button to enable MetaMask for this domain.

If you do not see the MetaMask popup, please click the icon in your browser address bar.

Common / Wallet Onboarding

Not Enabled

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } notEnabled />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding Save address to CMS profile 1`] = `

Wallet Connected

Your wallet is connected. Now you can add your public wallet address to your WordPress user profile.

Your wallet address

0xabc1230000000000000000000000000000abc123

Common / Wallet Onboarding

Save address to CMS profile

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } metamaskWalletAddress = " 0xabc1230000000000000000000000000000abc123 " saveAddressToProfile = { saveAddressToProfile } />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; exports[`Storyshots Common / Wallet Onboarding Wrong Network 1`] = `

Change your network

Looks like you’re using an unsupported Ethereum network. Make sure you're using the Main Ethereum Network . Read this tutorial to switch networks in MetaMask

Once you are on the correct network, refresh this page.

Common / Wallet Onboarding

Wrong Network

Story Source

            
< StorybookProvider >
< WalletOnboarding enable = { enable } wrongNetwork requiredNetworkNiceName = " Main Ethereum Network " />
</ StorybookProvider >

Prop Types

" StorybookProvider " Component

No propTypes defined!

" WalletOnboarding " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/__test__/setupTests.ts ================================================ import * as Enzyme from "enzyme"; // @ts-ignore import Adapter from "enzyme-adapter-react-16"; Enzyme.configure({ adapter: new Adapter() }); ================================================ FILE: packages/components/src/__test__/storyshot.test.ts ================================================ import initStoryshots, { renderOnly } from "@storybook/addon-storyshots"; initStoryshots({ test: renderOnly, }); ================================================ FILE: packages/components/src/containers/ButtonActions.tsx ================================================ import * as React from "react"; import styled from "styled-components"; export const ButtonActions = styled.div` margin: 20px; display: flex; flex-direction: row; justify-content: flex-end; `; ================================================ FILE: packages/components/src/containers/PaddedSection.tsx ================================================ import * as React from "react"; import styled from "styled-components"; export const PaddedSection = styled.div` padding: 20px; `; ================================================ FILE: packages/components/src/containers/index.tsx ================================================ export * from "./ButtonActions"; export * from "./PaddedSection"; ================================================ FILE: packages/components/src/context/AuthService.ts ================================================ import ApolloClient from "apollo-client"; import { clearApolloSession, setApolloSession, getCurrentUserQuery, getApolloSession, AuthLoginResponse, } from "@joincivil/utils"; import gql from "graphql-tag"; const authLoginEthMutation = gql` mutation($input: UserSignatureInput!) { authWeb3: authLoginEth(input: $input) { token refreshToken uid } } `; const authSignupEthMutation = gql` mutation($input: UserSignatureInput!) { authWeb3: authSignupEth(input: $input) { token refreshToken uid } } `; export interface AuthServiceOptions { apolloClient: ApolloClient; onAuthChange(currentUser: any): void; } export class AuthService { public currentUser?: any; public loading = false; private apolloClient: ApolloClient; private onAuthChange: (currentUser?: any) => void; constructor(opts: AuthServiceOptions) { this.apolloClient = opts.apolloClient; this.onAuthChange = opts.onAuthChange; setImmediate(() => this.handleInitialState()); } public async handleInitialState(): Promise { const existingSession = getApolloSession(); if (existingSession && this.apolloClient) { this.currentUser = await this.fetchCurrentUser(); if (this.onAuthChange) { this.onAuthChange(this.currentUser); } } } public getSession(): AuthLoginResponse | null { return getApolloSession(); } public logout(): void { console.log("AuthService logout"); clearApolloSession(); delete this.currentUser; if (this.onAuthChange) { this.onAuthChange(); } } public async authenticate(signature: any): Promise { console.log("sending authenticate mutation", signature); return this.graphqlLoginSignup(authLoginEthMutation, signature); } public async signup(signature: any): Promise { console.log("sending signup mutation", signature); return this.graphqlLoginSignup(authSignupEthMutation, signature); } public async loginUser(session: any): Promise { setApolloSession(session); this.currentUser = await this.fetchCurrentUser(); if (this.onAuthChange) { this.onAuthChange(this.currentUser); } } public async fetchCurrentUser(): Promise { this.loading = true; const result = await this.apolloClient.query({ query: getCurrentUserQuery, fetchPolicy: "no-cache" }); this.loading = false; if (result.errors) { throw new Error("error fetching user"); } return result.data.currentUser; } public async showWeb3Login(): Promise { console.error("web3 auth not yet initialized"); } public async showWeb3Signup(): Promise { console.error("web3 auth not yet initialized"); } /** If user is logged in, but web3 not enabled, enable it. */ public ensureLoggedInUserEnabled(): void { console.error("web3 auth not yet initialized"); } public setShowWeb3Login(func: () => Promise): void { this.showWeb3Login = func; } public setShowWeb3Signup(func: () => Promise): void { this.showWeb3Signup = func; } public setEnsureLoggedInUserEnabled(func: () => void): void { this.ensureLoggedInUserEnabled = func; } private async graphqlLoginSignup(mutation: any, signature: any): Promise { // TODO(dankins): graphql API requires messageHash, r,s,v but they aren't actually used const signatureWithHack = { ...signature, messageHash: "n/a", r: "n/a", s: "n/a", v: "n/a" }; const res = await this.apolloClient.mutate({ mutation, variables: { input: signatureWithHack }, }); if (res && res.data && res.data.authWeb3) { await this.loginUser(res.data.authWeb3); } else { console.error("Failed to validate and log in with ETH address. Response:", res); throw Error("Failed to validate and log in with ETH address"); } } } ================================================ FILE: packages/components/src/context/CivilContext.ts ================================================ import * as React from "react"; import { Civil, UniswapService, FeatureFlagService, EthersProviderResult, makeEthersProvider } from "@joincivil/core"; import { AuthService } from "./AuthService"; import ApolloClient from "apollo-client"; export enum RENDER_CONTEXT { DAPP, EMBED, } export interface ICivilContext { // services civil?: Civil; uniswap: UniswapService; features: FeatureFlagService; auth: AuthService; // web3 web3Provider: any; network: number; // fields that should trigger context re-renders currentUser: any; renderContext: RENDER_CONTEXT; /** See `packages/dapp/src/helpers/config.ts` */ config: any; // other things that should probably be put into a service waitForTx(txHash: string): Promise; fireAnalyticsEvent(category: string, event: string, label: string, value: number): void; setAnalyticsEvent(fire: any): void; } export interface CivilContextOptions { web3: any; featureFlags: string[]; config: any; renderContext?: RENDER_CONTEXT; apolloClient?: ApolloClient; onAuthChange?(nextUser: any): void; } export function buildCivilContext(opts: CivilContextOptions): ICivilContext { const { web3, apolloClient, config, featureFlags, onAuthChange } = opts; if (!web3) { throw new Error("expecting web3 to be initialized"); } console.log("building new context"); const civil = new Civil({ web3Provider: opts.web3.currentProvider }); const web3Provider = web3.currentProvider; const network = web3.currentProvider.networkVersion || config.DEFAULT_ETHEREUM_NETWORK; const auth = new AuthService({ apolloClient: apolloClient!, onAuthChange: onAuthChange! }); const features = new FeatureFlagService(featureFlags); const { provider, signer }: EthersProviderResult = makeEthersProvider(web3Provider, network); const uniswap = new UniswapService(provider, signer, network); const ctx: ICivilContext = { // services civil, auth, features, uniswap, // web3 web3Provider: web3.currentProvider, // fields that should trigger context re-renders currentUser: auth.currentUser, network, renderContext: opts.renderContext || RENDER_CONTEXT.DAPP, // other things that should probably be put into a service config, fireAnalyticsEvent: (category: string, event: string, label: string, value: number) => undefined, setAnalyticsEvent: (fire: any): void => { ctx.fireAnalyticsEvent = fire; }, waitForTx: async (txHash: string) => provider.waitForTransaction(txHash), }; return ctx; } // @ts-ignore ignore default value typescript error export const CivilContext = React.createContext(null); ================================================ FILE: packages/components/src/context/CivilProvider.tsx ================================================ import * as React from "react"; import { CivilContext, buildCivilContext } from "./CivilContext"; import { KirbyEthereum, KirbyEthereumProvider, KirbyEthereumContext } from "@kirby-web3/ethereum-react"; import { ApolloConsumer } from "react-apollo"; import ApolloClient from "apollo-client"; import { IdentityParentPlugin } from "./IdentityParentPlugin"; export interface CivilInnerProviderProps { config: any; featureFlags: string[]; apolloClient?: ApolloClient; } const CivilInnerProvider: React.FunctionComponent = ({ children, featureFlags, config, apolloClient, }) => { // context const kirbyCtx = React.useContext(KirbyEthereumContext); const web3 = kirbyCtx.web3; if (kirbyCtx === null) { return
; } const [currentUser, setCurrentUser] = React.useState(null); const baseContext = React.useMemo(() => { function onAuthChange(nextUser: any): void { console.log("auth change", nextUser); setCurrentUser(nextUser); } const ctx = buildCivilContext({ web3, apolloClient: apolloClient!, featureFlags, config, onAuthChange }); return ctx; }, []); // state const civilContext = React.useMemo(() => { return { ...baseContext, currentUser }; }, [baseContext, currentUser]); // render return {children}; }; export interface CivilProviderProps extends CivilInnerProviderProps { plugins?: any[]; pluginConfig: any; } export const CivilProvider: React.FunctionComponent = ({ children, featureFlags, pluginConfig, config, }) => { const plugins = React.useMemo(() => { return [new IdentityParentPlugin()]; }, []); return ( {client => ( {children} )} ); }; ================================================ FILE: packages/components/src/context/IdentityParentPlugin.ts ================================================ import { ParentPlugin, DMZ } from "@kirby-web3/parent-core"; import { EthereumParentPlugin } from "@kirby-web3/plugin-ethereum"; export const IDENTITY_LOGIN_REQUEST = "IDENTITY_LOGIN_REQUEST"; export const IDENTITY_LOGIN_RESPONSE = "IDENTITY_LOGIN_RESPONSE"; export const IDENTITY_SIGNUP_REQUEST = "IDENTITY_SIGNUP_REQUEST"; export interface LoginRequest { service: string; challenge: string; } export interface LoginResponse { did: string; } export type IdentityPluginState = any; export interface IdentityLoginRequestAction { type: typeof IDENTITY_LOGIN_REQUEST; payload: LoginRequest; } export type IdentityPluginActions = IdentityLoginRequestAction; export interface Config { readOnlyNodeURI: string; } export interface ParentDependencies { ethereum: EthereumParentPlugin; dmz: DMZ; } export class IdentityParentPlugin extends ParentPlugin { public name = "identity"; public dependsOn = ["ethereum", "dmz"]; public web3: any; public provider: any; public reducer(state: IdentityPluginState = {}, action: any): any { return state; } public async login(service: string): Promise { this.logger("starting DID login"); const response = await this.dependencies.dmz.send({ type: IDENTITY_LOGIN_REQUEST, payload: { service } }); this.logger("DID login response", response); return response; } public async signup(service: string): Promise { this.logger("starting DID signup"); const response = await this.dependencies.dmz.send({ type: IDENTITY_SIGNUP_REQUEST, payload: { service } }); this.logger("DID signup response", response); return response; } } ================================================ FILE: packages/components/src/context/index.ts ================================================ export * from "./CivilContext"; export * from "./CivilProvider"; ================================================ FILE: packages/components/src/features/FeatureFlag.tsx ================================================ import * as React from "react"; import { CivilContext, ICivilContext } from "../context"; export interface FeatureFlagProps { feature: string; replacement?: JSX.Element; replacementComponent?: React.ComponentType; children: any; } export class FeatureFlag extends React.Component { public static contextType = CivilContext; public context!: ICivilContext; public render(): JSX.Element { const { feature, children, replacement, replacementComponent } = this.props; if (this.context.features.featureEnabled(feature)) { return <>{children}; } else if (replacementComponent) { const Replacement = replacementComponent; return ; } else { return <>{replacement}; } } } ================================================ FILE: packages/components/src/features/index.ts ================================================ export * from "./FeatureFlag"; ================================================ FILE: packages/components/src/hooks/useAsyncEffect.ts ================================================ import * as React from "react"; export function useAsyncEffect(fn: () => Promise, watcher: any[]): void { React.useEffect(() => { fn(); // tslint:disable-line }, watcher); } ================================================ FILE: packages/components/src/hooks/useIntervalEffect.ts ================================================ import * as React from "react"; import { useAsyncEffect } from "./useAsyncEffect"; const { useEffect, useState } = React; export function useIntervalEffect(fn: () => Promise, intervalMS: number): void { const [ticker, setTicker] = useState(0); useEffect(() => { const interval = setInterval(() => setTicker(ticker + 1), intervalMS); return function cleanup(): void { clearInterval(interval); }; }); useAsyncEffect(fn, [ticker]); } ================================================ FILE: packages/components/src/hooks/useStateWithLocalStorage.ts ================================================ import * as React from "react"; import { fetchItem, setItem, removeItem, startLocalStorageUpdateBroadcast, CIVIL_LOCAL_STORAGE_EVENTS, } from "@joincivil/utils"; const storageKeys: any = {}; window.addEventListener( CIVIL_LOCAL_STORAGE_EVENTS.SET_ITEM, ev => { const { key: updatedKey, value: updatedValue } = (ev as any).detail; const handler = storageKeys[`${updatedKey}::${CIVIL_LOCAL_STORAGE_EVENTS.SET_ITEM}`]; if (handler) { handler(updatedValue); } ev.stopPropagation(); }, false, ); window.addEventListener( CIVIL_LOCAL_STORAGE_EVENTS.UPDATE_ITEM, ev => { const { key: updatedKey, value: updatedValue } = (ev as any).detail; const handler = storageKeys[`${updatedKey}::${CIVIL_LOCAL_STORAGE_EVENTS.UPDATE_ITEM}`]; if (typeof handler === "function") { handler(updatedValue); } ev.stopPropagation(); }, false, ); startLocalStorageUpdateBroadcast(); function areValuesEqual(prevValue: any, newValue: any): boolean { if (typeof prevValue === "object" && typeof newValue === "object") { let isEqual = prevValue === newValue; if (!isEqual) { const prevValueKeys = Object.keys(prevValue); const newValueKeys = Object.keys(newValue); if (prevValueKeys.length !== newValueKeys.length) { isEqual = false; } else { isEqual = true; for (const k of prevValueKeys) { if (prevValue[k] !== newValue[k]) { isEqual = false; break; } } } return isEqual; } } return prevValue === newValue; } export default function useStateWithLocalStorage(key: string, defaultValue?: any): [any, React.Dispatch] { const [value, setStateValue] = React.useState(() => { try { const item = fetchItem(key); return item; } catch (err) { return defaultValue; } }); const setValue = (newValue: any, skipLocalStorageUpdate?: boolean): void => { setStateValue(newValue); if (!skipLocalStorageUpdate) { if (typeof value === "undefined" || value === null) { removeItem(key); } else { setItem(key, newValue); } } }; const refreshValueFromLocalStorage = (): void => { try { const item = fetchItem(key); setStateValue(item); } catch (err) { throw new Error(`Error refreshing state value from localStorage, key=${key}`); } }; storageKeys[`${key}::${CIVIL_LOCAL_STORAGE_EVENTS.SET_ITEM}`] = (updatedValue: any): void => { if (!areValuesEqual(value, updatedValue)) { setStateValue(updatedValue); } }; storageKeys[`${key}::${CIVIL_LOCAL_STORAGE_EVENTS.UPDATE_ITEM}`] = (updatedValue: any): void => { refreshValueFromLocalStorage(); }; return [value, setValue]; } ================================================ FILE: packages/components/src/icons/__snapshots__/icon.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / icons / SVG Icons ApplicationInProgressIcon 1`] = `

Pattern Library / icons / SVG Icons

ApplicationInProgressIcon

Story Source

            
< Container >
< ApplicationInProgressIcon />
</ Container >

Prop Types

" ApplicationInProgressIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ApprovedNewsroomsIcon 1`] = `

Pattern Library / icons / SVG Icons

ApprovedNewsroomsIcon

Story Source

            
< Container >
< ApprovedNewsroomsIcon />
</ Container >

Prop Types

" ApprovedNewsroomsIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ArticleIndexIcon 1`] = `

Pattern Library / icons / SVG Icons

ArticleIndexIcon

Story Source

            
< Container >
< ArticleIndexIcon />
</ Container >

Prop Types

" ArticleIndexIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ArticleIndexPanelIcon 1`] = `

Pattern Library / icons / SVG Icons

ArticleIndexPanelIcon

Story Source

            
< Container >
< ArticleIndexPanelIcon />
</ Container >

Prop Types

" ArticleIndexPanelIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ArticleSignIcon 1`] = `

Pattern Library / icons / SVG Icons

ArticleSignIcon

Story Source

            
< Container >
< ArticleSignIcon />
</ Container >

Prop Types

" ArticleSignIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ArticleSignPanelIcon 1`] = `

Pattern Library / icons / SVG Icons

ArticleSignPanelIcon

Story Source

            
< Container >
< ArticleSignPanelIcon />
</ Container >

Prop Types

" ArticleSignPanelIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons BellIcon 1`] = `

Pattern Library / icons / SVG Icons

BellIcon

Story Source

            
< Container >
< BellIcon />
</ Container >

Prop Types

" BellIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons BookreaderIcon 1`] = `

Pattern Library / icons / SVG Icons

BookreaderIcon

Story Source

            
< Container >
< BookreaderIcon />
</ Container >

Prop Types

" BookreaderIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons BrainIcon 1`] = `

Pattern Library / icons / SVG Icons

BrainIcon

Story Source

            
< Container >
< BrainIcon />
</ Container >

Prop Types

" BrainIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons CVLToken 1`] = `
CVL

Pattern Library / icons / SVG Icons

CVLToken

Story Source

            
< Container >
< CvlToken />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" CvlToken " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons Chevron 1`] = `

Pattern Library / icons / SVG Icons

Chevron

Story Source

            
< Container >
< Chevron />
</ Container >

Prop Types

" Chevron " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons CivilTutorialIcon 1`] = `

Pattern Library / icons / SVG Icons

CivilTutorialIcon

Story Source

            
< Container >
< CivilTutorialIcon />
</ Container >

Prop Types

" CivilTutorialIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ClockIcon 1`] = `

Pattern Library / icons / SVG Icons

ClockIcon

Story Source

            
< Container >
< ClockIcon />
</ Container >

Prop Types

" ClockIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons CloseXIcon 1`] = `

Pattern Library / icons / SVG Icons

CloseXIcon

Story Source

            
< Container >
< CloseXIcon />
</ Container >

Prop Types

" CloseXIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons CommitVoteSuccessIcon 1`] = `

Pattern Library / icons / SVG Icons

CommitVoteSuccessIcon

Story Source

            
< Container >
< CommitVoteSuccessIcon />
</ Container >

Prop Types

" CommitVoteSuccessIcon " Component

No propTypes defined!

" Container " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons DashboardNewsroomApplicationIcon 1`] = `

Pattern Library / icons / SVG Icons

DashboardNewsroomApplicationIcon

Story Source

            
< Container >
< DashboardNewsroomApplicationIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" DashboardNewsroomApplicationIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons DisclosureArrowIcon 1`] = `

Pattern Library / icons / SVG Icons

DisclosureArrowIcon

Story Source

            
< Container >
< DisclosureArrowIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" DisclosureArrowIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons DropdownArrow 1`] = `

Pattern Library / icons / SVG Icons

DropdownArrow

Story Source

            
< Container >
< DropdownArrow />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" DropdownArrow " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons EmbedIcon 1`] = `

Pattern Library / icons / SVG Icons

EmbedIcon

Story Source

            
< Container >
< EmbedIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" EmbedIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ErrorIcon 1`] = `

Pattern Library / icons / SVG Icons

ErrorIcon

Story Source

            
< Container >
< ErrorIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ErrorIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ExamIcon 1`] = `

Pattern Library / icons / SVG Icons

ExamIcon

Story Source

            
< Container >
< ExamIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ExamIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ExchangeArrowsIcon 1`] = `

Pattern Library / icons / SVG Icons

ExchangeArrowsIcon

Story Source

            
< Container >
< ExchangeArrowsIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ExchangeArrowsIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ExpandDownArrow 1`] = `

Pattern Library / icons / SVG Icons

ExpandDownArrow

Story Source

            
< Container >
< ExpandDownArrow />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ExpandDownArrow " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons FacebookIcon 1`] = `

Pattern Library / icons / SVG Icons

FacebookIcon

Story Source

            
< Container >
< Styled(_FacebookIcon) />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" Styled(_FacebookIcon) " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons GrantSubmitIcon 1`] = `

Pattern Library / icons / SVG Icons

GrantSubmitIcon

Story Source

            
< Container >
< GrantSubmitIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" GrantSubmitIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons GreenCheckMark 1`] = `

Pattern Library / icons / SVG Icons

GreenCheckMark

Story Source

            
< Container >
< GreenCheckMark />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" GreenCheckMark " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons HamburgerIcon 1`] = `

Pattern Library / icons / SVG Icons

HamburgerIcon

Story Source

            
< Container >
< HamburgerIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" HamburgerIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons HollowGreenCheck 1`] = `

Pattern Library / icons / SVG Icons

HollowGreenCheck

Story Source

            
< Container >
< HollowGreenCheck />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" HollowGreenCheck " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons HollowRedNoGood 1`] = `

Pattern Library / icons / SVG Icons

HollowRedNoGood

Story Source

            
< Container >
< HollowRedNoGood />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" HollowRedNoGood " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons InfoNotification 1`] = `

Pattern Library / icons / SVG Icons

InfoNotification

Story Source

            
< Container >
< InfoNotification />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" InfoNotification " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons LockOpenIcon 1`] = `

Pattern Library / icons / SVG Icons

LockOpenIcon

Story Source

            
< Container >
< LockOpenIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" LockOpenIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons MetaMaskFrontIcon 1`] = `

Pattern Library / icons / SVG Icons

MetaMaskFrontIcon

Story Source

            
< Container >
< MetaMaskFrontIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" MetaMaskFrontIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons MetaMaskSideIcon 1`] = `

Pattern Library / icons / SVG Icons

MetaMaskSideIcon

Story Source

            
< Container >
< MetaMaskSideIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" MetaMaskSideIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons NetworkIcon 1`] = `

Pattern Library / icons / SVG Icons

NetworkIcon

Story Source

            
< Container >
< NetworkIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" NetworkIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons NorthEastArrow 1`] = `

Pattern Library / icons / SVG Icons

NorthEastArrow

Story Source

            
< Container >
< NorthEastArrow />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" NorthEastArrow " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons OctopusErrorIcon 1`] = `

Pattern Library / icons / SVG Icons

OctopusErrorIcon

Story Source

            
< Container >
< OctopusErrorIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" OctopusErrorIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons RegistryEmptyIcon 1`] = `

Pattern Library / icons / SVG Icons

RegistryEmptyIcon

Story Source

            
< Container >
< RegistryEmptyIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" RegistryEmptyIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons RejectedNewsroomsIcon 1`] = `

Pattern Library / icons / SVG Icons

RejectedNewsroomsIcon

Story Source

            
< Container >
< RejectedNewsroomsIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" RejectedNewsroomsIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons RequestAppealSuccessIcon 1`] = `

Pattern Library / icons / SVG Icons

RequestAppealSuccessIcon

Story Source

            
< Container >
< RequestAppealSuccessIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" RequestAppealSuccessIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons RevealVoteSuccessIcon 1`] = `

Pattern Library / icons / SVG Icons

RevealVoteSuccessIcon

Story Source

            
< Container >
< RevealVoteSuccessIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" RevealVoteSuccessIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons ReviewIcon 1`] = `

Pattern Library / icons / SVG Icons

ReviewIcon

Story Source

            
< Container >
< ReviewIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" ReviewIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons SubmitChallengeSuccessIcon 1`] = `

Pattern Library / icons / SVG Icons

SubmitChallengeSuccessIcon

Story Source

            
< Container >
< SubmitChallengeSuccessIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" SubmitChallengeSuccessIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons TokenWalletIcon 1`] = `

Pattern Library / icons / SVG Icons

TokenWalletIcon

Story Source

            
< Container >
< TokenWalletIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" TokenWalletIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons TrendsIcon 1`] = `

Pattern Library / icons / SVG Icons

TrendsIcon

Story Source

            
< Container >
< TrendsIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" TrendsIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons TwitterIcon 1`] = `

Pattern Library / icons / SVG Icons

TwitterIcon

Story Source

            
< Container >
< Styled(_TwitterIcon) />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" Styled(_TwitterIcon) " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons VerifyIdentityIcon 1`] = `

Pattern Library / icons / SVG Icons

VerifyIdentityIcon

Story Source

            
< Container >
< VerifyIdentityIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" VerifyIdentityIcon " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons WaitForApply 1`] = `

Pattern Library / icons / SVG Icons

WaitForApply

Story Source

            
< Container >
< WaitForApply />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" WaitForApply " Component

No propTypes defined!
`; exports[`Storyshots Pattern Library / icons / SVG Icons WarningIcon 1`] = `

Pattern Library / icons / SVG Icons

WarningIcon

Story Source

            
< Container >
< WarningIcon />
</ Container >

Prop Types

" Container " Component

No propTypes defined!

" WarningIcon " Component

No propTypes defined!
`; ================================================ FILE: packages/components/src/icons/index.ts ================================================ export { ApplicationInProgressIcon, ApprovedNewsroomsIcon, ArticleIndexIcon, ArticleIndexPanelIcon, ArticleSignIcon, ArticleSignPanelIcon, BellIcon, BookreaderIcon, BrainIcon, CCAmexIcon, CCDiscoverIcon, CCMastercardIcon, CCSecurityCodeIcon, CCVisaIcon, Chevron, CivilIcon, CivilTutorialIcon, CvlToken, ClockIcon, CloseXIcon, CommitVoteSuccessIcon, DashboardNewsroomApplicationIcon, DisclosureArrowIcon, DropdownArrow, EmbedIcon, ErrorIcon, ExamIcon, ExchangeArrowsIcon, ExpandDownArrow, FacebookIcon, GreenCheckMark, HamburgerIcon, HollowGrayNotGranted, HollowGreenCheck, HollowRedNoGood, InfoNotification, InstagramIcon, LockOpenIcon, MediumIcon, MetaMaskFrontIcon, MetaMaskSideIcon, NetworkIcon, NorthEastArrow, OctopusErrorIcon, RegistryEmptyIcon, RejectedNewsroomsIcon, RevealVoteSuccessIcon, ReviewIcon, RequestAppealSuccessIcon, ShareEmailIcon, ShareTwitterIcon, SubmitChallengeSuccessIcon, TelegramIcon, TokenWalletIcon, TrendsIcon, TwitterIcon, VerifyIdentityIcon, WarningIcon, WaitForApply, GrantSubmitIcon, ZoomInIcon, ZoomOutIcon, } from "@joincivil/elements"; ================================================ FILE: packages/components/src/icons/logos/Paypal.tsx ================================================ import * as React from "react"; export const PaypalLogoIcon = (): JSX.Element => { return ( ); }; ================================================ FILE: packages/components/src/icons/logos/index.ts ================================================ export * from "./Paypal"; ================================================ FILE: packages/components/src/imageUrls.ts ================================================ import metaMaskNetworkSwitchImgUrl from "./images/img-metamask-networkswitch@2x.png"; import metaMaskLoginImgUrl from "./images/img-metamask-login@2x.png"; import metaMaskFrontLargeImgUrl from "./images/img-metamask-large-front@2x.png"; import metaMaskConnectImgUrl from "./images/img-metamask-connectreq-banner@2x.png"; import metaMaskSignImgUrl from "./images/img-metamask-sign@2x.png"; import applicationSavedImgUrl from "./images/img-application-saved@2x.png"; import applicationSubmittedImgUrl from "./images/img-application-submitted@2x.png"; import grantSubmittedImgUrl from "./images/img-grant-submitted@2x.png"; import defaultNewsroomImgUrl from "./images/img-default-newsroom@2x.png"; import storyPlaceholderImgUrl from "./images/img-story-placeholder.png"; // So that we can host this image and access it from embed code instead of inlining huge svg string: import loadingImgUrl from "./images/loading.svg"; export { metaMaskNetworkSwitchImgUrl, metaMaskLoginImgUrl, metaMaskFrontLargeImgUrl, metaMaskConnectImgUrl, metaMaskSignImgUrl, applicationSavedImgUrl, applicationSubmittedImgUrl, grantSubmittedImgUrl, defaultNewsroomImgUrl, storyPlaceholderImgUrl, loadingImgUrl, }; ================================================ FILE: packages/components/src/index.ts ================================================ export * from "./containers"; export * from "./context"; export * from "./input"; export * from "./Account"; export * from "./Button"; export * from "./Card"; export * from "./ChevronAnchor"; export * from "./ChevronAnchorLeft"; export * from "./FullscreenModal"; export * from "./Heading"; export * from "./Message"; export * from "./styleConstants"; export * from "./LoadingIndicator"; export * from "./LoadingMessage"; export * from "./Modal"; export * from "./ModalContent"; export * from "./StepProcess"; export * from "./TransactionButton"; export * from "./DetailTransactionButton"; export * from "./DetailsButtonComponent"; export * from "./SignConstitutionButton"; export * from "./Collapsable"; export * from "./AddressWithCopyButton"; export * from "./AddressWithMetaMaskIcon"; export * from "./ListingSummary"; export * from "./ListingDetailHeader"; export * from "./ListingDetailPhaseCard"; export * from "./PhaseCountdown"; export * from "./QuestionToolTip"; export * from "./ToolTip"; export * from "./ListingHistoryEvent"; export * from "./ViewTransactionLink"; export * from "./TCRUserDashboard"; export * from "./ChallengeResultsChart"; export * from "./imageUrls"; export * from "./icons"; export * from "./theme"; export * from "./Tabs"; export * from "./Hero"; export * from "./ClipLoader"; export * from "./ClaimRewards"; export * from "./RescueTokens"; export * from "./MetaMaskModal"; export * from "./Notice"; export * from "./ReviewVote"; export * from "./onboardingStyledComponents"; export * from "./WalletOnboarding"; export * from "./WalletOnboardingV2"; export * from "./Table"; export * from "./Parameterizer"; export * from "./UserStatement"; export * from "./MetaMaskLogoButton"; export * from "./CardTransactionButton"; export * from "./ProgressModalContent"; export * from "./RegistryEmpty"; export * from "./Layout"; export * from "./SnackBar"; export * from "./DAppMessageContent"; export * from "./EmailSignup"; export * from "./Tokens"; export * from "./ExecuteOnMount"; export * from "./AuthenticatedRoute"; export * from "./EthAddressViewer"; export * from "./Notice"; export * from "./CurrencyConverter"; export * from "./GasEstimate"; export * from "./features"; export * from "./CopyToClipboard"; export * from "./HelmetHelper"; export * from "./WithNewsroomChannelHOC"; export * from "./Contributors"; export * from "./Comments"; export * from "./StoryFeed"; export * from "./Payments"; ================================================ FILE: packages/components/src/input/AddressInput.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { AddressInput } from "./AddressInput"; storiesOf("Pattern Library / inputs / AddressInput", module) .add("valid", () => { return ( undefined} /> ); }) .add("invalid", () => { return undefined} />; }); ================================================ FILE: packages/components/src/input/AddressInput.tsx ================================================ import * as React from "react"; import { TextInput } from "./Input"; import { EthAddress } from "@joincivil/typescript-types"; import { isWellFormattedAddress } from "@joincivil/utils"; export interface AddressInputProps { address: EthAddress; onChange(name: any, value: any): void; } export class AddressInput extends React.Component { public invalid(): boolean { return !!this.props.address && !isWellFormattedAddress(this.props.address); } public render(): JSX.Element { const invalid = this.invalid(); return ( ); } } ================================================ FILE: packages/components/src/input/Checkbox.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../styleConstants"; import { CheckboxTheme } from "./SlideCheckbox"; export enum CheckboxSizes { SMALL = "SMALL", } interface BoxProps { locked?: boolean; size?: CheckboxSizes; } const Box = styled.span` position: absolute; cursor: ${(props: BoxProps) => (props.locked ? "default" : "pointer")}; top: 0; left: 0; bottom: 0; right: 0; &:after { content: ""; position: absolute; display: none; left: 4px; top: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "1" : "0")}px; width: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "3" : "5")}px; height: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "7" : "10")}px; border: solid white; border-width: 0 3px 3px 0; transform: rotate(45deg); } `; interface ContainerProps { locked?: boolean; theme?: CheckboxTheme; size?: CheckboxSizes; } const Container = styled.label` position: relative; display: inline-block; box-sizing: content-box; width: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "16" : "20")}px; height: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "16" : "20")}px; vertical-align: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "middle" : "bottom")}; input { display: none; } input + ${Box} { border-radius: 2px; color: transparent; border: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "1" : "2")}px solid ${props => props.theme.checkboxInactiveColor}; background-color: transparent; } input:checked + ${Box} { color: ${colors.basic.WHITE}; border: ${(props: ContainerProps) => (props.size === CheckboxSizes.SMALL ? "1" : "2")}px solid ${props => props.theme.checkboxActiveColor}; background-color: ${props => props.theme.checkboxActiveColor}; opacity: ${(props: ContainerProps) => (props.locked ? 0.7 : 1)}; } input:checked + ${Box}:after { display: block; } `; export const DEFAULT_CHECKBOX_THEME = { checkboxInactiveColor: colors.accent.CIVIL_GRAY_2, checkboxActiveColor: colors.accent.CIVIL_BLUE, }; Container.defaultProps = { theme: DEFAULT_CHECKBOX_THEME, }; export interface CheckboxProps { checked: boolean; locked?: boolean; size?: CheckboxSizes; id?: string; onClick(): void; } export const Checkbox = (props: CheckboxProps) => { return ( { if (!props.locked) { props.onClick(); } }} checked={props.checked} id={props.id} type="checkbox" /> ); }; ================================================ FILE: packages/components/src/input/Dropdown.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { Dropdown, DropdownGroup, DropdownItem } from "./Dropdown"; storiesOf("Pattern Library / Dropdown", module).add("Dropdown", () => { return ( Click to Activate}> Account Help Center Sign Out ); }); ================================================ FILE: packages/components/src/input/Dropdown.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { Link } from "react-router-dom"; import { colors, fonts } from "../styleConstants"; export interface DropdownProps { className?: string; position?: string; // right or left target: JSX.Element; } export interface DropdownState { open: boolean; } export class DropdownComponent extends React.Component { private wrapperRef: any; constructor(props: DropdownProps) { super(props); this.state = { open: false }; this.toggle = this.toggle.bind(this); this.setWrapperRef = this.setWrapperRef.bind(this); this.handleClickOutside = this.handleClickOutside.bind(this); } public componentWillUnmount(): void { document.removeEventListener("mousedown", this.handleClickOutside.bind(this)); } public render(): JSX.Element { return (
this.toggle()}>{this.props.target}
{this.state.open ? (
this.setWrapperRef(ref)}>
this.toggle()}>{this.props.children}
) : null}
); } private handleClickOutside(event: any): void { if (this.wrapperRef && !this.wrapperRef.contains(event.target)) { this.toggle(); } } private setWrapperRef(node: any): void { this.wrapperRef = node; } private toggle(): void { if (this.state.open) { document.removeEventListener("mousedown", ev => this.handleClickOutside(ev)); } else { document.addEventListener("mousedown", ev => this.handleClickOutside(ev)); } this.setState({ open: !this.state.open }); } } export const Dropdown = styled(DropdownComponent)` > div:first-child { cursor: pointer; } > div:nth-child(2) { font-family: ${fonts.SANS_SERIF}; position: relative; z-index: 100; > div { position: absolute; ${props => (props.position === "left" ? "left" : "right")}: 3px; top: 10px; width: 200px; max-width: 200px; background-color: ${colors.basic.WHITE}; box-shadow: rgba(0, 0, 0, 0.2) 0px 1px 2px, rgba(0, 0, 0, 0.2) 0px 1px 2px; border: 1px solid ${colors.accent.CIVIL_GRAY_3}; :before, :after { content: " "; height: 0; width: 0; position: absolute; border: 8px solid transparent; /* arrow size */ } :before { border-bottom-color: white; /* arrow color */ /* positioning */ position: absolute; top: -15px; ${props => (props.position === "left" ? "left" : "right")}: 10px; z-index: 2; } :after { border-bottom-color: ${colors.accent.CIVIL_GRAY_3}; /* arrow color */ /* positioning */ position: absolute; top: -16px; ${props => (props.position === "left" ? "left" : "right")}: 10px; z-index: 1; } } } `; export const DropdownGroup = styled.ul` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; list-style-type: none; margin: 0; padding: 0; li:hover { background-color: ${colors.accent.CIVIL_GRAY_4}; } `; export interface DropdownItemProps { className?: string; children?: any; onClick?(): void; } const DropdownItemComponent = ({ className, children, onClick }: DropdownItemProps) => { return (
  • {children}
  • ); }; export const DropdownItem = styled(DropdownItemComponent)` display: block; text-decoration: none; color: black; padding: 15px; a:hover { background-color: ${colors.accent.CIVIL_GRAY_4}; } `; export interface DropdownLinkProps { to: string; className?: string; children?: any; } const DropdownLinkComponent = ({ className, to, children }: DropdownLinkProps) => { return (
  • {children}
  • ); }; export const DropdownLink = styled(DropdownLinkComponent)` a { display: block; text-decoration: none; color: black; padding: 15px; } a:hover { background-color: ${colors.accent.CIVIL_GRAY_4}; } `; ================================================ FILE: packages/components/src/input/ImageFileToDataUri.tsx ================================================ import * as React from "react"; import { InvertedButton, BorderlessButton, buttonSizes } from "../Button"; import { Modal } from "../Modal"; import { colors, fonts } from "../styleConstants"; import styled from "styled-components"; import Dropzone from "react-dropzone"; export interface ImageFileToDataUriState { modalOpen: boolean; error?: string; } export interface ImageFileToDataUriProps { buttonText?: string; maxBytes?: number; maxSizeText?: string; info?: string; validMimeTypes?: string[]; onChange(dataUri: string): void; } export interface ImageFileToDataUriDefaultProps { maxBytes: number; maxSizeText: string; info: string; validMimeTypes: string[]; } const DropArea = styled.div` cursor: pointer; outline: none; width: 100%; box-sizing: border-box; height: 200px; border: 3px dashed ${colors.primary.CIVIL_GRAY_2}; color: ${colors.primary.CIVIL_GRAY_2}; border-radius: 5px; display: flex; justify-content: center; align-items: center; padding: 30px; &:hover { border-color: ${colors.primary.CIVIL_BLUE_1}; } p { font-size: 18px; font-family: ${fonts.SANS_SERIF}; } `; const ButtonContainer = styled.div` display: flex; justify-content: flex-end; margin-top: 25px; `; const Error = styled.p` color: ${colors.accent.CIVIL_RED}; `; export class ImageFileToDataUri extends React.Component< ImageFileToDataUriProps & ImageFileToDataUriDefaultProps, ImageFileToDataUriState > { public static defaultProps: ImageFileToDataUriDefaultProps = { maxBytes: 256 * 1024, maxSizeText: "250KB", info: "Recommended dimensions 260x260px, maximum file size 250KB. Image will be displayed constrained to a square.", validMimeTypes: ["image/gif", "image/png", "image/jpeg"], }; constructor(props: ImageFileToDataUriProps & ImageFileToDataUriDefaultProps) { super(props); this.state = { modalOpen: false, }; } public renderModal(): JSX.Element | null { if (!this.state.modalOpen) { return null; } return (

    {this.props.info}

    {({ getRootProps, getInputProps }: any) => (

    Drop files here, or click to select files

    )}
    {this.state.error && {this.state.error}} this.setState({ modalOpen: false })}> Close
    ); } public render(): JSX.Element { return ( <> this.setState({ modalOpen: true })}> {" "} {this.props.buttonText || "Add Image"}{" "} {this.renderModal()} ); } private createDataUrlFromFile = (acceptedFiles: any) => { const reader = new FileReader(); reader.onload = (event: any) => { const dataUri = event.target!.result; if (!dataUri || !dataUri.length) { this.setState({ error: "Invalid image, please try another file." }); return; } const mimeMatch = dataUri.match(/data:([^;]*);/); const mimeType = mimeMatch && mimeMatch[1]; if (this.props.validMimeTypes.indexOf(mimeType) === -1) { this.setState({ error: `Invalid file type "${mimeType}", please try another file. Valid file types: ${this.props.validMimeTypes.join( ", ", )}.`, }); return; } // Image data URI lengths are 1/3 longer than number of bytes in image file, don't know exactly why but tested for jpgs gifs and pngs of various sizes and it's spot on so divide by 4/3 to get bytes. const fileSize = dataUri.length / (4 / 3); if (fileSize > this.props.maxBytes) { this.setState({ error: `Uploaded image is ${Math.round(fileSize / 1024)}KB, which is too large. Max size: ${ this.props.maxSizeText }`, }); return; } this.props.onChange(dataUri); this.setState({ modalOpen: false, error: undefined }); }; reader.readAsDataURL(acceptedFiles[0]); }; } ================================================ FILE: packages/components/src/input/Input.stories.tsx ================================================ import { storiesOf } from "@storybook/react"; import * as React from "react"; import { TextInput, HeaderInput, CurrencyInput, TextareaInput } from "./Input"; import { InputGroup } from "./InputGroup"; import { RadioInput, RadioButton } from "./RadioInput"; import { CurrencyInputWithButton, TextInputWithButton } from "./InputWithButton"; import { ImageFileToDataUri } from "./ImageFileToDataUri"; import { SubmitLink } from "./SubmitLink"; type changeCallback = (name: string, value: any) => any; interface ControlProps { children(state: any, onChange: changeCallback): React.ReactNode; } class ControlComponent extends React.Component { constructor(props: any) { super(props); this.state = {}; } public render(): React.ReactNode { return this.props.children(this.state, this.onChange); } private onChange = (name: string, value: any): any => { console.log("change: ", name, value); this.setState({ [name]: value }); }; } storiesOf("Pattern Library / Inputs", module) .add("Text Input", () => { return ( {(state: any, onChange: changeCallback) => ( )} ); }) .add("Input Group", () => { return ( {(state: any, onChange: changeCallback) => ( )} ); }) .add("Header Input", () => { return ( {(state: any, onChange: changeCallback) => ( )} ); }) .add("Currency Input", () => { return ( {(state: any, onChange: changeCallback) => ( )} ); }) .add("Radio Input", () => { let result: any; const onChange = (name: string, value: any) => { console.log("Radio Input change", name, value, result.RadioGroup.value); }; return (
    (result = ref)} > Daily Weekly Monthly Yearly
    ); }) .add("Textarea Input", () => { return ( {(state: any, onChange: changeCallback) => ( )} ); }) .add("Text Input With Button", () => { return ( {(state: any, onChange: changeCallback) => ( console.log("TextInputWithButton button was clicked")} /> )} ); }) .add("Currency Input With Button", () => { return ( {(state: any, onChange: changeCallback) => ( CVL} onButtonClick={() => console.log("CurrencyInputWithButton button was clicked")} /> )} ); }) .add("image file to data uri", () => { return ( {(state: any, onChange: changeCallback) => { return onChange("name", dataUri)} />; }} ); }) .add("Submit a link", () => { return ( {(state: any, onChange: changeCallback) => ( console.log("Link submitted")} /> )} ); }); ================================================ FILE: packages/components/src/input/Input.tsx ================================================ export { InputIcon, InputLabel, ErrorMessage, InputBaseProps, InputBase, InputProps, TextInput, NumericInput, CurrencyProps, CurrencyInput, TextProps, HeaderInput, TextareaProps, TextareaInput, URLInput, } from "@joincivil/elements"; ================================================ FILE: packages/components/src/input/InputGroup.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../styleConstants"; import { TextInput, InputLabel, InputProps, ErrorMessage } from "./Input"; const StyledInputGroupContainer = styled.div` margin: 0 0 10px; `; const StyledInputGroup = styled.div` align-items: 100%; box-sizing: border-box; display: flex; position: relative; margin: 5px 0; width: 100%; & > div { margin-bottom: 0; } && input { margin: 0; } `; const StyledInputGroupPrepend = styled.div` display: flex; box-sizing: border-box; & > span { margin-right: -1px; } `; const StyledInputGroupAppend = styled.div` display: flex; box-sizing: border-box; & > span { margin-left: -1px; } `; interface InputGroupTextProps { noPadding?: boolean; } const InputGroupText = styled.span` border: 1px solid ${colors.accent.CIVIL_GRAY_3}; display: flex; font-size: inherit; padding: ${(props: InputGroupTextProps) => (props.noPadding ? "0" : "10px")}; text-align: center; white-space: nowrap; `; const InputGroupAppend: React.FunctionComponent = props => { return ( {props.children} ); }; const InputGroupPrepend: React.FunctionComponent = props => { return ( {props.children} ); }; export interface InputGroupProps { append?: string | JSX.Element; prepend?: string | JSX.Element; noAppendPadding?: boolean; inputComponent?: React.ComponentClass | React.FunctionComponent; } export const InputGroup: React.FunctionComponent = (props: any) => { const { label, append, prepend, placeholder, noAppendPadding, invalid, invalidMessage, ...inputProps } = props; const Input = props.inputComponent || TextInput; return ( {!props.noLabel && {label || placeholder}} {prepend && {props.prepend}} {append && {props.append}} {invalid && invalidMessage && {invalidMessage}} ); }; ================================================ FILE: packages/components/src/input/InputWithButton.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors, fonts } from "../styleConstants"; import { InvertedButton, buttonSizes } from "../Button"; import { NumericInput, TextInput, InputProps } from "./Input"; export interface InputContainerProps { buttonText?: string; icon?: JSX.Element; children( isFocused: boolean, setFocused: () => void, setUnfocused: (ev: any) => void, setInputRef: (el: any) => void, ): React.ReactNode; onButtonClick?(ev: any): void; } export interface InputWithButtonProps extends InputProps { buttonText: string; icon?: JSX.Element; onButtonClick(ev: any): void; } export interface InputWithButtonState { isFocused: boolean; } const StyledTextInputButton = styled.div` border: 1px solid; border-color: ${props => (props.isFocused ? colors.accent.CIVIL_BLUE : colors.accent.CIVIL_GRAY_3)}; border-radius: 3px; font-size: 21px; padding: 26px 20px; position: relative; & > div { margin: 0; } & > div > input, & > div > input:focus { border: none; margin: 0; padding: 0; } `; const StyledIcon = styled.div` color: ${colors.accent.CIVIL_GRAY_2}; font-family: ${fonts.SANS_SERIF}; font-size: 18px; line-height: 21px; position: absolute; right: 40px; top: calc(50% - 10px); `; const StyledButtonContainer = styled.div` position: absolute; right: 40px; top: calc(50% - 18px); `; class InputContainer extends React.Component { private inputElement: HTMLInputElement | undefined = undefined; private buttonElement: HTMLButtonElement | undefined = undefined; constructor(props: InputContainerProps) { super(props); this.state = { isFocused: false, }; } public render(): JSX.Element { return ( {this.props.children(this.state.isFocused, this.setFocused, this.setUnfocused, this.setInputRef)} {this.props.buttonText && this.state.isFocused && ( {this.props.buttonText} )} {!this.state.isFocused && this.props.icon && {this.props.icon}} ); } private handleButtonClick = (ev: any) => { if (this.props.onButtonClick) { this.props.onButtonClick(ev); } if (this.inputElement) { this.inputElement.blur(); this._setUnfocused(); } }; private setFocusState = (isFocused: boolean): void => { this.setState(() => ({ isFocused })); }; private setFocused = () => this.setFocusState(true); private _setUnfocused = () => this.setFocusState(false); private setUnfocused = (ev: any) => { if (ev.relatedTarget === this.buttonElement) { ev.preventDefault(); } else { this._setUnfocused(); } }; private setInputRef = (el: HTMLInputElement) => (this.inputElement = el); private setButtonRef = (el: HTMLButtonElement) => (this.buttonElement = el); } export const TextInputWithButton: React.FunctionComponent = props => { const { onButtonClick, icon, buttonText, ...restProps } = props; const inputProps = { ...restProps, noLabel: true }; const containerProps = { onButtonClick, buttonText, icon }; return ( {( isFocused: boolean, setFocused: () => void, setUnfocused: (ev: any) => void, setInputRef: (el: any) => void, ) => { return ( <> ); }} ); }; export const CurrencyInputWithButton: React.FunctionComponent = props => { const { onButtonClick, icon, buttonText, ...restProps } = props; const inputProps = { ...restProps, noLabel: true }; const containerProps = { onButtonClick, buttonText, icon }; return ( {( isFocused: boolean, setFocused: () => void, setUnfocused: (ev: any) => void, setInputRef: (el: any) => void, ) => { return ( <> ); }} ); }; export const CurrencyInputWithoutButton: React.FunctionComponent = props => { const { icon, ...restProps } = props; const inputProps = { ...restProps, noLabel: true }; const containerProps = { icon }; return ( {( isFocused: boolean, setFocused: () => void, setUnfocused: (ev: any) => void, setInputRef: (el: any) => void, ) => { return ( <> ); }} ); }; ================================================ FILE: packages/components/src/input/RadioInput.tsx ================================================ export { RadioButton, RadioCardInput, RadioButtonDiv, RadioButtonProps, RadioInput, RadioCardInputProps, } from "@joincivil/elements"; ================================================ FILE: packages/components/src/input/SaltInput.tsx ================================================ import * as React from "react"; import { TextInput } from "../input/"; import { wordsToSalt, saltToWords } from "@joincivil/utils"; export interface SaltInputProps { name: string; label?: string; placeholder?: string; salt?: string; invalid?: boolean; invalidMessage?: string; onChange(name: string, value: string): void; } export interface SaltInputState { isValid: boolean; value?: string; } export class SaltInput extends React.Component { constructor(props: SaltInputProps) { super(props); const { salt } = this.props; this.state = { isValid: false, value: salt ? saltToWords(salt).join(" ") : "", }; } public render(): JSX.Element { const { name, label, placeholder, invalid, invalidMessage } = this.props; const { value } = this.state; const inputProps = { name, label, placeholder, invalid, invalidMessage, value, onChange: this.handleChange, }; return ; } private handleChange = (name: string, value: string): void => { const { onChange } = this.props; const nextState = { ...this.state }; const onlyLetters = value.replace(/[^a-z ]/, "").replace(/[ ]+/, " "); nextState.value = onlyLetters; try { const saltNum = wordsToSalt(onlyLetters); nextState.isValid = true; onChange(name, saltNum.toString()); } catch (err) { nextState.isValid = false; onChange(name, ""); } this.setState(nextState); }; } ================================================ FILE: packages/components/src/input/SimpleImageFileToDataUri.tsx ================================================ import * as React from "react"; import { InvertedButton, buttonSizes } from "../Button"; import { colors, fonts, mediaQueries } from "../styleConstants"; import styled from "styled-components"; import Dropzone from "react-dropzone"; import { PhotoDragIcon } from "@joincivil/elements"; export interface SimpleImageFileToDataUriProps { buttonText?: string; onChange(dataUri: string): void; } const DropArea = styled.div` width: 336px; box-sizing: border-box; height: 336px; ${mediaQueries.MOBILE} { width: 200px; height: 200px; } background-color: #f9faff; border: 2px dashed ${colors.primary.CIVIL_BLUE_1}; color: ${colors.primary.CIVIL_GRAY_2}; border-radius: 168px; display: flex; justify-content: center; align-items: center; flex-direction: column; padding: 30px; ${mediaQueries.MOBILE} { padding-left: 10px; padding-right: 10px; } p { font-size: 18px; font-family: ${fonts.SANS_SERIF}; } `; const ImageSelectionContainer = styled.div` display: flex; flex-direction: column; align-items: center; justify-content: space-between; height: 450px; ${mediaQueries.MOBILE} { height: 300px; width: 240px; } `; const DragAndDropText = styled.span` width: 300px; ${mediaQueries.MOBILE} { width: 150px; } text-align: center; `; export class SimpleImageFileToDataUri extends React.Component { private readonly inputOpenFileRef: React.RefObject; constructor(props: SimpleImageFileToDataUriProps) { super(props); this.inputOpenFileRef = React.createRef(); } public showOpenFileDlg = () => { this.inputOpenFileRef!.current!.click(); }; public renderDropZone(): JSX.Element | null { return ( <> {({ getRootProps, getInputProps }: any) => (

    Drag and drop an image here
    )}
    ); } public render(): JSX.Element { return ( {this.renderDropZone()} or this.showOpenFileDlg()}> {" "} {this.props.buttonText || "Upload Image"}{" "} ); } private createDataUrlFromFile = (acceptedFiles: any) => { this.loadAsDataURLFromFile(acceptedFiles[0]); }; private createDataUrlFromFile2 = (e: any) => { this.loadAsDataURLFromFile(e.target.files[0]); }; private loadAsDataURLFromFile = (file: any) => { const reader = new FileReader(); reader.onload = (event: any) => { this.props.onChange(event.target!.result); this.setState({ modalOpen: false }); }; reader.readAsDataURL(file); }; } ================================================ FILE: packages/components/src/input/SlideCheckbox.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../styleConstants"; export interface CheckboxTheme { checkboxActiveColor: string; checkboxInactiveColor: string; } const Slider = styled.span` position: absolute; cursor: pointer; top: 0; left: 0; bottom: 0; right: 0; border-radius: 34px; transition: 0.4s; &:before { position: absolute; content: ""; height: 10px; width: 10px; left: 1.7px; top: 1.7px; transition: 0.4s; border-radius: 50%; } `; Slider.defaultProps = { theme: { checkboxInactiveColor: colors.accent.CIVIL_GRAY_2, checkboxActiveColor: colors.accent.CIVIL_BLUE, }, }; const Switch = styled.label` box-sizing: content-box; position: relative; display: inline-block; width: 32px; height: 19px; input { display: none; } input + ${Slider} { background-color: transparent; border: 2px solid ${props => props.theme.checkboxInactiveColor}; } input + ${Slider}:before { background-color: ${props => props.theme.checkboxInactiveColor}; } input:checked + ${Slider} { border: 2px solid ${props => props.theme.checkboxActiveColor}; background-color: ${props => props.theme.checkboxActiveColor}; } input:focus + ${Slider} { box-shadow: 0 0 1px #2196f3; } input:checked + ${Slider}:before { background-color: ${colors.basic.WHITE}; transform: translateX(12px); } `; Switch.defaultProps = { theme: { checkboxInactiveColor: colors.accent.CIVIL_GRAY_2, checkboxActiveColor: colors.accent.CIVIL_BLUE, }, }; export interface SlideCheckboxProps { checked: boolean; locked?: boolean; onClick(): void; } export const SlideCheckbox = (props: SlideCheckboxProps) => { return ( { if (!props.locked) { props.onClick(); } }} checked={props.checked} type="checkbox" /> ); }; ================================================ FILE: packages/components/src/input/SubmitLink.tsx ================================================ import * as React from "react"; import { URLInput } from "../input/"; import { Button } from "../Button"; import styled from "styled-components"; import { fonts, colors, mediaQueries } from "../styleConstants"; export const SubmitLinkStyled = styled.div` align-items: flex-start; display: flex; ${Button} { border-radius: 0; font-size: 14px; letter-spacing: 0; margin: 5px 0 0 10px; padding: 10px 15px; width: 200px; } ${mediaQueries.MOBILE} { display: block; ${Button} { margin: 0; width: 100%; } } `; export interface SubmitLinkResponseProps { error: boolean; } export const ResponseText = styled.p` color: ${colors.accent.CIVIL_RED}; ${(props: SubmitLinkResponseProps) => (props.error ? colors.accent.CIVIL_RED : colors.primary.BLACK)}; font: ${fonts.SANS_SERIF}; font-size: 12px; `; export interface SubmitLinkProps { name: string; buttonText?: string; placeholder?: string; submitting: boolean; success: boolean; error: boolean; onSubmit(): void; onChange(name: string, value: string): void; } export const SubmitLink: React.FunctionComponent = props => { const { buttonText, name, placeholder, submitting, success, error, onChange, onSubmit } = props; return ( <>
    {error && <>There was an error submitting your link. Please try again.} {success && <>Your link has been submitted.}
    ); }; ================================================ FILE: packages/components/src/input/__snapshots__/AddressInput.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / inputs / AddressInput invalid 1`] = `
    The address you have entered is invalid

    Pattern Library / inputs / AddressInput

    invalid

    Story Source

                
    < AddressInput address = " 0x8c722b8ac728add7780a66017e " onChange = { onChange } />

    Prop Types

    " AddressInput " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / inputs / AddressInput valid 1`] = `

    Pattern Library / inputs / AddressInput

    valid

    Story Source

                
    < AddressInput address = " 0x8c722b8ac728add7780a66017e8dadba530ee261 " onChange = { onChange } />

    Prop Types

    " AddressInput " Component

    No propTypes defined!
    `; ================================================ FILE: packages/components/src/input/__snapshots__/Dropdown.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Dropdown Dropdown 1`] = `
    Click to Activate

    Pattern Library / Dropdown

    Dropdown

    Story Source

                
    < Styled(DropdownComponent) position = " left " target = { <span /> } >
    < styled.ul >
    < Styled(DropdownItemComponent) >
    Account
    </ Styled(DropdownItemComponent) >
    < Styled(DropdownItemComponent) >
    Help Center
    </ Styled(DropdownItemComponent) >
    < Styled(DropdownItemComponent) >
    Sign Out
    </ Styled(DropdownItemComponent) >
    </ styled.ul >
    </ Styled(DropdownComponent) >

    Prop Types

    " Styled(DropdownComponent) " Component

    No propTypes defined!

    " Styled(DropdownItemComponent) " Component

    No propTypes defined!

    " styled.ul " Component

    No propTypes defined!
    `; ================================================ FILE: packages/components/src/input/__snapshots__/Input.stories.storyshot ================================================ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Storyshots Pattern Library / Inputs Currency Input 1`] = `
    USD
    USD } label="Currency Input" min="2" name="CurrencyInput" onChange={[Function]} placeholder="$0.00" step="2" type="number" />

    Pattern Library / Inputs

    Currency Input

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Currency Input With Button 1`] = `
    CVL

    Pattern Library / Inputs

    Currency Input With Button

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Header Input 1`] = `

    Pattern Library / Inputs

    Header Input

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Input Group 1`] = `
    CVL

    Pattern Library / Inputs

    Input Group

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Radio Input 1`] = `

    Pattern Library / Inputs

    Radio Input

    Story Source

                
    < div >
    < Unknown
      
    onChange = { onChange }

      
    label = " Group of radio buttons "

      
    name = " RadioGroup "

      
    inputRef = { inputRef }
    >
    < Unknown value = " daily " >
    Daily
    </ Unknown >
    < Unknown value = " weekly " >
    Weekly
    </ Unknown >
    < Unknown value = " monthly " >
    Monthly
    </ Unknown >
    < Unknown value = " yearly " >
    Yearly
    </ Unknown >
    </ Unknown >
    </ div >

    Prop Types

    " Unknown " Component

    No propTypes defined!

    " Unknown " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Submit a link 1`] = `

    Pattern Library / Inputs

    Submit a link

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Text Input 1`] = `

    Pattern Library / Inputs

    Text Input

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Text Input With Button 1`] = `

    Pattern Library / Inputs

    Text Input With Button

    Story Source

                
    < ControlComponent >
    </ ControlComponent >

    Prop Types

    " ControlComponent " Component

    No propTypes defined!
    `; exports[`Storyshots Pattern Library / Inputs Textarea Input 1`] = `
    ); } return ( ); }; export const InputBase = styled(InputBaseComponent)` margin-bottom: 10px; display: inline-grid; width: 100%; display: flex; flex-direction: column-reverse; font-family: ${fonts.SANS_SERIF}; > div { display: flex; flex-direction: row; } > input, > textarea { box-sizing: border-box; font-size: inherit; margin: 5px 0px 10px 0; padding: 10px; border: 1px solid ${colors.accent.CIVIL_GRAY_3}; outline: none; } > input::placeholder, > textarea::placeholder { color: ${colors.accent.CIVIL_GRAY_3}; } > input:focus, > textarea:focus { border-bottom: 1px solid ${colors.accent.CIVIL_BLUE}; } &.civil-input-error { color: ${colors.accent.CIVIL_RED}; } &.civil-input-error > input { color: ${colors.accent.CIVIL_RED}; border-bottom-color: ${colors.accent.CIVIL_RED}; } `; export interface InputProps { name: string; value?: string; placeholder?: string; autocomplete?: string; label?: string | JSX.Element; icon?: JSX.Element; className?: string; invalid?: boolean; disabled?: boolean; invalidMessage?: string; noLabel?: boolean; readOnly?: boolean; inputRef?: | ((instance: HTMLInputElement | HTMLTextAreaElement | null) => void) | React.RefObject; type?: string; min?: string; step?: string; onBlur?(ev: any): void; onFocus?(ev: any): void; onKeyPress?(ev: any): void; onChange?(name: string, value: string): any; } export const TextInput = (props: InputProps) => { return ; }; export const NumericInput = (props: InputProps) => { return ; }; export interface CurrencyProps extends InputProps { currency: string; } export const CurrencyInput = (props: InputProps) => { const icon = props.icon || USD; return ; }; export interface TextProps extends InputProps { currency: string; } export const HeaderInput = styled(TextInput)` > input { font-size: 25px; } `; export interface TextareaProps { height?: string; maxLength?: string; } export const TextareaInput = (props: TextareaProps & InputProps) => { return ; }; export const URLInput = (props: InputProps) => { return ; }; ================================================ FILE: packages/elements/src/inputs/RadioInput.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { colors } from "../colors/index"; import { SecondaryButton } from "../buttons/Button"; import { InputLabel } from "./Input"; import { Heading, SubHeading } from "../text/headings"; import { OvalImage } from "../icons/logos/index"; export interface RadioButtonProps { className?: string; inputRef?: any; onChange?: any; value: any; disabled?: boolean; name?: string; defaultValue?: any; } export const RadioButtonDiv = styled.div` input { display: none; } input:checked + button { background-color: ${colors.accent.CIVIL_BLUE}; border: 1px solid ${colors.accent.CIVIL_BLUE}; color: ${colors.basic.WHITE}; } `; export const RadioButton: React.FunctionComponent = props => { let input: any; const { onChange, children, name } = props; const clickHandler = () => { input.checked = true; if (onChange) { onChange(props.name, input.value); } }; const defaultChecked = props.defaultValue === props.value; return ( (input = ref)} /> {children} ); }; export const RadioBtnCircle = styled.div` background-color: ${colors.basic.WHITE}; border-radius: 50%; box-shadow: inset 0 0 0 1px ${colors.accent.CIVIL_GRAY_2}; height: 18px; left: 2px; position: absolute; top: calc(50% - 9px); width: 18px; `; export const RadioBtnStandardStyled = styled.div` width: 100%; input { display: none; } input:checked + button { ${RadioBtnCircle} { background-color: ${colors.basic.WHITE}; box-shadow: inset 0 0 0 6px ${colors.accent.CIVIL_BLUE}; height: 19px; width: 19px; } } `; export const RadioBtn = styled.button` background-color: ${colors.basic.WHITE}; border: none; color: ${colors.accent.CIVIL_GRAY_1}; cursor: pointer; font-size: 14px; letter-spacing: -0.09px; line-height: 24px; margin-bottom: 10px; outline: none; padding-left: 30px; position: relative; text-align: left; `; export const RadioButtonStandard: React.FunctionComponent = props => { let input: any; const { onChange, children, value, name } = props; const clickHandler = () => { input.checked = true; if (onChange) { onChange(name, input.value); } }; const defaultChecked = props.defaultValue === props.value; return ( (input = ref)} /> {children} ); }; export interface RadioInputProps { name: string; label?: string; defaultValue?: any; onChange?: any; inputRef?: any; className?: any; children?: any; } const RadioDiv = styled.div` > div { display: flex; flex-direction: rows; flex-wrap: wrap; align-items: center; justify-content: center; } `; export const RadioInput = (props: RadioInputProps) => { const { defaultValue, onChange, label, name, inputRef, children } = props; const childrenWithProps = React.Children.map(children, (child: React.ReactChild) => React.cloneElement(child as React.ReactElement, { name, onChange, defaultValue }), ); return ( {label ? {label} : null}
    {childrenWithProps}
    ); }; export const RadioGroup = RadioInput; export interface RadioCardInputProps { heading: string; subheading?: string; value: any; image?: any; className?: string; inputRef?: any; onChange?: any; name?: string; disabled?: boolean; defaultValue?: any; prioritized?: boolean; } const StyledRadioCardInput = styled.div` display: flex; flex-direction: row; align-items: center; background-color: #ffffff; border: 1px solid #ebebeb; border-radius: 4px; box-shadow: 0 2px 4px 0 #e6e6e6; width: 311px; height: 117px; margin-top: 15px; cursor: pointer; > div:nth-child(2) { margin: 18px; } > div:nth-child(3) { flex-grow: 1; } > input { display: none; } `; const EnabledStyledRadioCardInput = styled(StyledRadioCardInput)` :hover { border: 1px solid #2b56ff; } `; const PrioritizedStyledRadioCardInput = styled(EnabledStyledRadioCardInput)` box-shadow: 0px 0px 2px 2px ${colors.accent.CIVIL_BLUE_FADED}; `; const DisabledStyledRadioCardInput = styled(StyledRadioCardInput)` background-color: ${colors.accent.CIVIL_GRAY_4}; cursor: not-allowed; `; export const RadioCardInput: React.FC = props => { let input: any; const { onChange, name, image, heading, subheading, disabled, prioritized } = props; const clickHandler = () => { input.checked = true; if (onChange) { onChange(props.name, input.value); } }; const defaultChecked = props.defaultValue === props.value; let SelectedStyledRadioCardInput = EnabledStyledRadioCardInput; if (disabled) { SelectedStyledRadioCardInput = DisabledStyledRadioCardInput; } else if (prioritized) { SelectedStyledRadioCardInput = PrioritizedStyledRadioCardInput; } return ( (input = ref)} /> {image}
    {heading} {subheading}
    ); }; ================================================ FILE: packages/elements/src/inputs/index.ts ================================================ export * from "./Input"; export * from "./RadioInput"; ================================================ FILE: packages/elements/src/layouts/index.ts ================================================ export const LayoutsTest = "test"; ================================================ FILE: packages/elements/src/module.d.ts ================================================ declare module "@storybook/addon-storyshots"; declare module "storybook-react-router"; declare module "*.png"; ================================================ FILE: packages/elements/src/share/SharePanel.tsx ================================================ import * as React from "react"; import { CSSTransition } from "react-transition-group"; import styled from "styled-components"; import { colors } from "../colors"; import { CloseXButton } from "../buttons"; import { mediaQueries } from "../containers"; const SharePanelInner = styled.div` background-color: ${colors.basic.WHITE}; opacity: 0; overflow: auto; padding: 10px 0; position: relative; width: 360px; ${mediaQueries.MOBILE_SMALL} { bottom: 0; right: 0; position: fixed; width: 100%; } `; const SharePanelOuter = styled.div` align-items: center; background-color: rgba(0, 0, 0, 0.4); bottom: 0; display: flex; justify-content: center; left: 0; position: fixed; overflow: auto; right: 0; top: 74px; z-index: 4; &.share-enter > div { opacity: 0; transform: scale(0.9); } &.share-enter-active > div { opacity: 1; transform: translateX(0); transition: opacity 300ms, transform 300ms; } &.share-enter-done > div { opacity: 1; } &.share-exit > div { opacity: 1; } &.share-exit-active > div { opacity: 0; transform: scale(0.9); transition: opacity 300ms, transform 300ms; } ${mediaQueries.MOBILE} { top: 54px; } ${mediaQueries.MOBILE_SMALL} { align-items: flex-end; &.share-enter > div { opacity: 1; transform: translate(0, 100%) scale(1); } &.share-enter-active > div { transform: translate(0); transition: transform 300ms; } &.share-exit > div { transform: translate(0); } &.share-exit-active > div { opacity: 1; transform: translate(0, 100%) scale(1); transition: transform 300ms; } } `; const SharePanelClose = styled.div` position: absolute; right: 20px; top: 20px; `; export interface SharePanelProps { open: boolean; handleClose?(): void; } export const SharePanel: React.FunctionComponent = props => { return ( {props.handleClose && ( )} {props.children} ); }; ================================================ FILE: packages/elements/src/share/ShareStory.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { ShareEmailIcon, LinkIcon, ShareTwitterIcon, HollowGreenCheck } from "../icons"; import { colors } from "../colors"; import { fonts } from "../text"; import { mediaQueries } from "../containers"; const ShareWrapper = styled.div` width: 360px; ${mediaQueries.MOBILE} { width: 100%; } `; const ShareHeader = styled.div` border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; font-family: ${fonts.SANS_SERIF}; padding: 20px 15px; h2 { font-family: ${fonts.SANS_SERIF}; font-size: 18px; font-weight: 600; line-height: 22px; margin: 0 0 10px; } `; const ShareContent = styled.p` font-family: ${fonts.SANS_SERIF}; font-size: 14px; line-height: 20px; margin: 0; a { color: ${colors.accent.CIVIL_BLUE}; display: block; overflow-wrap: break-word; text-decoration: none; word-wrap: break-word; &:hover { color: ${colors.accent.CIVIL_BLUE}; text-decoration: underline; } } `; const ShareOptions = styled.div` padding: 0 15px 15px; a, button { align-items: center; background-color: ${colors.basic.WHITE}; border: none; border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; color: ${colors.primary.BLACK}; cursor: pointer; display: flex; font-family: ${fonts.SANS_SERIF}; font-size: 14px; justify-content: space-between; line-height: 17px; padding: 15px 0; text-decoration: none; transition: color 0.2s ease; width: 100%; &:hover { color: ${colors.accent.CIVIL_BLUE}; } } `; const ShareCopyFeedback = styled.span` align-items: center; display: flex; font-size: 13px; margin-top: 5px; width: 100%; svg { margin-right: 3px; } `; export interface ShareStoryProps { title: string; url: string; } export interface ShareStoryState { copied: boolean; } export class ShareStory extends React.Component { public constructor(props: ShareStoryProps) { super(props); this.state = { copied: false, }; } public render(): JSX.Element { return (

    Share

    {this.props.title} {this.state.copied ? ( copied ) : ( {this.props.url} )}
    <>Share to Twitter <>Share via Email {/* TODO(sruddy) add copy embed when embeds are ready <>Embed Story Boost */}
    ); } private getEmailURL = () => { const emailShare = "mailto:?subject=" + encodeURI(this.props.title) + "&body=" + encodeURI(this.props.url); return emailShare; }; private getTweetURL = () => { const twitterShare = "https://twitter.com/intent/tweet?text=" + encodeURI(this.props.title) + "&url=" + this.props.url; return twitterShare; }; // @TODO This should ideally re-use `copyToClipboard` from `utils`, but `elements` shouldn't depend on `utils`. Either this should be in `components`, or should be in some new package that has fewer deps than `components` but more than `elements`, and/or we break out some stuff from `utils` because right now `utils` depends on everything too. private copyURL = () => { const textArea = document.createElement("textarea"); textArea.innerText = this.props.url; document.body.appendChild(textArea); textArea.select(); document.execCommand("copy"); textArea.remove(); this.setState({ copied: true }); }; } ================================================ FILE: packages/elements/src/share/index.ts ================================================ export * from "./ShareStory"; export * from "./SharePanel"; ================================================ FILE: packages/elements/src/text/fonts.ts ================================================ export const fonts = { SERIF: `"Spectral", serif`, SANS_SERIF: `"Libre Franklin", sans-serif`, SANS_SERIF_BOLD: `"LibreFranklin-Bold", sans-serif`, MONOSPACE: `"SF Mono", "Segoe UI Mono", "Roboto Mono", "Ubuntu Mono", Menlo, Courier, monospace;`, }; ================================================ FILE: packages/elements/src/text/headings.tsx ================================================ import * as React from "react"; import styled from "styled-components"; export const Heading = styled.span` display: block; margin: 6px; color: ${props => props.theme.headingColor}; font-family: ${props => props.theme.headingFont}; font-size: 18px; font-weight: 500; line-height: 26px; `; export const SubHeading = styled.span` display: block; margin: 6px; color: ${props => props.theme.subheadingColor}; font-family: ${props => props.theme.headingFont}; font-size: 14px; font-weight: 500; line-height: 24px; `; ================================================ FILE: packages/elements/src/text/index.ts ================================================ export * from "./fonts"; ================================================ FILE: packages/elements/tsconfig.json ================================================ { "extends": "../../tsconfig", "compilerOptions": { "outDir": "build/", "declaration": true, "declarationDir": "build/", "jsx": "react", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "lib": ["dom", "es2017"] }, "include": ["./src/**/*.ts", "./src/**/*.tsx"] } ================================================ FILE: packages/elements/tslint.json ================================================ { "extends": ["@joincivil/tslint-rules"], "rules": { "variable-name": [true, "ban-keywords", "allow-leading-underscore"], "no-unused-variable": [true, { "ignore-pattern": "^React|styled|StyledComponentClass" }] } } ================================================ FILE: packages/ethapi/LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS ================================================ FILE: packages/ethapi/README.md ================================================ # @joincivil/ethapi An abstraction of Ethereum communication [![license](https://img.shields.io/badge/license-Apache%20v2.0-green.svg)](./LICENSE) ================================================ FILE: packages/ethapi/package.json ================================================ { "name": "@joincivil/ethapi", "homepage": "https://github.com/joincivil/Civil", "version": "0.4.9", "description": "An abstraction of Ethereum communication", "main": "build/index.js", "types": "build/index.d.ts", "scripts": { "build": "tsc", "build:watch": "tsc -w", "lint": "tslint --project ./", "clean": "rimraf build/" }, "author": "The Civil Media Company", "license": "Apache-2.0", "devDependencies": { "@joincivil/typescript-types": "^1.4.8", "@types/debug": "^0.0.30", "@types/lodash": "^4.14.99", "typescript": "^3.6.2" }, "bugs": { "url": "https://github.com/joincivil/Civil/issues" }, "dependencies": { "@joincivil/utils": "^1.9.9", "bn.js": "4.11.6", "debug": "^4.1.0", "ethereumjs-abi": "^0.6.7", "ethereumjs-util": "^5.2.0", "lodash": "^4.17.10", "rxjs": "^5.5.6", "web3": "^1.2.4", "web3-core": "^1.2.4", "web3-core-helpers": "^1.2.4", "web3-eth": "^1.2.4", "web3-eth-abi": "^1.2.4", "web3-eth-contract": "^1.2.4", "web3-providers-http": "^1.2.4", "web3-providers-ws": "^1.2.4", "web3-utils": "^1.2.4" }, "publishConfig": { "access": "public" } } ================================================ FILE: packages/ethapi/src/abidecoder.ts ================================================ import { isUndefined } from "lodash"; import { AbiType, DecodedLogEntry } from "@joincivil/typescript-types"; import Web3 from "web3"; import { Log } from "web3-core"; import { AbiItem } from "web3-utils"; import { JsonRpcPayload } from "web3-core-helpers"; // JsonRpcResponse is in the latest version of web3-core-helpers but not released yet type JsonRpcResponse = any; const stubProvider = { send: (payload: JsonRpcPayload, callback: JsonRpcResponse) => ({}), host: "x", supportsSubscriptions: () => false, sendBatch: async (methods: any, moduleInstance: any) => Promise.reject([]), connected: false, disconnect: () => true, }; export class AbiDecoder { private savedABIs: any[] = []; private methodIds: { [signatureHash: string]: AbiItem } = {}; constructor(abiArrays: any[][]) { abiArrays.forEach(this.addABI.bind(this)); } public tryToDecodeLogOrNoop(log: Log): LogType { const methodId = log.topics[0]; const event = this.methodIds[methodId as string]; if (isUndefined(event)) { // @ts-ignore return log; } // @ts-ignore const decoded = new Web3(stubProvider).eth.abi.decodeLog(event.inputs!, log.data, log.topics); return ({ ...log, event: event.name as any, args: decoded, } as any) as LogType; } private addABI(abiArray: AbiItem[]): void { abiArray.forEach(abi => { if (abi.type === AbiType.Event) { const abiTypes = abi.inputs!.map(input => input.type); const signature = `${abi.name}(${abiTypes.join(",")})`; const signatureHash = new Web3(stubProvider).utils.sha3(signature); this.methodIds[signatureHash] = abi; } }); this.savedABIs = this.savedABIs.concat(abiArray); } } /* Copyright 2017 ZeroEx Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ ================================================ FILE: packages/ethapi/src/ethapi.ts ================================================ import { CivilErrors, delay, hashPersonalMessage } from "@joincivil/utils"; import Debug from "debug"; import { bufferToHex, fromRpcSig, fromUtf8, toBuffer } from "ethereumjs-util"; import { ReplaySubject, Observable } from "rxjs"; import { ContractOptions, BigNumber, bigNumberify, DecodedTransactionReceipt, EthAddress, EthSignedMessage, TxHash, } from "@joincivil/typescript-types"; import { AbiDecoder } from "./abidecoder"; import { requireAccount } from "./helpers"; import Web3 from "web3"; import Contract from "web3-eth-contract"; import { Block } from "web3-eth"; import { Transaction, TransactionConfig, Log, TransactionReceipt, provider as Provider } from "web3-core"; import { AbiItem } from "web3-utils"; const debug = Debug("civil:ethapi"); export const DEFAULT_HTTP_NODE = "http://127.0.0.1:8545"; const POLL_MILLISECONDS = 5000; export class EthApi { // Initialized for sure by the helper method setProvider used in constructor private web3!: Web3; private abiDecoder: AbiDecoder; private accountObservable: ReplaySubject; private networkObservable: ReplaySubject; // TODO(ritave): Use abi decoding seperatly in just the generated smart-contracts constructor(provider: Provider, abis: any[][]) { this.currentProvider = provider; this.abiDecoder = new AbiDecoder(abis); this.accountObservable = new ReplaySubject(1); this.web3.eth .getAccounts() .then(accounts => { const account = accounts && accounts.length > 0 ? accounts[0] : undefined; this.web3.eth.defaultAccount = account!; if (account) { this.accountObservable.next(account); } }) .catch(err => { console.error("error getting accounts", err); }); // @ts-ignore `on` exists for providers that support subscriptions if (provider.on) { // @ts-ignore `on` exists for providers that support subscriptions provider.on("accountsChanged", accounts => { const account = accounts && accounts.length > 0 ? accounts[0] : undefined; this.web3.eth.defaultAccount = account!; if (account) { this.accountObservable.next(account); } }); } this.networkObservable = new ReplaySubject(1); this.web3.eth.net .getId() .then(network => { this.networkObservable.next(network); }) .catch(err => { console.error("error getting network", err); }); // @ts-ignore `on` exists for providers that support subscriptions if (provider.on) { // @ts-ignore `on` exists for providers that support subscriptions provider.on("networkChanged", network => { this.networkObservable.next(network); }); } } public get currentProvider(): Provider { return this.web3.currentProvider; } public set currentProvider(provider: Provider) { // TODO(ritave): Cancel any pending calls to the previous provider console.log("provider change"); // @ts-ignore this.web3 = new Web3(provider); } public get accountStream(): Observable { return this.accountObservable; } public get networkStream(): Observable { return this.networkObservable; } public async network(): Promise { const network = await this.networkObservable.first().toPromise(); return network; } public async getAccount(): Promise { return this.web3.eth.defaultAccount; } public async getGasPriceString(): Promise { // @ts-ignore @types/web3 are wrong - this really does return a string // https://web3js.readthedocs.io/en/v1.2.1/web3-eth.html#getgasprice return this.web3.eth.getGasPrice(); } public async getGasPrice(): Promise { return this.getGasPriceString().then(gp => new BigNumber(gp)); } public async getBlock(blockNumber: number | "latest" | "pending"): Promise { return this.web3.eth.getBlock(blockNumber); } public async getLatestBlockNumber(): Promise { return this.web3.eth.getBlockNumber(); } public async getConfirmations(startBlock: number): Promise { const block = await this.getLatestBlockNumber(); return block - startBlock; } public async getCode(address: EthAddress): Promise { return this.web3.eth.getCode(address); } public async sendTransaction(txData: TransactionConfig): Promise { // TOOD(dankins): handle rejection // tslint:disable-next-line:no-unbound-method return new Promise((resolve, reject) => { this.web3.eth .sendTransaction(txData) .once("transactionHash", hash => { resolve(hash); }) .catch(reject); }); } public async getTransaction(txHash: TxHash): Promise { return this.web3.eth.getTransaction(txHash); } public async signMessage(message: string, account?: EthAddress): Promise { const messageHex = fromUtf8(message); const signerAccount = account || (await requireAccount(this).toPromise()); // @ts-ignore types are wrong, password is not required const signature = await this.web3.eth.personal.sign(messageHex, signerAccount); const rsv = fromRpcSig(signature); return { ...hashPersonalMessage(message), signature, message, r: bufferToHex(rsv.r), s: bufferToHex(rsv.s), v: bufferToHex(toBuffer(rsv.v)), signer: signerAccount, }; } /** * Converts an address to a web3 checksummed address * @param address */ public toChecksumAddress(address: string): string { return this.web3.utils.toChecksumAddress(address); } /** * Converts a given number into a BigNumber instance * @param numberOrHexString */ public toBigNumber(amount: number | string | BigNumber): any { if (typeof amount === "number") { return bigNumberify(amount); } else if (amount instanceof BigNumber) { return amount; } else if (typeof amount === "string" && amount.startsWith("")) { console.log("found a weird bignumber:", amount); return bigNumberify(0); } return bigNumberify(amount); } public toWei(amount: number): BigNumber { const wei = this.web3.utils.toWei(amount.toString()); return this.toBigNumber(wei); } public async accountBalace(account: EthAddress): Promise { const balance = await this.web3.eth.getBalance(account); return parseFloat(this.web3.utils.fromWei(balance, "ether")); } /** * Awaits to confirm that the transaction was succesfull * @param txHash Transaction hash which will be checked * @param blockConfirmations Blockchain can get reorganized and the transaction can go to mempool, * wait for some for confirmations */ public async awaitReceipt( txHash: TxHash, blockConfirmations: number = 1, // wait till the api says the current block is confirmed ): Promise { while (true) { const receipt = await this.getReceipt(txHash); if (!receipt) { // TODO(ritave): Move to pending block parsing instead of polling await delay(POLL_MILLISECONDS); continue; } this.checkForEvmException(receipt); await this.awaitConfirmations(receipt.blockNumber, blockConfirmations); return receipt; } } public async awaitConfirmations(startblock: number, confirmations: number): Promise { while (true) { const confirmationsSoFar = await this.getConfirmations(startblock); if (confirmationsSoFar >= confirmations) { return; } else { await delay(POLL_MILLISECONDS); } } } /** * Low-level call, * Tries to get the receipt from blockchain and automatically decodes it's logs * into proper Events from our smart-contracts * *Warning:* The transaction receipt can be returned even if the transaction has failed, check the `status` field * @param txHash Transaction hash for which the receipt is returned * @returns Null if the transaction is not yet inside the blockchain (still in mempool), decoded transaction otherwise */ public async getReceipt( txHash: TxHash, ): Promise { const receipt = await this.web3.eth.getTransactionReceipt(txHash); if (receipt) { return this.receiptToDecodedReceipt(receipt); } return null; } public getContractClass(abi: AbiItem[], address?: string, options?: ContractOptions | undefined): typeof Contract { const contract = new this.web3.eth.Contract(abi, address, options); if (!contract.options.address) { contract.options.address = address!; } return contract; } public async estimateGas(options: TransactionConfig): Promise { return this.web3.eth.estimateGas(options); } private receiptToDecodedReceipt | TransactionReceipt>( receipt: TransactionReceipt, ): R { receipt.logs = receipt.logs!.map((log: Log) => this.abiDecoder.tryToDecodeLogOrNoop(log)); return (receipt as any) as R; } private checkForEvmException(receipt: TransactionReceipt): void { // tslint:disable-next-line // https://ethereum.stackexchange.com/questions/28077/how-do-i-detect-a-failed-transaction-after-the-byzantium-fork-as-the-revert-opco/28078#28078 // Pre-Bizantium, let's just throw, Civil didn't exist before Bizantium if (receipt.status === null) { debug("Warning: Pre-Bizantium block, not supported"); throw new Error(CivilErrors.EvmException); } if (receipt.status === false) { throw new Error(CivilErrors.EvmException); } } } ================================================ FILE: packages/ethapi/src/globals.d.ts ================================================ declare module "web3/lib/solidity/coder" { const decodeParams: (types: string[], data: string) => any[]; } declare module "web3-eth-contract"; ================================================ FILE: packages/ethapi/src/helpers.ts ================================================ import { EthAddress } from "@joincivil/typescript-types"; import { CivilErrors, isDefined } from "@joincivil/utils"; import { Observable } from "rxjs/Observable"; import { EthApi } from "./ethapi"; export function requireAccount(ethApi: EthApi): Observable { return ethApi.accountStream.first().map(account => { if (isDefined(account)) { return account; } throw new Error(CivilErrors.NoUnlockedAccount); }); } export function hasInjectedProvider(): boolean { return typeof window !== "undefined" && (window as any).web3 !== undefined; } export async function currentAccount(ethApi: EthApi): Promise { return ethApi.accountStream.first().toPromise(); } export async function currentNetwork(ethApi: EthApi): Promise { return ethApi.networkStream.first().toPromise(); } export enum EthereumUnits { wei = "1", kwei = "1000", mwei = "1000000", gwei = "1000000000", microether = "1000000000000", milliether = "1000000000000000", ether = "1000000000000000000", kether = "1000000000000000000000", mether = "1000000000000000000000000", gether = "1000000000000000000000000000", tether = "1000000000000000000000000000000", babbage = "1000", lovelace = "1000000", shannon = "1000000000", szabo = "1000000000000", finney = "1000000000000000", } ================================================ FILE: packages/ethapi/src/index.ts ================================================ export * from "./ethapi"; export * from "./helpers"; export * from "./infura"; ================================================ FILE: packages/ethapi/src/infura.ts ================================================ export const INFURA_WEBSOCKET_HOSTS = { MAINNET: "wss://mainnet.infura.io/ws/v3", RINKEBY: "wss://rinkeby.infura.io/ws/v3", ROPSTEN: "wss://ropsten.infura.io/ws/v3", }; ================================================ FILE: packages/ethapi/tsconfig.json ================================================ { "extends": "../../tsconfig", "compilerOptions": { "outDir": "build/", "declarationDir": "build/", "allowSyntheticDefaultImports": true, "esModuleInterop": true }, "include": ["./src/**/*.ts"] // https://github.com/ReactiveX/rxjs/issues/3031 } ================================================ FILE: packages/ethapi/tslint.json ================================================ { "extends": ["@joincivil/tslint-rules"] } ================================================ FILE: packages/kirby/.gitignore ================================================ # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. # dependencies /node_modules /.pnp .pnp.js # testing /coverage # production /build # misc .DS_Store .env.local .env.development.local .env.test.local .env.production.local npm-debug.log* yarn-debug.log* yarn-error.log* ================================================ FILE: packages/kirby/.releaserc ================================================ { "plugins": [ [ "@semantic-release/commit-analyzer", { "preset": "angular", "releaseRules": [ { "type": "docs", "scope": "README", "release": "patch" }, { "type": "refactor", "release": "patch" }, { "type": "style", "release": "patch" } ], "parserOpts": { "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES"] } } ], [ "@semantic-release/release-notes-generator", { "preset": "angular", "parserOpts": { "noteKeywords": ["BREAKING CHANGE", "BREAKING CHANGES", "BREAKING"] }, "writerOpts": { "commitsSort": ["subject", "scope"] } } ] ] } ================================================ FILE: packages/kirby/README.md ================================================ This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). ## Available Scripts In the project directory, you can run: ### `npm start` Runs the app in the development mode.
    Open [http://localhost:3000](http://localhost:3000) to view it in the browser. The page will reload if you make edits.
    You will also see any lint errors in the console. ### `npm test` Launches the test runner in the interactive watch mode.
    See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. ### `npm run build` Builds the app for production to the `build` folder.
    It correctly bundles React in production mode and optimizes the build for the best performance. The build is minified and the filenames include the hashes.
    Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. ### `npm run eject` **Note: this is a one-way operation. Once you `eject`, you can’t go back!** If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. ## Learn More You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). To learn React, check out the [React documentation](https://reactjs.org/). ================================================ FILE: packages/kirby/package.json ================================================ { "name": "@joincivil/kirby", "version": "0.1.0", "private": false, "publishConfig": { "access": "public" }, "main": "build/index.js", "types": "build/index.d.ts", "dependencies": { "@joincivil/elements": "^0.0.1", "@kirby-web3/child-core": "^1.7.0", "@kirby-web3/child-react": "^1.1.13", "@kirby-web3/plugin-connext": "^1.1.13", "@kirby-web3/plugin-ethereum": "^1.11.0", "@types/jest": "24.0.15", "@types/node": "12.6.8", "@types/reach__router": "^1.2.4", "@types/react": "16.8.23", "@types/react-dom": "16.8.5", "ethers": "^4.0.37", "query-string": "^6.8.3", "react": "^16.11.0", "react-dom": "^16.11.0", "react-redux": "^7.1.0", "react-scripts": "3.1.1", "redux": "^4.0.4", "styled-components": "^4.3.2" }, "devDependencies": { "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", "react-test-renderer": "^16.11.0", "typescript": "^3.6.2" }, "scripts": { "build": "tsc", "build:watch": "tsc -w", "lint": "tslint --project ./", "clean": "rimraf build/" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } } ================================================ FILE: packages/kirby/src/KirbyApp.tsx ================================================ import React from "react"; import { KirbyChildProvider, overrideTheme } from "@kirby-web3/child-react"; import { EthereumChildPlugin, SignatureInterceptorPlugin, IDToNetwork } from "@kirby-web3/plugin-ethereum"; import { ConnextChildPlugin } from "@kirby-web3/plugin-connext"; import { Viewport } from "./viewport/Viewport"; import { createGlobalStyle } from "styled-components"; import { CivilIDPlugin } from "./plugins/CivilID"; const GlobalStyle = createGlobalStyle` .por_portis-widget-frame { top: 0 !important; bottom: auto !important; } @media (max-width: 576px) { .por_portis-widget-frame { top: 0 !important; bottom: auto !important; } } `; const theme = overrideTheme({ headingFont: "Libre Franklin", }); export interface KirbyAppProps { config: { INFURA_APP_KEY: string; PORTIS_APP_ID: string; DEFAULT_ETHEREUM_NETWORK: string; }; } const KirbyApp: React.FunctionComponent = ({ config }) => { console.log("loading kirby with config", config); const plugins = React.useMemo(() => { return [ new CivilIDPlugin(), new ConnextChildPlugin({ ethProviderUrl: "https://rinkeby.infura.io/v3/" + config.INFURA_APP_KEY, nodeUrl: "wss://rinkeby.indra.connext.network/api/messaging", }), new SignatureInterceptorPlugin({ autoSign: false }), new EthereumChildPlugin({ burnerPreference: "never", networks: { mainnet: "wss://mainnet.infura.io/ws/v3/" + config.INFURA_APP_KEY, rinkeby: "wss://rinkeby.infura.io/ws/v3/" + config.INFURA_APP_KEY, }, defaultNetwork: IDToNetwork[parseInt(config.DEFAULT_ETHEREUM_NETWORK, 10)], portis: { appID: config.PORTIS_APP_ID, }, }), ]; }, [config]); return ( ); }; export default KirbyApp; ================================================ FILE: packages/kirby/src/common/colors.ts ================================================ export enum colors { pink = "#ff4081", purple = "#aa66cc", orange = "#ffbb33", lightBlue = "#ff4444", blue = "#0d47a1", green = "#00C851", red = "#ff4444", } ================================================ FILE: packages/kirby/src/common/containers/layouts.tsx ================================================ import styled from "styled-components"; export const PageLayout = styled.div` background-color: #ffffff; border-radius: 4px 4px 4px; box-shadow: 0 2px 8px 0 rgba(128, 128, 128, 0.5); width: 375px; height: 500px; display: flex; flex-direction: column; align-items: center; padding: 5px; `; export const CenteredPage = styled(PageLayout)` flex-direction: row; align-items: center; padding: 5px; `; export const SwitchAuthTypeDiv = styled.div` margin-top: 10px; margin-bottom: 10px; margin-left: 10px; `; export const WaitingForConnectionDiv = styled.div` display: flex; height: 300px; flex-direction: column; align-items: center; justify-content: space-around; `; ================================================ FILE: packages/kirby/src/common/input/WalletOptions.tsx ================================================ import * as React from "react"; import { RadioGroup, RadioCardInput, MetaMask, Portis } from "@joincivil/elements"; import { ProviderTypes } from "@kirby-web3/plugin-ethereum"; export interface WalletOptionsProps { optionPrefix?: string; onChange(selection: ProviderTypes): void; } export const WalletOptions: React.FunctionComponent = ({ optionPrefix, onChange }) => { const hasInjectedWeb3 = (window as any).ethereum; const metaMaskSubheading = hasInjectedWeb3 ? "Your browser has Web3 built-in! Click here to use your built-in Web3 wallet." : "To use this option, you can install the MetaMask extension, or use another Web3 browser."; const prefix = optionPrefix ? optionPrefix + " " : ""; return ( onChange(provider)}> } value={ProviderTypes.METAMASK} heading={prefix + "MetaMask"} subheading={metaMaskSubheading} disabled={!hasInjectedWeb3} prioritized={hasInjectedWeb3} /> } value={ProviderTypes.PORTIS} heading={prefix + "Portis"} subheading="Web3 Wallet that does not require any downloads" /> ); }; ================================================ FILE: packages/kirby/src/common/text/index.tsx ================================================ import styled from "styled-components"; import { colors } from "../colors"; export interface FocusWordProps { color: colors; } export const FocusWord = styled.span` padding: 10px; color: ${(props: FocusWordProps) => props.color}; `; export const CenteredTextBlock = styled.div` margin-top: 20px; text-align: center; font-size: 28px; `; export const Notice = styled.div` background-color: ${colors.lightBlue}; font-size: 13px; width: 95%; margin: 10px 0; padding: 5px 10px; `; // Otherwise no href means no pointer. export const PointerAnchor = styled.a` cursor: pointer; `; ================================================ FILE: packages/kirby/src/index.tsx ================================================ import KirbyApp from "./KirbyApp"; export default KirbyApp; export { KirbyApp }; ================================================ FILE: packages/kirby/src/plugins/CivilID.ts ================================================ import { Action, MiddlewareAPI, Dispatch } from "redux"; import { ChildPlugin, PARENT_REQUEST, ParentHandler, ViewPlugin } from "@kirby-web3/child-core"; import { EthereumChildPlugin } from "@kirby-web3/plugin-ethereum"; import * as ethers from "ethers"; import { IDENTITY_LOGIN_REQUEST, IDENTITY_LOGIN_RESPONSE, IDENTITY_SIGNUP_REQUEST, LoginResponse } from "./common"; // action types // state export interface ChildPluginState { pendingLoginRequest?: { requestID: number; message: string; domain: string; }; pendingSignupRequest?: { requestID: number; message: string; domain: string; }; } // actions export interface IdentityLoginResponseAction { type: typeof IDENTITY_LOGIN_RESPONSE; payload: LoginResponse; } // action union type export type ChildPluginActions = IdentityLoginResponseAction; export interface ChildDependencies { ethereum: EthereumChildPlugin; iframe: ParentHandler; } export class CivilIDPlugin extends ChildPlugin { public name = "civilid"; public dependsOn = ["view", "ethereum", "iframe"]; public channel?: any; public middleware = (api: MiddlewareAPI) => (next: Dispatch) => (action: any): void => { if (action.type === PARENT_REQUEST) { switch (action.data.type) { case IDENTITY_LOGIN_REQUEST: (this.dependencies.view as ViewPlugin).requestView("/identity/login"); next(action); break; case IDENTITY_SIGNUP_REQUEST: (this.dependencies.view as ViewPlugin).requestView("/identity/signup"); next(action); break; default: next(action); } } else { next(action); } }; public reducer(state: ChildPluginState = {}, action: any): any { if (action.type === PARENT_REQUEST && action.data.type === IDENTITY_LOGIN_REQUEST) { return { ...state, pendingLoginRequest: this.buildSignatureRequest(action.requestID, this.dependencies.iframe.parentDomain), }; } else if (action.type === PARENT_REQUEST && action.data.type === IDENTITY_SIGNUP_REQUEST) { return { ...state, pendingSignupRequest: this.buildSignatureRequest(action.requestID, this.dependencies.iframe.parentDomain), }; } return state; } public async startup(): Promise { this.logger("starting up"); } public buildSignatureRequest(requestID: string, domain: string): any { const message = `Authenticate to ${domain} @ ${new Date().toISOString()}`; return { message, requestID, domain, }; } public sendLoginResponse(signer: string, signature: string): void { const state = this.getState().civilid as ChildPluginState; const { requestID, domain, ...request } = state.pendingLoginRequest!; const response = { signer, signature, ...request }; this.dependencies.iframe.respond(requestID, response); } public cancelLogin(reason?: any): void { const state = this.getState().civilid as ChildPluginState; const { requestID } = state.pendingLoginRequest!; this.dependencies.iframe.reject(requestID, reason || "cancelled"); } public sendSignupResponse(signer: string, signature: string): void { const state = this.getState().civilid as ChildPluginState; const { requestID, domain, ...request } = state.pendingSignupRequest!; const response = { signer, signature, ...request }; this.dependencies.iframe.respond(requestID, response); } public cancelSignup(reason?: any): void { const state = this.getState().civilid as ChildPluginState; const { requestID } = state.pendingSignupRequest!; this.dependencies.iframe.reject(requestID, reason || "cancelled"); } public generateWallet(mnemonic: string): void { const walletPath = "m/44'/60'/0'/0/0"; const hdnode = ethers.utils.HDNode.fromMnemonic(mnemonic); const node = hdnode.derivePath(walletPath); console.log("node", node.derivePath("1")); console.log("node1", node.derivePath("2")); console.log("node2", node.derivePath("3")); console.log("node3", node.derivePath("4")); } } ================================================ FILE: packages/kirby/src/plugins/common.ts ================================================ export const IDENTITY_LOGIN_REQUEST = "IDENTITY_LOGIN_REQUEST"; export const IDENTITY_LOGIN_RESPONSE = "IDENTITY_LOGIN_RESPONSE"; export const IDENTITY_SIGNUP_REQUEST = "IDENTITY_SIGNUP_REQUEST"; export interface LoginRequest { service: string; } export interface SignupRequest { service: string; } export interface LoginResponse { did: string; } ================================================ FILE: packages/kirby/src/viewport/Viewport.tsx ================================================ import * as React from "react"; import { useSelector as useKirbySelector } from "@kirby-web3/child-react"; import { Web3Enable } from "../views/Web3Enable"; import { SignatureConfirm } from "../views/SignatureConfirm"; import { Login } from "../views/identity/Login"; import { Signup } from "../views/identity/Signup"; export const Viewport: React.FC = () => { const view = useKirbySelector((state: any) => state.view.queue); if (view.length === 0) { return
    empty queue
    ; } else { switch (view[0].route) { case "/identity/login": return ; case "/identity/signup": return ; case "/ethereum/confirm-signature": return ; case "/ethereum/web3enable": return ; default: // @ts-ignore return
    error determining view
    ; } } }; ================================================ FILE: packages/kirby/src/views/SignatureConfirm.tsx ================================================ import * as React from "react"; import { CoreContext, useSelector as useKirbySelector, CenteredPage } from "@kirby-web3/child-react"; import { SignatureInterceptorPlugin, ProviderTypes } from "@kirby-web3/plugin-ethereum"; export const SignatureConfirm: React.FunctionComponent = () => { // context const ctx = React.useContext(CoreContext); const sig = ctx.core.plugins.signatureInterceptor as SignatureInterceptorPlugin; // state const [isPending, setPending] = React.useState(false); // kirby selectors const providerType = useKirbySelector((state: any) => state.ethereum.providerType); const plaintext = useKirbySelector((state: any) => { if (state.signatureInterceptor.requests && state.signatureInterceptor.requests[0]) { return state.signatureInterceptor.requests[0].plaintext; } }); // memos React.useMemo(() => { // these providers will prompt the user through their own UI if ([ProviderTypes.METAMASK, ProviderTypes.PORTIS].indexOf(providerType) > -1) { sig.approveAction(); setPending(true); } }, []); if (isPending) { return <>; } return ( signature requested:
    {plaintext}
    ); }; ================================================ FILE: packages/kirby/src/views/Web3Enable.tsx ================================================ import * as React from "react"; import { CoreContext, useSelector, CenteredPage } from "@kirby-web3/child-react"; import { EthereumChildPlugin } from "@kirby-web3/plugin-ethereum"; import { ViewPlugin } from "@kirby-web3/child-core"; import { ClipLoader } from "@joincivil/elements"; import { WalletOptions } from "../common/input/WalletOptions"; import { SwitchAuthTypeDiv } from "../common/containers/layouts"; const WAITING_FOR_CONNECTION = "Waiting for Web3 Wallet Connection..."; export const Web3Enable: React.FC = () => { const ctx = React.useContext(CoreContext); const [status, setStatus] = React.useState("provided"); const ethPlugin = ctx.core.plugins.ethereum as EthereumChildPlugin; const viewData = useSelector((state: any) => { if (state.view && state.view.queue && state.view.queue[0]) { return state.view.queue[0].data; } }); React.useEffect(() => { if (viewData.requestID) { if (viewData.providerPreference) { selection(viewData.providerPreference as string, true).catch(err => console.log("error with selection", err)); } else { setStatus("select"); } } }, [viewData]); async function selection(provider: string, providerKnown: boolean = false): Promise { console.log("selected:", provider, viewData.requestID, viewData.network); try { if (providerKnown) { setStatus("enabling known provider"); } else { setStatus("enabling provider"); } await ethPlugin.enableWeb3(viewData.requestID, provider, viewData.network as any); setStatus("done"); (ctx.core.plugins.view as ViewPlugin).completeView(); } catch (err) { console.log("error with enableWeb3: ", err); (ctx.core.plugins.view as ViewPlugin).completeView(); } } if (status === "provided") { return <>; } else if (status === "enabling known provider") { return <>; } else if (status === "enabling provider") { return ( {WAITING_FOR_CONNECTION} ); } return ( Enable your web3 wallet Don't want to connect a Web3 wallet at this time?{" "}
    { ethPlugin.cancelEnableWeb3(viewData.requestID); (ctx.core.plugins.view as ViewPlugin).completeView(); }} > Close ); }; ================================================ FILE: packages/kirby/src/views/identity/Login.tsx ================================================ import * as React from "react"; import { CoreContext, useSelector as useKirbySelector, CenteredPage } from "@kirby-web3/child-react"; import { ClipLoader } from "@joincivil/elements"; import { Notice, PointerAnchor } from "../../common/text"; import { EthereumChildPlugin } from "@kirby-web3/plugin-ethereum"; import { CivilIDPlugin } from "../../plugins/CivilID"; import { ViewPlugin } from "@kirby-web3/child-core"; import { WaitingForConnectionDiv, SwitchAuthTypeDiv } from "../../common/containers/layouts"; import { WalletOptions } from "../../common/input/WalletOptions"; const CIVIL_DOMAINS = [ "http://localhost:3000", "https://staging.civil.app", "https://test.civil.app", "https://registry.civil.co", "https://civil.co", ]; const WAITING_FOR_CONNECTION = "Waiting for Web3 Wallet Connection..."; const WAITING_FOR_SIGNATURE = "Waiting for Signature..."; export const Login: React.FunctionComponent = () => { const ctx = React.useContext(CoreContext); const identityPlugin = ctx.core.plugins.civilid as CivilIDPlugin; const parentDomain = useKirbySelector((state: any) => state.iframe.parentDomain); const ready = useKirbySelector((state: any) => state.civilid.pendingLoginRequest); const service = useKirbySelector((state: any) => ready && state.civilid.pendingLoginRequest.service); const isCivil = service === "Civil" && CIVIL_DOMAINS.indexOf(parentDomain) > -1; const [hideSelections, setHideSelections] = React.useState(false); const [selectionProcess, setSelectionProcess] = React.useState("none"); React.useEffect(() => { (ctx.core.plugins.view as ViewPlugin).onParentClick(() => { identityPlugin.cancelLogin(); (ctx.core.plugins.view as ViewPlugin).completeView(); }); }, [ctx.core.plugins.view, identityPlugin]); async function selection(provider: string): Promise { setHideSelections(true); setSelectionProcess(WAITING_FOR_CONNECTION); const network = ctx.core.plugins.ethereum.config.defaultNetwork; const ethPlugin = ctx.core.plugins.ethereum as EthereumChildPlugin; const request = ctx.store.getState().civilid.pendingLoginRequest; await ethPlugin.changeProvider(provider, network as any); const accounts = await (ethPlugin.web3 as any).eth.getAccounts(); const signer = accounts[0]; try { setSelectionProcess(WAITING_FOR_SIGNATURE); const signature = await (ethPlugin.web3 as any).eth.personal.sign(request.message, signer); identityPlugin.sendLoginResponse(signer, signature); } catch (err) { console.error("error with signature"); identityPlugin.cancelLogin(err); } (ctx.core.plugins.view as ViewPlugin).completeView(); } return ( {isCivil ? null : ( {parentDomain} is requesting to log in. )} {hideSelections && ( <>{selectionProcess} )} {!hideSelections && ( <> Not a Civil member?{" "} { identityPlugin.cancelLogin("switch to sign up"); (ctx.core.plugins.view as ViewPlugin).completeView(); }} > Sign up to join )} ); }; ================================================ FILE: packages/kirby/src/views/identity/Signup.tsx ================================================ import * as React from "react"; import styled from "styled-components"; import { CoreContext, useSelector as useKirbySelector, CenteredPage } from "@kirby-web3/child-react"; import { EthereumChildPlugin } from "@kirby-web3/plugin-ethereum"; import { ViewPlugin } from "@kirby-web3/child-core"; import { ClipLoader } from "@joincivil/elements"; import { Notice } from "../../common/text"; import { CivilIDPlugin } from "../../plugins/CivilID"; import { SwitchAuthTypeDiv, WaitingForConnectionDiv } from "../../common/containers/layouts"; import { WalletOptions } from "../../common/input/WalletOptions"; const CIVIL_DOMAINS = [ "http://localhost:3000", "https://staging.civil.app", "https://test.civil.app", "https://registry.civil.co", "https://civil.co", ]; const WAITING_FOR_CONNECTION = "Waiting for Web3 Wallet Connection..."; const WAITING_FOR_SIGNATURE = "Waiting for Signature..."; const SignupFooter = styled.div` border-top: 1px solid #d8d8d8; margin-top: 40px; padding-top: 20px; text-align: center; font-size: 15px; `; export const Signup: React.FunctionComponent = () => { const ctx = React.useContext(CoreContext); const identityPlugin = ctx.core.plugins.civilid as CivilIDPlugin; const parentDomain = useKirbySelector((state: any) => state.iframe.parentDomain); const ready = useKirbySelector((state: any) => state.civilid.pendingSignupRequest); const service = useKirbySelector((state: any) => ready && state.civilid.pendingSignupRequest.service); const isCivil = service === "Civil" && CIVIL_DOMAINS.indexOf(parentDomain) > -1; const [hideSelections, setHideSelections] = React.useState(false); const [selectionProcess, setSelectionProcess] = React.useState("none"); React.useEffect(() => { (ctx.core.plugins.view as ViewPlugin).onParentClick(() => { identityPlugin.cancelSignup(); (ctx.core.plugins.view as ViewPlugin).completeView(); }); }, [ctx.core.plugins.view, identityPlugin]); async function selection(provider: string): Promise { setHideSelections(true); setSelectionProcess(WAITING_FOR_CONNECTION); const network = ctx.core.plugins.ethereum.config.defaultNetwork; const ethPlugin = ctx.core.plugins.ethereum as EthereumChildPlugin; const request = ctx.store.getState().civilid.pendingSignupRequest; await ethPlugin.changeProvider(provider, network as any); const accounts = await (ethPlugin.web3 as any).eth.getAccounts(); const signer = accounts[0]; console.log("preparing to sign:", signer, request); try { setSelectionProcess(WAITING_FOR_SIGNATURE); const signature = await (ethPlugin.web3 as any).eth.personal.sign(request.message, signer); identityPlugin.sendSignupResponse(signer, signature); setHideSelections(false); } catch (err) { console.error("error with signature"); identityPlugin.cancelSignup(); setHideSelections(false); } (ctx.core.plugins.view as ViewPlugin).completeView(); } return ( {isCivil ? null : ( {parentDomain} would like you to sign up to their service. )} {hideSelections && ( <>{selectionProcess} )} {!hideSelections && ( <> Already a Civil member?{" "} { identityPlugin.cancelSignup("switch to log in"); (ctx.core.plugins.view as ViewPlugin).completeView(); }} > Click to Log In {isCivil ? renderTerms() : null} )} ); function renderTerms(): JSX.Element { return ( By signing up, you accept Civil's Terms of Use {" "} and{" "} Privacy Policy . ); } }; ================================================ FILE: packages/kirby/tsconfig.json ================================================ { "extends": "../../tsconfig", "compilerOptions": { "outDir": "build/", "declaration": true, "declarationDir": "build/", "jsx": "react", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "lib": ["dom", "es2017"] }, "include": ["./src/**/*.ts", "./src/**/*.tsx"] } ================================================ FILE: packages/kirby/tslint.json ================================================ { "extends": ["@joincivil/tslint-rules"], "rules": { "variable-name": [true, "ban-keywords", "allow-leading-underscore"] } } ================================================ FILE: packages/newsroom-manager/package.json ================================================ { "name": "@joincivil/newsroom-manager", "version": "1.8.11", "description": "ui for managing a newsroom contract", "main": "build/index.js", "types": "build/index.d.ts", "repository": "https://github.com/joincivil/Civil", "license": "MIT", "private": false, "scripts": { "build": "tsc", "build:watch": "tsc -w", "lint": "tslint --project ./", "clean": "rimraf build/", "prepublish": "run-s build", "test": "echo \"add tests please\"" }, "dependencies": { "@joincivil/components": "^1.9.10", "@joincivil/core": "^4.8.11", "@joincivil/ethapi": "^0.4.9", "@joincivil/utils": "^1.9.9", "@types/react": "^16.8.10", "@types/styled-components": "^4.1.18", "ethereumjs-util": "^5.2.0", "ipfs-api": "^26.1.2", "lodash": "^4.17.10" }, "devDependencies": { "@joincivil/typescript-types": "^1.4.9", "@types/redux-thunk": "^2.1.0", "immutable": "^3.8.2", "npm-run-all": ">=4.1.5", "react": "^16.11.0", "react-dom": "^16.11.0", "react-redux": "^7.1.1", "redux": "^4.0.0", "rimraf": "^2.6.2", "styled-components": "^5.0.0-beta.8", "typescript": "^3.6.2" }, "peerDependencies": { "react": "^16.8", "react-dom": "^16.8" }, "publishConfig": { "access": "public" } } ================================================ FILE: packages/newsroom-manager/src/ApplyToTCR.tsx ================================================ import * as React from "react"; import { StepHeader, StepFormSection, TransactionButton } from "@joincivil/components"; import styled from "styled-components"; import { EthAddress } from "@joincivil/typescript-types"; import { connect } from "react-redux"; import { CivilContext, CivilContextValue } from "./CivilContext"; export interface ApplyToTCRProps { address?: EthAddress; newsroom?: any; } const FormSectionInner = styled("div")` padding: 46px; background-color: #fffef6; opacity: 0.8; margin: 16px -38px; `; export class ApplyToTCRComponent extends React.Component { public render(): JSX.Element { return ( <> Apply to the Civil Registry {(value: CivilContextValue) => { return ( <> { const multisigAddr = await this.props.newsroom.getMultisigAddress(); const tcr = await value.civil!.tcrSingletonTrusted(); const parameterizer = await tcr.getParameterizer(); const minDeposit = await parameterizer.getParameterValue("minDeposit"); const token = await tcr.getToken(); return token.transfer(multisigAddr, minDeposit); }, }, ]} > Send CVL to Multisig { const multisigAddr = await this.props.newsroom.getMultisigAddress(); const tcr = await value.civil!.tcrSingletonTrustedMultisigSupport(multisigAddr); const parameterizer = await tcr.getParameterizer(); const minDeposit = await parameterizer.getParameterValue("minDeposit"); const token = await tcr.getToken(); const approvedTokens = await token.getApprovedTokensForSpender(tcr.address, multisigAddr); if (approvedTokens.lt(minDeposit)) { return token.approveSpender(tcr.address, minDeposit); } return; }, }, { transaction: async () => { const multisigAddr = await this.props.newsroom.getMultisigAddress(); const tcr = await value.civil!.tcrSingletonTrustedMultisigSupport(multisigAddr); const parameterizer = await tcr.getParameterizer(); const deposit = await parameterizer.getParameterValue("minDeposit"); return tcr.apply(this.props.address!, deposit, ""); }, }, ]} > Apply to TCR ); }} ); } } const mapStateToProps = (state: any, ownProps: ApplyToTCRProps): ApplyToTCRProps => { const newsroom = state.newsrooms.get(ownProps.address); return { ...ownProps, newsroom: newsroom ? newsroom.newsroom : null, }; }; export const ApplyToTCR = connect(mapStateToProps)(ApplyToTCRComponent); ================================================ FILE: packages/newsroom-manager/src/ApplyToTCRPlaceholder.tsx ================================================ import * as React from "react"; import { StepHeader, StepFormSection, BorderlessButton, WaitForApply, buttonSizes } from "@joincivil/components"; import styled from "styled-components"; import { EthAddress } from "@joincivil/typescript-types"; import { connect } from "react-redux"; export interface ApplyToTCRProps { address?: EthAddress; newsroom?: any; } const FormSectionInner = styled("div")` padding: 46px; background-color: #fffef6; opacity: 0.8; margin: 16px -38px; `; const LearnMoreButton = styled(BorderlessButton)` margin-left: 0; padding-left: 0; `; const P = styled("p")` font-size: 14px; `; const H = styled("h4")` color: #000; margin-bottom: 0; `; export class ApplyToTCRComponent extends React.Component { public render(): JSX.Element { return ( <> Apply to the Civil Registry

    Your current newsroom application is saved. Thank you for filling out your newsroom application. We are launching the Civil Registry soon and you will need to come back to complete your newsroom application once that happens.

    You are able to edit your application at any time before submission.

    You'll recieve a notification message in your WordPress dashboard when you are able to apply to the Registry.


    What is the Civil Registry? Learn More
    ); } } const mapStateToProps = (state: any, ownProps: ApplyToTCRProps): ApplyToTCRProps => { const newsroom = state.newsrooms.get(ownProps.address); return { ...ownProps, newsroom: newsroom ? newsroom.newsroom : null, }; }; export const ApplyToTCRPlaceholder = connect(mapStateToProps)(ApplyToTCRComponent); ================================================ FILE: packages/newsroom-manager/src/CivilContext.tsx ================================================ import { Civil } from "@joincivil/core"; import * as React from "react"; export interface CivilContextValue { civil: Civil | undefined; account?: string; requiredNetwork: string; currentNetwork?: string; } const defaultContext: CivilContextValue = { civil: undefined, account: undefined, currentNetwork: undefined, requiredNetwork: "rinkeby|ganache", }; export const CivilContext = React.createContext(defaultContext); ================================================ FILE: packages/newsroom-manager/src/CompleteYourProfile.tsx ================================================ import { AddressInput, BorderlessButton, buttonSizes, colors, DetailTransactionButton, fonts, StepDescription, StepHeader, StepFormSection, Transaction, TransactionButtonModalFlowState, MetaMaskModal, ModalHeading, Modal, Button, } from "@joincivil/components"; import { EthAddress } from "@joincivil/typescript-types"; import { NewsroomRoles } from "@joincivil/utils"; import * as React from "react"; import { connect, DispatchProp } from "react-redux"; import styled from "styled-components"; import { addAndHydrateEditor, addAndHydrateOwner } from "./actionCreators"; import { CivilContext, CivilContextValue } from "./CivilContext"; import { NewsroomUser, UserTypes } from "./NewsroomUser"; import { FormTitle, QuestionToolTip } from "./styledComponents"; import { StateWithNewsroom } from "./reducers"; import { getUserObject } from "./utils"; import { UserData } from "./types"; import { TransactionButtonInner } from "./TransactionButtonInner"; import { isValidAddress } from "ethereumjs-util"; export interface CompleteYourProfileComponentExternalProps { userIsOwner?: boolean; userIsEditor?: boolean; address?: EthAddress; profileWalletAddress?: EthAddress; renderUserSearch?(onSetAddress: any): JSX.Element; } export interface CompleteYourProfileComponentProps { owners: UserData[]; editors: UserData[]; userIsOwner?: boolean; userIsEditor?: boolean; address?: EthAddress; newsroom: any; active?: boolean; } export interface CompleteYourProfileComponentState extends TransactionButtonModalFlowState { addOwner: boolean; addEditor: boolean; newOwner: EthAddress; newEditor: EthAddress; disableOwnerAdd: boolean; disableEditorAdd: boolean; } const Section = styled.div` display: flex; flex-direction: column; align-items: flex-start; justify-content: space-between; margin-bottom: 20px; `; const FormTitleSection = styled(Section)` flex-direction: row; justify-content: flex-start; `; const FormDescription = styled.p` font-family: ${fonts.SANS_SERIF}; color: ${colors.accent.CIVIL_GRAY_2}; font-size: 15px; width: 430px; margin-left: 50px; `; const AddButton = styled(BorderlessButton)` padding-left: 0px; `; const Description = styled(StepDescription)` font-size: 14px; `; class CompleteYourProfileComponent extends React.Component< CompleteYourProfileComponentProps & CompleteYourProfileComponentExternalProps & DispatchProp, CompleteYourProfileComponentState > { constructor(props: CompleteYourProfileComponentProps & DispatchProp) { super(props); this.state = { addOwner: false, addEditor: false, newOwner: "", newEditor: "", modalOpen: false, disableEditorAdd: true, disableOwnerAdd: true, }; } public renderPreMetamMask(): JSX.Element | null { if (!this.state.isPreTransactionModalOpen) { return null; } const message = this.state.addEditor ? "Open MetaMask to add Civil Member" : "Open MetaMask to add Civil Officer"; return ( this.cancelTransaction()} startTransaction={() => this.startTransaction()} > {message} ); } public renderMetaMaskRejectionModal(): JSX.Element | null { if (!this.state.metaMaskRejectionModal) { return null; } const message = this.state.addEditor ? "Your new Civil Member was not added" : "Your new Civil Officer was not added"; const denialMessage = this.state.addEditor ? "To add a new Civil Member, you need to confirm the transaction in your MetaMask wallet." : "To add a new Civil Officer, you need to confirm the transaction in your MetaMask wallet."; return ( {(value: CivilContextValue) => ( this.cancelTransaction()} restartTransactions={this.getTransaction(true)} > {message} )} ); } public renderAwaitingTransactionModal(): JSX.Element | null { if (!this.state.isWaitingTransactionModalOpen) { return null; } return ( this.cancelTransaction()} startTransaction={() => this.startTransaction()} > Waiting to Confirm in MetaMask ); } public renderProgressModal(): JSX.Element | null { if (!this.state.modalOpen) { return null; } const message = this.state.addEditor ? "A Civil Member is being added to your newsroom smart contract" : "A Civil Officer is being added to your newsroom smart contract"; return (

    {message}

    You have confirmed the transaction in your MetaMask wallet and it is currently processing

    Note, that this could take a while depending on traffic on the Ethereum network. You can close this while the transaction is processing.

    ); } public renderCompleteModal(): JSX.Element | null { if (!this.state.completeModalOpen) { return null; } const message = this.state.addEditor ? "A Civil Member has been added to the newsroom smart contract!" : "A Civil Officer has been added to the newsroom smart contract!"; return (

    {message}

    The transaction has completed and the {this.state.addEditor ? "Civil Member" : "Civil Officer"} was added. You can keep adding officers and members to your newsroom smart contract or continue to the next step to create your Registry profile.

    ); } public renderEditorInputs(): JSX.Element { const onSetAddress = (address: string) => { const valid = isValidAddress(address); this.setState({ newEditor: address, disableEditorAdd: !valid }); }; return this.props.renderUserSearch ? ( this.props.renderUserSearch(onSetAddress) ) : ( onSetAddress(val)} /> ); } public renderOwnerInputs(): JSX.Element { const onSetAddress = (address: string) => { const valid = isValidAddress(address); this.setState({ newOwner: address, disableOwnerAdd: !valid }); }; return this.props.renderUserSearch ? ( this.props.renderUserSearch(onSetAddress) ) : ( onSetAddress(val)} /> ); } public renderAddEditorForm(): JSX.Element { if (!this.state.addEditor) { return ( this.setState({ addEditor: true })}> + Add Civil Member ); } else { return ( {(value: CivilContextValue) => ( <> {this.renderEditorInputs()} Add Civil Member )} ); } } public renderAddOwnerForm(): JSX.Element { if (this.props.userIsEditor && !this.props.userIsOwner) { return (

    You are on the contract as a Member, not an Officer, so you cannot add additional Officers. You may add and remove Civil Members below.

    ); } else if (!this.state.addOwner) { return ( this.setState({ addOwner: true })}> + Add Civil Officer ); } else { return ( {(value: CivilContextValue) => ( <> {this.renderOwnerInputs()} Add Civil Officer )} ); } } public render(): JSX.Element { return ( <> Add accounts to your newsroom smart contract Add additional officers and members to your newsroom smart contract. You will need their public wallet addresses. This step is optional, but recommended. Civil Officer An Officer is an admin role that has all possible capabilities in the newsroom smart contract. They can add additional officers and members and have access to your newsroom's funds and Civil Registry application.
    {this.props.owners.map(item => { return ( ); })}
    {this.renderAddOwnerForm()}
    Civil Member A Member is the standard role in the newsroom smart contract. They have permission to sign, index and archive posts on the blockchain. They cannot add Civil Officers to you newsroom smart contract or access your newsroom's funds.
    {this.props.editors.map(item => ( ))}
    {this.renderAddEditorForm()}
    {this.renderPreMetamMask()} {this.renderAwaitingTransactionModal()} {this.renderMetaMaskRejectionModal()} {this.renderCompleteModal()} {this.renderProgressModal()} ); } private getTransaction = (noPreModal?: boolean): Transaction[] => { return [ { requireBeforeTransaction: noPreModal ? undefined : this.requireBeforeTransaction, transaction: async (): Promise => { this.setState({ metaMaskRejectionModal: false, isWaitingTransactionModalOpen: true, isPreTransactionModalOpen: false, }); return this.state.addEditor ? this.addEditor() : this.addOwner(); }, postTransaction: result => { if (this.state.addEditor) { this.props.dispatch!(addAndHydrateEditor(this.props.address!, this.state.newEditor)); } else { this.props.dispatch!(addAndHydrateOwner(this.props.address!, this.state.newOwner)); } this.setState({ modalOpen: false, completeModalOpen: true, newOwner: "", newEditor: "", }); }, handleTransactionHash: txhash => { this.setState({ modalOpen: true, isWaitingTransactionModalOpen: false, }); }, handleTransactionError: (err: Error) => { this.setState({ isWaitingTransactionModalOpen: false }); if (err.message === "Error: MetaMask Tx Signature: User denied transaction signature.") { this.setState({ metaMaskRejectionModal: true }); } }, }, ]; }; private requireBeforeTransaction = async () => { return new Promise((res, rej) => { this.setState({ startTransaction: res, cancelTransaction: rej, isPreTransactionModalOpen: true, }); }); }; private cancelTransaction = () => { if (this.state.cancelTransaction) { this.state.cancelTransaction(); } this.setState({ cancelTransaction: undefined, startTransaction: undefined, isPreTransactionModalOpen: false, metaMaskRejectionModal: false, }); }; private startTransaction = () => { if (this.state.startTransaction) { this.state.startTransaction(); } this.setState({ cancelTransaction: undefined, startTransaction: undefined, isPreTransactionModalOpen: false, isWaitingTransactionModalOpen: true, }); }; private addOwner = async (): Promise => { return this.props.newsroom.addOwner(this.state.newOwner); }; private addEditor = async (): Promise => { return this.props.newsroom.addRole(this.state.newEditor, NewsroomRoles.Editor); }; } const mapStateToProps = ( state: StateWithNewsroom, ownProps: CompleteYourProfileComponentExternalProps, ): CompleteYourProfileComponentProps & CompleteYourProfileComponentExternalProps => { const { address } = ownProps; const newsroom = state.newsrooms.get(address || "") || { wrapper: { data: {} } }; const owners: UserData[] = (newsroom.wrapper.data.owners || []).map(getUserObject.bind(null, state)); const editors: UserData[] = ((newsroom.editors && newsroom.editors.toArray()) || []).map( getUserObject.bind(null, state), ); return { ...ownProps, address, owners, editors, newsroom: newsroom.newsroom, }; }; export const CompleteYourProfile = connect(mapStateToProps)(CompleteYourProfileComponent); ================================================ FILE: packages/newsroom-manager/src/CreateCharterPartOne.tsx ================================================ import * as React from "react"; import { connect, DispatchProp } from "react-redux"; import { find, findIndex } from "lodash"; import styled from "styled-components"; import { colors, StepHeader, StepProps, StepDescription, QuestionToolTip } from "@joincivil/components"; import { EthAddress, CharterData, RosterMember as RosterMemberInterface } from "@joincivil/typescript-types"; import { isValidHttpUrl } from "@joincivil/utils"; import { RosterMember } from "./RosterMember"; import { FormSection, FormTitle, FormSubhead, FormRow, FormRowItem, HelperText, StyledTextInput, StyledTextareaInput, } from "./styledComponents"; import { StateWithNewsroom } from "./reducers"; import { getUserObject } from "./utils"; import { UserData } from "./types"; export interface CreateCharterPartOneExternalProps extends StepProps { charter: Partial; address?: EthAddress; updateCharter(charter: Partial): void; } export interface CreateCharterPartOneProps extends CreateCharterPartOneExternalProps { owners: UserData[]; editors: UserData[]; } const LogoFormWrap = styled.div` display: flex; justify-content: space-between; margin-top: -4px; `; const LogoURLWrap = styled.div` flex-grow: 2; margin-right: 15px; padding-right: 15px; border-right: 1px solid ${colors.accent.CIVIL_GRAY_4}; `; const LogoURLInput = styled(StyledTextInput)` &, input { margin-bottom: 0; } `; const LogoImgWrap = styled.div` position: relative; width: 100px; `; const LogoImg = styled.img` position: absolute; width: 100px; height: auto; top: -50%; `; const NewsroomURLInput = styled(StyledTextInput)` max-width: 400px; `; const TaglineTextarea = styled(StyledTextareaInput)` height: 80px; margin: -4px 0 0; `; const AddRosterMember = styled.a` display: block; cursor: pointer; padding: 22px 0 22px 30px; text-decoration: none; font-weight: bold; border-top: 1px solid ${colors.accent.CIVIL_GRAY_4}; border-bottom: 1px solid ${colors.accent.CIVIL_GRAY_4}; outline: none !important; box-shadow: none !important; `; class CreateCharterPartOneComponent extends React.Component> { public render(): JSX.Element { const charter = this.props.charter; const contractUsers = this.props.owners.concat(this.props.editors); return ( <> Create your Registry profile Add your Newsroom profile information. This will be included on your smart contract and shown on your listing page in the Civil Registry. Newsroom Profile

    Enter your newsroom profile details.

    Logo Customize > Site Identity it will be used here. We recommend the image be square and at minimum 300 x 300 pixels." } /> {charter.logoUrl && } Must be image URL
    Newsroom URL
    Tagline 120} invalidMessage={"Too long"} /> Maximum of 120 Characters
    Twitter URL
    Facebook URL
    Newsroom Roster

    Select the participants in your WordPress newsroom you want to add your roster and include any relevant credentials.

    {(charter.roster || []).map((member, i) => { const contractUser = find(contractUsers, user => user.rosterData.ethAddress === member.ethAddress); return ( ); })} Add Additional Roster Member
    ); } private charterInputChange = (name: string, val: string) => { this.props.updateCharter({ ...this.props.charter, [name]: val, }); }; private charterSocialInputChange = (type: string, url: string) => { this.props.updateCharter({ ...this.props.charter, socialUrls: { ...this.props.charter.socialUrls, [type]: url, }, }); }; private addRosterMember = (e: any) => { e.preventDefault(); const newMember = {}; this.props.updateCharter({ ...this.props.charter, roster: (this.props.charter.roster || []).concat(newMember as RosterMemberInterface), }); }; private rosterMemberUpdate = ( oldVal: Partial, newVal: Partial, deleteMember?: boolean, ) => { const roster = (this.props.charter.roster || []).slice(); if ( newVal.ethAddress && oldVal.ethAddress !== newVal.ethAddress && find(roster, rosterMember => rosterMember.ethAddress === newVal.ethAddress) ) { // Address being updated to an address already on roster, an edge-case that would put UI in a weird state, a pain to handle, so just alert for now and don't apply change. alert('Wallet address "' + newVal.ethAddress + '" already exists your newsroom roster.'); return; } const key = oldVal.ethAddress ? "ethAddress" : "name"; const memberIndex = findIndex(roster, rosterMember => rosterMember[key] === oldVal[key]); if (deleteMember) { roster.splice(memberIndex, 1); } else { roster[memberIndex] = newVal as RosterMemberInterface; } this.props.updateCharter({ ...this.props.charter, roster, }); }; private invalidUrlInput = (url?: string): boolean => { return !!url && !isValidHttpUrl(url); }; } const mapStateToProps = ( state: StateWithNewsroom, ownProps: CreateCharterPartOneExternalProps, ): CreateCharterPartOneProps => { const newsroom = state.newsrooms.get(ownProps.address || "") || { wrapper: { data: {} } }; const owners: UserData[] = (newsroom.wrapper.data.owners || []).map(getUserObject.bind(null, state)); const editors: UserData[] = ((newsroom.editors && newsroom.editors.toArray()) || []).map( getUserObject.bind(null, state), ); return { ...ownProps, owners, editors, }; }; export const CreateCharterPartOne = connect(mapStateToProps)(CreateCharterPartOneComponent); ================================================ FILE: packages/newsroom-manager/src/CreateCharterPartTwo.tsx ================================================ import * as React from "react"; import { connect, DispatchProp } from "react-redux"; import styled from "styled-components"; import { StepHeader, StepProps, StepDescription, TextareaInput } from "@joincivil/components"; import { CharterData } from "@joincivil/typescript-types"; import { FormSection, FormTitle, FormSubhead } from "./styledComponents"; import { StateWithNewsroom } from "./reducers"; export interface CreateCharterPartTwoProps extends StepProps { charter: Partial; updateCharter(charter: Partial): void; } const Textarea = styled(TextareaInput)` height: 140px; `; class CreateCharterPartTwoComponent extends React.Component> { constructor(props: CreateCharterPartTwoProps & DispatchProp) { super(props); } public render(): JSX.Element { return ( <> Write your charter Civil’s Registry is based on transparency and trust, so we ask newsrooms to be as open and clear as possible in answering the following questions. The aim is to ensure the Civil community is able to make an informed decision about new applicants and uphold the highest standards of journalism. We ask that any newsroom applying to the registry provide the information below to the best of their ability. {/*TODO: link "Civil Registry" to registry once it's launch*/} This information will also be included on your smart contract and shown on your listing page in the Civil Registry.{" "} Note that the information you provide will be public on the platform and used by the Civil community as the basis for accepting or rejecting your newsroom. We recommend reviewing the{" "} Constitution {" "} closely to familiarize yourself with Civil’s code of ethics before filling it out. {" "} You can change or amend this charter at any time. Identify your newsroom's journalistic mission. Please describe your newsroom's mission or purpose.