This commit is contained in:
Markos Gogoulos
2026-02-01 13:38:48 +02:00
parent 27828d798e
commit f28ce5990b
18 changed files with 118 additions and 64 deletions

View File

@@ -1 +1 @@
VERSION = "8.08" VERSION = "8.09"

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { translateString, inEmbeddedApp } from '../utils/helpers/'; import { translateString, inSelectMediaEmbedMode } from '../utils/helpers/';
interface MediaListHeaderProps { interface MediaListHeaderProps {
title?: string; title?: string;
@@ -11,12 +11,12 @@ interface MediaListHeaderProps {
export const MediaListHeader: React.FC<MediaListHeaderProps> = (props) => { export const MediaListHeader: React.FC<MediaListHeaderProps> = (props) => {
const viewAllText = props.viewAllText || translateString('VIEW ALL'); const viewAllText = props.viewAllText || translateString('VIEW ALL');
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
return ( return (
<div className={(props.className ? props.className + ' ' : '') + 'media-list-header'} style={props.style}> <div className={(props.className ? props.className + ' ' : '') + 'media-list-header'} style={props.style}>
<h2>{props.title}</h2> <h2>{props.title}</h2>
{!isEmbedMode && props.viewAllLink ? ( {!isSelectMediaMode && props.viewAllLink ? (
<h3> <h3>
{' '} {' '}
<a href={props.viewAllLink} title={viewAllText}> <a href={props.viewAllLink} title={viewAllText}>

View File

@@ -1,13 +1,13 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useMediaItem } from '../../utils/hooks/'; import { useMediaItem } from '../../utils/hooks/';
import { PositiveInteger, PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/'; import { PositiveInteger, PositiveIntegerOrZero, inSelectMediaEmbedMode } from '../../utils/helpers/';
import { MediaItemThumbnailLink, itemClassname } from './includes/items/'; import { MediaItemThumbnailLink, itemClassname } from './includes/items/';
import { Item } from './Item'; import { Item } from './Item';
export function MediaItem(props) { export function MediaItem(props) {
const type = props.type; const type = props.type;
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] = const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
useMediaItem({ ...props, type }); useMediaItem({ ...props, type });
@@ -21,14 +21,14 @@ export function MediaItem(props) {
const ItemMain = ({ children }) => <div className="item-main">{children}</div>; const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
const titleComponent = isEmbedMode const titleComponent = isSelectMediaMode
? () => <ItemTitle title={props.title} /> ? () => <ItemTitle title={props.title} />
: titleComponentOrig; : titleComponentOrig;
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig; const UnderThumbWrapper = isSelectMediaMode ? ItemMain : UnderThumbWrapperOrig;
function thumbnailComponent() { function thumbnailComponent() {
if (isEmbedMode) { if (isSelectMediaMode) {
// In embed mode, render thumbnail without link // In embed mode, render thumbnail without link
const thumbStyle = thumbnailUrl ? { backgroundImage: "url('" + thumbnailUrl + "')" } : null; const thumbStyle = thumbnailUrl ? { backgroundImage: "url('" + thumbnailUrl + "')" } : null;
return ( return (
@@ -57,13 +57,13 @@ export function MediaItem(props) {
const finalClassname = containerClassname + const finalClassname = containerClassname +
(props.showSelection ? ' with-selection' : '') + (props.showSelection ? ' with-selection' : '') +
(props.isSelected ? ' selected' : '') + (props.isSelected ? ' selected' : '') +
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : ''); (props.hasAnySelection || isSelectMediaMode ? ' has-any-selection' : '');
const handleItemClick = (e) => { const handleItemClick = (e) => {
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
// In embed mode or if there's any selection active, clicking the item should toggle selection // In select media mode or if there's any selection active, clicking the item should toggle selection
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) { if ((isSelectMediaMode || props.hasAnySelection) && props.onCheckboxChange) {
// Check if clicking on the checkbox itself, edit icon, or view icon // Check if clicking on the checkbox itself, edit icon, or view icon
if (e.target.closest('.item-selection-checkbox') || if (e.target.closest('.item-selection-checkbox') ||
e.target.closest('.item-edit-icon') || e.target.closest('.item-edit-icon') ||
@@ -93,12 +93,12 @@ export function MediaItem(props) {
</div> </div>
)} )}
{!isEmbedMode && editMediaComponent()} {!isSelectMediaMode && editMediaComponent()}
{!isEmbedMode && viewMediaComponent()} {!isSelectMediaMode && viewMediaComponent()}
{thumbnailComponent()} {thumbnailComponent()}
{isEmbedMode ? ( {isSelectMediaMode ? (
<UnderThumbWrapper> <UnderThumbWrapper>
{titleComponent()} {titleComponent()}
{metaComponents()} {metaComponents()}

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useMediaItem } from '../../utils/hooks/'; import { useMediaItem } from '../../utils/hooks/';
import { PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/'; import { PositiveIntegerOrZero, inSelectMediaEmbedMode } from '../../utils/helpers/';
import { MediaDurationInfo } from '../../utils/classes/'; import { MediaDurationInfo } from '../../utils/classes/';
import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions'; import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions';
import { MediaItemDuration, MediaItemPlaylistIndex, itemClassname } from './includes/items/'; import { MediaItemDuration, MediaItemPlaylistIndex, itemClassname } from './includes/items/';
@@ -9,7 +9,7 @@ import { MediaItem } from './MediaItem';
export function MediaItemAudio(props) { export function MediaItemAudio(props) {
const type = props.type; const type = props.type;
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] = const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
useMediaItem({ ...props, type }); useMediaItem({ ...props, type });
@@ -23,11 +23,11 @@ export function MediaItemAudio(props) {
const ItemMain = ({ children }) => <div className="item-main">{children}</div>; const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
const titleComponent = isEmbedMode const titleComponent = isSelectMediaMode
? () => <ItemTitle title={props.title} /> ? () => <ItemTitle title={props.title} />
: titleComponentOrig; : titleComponentOrig;
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig; const UnderThumbWrapper = isSelectMediaMode ? ItemMain : UnderThumbWrapperOrig;
const _MediaDurationInfo = new MediaDurationInfo(); const _MediaDurationInfo = new MediaDurationInfo();
@@ -38,7 +38,7 @@ export function MediaItemAudio(props) {
const durationISO8601 = _MediaDurationInfo.ISO8601(); const durationISO8601 = _MediaDurationInfo.ISO8601();
function thumbnailComponent() { function thumbnailComponent() {
if (isEmbedMode) { if (isSelectMediaMode) {
// In embed mode, render thumbnail without link // In embed mode, render thumbnail without link
return ( return (
<div <div
@@ -99,11 +99,11 @@ export function MediaItemAudio(props) {
const finalClassname = containerClassname + const finalClassname = containerClassname +
(props.showSelection ? ' with-selection' : '') + (props.showSelection ? ' with-selection' : '') +
(props.isSelected ? ' selected' : '') + (props.isSelected ? ' selected' : '') +
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : ''); (props.hasAnySelection || isSelectMediaMode ? ' has-any-selection' : '');
const handleItemClick = (e) => { const handleItemClick = (e) => {
// In embed mode or if there's any selection active, clicking the item should toggle selection // In embed mode or if there's any selection active, clicking the item should toggle selection
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) { if ((isSelectMediaMode || props.hasAnySelection) && props.onCheckboxChange) {
// Check if clicking on the checkbox itself, edit icon, or view icon // Check if clicking on the checkbox itself, edit icon, or view icon
if (e.target.closest('.item-selection-checkbox') || if (e.target.closest('.item-selection-checkbox') ||
e.target.closest('.item-edit-icon') || e.target.closest('.item-edit-icon') ||
@@ -135,12 +135,12 @@ export function MediaItemAudio(props) {
</div> </div>
)} )}
{!isEmbedMode && editMediaComponent()} {!isSelectMediaMode && editMediaComponent()}
{!isEmbedMode && viewMediaComponent()} {!isSelectMediaMode && viewMediaComponent()}
{thumbnailComponent()} {thumbnailComponent()}
{isEmbedMode ? ( {isSelectMediaMode ? (
<UnderThumbWrapper> <UnderThumbWrapper>
{titleComponent()} {titleComponent()}
{metaComponents()} {metaComponents()}

View File

@@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { useMediaItem } from '../../utils/hooks/'; import { useMediaItem } from '../../utils/hooks/';
import { PositiveIntegerOrZero, inEmbeddedApp } from '../../utils/helpers/'; import { PositiveIntegerOrZero, inSelectMediaEmbedMode } from '../../utils/helpers/';
import { MediaDurationInfo } from '../../utils/classes/'; import { MediaDurationInfo } from '../../utils/classes/';
import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions.jsx'; import { MediaPlaylistOptions } from '../media-playlist-options/MediaPlaylistOptions.jsx';
import { MediaItemVideoPlayer, MediaItemDuration, MediaItemVideoPreviewer, MediaItemPlaylistIndex, itemClassname } from './includes/items/'; import { MediaItemVideoPlayer, MediaItemDuration, MediaItemVideoPreviewer, MediaItemPlaylistIndex, itemClassname } from './includes/items/';
@@ -9,7 +9,7 @@ import { MediaItem } from './MediaItem';
export function MediaItemVideo(props) { export function MediaItemVideo(props) {
const type = props.type; const type = props.type;
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] = const [titleComponentOrig, descriptionComponent, thumbnailUrl, UnderThumbWrapperOrig, editMediaComponent, metaComponents, viewMediaComponent] =
useMediaItem({ ...props, type }); useMediaItem({ ...props, type });
@@ -23,11 +23,11 @@ export function MediaItemVideo(props) {
const ItemMain = ({ children }) => <div className="item-main">{children}</div>; const ItemMain = ({ children }) => <div className="item-main">{children}</div>;
const titleComponent = isEmbedMode const titleComponent = isSelectMediaMode
? () => <ItemTitle title={props.title} /> ? () => <ItemTitle title={props.title} />
: titleComponentOrig; : titleComponentOrig;
const UnderThumbWrapper = isEmbedMode ? ItemMain : UnderThumbWrapperOrig; const UnderThumbWrapper = isSelectMediaMode ? ItemMain : UnderThumbWrapperOrig;
const _MediaDurationInfo = new MediaDurationInfo(); const _MediaDurationInfo = new MediaDurationInfo();
@@ -42,8 +42,8 @@ export function MediaItemVideo(props) {
} }
function thumbnailComponent() { function thumbnailComponent() {
if (isEmbedMode) { if (isSelectMediaMode) {
// In embed mode, render thumbnail without link // In select media mode, render thumbnail without link
return ( return (
<div <div
key="item-thumb" key="item-thumb"
@@ -109,11 +109,11 @@ export function MediaItemVideo(props) {
const finalClassname = containerClassname + const finalClassname = containerClassname +
(props.showSelection ? ' with-selection' : '') + (props.showSelection ? ' with-selection' : '') +
(props.isSelected ? ' selected' : '') + (props.isSelected ? ' selected' : '') +
(props.hasAnySelection || isEmbedMode ? ' has-any-selection' : ''); (props.hasAnySelection || isSelectMediaMode ? ' has-any-selection' : '');
const handleItemClick = (e) => { const handleItemClick = (e) => {
// In embed mode or if there's any selection active, clicking the item should toggle selection // In select media mode or if there's any selection active, clicking the item should toggle selection
if ((isEmbedMode || props.hasAnySelection) && props.onCheckboxChange) { if ((isSelectMediaMode || props.hasAnySelection) && props.onCheckboxChange) {
// Check if clicking on the checkbox itself, edit icon, or view icon // Check if clicking on the checkbox itself, edit icon, or view icon
if (e.target.closest('.item-selection-checkbox') || if (e.target.closest('.item-selection-checkbox') ||
e.target.closest('.item-edit-icon') || e.target.closest('.item-edit-icon') ||
@@ -145,12 +145,12 @@ export function MediaItemVideo(props) {
</div> </div>
)} )}
{!isEmbedMode && editMediaComponent()} {!isSelectMediaMode && editMediaComponent()}
{!isEmbedMode && viewMediaComponent()} {!isSelectMediaMode && viewMediaComponent()}
{props.hasMediaViewer ? videoViewerComponent() : thumbnailComponent()} {props.hasMediaViewer ? videoViewerComponent() : thumbnailComponent()}
{isEmbedMode ? ( {isSelectMediaMode ? (
<UnderThumbWrapper> <UnderThumbWrapper>
{titleComponent()} {titleComponent()}
{metaComponents()} {metaComponents()}

View File

@@ -5,7 +5,7 @@ import { LinksContext, MemberContext, SiteContext } from '../../utils/contexts/'
import { PageStore, ProfilePageStore } from '../../utils/stores/'; import { PageStore, ProfilePageStore } from '../../utils/stores/';
import { PageActions, ProfilePageActions } from '../../utils/actions/'; import { PageActions, ProfilePageActions } from '../../utils/actions/';
import { CircleIconButton, PopupMain } from '../_shared'; import { CircleIconButton, PopupMain } from '../_shared';
import { translateString, inEmbeddedApp } from '../../utils/helpers/'; import { translateString, inEmbeddedApp, inSelectMediaEmbedMode } from '../../utils/helpers/';
class ProfileSearchBar extends React.PureComponent { class ProfileSearchBar extends React.PureComponent {
constructor(props) { constructor(props) {
@@ -372,7 +372,7 @@ class NavMenuInlineTabs extends React.PureComponent {
} }
render() { render() {
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
return ( return (
<nav ref="tabsNav" className="profile-nav items-list-outer list-inline list-slider"> <nav ref="tabsNav" className="profile-nav items-list-outer list-inline list-slider">
@@ -380,7 +380,7 @@ class NavMenuInlineTabs extends React.PureComponent {
{this.state.displayPrev ? this.previousBtn : null} {this.state.displayPrev ? this.previousBtn : null}
<ul className="items-list-wrap" ref="itemsListWrap"> <ul className="items-list-wrap" ref="itemsListWrap">
{!isEmbedMode ? ( {!isSelectMediaMode ? (
<InlineTab <InlineTab
id="about" id="about"
isActive={'about' === this.props.type} isActive={'about' === this.props.type}
@@ -411,7 +411,7 @@ class NavMenuInlineTabs extends React.PureComponent {
/> />
) : null} ) : null}
{!isEmbedMode && MemberContext._currentValue.can.saveMedia ? ( {!isSelectMediaMode && MemberContext._currentValue.can.saveMedia ? (
<InlineTab <InlineTab
id="playlists" id="playlists"
isActive={'playlists' === this.props.type} isActive={'playlists' === this.props.type}
@@ -772,7 +772,7 @@ export default function ProfilePagesHeader(props) {
)} )}
<div className="profile-info-nav-wrap"> <div className="profile-info-nav-wrap">
{inEmbeddedApp() ? ( {inSelectMediaEmbedMode() ? (
<div className="profile-info"> <div className="profile-info">
<div className="profile-info-inner"> <div className="profile-info-inner">
<div> <div>

View File

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { ApiUrlContext, LinksConsumer, MemberContext } from '../utils/contexts'; import { ApiUrlContext, LinksConsumer, MemberContext } from '../utils/contexts';
import { PageStore, ProfilePageStore } from '../utils/stores'; import { PageStore, ProfilePageStore } from '../utils/stores';
import { ProfilePageActions, PageActions } from '../utils/actions'; import { ProfilePageActions, PageActions } from '../utils/actions';
import { inEmbeddedApp, translateString } from '../utils/helpers/'; import { inEmbeddedApp, inSelectMediaEmbedMode, translateString } from '../utils/helpers/';
import { MediaListWrapper } from '../components/MediaListWrapper'; import { MediaListWrapper } from '../components/MediaListWrapper';
import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader'; import ProfilePagesHeader from '../components/profile-page/ProfilePagesHeader';
import ProfilePagesContent from '../components/profile-page/ProfilePagesContent'; import ProfilePagesContent from '../components/profile-page/ProfilePagesContent';
@@ -202,13 +202,13 @@ export class ProfileMediaPage extends Page {
} }
handleMediaSelection(mediaId, isSelected) { handleMediaSelection(mediaId, isSelected) {
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
this.setState((prevState) => { this.setState((prevState) => {
const newSelectedMedia = new Set(); const newSelectedMedia = new Set();
// In embed mode, only allow single selection // In select media mode, only allow single selection
if (isEmbedMode) { if (isSelectMediaMode) {
if (isSelected) { if (isSelected) {
newSelectedMedia.add(mediaId); newSelectedMedia.add(mediaId);
console.log('Selected media item:', mediaId); console.log('Selected media item:', mediaId);
@@ -933,7 +933,7 @@ export class ProfileMediaPage extends Page {
const authorData = ProfilePageStore.get('author-data'); const authorData = ProfilePageStore.get('author-data');
const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username; const isMediaAuthor = authorData && authorData.username === MemberContext._currentValue.username;
const isEmbedMode = inEmbeddedApp(); const isSelectMediaMode = inSelectMediaEmbedMode();
// Check if any filters are active (excluding default sort and tags) // Check if any filters are active (excluding default sort and tags)
const hasActiveFilters = const hasActiveFilters =
@@ -965,16 +965,16 @@ export class ProfileMediaPage extends Page {
this.state.author ? ( this.state.author ? (
<ProfilePagesContent key="ProfilePagesContent"> <ProfilePagesContent key="ProfilePagesContent">
<MediaListWrapper <MediaListWrapper
title={isEmbedMode ? undefined : this.state.title} title={isSelectMediaMode ? undefined : this.state.title}
className="items-list-ver" className="items-list-ver"
style={isEmbedMode ? { marginTop: '24px' } : undefined} style={isSelectMediaMode ? { marginTop: '24px' } : undefined}
showBulkActions={!isEmbedMode && isMediaAuthor} showBulkActions={!isSelectMediaMode && isMediaAuthor}
selectedCount={this.state.selectedMedia.size} selectedCount={this.state.selectedMedia.size}
totalCount={this.state.availableMediaIds.length} totalCount={this.state.availableMediaIds.length}
onBulkAction={this.handleBulkAction} onBulkAction={this.handleBulkAction}
onSelectAll={this.handleSelectAll} onSelectAll={this.handleSelectAll}
onDeselectAll={this.handleDeselectAll} onDeselectAll={this.handleDeselectAll}
showAddMediaButton={!isEmbedMode && isMediaAuthor} showAddMediaButton={!isSelectMediaMode && isMediaAuthor}
> >
<ProfileMediaFilters <ProfileMediaFilters
hidden={this.state.hiddenFilters} hidden={this.state.hiddenFilters}
@@ -997,7 +997,7 @@ export class ProfileMediaPage extends Page {
hideViews={!PageStore.get('config-media-item').displayViews} hideViews={!PageStore.get('config-media-item').displayViews}
hideDate={!PageStore.get('config-media-item').displayPublishDate} hideDate={!PageStore.get('config-media-item').displayPublishDate}
canEdit={isMediaAuthor} canEdit={isMediaAuthor}
showSelection={isMediaAuthor || isEmbedMode} showSelection={isMediaAuthor || isSelectMediaMode}
hasAnySelection={this.state.selectedMedia.size > 0} hasAnySelection={this.state.selectedMedia.size > 0}
selectedMedia={this.state.selectedMedia} selectedMedia={this.state.selectedMedia}
onMediaSelection={this.handleMediaSelection} onMediaSelection={this.handleMediaSelection}

View File

@@ -18,3 +18,29 @@ export function inEmbeddedApp() {
return false; return false;
} }
} }
export function isSelectMediaMode() {
try {
const params = new URL(globalThis.location.href).searchParams;
const action = params.get('action');
if (action === 'select_media') {
sessionStorage.setItem('media_cms_select_media', 'true');
return true;
}
// Clear if action is explicitly something else
if (action && action !== 'select_media') {
sessionStorage.removeItem('media_cms_select_media');
return false;
}
return sessionStorage.getItem('media_cms_select_media') === 'true';
} catch (e) {
return false;
}
}
export function inSelectMediaEmbedMode() {
return inEmbeddedApp() && isSelectMediaMode();
}

View File

@@ -4,10 +4,38 @@ namespace tiny_mediacms;
use context; use context;
use moodle_url; use moodle_url;
use editor_tiny\plugin;
use editor_tiny\plugin_with_buttons;
use editor_tiny\plugin_with_menuitems;
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
class plugininfo extends \editor_tiny\plugin { class plugininfo extends plugin implements plugin_with_buttons, plugin_with_menuitems {
/**
* Whether the plugin is enabled
*/
public static function is_enabled(context $context, array $options, array $fpoptions, ?\editor_tiny\editor $editor = null): bool {
return isloggedin() && !isguestuser();
}
/**
* Get available buttons
*/
public static function get_available_buttons(): array {
return [
'tiny_mediacms/tiny_mediacms',
];
}
/**
* Get available menu items
*/
public static function get_available_menuitems(): array {
return [
'tiny_mediacms/tiny_mediacms',
];
}
/** /**
* Get the plugin configuration for the editor. * Get the plugin configuration for the editor.

View File

@@ -36,7 +36,7 @@ class SelectMediaView(View):
def get(self, request): def get(self, request):
"""Display media selection interface - redirects to user's profile page""" """Display media selection interface - redirects to user's profile page"""
profile_url = f"/user/{request.user.username}?mode=embed_mode" profile_url = f"/user/{request.user.username}?mode=embed_mode&action=select_media"
return HttpResponseRedirect(profile_url) return HttpResponseRedirect(profile_url)
@method_decorator(csrf_exempt) @method_decorator(csrf_exempt)

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long