<commit_before>const injectIntl = require('react-intl').injectIntl;
const PropTypes = require('prop-types');
const intlShape = require('react-intl').intlShape;
const FormattedMessage = require('react-intl').FormattedMessage;

const MediaQuery = require('react-responsive').default;
const React = require('react');
const Formsy = require('formsy-react').default;
const classNames = require('classnames');

const GUI = require('scratch-gui').default;
const IntlGUI = injectIntl(GUI);

const AdminPanel = require('../../components/adminpanel/adminpanel.jsx');
const decorateText = require('../../lib/decorate-text.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
const Avatar = require('../../components/avatar/avatar.jsx');
const Banner = require('./banner.jsx');
const ModInfo = require('./mod-info.jsx');
const RemixCredit = require('./remix-credit.jsx');
const RemixList = require('./remix-list.jsx');
const Stats = require('./stats.jsx');
const StudioList = require('./studio-list.jsx');
const Subactions = require('./subactions.jsx');
const InplaceInput = require('../../components/forms/inplace-input.jsx');
const TopLevelComment = require('./comment/top-level-comment.jsx');
const ComposeComment = require('./comment/compose-comment.jsx');
const ExtensionChip = require('./extension-chip.jsx');
const thumbnailUrl = require('../../lib/user-thumbnail');

const projectShape = require('./projectshape.jsx').projectShape;
require('./preview.scss');

const frameless = require('../../lib/frameless');

// disable enter key submission on formsy input fields; otherwise formsy thinks
// we meant to trigger the "See inside" button. Instead, treat these keypresses
// as a blur, which will trigger a save.
const onKeyPress = e => {
    if (e.target.type === 'text' && e.which === 13 /* Enter */) {
        e.preventDefault();
        e.target.blur();
    }
};

const PreviewPresentation = ({
    addToStudioOpen,
    adminModalOpen,
    adminPanelOpen,
    assetHost,
    backpackHost,
    canAddToStudio,
    canDeleteComments,
    canRemix,
    canReport,
    canRestoreComments,
    canSave,
    canShare,
    canUseBackpack,
    cloudHost,
    comments,
    editable,
    extensions,
    faved,
    favoriteCount,
    intl,
    isFullScreen,
    isLoggedIn,
    isNewScratcher,
    isRemixing,
    isScratcher,
    isShared,
    justRemixed,
    justShared,
    loveCount,
    loved,
    modInfo,
    moreCommentsToLoad,
    onAddComment,
    onAddToStudioClicked,
    onAddToStudioClosed,
    onCloseAdminPanel,
    onCopyProjectLink,
    onDeleteComment,
    onFavoriteClicked,
    onLoadMore,
    onLoveClicked,
    onOpenAdminPanel,
    onRemix,
    onRemixing,
    onReportClicked,
    onReportClose,
    onReportComment,
    onReportSubmit,
    onRestoreComment,
    onSeeAllComments,
    onSeeInside,
    onShare,
    onToggleComments,
    onToggleStudio,
    onUpdate,
    onUpdateProjectId,
    originalInfo,
    parentInfo,
    projectHost,
    projectId,
    projectInfo,
    projectStudios,
    remixes,
    replies,
    reportOpen,
    showModInfo,
    singleCommentId,
    userOwnsProject,
    visibilityInfo
}) => {
    const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : '';
    const revisedDate = ((projectInfo.history && projectInfo.history.modified)) ? projectInfo.history.modified : '';

    // Allow embedding html in banner messages coming from the server
    const embedCensorMessage = message => (
        // eslint-disable-next-line react/no-danger
        <span dangerouslySetInnerHTML={{__html: message}} />
    );

    let banner;
    if (visibilityInfo.deleted) { // If both censored and deleted, prioritize deleted banner
        banner = (<Banner
            className="banner-danger"
            message={<FormattedMessage id="project.deletedBanner" />}
        />);
    } else if (visibilityInfo.censored) {
        if (visibilityInfo.reshareable) {
            banner = (<Banner
                actionMessage={<FormattedMessage id="project.share.shareButton" />}
                className="banner-danger"
                message={embedCensorMessage(visibilityInfo.message)}
                onAction={onShare}
            />);
        } else {
            banner = (<Banner
                className="banner-danger"
                message={embedCensorMessage(visibilityInfo.message)}
            />);
        }
    } else if (justRemixed && isNewScratcher) {
        banner = (
            <Banner
                className="banner-success"
                message={
                    <FormattedMessage
                        id="project.remix.justRemixed"
                        values={{title: projectInfo.title}}
                    /><commit_msg>show remixed banner to all, not just new scratchers<commit_after>const injectIntl = require('react-intl').injectIntl;
const PropTypes = require('prop-types');
const intlShape = require('react-intl').intlShape;
const FormattedMessage = require('react-intl').FormattedMessage;

const MediaQuery = require('react-responsive').default;
const React = require('react');
const Formsy = require('formsy-react').default;
const classNames = require('classnames');

const GUI = require('scratch-gui').default;
const IntlGUI = injectIntl(GUI);

const AdminPanel = require('../../components/adminpanel/adminpanel.jsx');
const decorateText = require('../../lib/decorate-text.jsx');
const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
const Avatar = require('../../components/avatar/avatar.jsx');
const Banner = require('./banner.jsx');
const ModInfo = require('./mod-info.jsx');
const RemixCredit = require('./remix-credit.jsx');
const RemixList = require('./remix-list.jsx');
const Stats = require('./stats.jsx');
const StudioList = require('./studio-list.jsx');
const Subactions = require('./subactions.jsx');
const InplaceInput = require('../../components/forms/inplace-input.jsx');
const TopLevelComment = require('./comment/top-level-comment.jsx');
const ComposeComment = require('./comment/compose-comment.jsx');
const ExtensionChip = require('./extension-chip.jsx');
const thumbnailUrl = require('../../lib/user-thumbnail');

const projectShape = require('./projectshape.jsx').projectShape;
require('./preview.scss');

const frameless = require('../../lib/frameless');

// disable enter key submission on formsy input fields; otherwise formsy thinks
// we meant to trigger the "See inside" button. Instead, treat these keypresses
// as a blur, which will trigger a save.
const onKeyPress = e => {
    if (e.target.type === 'text' && e.which === 13 /* Enter */) {
        e.preventDefault();
        e.target.blur();
    }
};

const PreviewPresentation = ({
    addToStudioOpen,
    adminModalOpen,
    adminPanelOpen,
    assetHost,
    backpackHost,
    canAddToStudio,
    canDeleteComments,
    canRemix,
    canReport,
    canRestoreComments,
    canSave,
    canShare,
    canUseBackpack,
    cloudHost,
    comments,
    editable,
    extensions,
    faved,
    favoriteCount,
    intl,
    isFullScreen,
    isLoggedIn,
    isNewScratcher,
    isRemixing,
    isScratcher,
    isShared,
    justRemixed,
    justShared,
    loveCount,
    loved,
    modInfo,
    moreCommentsToLoad,
    onAddComment,
    onAddToStudioClicked,
    onAddToStudioClosed,
    onCloseAdminPanel,
    onCopyProjectLink,
    onDeleteComment,
    onFavoriteClicked,
    onLoadMore,
    onLoveClicked,
    onOpenAdminPanel,
    onRemix,
    onRemixing,
    onReportClicked,
    onReportClose,
    onReportComment,
    onReportSubmit,
    onRestoreComment,
    onSeeAllComments,
    onSeeInside,
    onShare,
    onToggleComments,
    onToggleStudio,
    onUpdate,
    onUpdateProjectId,
    originalInfo,
    parentInfo,
    projectHost,
    projectId,
    projectInfo,
    projectStudios,
    remixes,
    replies,
    reportOpen,
    showModInfo,
    singleCommentId,
    userOwnsProject,
    visibilityInfo
}) => {
    const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : '';
    const revisedDate = ((projectInfo.history && projectInfo.history.modified)) ? projectInfo.history.modified : '';

    // Allow embedding html in banner messages coming from the server
    const embedCensorMessage = message => (
        // eslint-disable-next-line react/no-danger
        <span dangerouslySetInnerHTML={{__html: message}} />
    );

    let banner;
    if (visibilityInfo.deleted) { // If both censored and deleted, prioritize deleted banner
        banner = (<Banner
            className="banner-danger"
            message={<FormattedMessage id="project.deletedBanner" />}
        />);
    } else if (visibilityInfo.censored) {
        if (visibilityInfo.reshareable) {
            banner = (<Banner
                actionMessage={<FormattedMessage id="project.share.shareButton" />}
                className="banner-danger"
                message={embedCensorMessage(visibilityInfo.message)}
                onAction={onShare}
            />);
        } else {
            banner = (<Banner
                className="banner-danger"
                message={embedCensorMessage(visibilityInfo.message)}
            />);
        }
    } else if (justRemixed) {
        banner = (
            <Banner
                className="banner-success"
                message={
                    <FormattedMessage
                        id="project.remix.justRemixed"
                        values={{title: projectInfo.title}}
                    />
{'fraction_non_alphanumeric': 0.12680859859446053, 'fraction_numerical': 0.00041339396444811904, 'mean_word_length': 2.826413602214314, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2251680', 'n_tokens_mistral': 2860, 'n_tokens_neox': 2768, 'n_words': 557}