[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Display a post's featured image. that allows users to configure: is link, aspect ratio, width, and 11 more options

[Assistant]
// File: packages/block-library/src/post-featured-image/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/post-featured-image",
	"title": "Featured Image",
	"category": "theme",
	"description": "Display a post's featured image.",
	"textdomain": "default",
	"attributes": {
		"isLink": {
			"type": "boolean",
			"default": false,
			"role": "content"
		},
		"aspectRatio": {
			"type": "string"
		},
		"width": {
			"type": "string"
		},
		"height": {
			"type": "string"
		},
		"scale": {
			"type": "string",
			"default": "cover"
		},
		"sizeSlug": {
			"type": "string"
		},
		"rel": {
			"type": "string",
			"attribute": "rel",
			"default": "",
			"role": "content"
		},
		"linkTarget": {
			"type": "string",
			"default": "_self",
			"role": "content"
		},
		"overlayColor": {
			"type": "string"
		},
		"customOverlayColor": {
			"type": "string"
		},
		"dimRatio": {
			"type": "number",
			"default": 0
		},
		"gradient": {
			"type": "string"
		},
		"customGradient": {
			"type": "string"
		},
		"useFirstImageFromPost": {
			"type": "boolean",
			"default": false
		}
	},
	"usesContext": [ "postId", "postType", "queryId" ],
	"example": {
		"viewportWidth": 350
	},
	"supports": {
		"align": [ "left", "right", "center", "wide", "full" ],
		"color": {
			"text": false,
			"background": false
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"width": true,
			"__experimentalSkipSerialization": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"width": true
			}
		},
		"filter": {
			"duotone": true
		},
		"shadow": {
			"__experimentalSkipSerialization": true
		},
		"html": false,
		"spacing": {
			"margin": true,
			"padding": true
		},
		"interactivity": {
			"clientNavigation": true
		}
	},
	"selectors": {
		"border": ".wp-block-post-featured-image img, .wp-block-post-featured-image .block-editor-media-placeholder, .wp-block-post-featured-image .wp-block-post-featured-image__overlay",
		"shadow": ".wp-block-post-featured-image img, .wp-block-post-featured-image .components-placeholder",
		"filter": {
			"duotone": ".wp-block-post-featured-image img, .wp-block-post-featured-image .wp-block-post-featured-image__placeholder, .wp-block-post-featured-image .components-placeholder__illustration, .wp-block-post-featured-image .components-placeholder::before"
		}
	},
	"editorStyle": "wp-block-post-featured-image-editor",
	"style": "wp-block-post-featured-image"
}

// File: packages/block-library/src/post-featured-image/index.js
/**
 * WordPress dependencies
 */
import { postFeaturedImage as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';

const { name } = metadata;
export { metadata, name };

export const settings = {
	icon,
	edit,
};

export const init = () => initBlock( { name, metadata, settings } );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Add an image or video with a text overlay. that allows users to configure: url, use featured image, id, and 19 more options

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/cover/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/cover",
	"title": "Cover",
	"category": "media",
	"description": "Add an image or video with a text overlay.",
	"textdomain": "default",
	"attributes": {
		"url": {
			"type": "string",
			"role": "content"
		},
		"useFeaturedImage": {
			"type": "boolean",
			"default": false
		},
		"id": {
			"type": "number"
		},
		"alt": {
			"type": "string",
			"default": ""
		},
		"hasParallax": {
			"type": "boolean",
			"default": false
		},
		"isRepeated": {
			"type": "boolean",
			"default": false
		},
		"dimRatio": {
			"type": "number",
			"default": 100
		},
		"overlayColor": {
			"type": "string"
		},
		"customOverlayColor": {
			"type": "string"
		},
		"isUserOverlayColor": {
			"type": "boolean"
		},
		"backgroundType": {
			"type": "string",
			"default": "image"
		},
		"focalPoint": {
			"type": "object"
		},
		"minHeight": {
			"type": "number"
		},
		"minHeightUnit": {
			"type": "string"
		},
		"gradient": {
			"type": "string"
		},
		"customGradient": {
			"type": "string"
		},
		"contentPosition": {
			"type": "string"
		},
		"isDark": {
			"type": "boolean",
			"default": true
		},
		"templateLock": {
			"type": [ "string", "boolean" ],
			"enum": [ "all", "insert", "contentOnly", false ]
		},
		"tagName": {
			"type": "string",
			"default": "div"
		},
		"sizeSlug": {
			"type": "string"
		},
		"poster": {
			"type": "string",
			"source": "attribute",
			"selector": "video",
			"attribute": "poster"
		}
	},
	"usesContext": [ "postId", "postType" ],
	"supports": {
		"anchor": true,
		"align": true,
		"html": false,
		"shadow": true,
		"spacing": {
			"padding": true,
			"margin": [ "top", "bottom" ],
			"blockGap": true,
			"__experimentalDefaultControls": {
				"padding": true,
				"blockGap": true
			}
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"style": true,
			"width": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"style": true,
				"width": true
			}
		},
		"color": {
			"heading": true,
			"text": true,
			"background": false,
			"__experimentalSkipSerialization": [ "gradients" ],
			"enableContrastChecker": false
		},
		"dimensions": {
			"aspectRatio": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"layout": {
			"allowJustification": false
		},
		"interactivity": {
			"clientNavigation": true
		},
		"filter": {
			"duotone": true
		},
		"allowedBlocks": true
	},
	"selectors": {
		"filter": {
			"duotone": ".wp-block-cover > .wp-block-cover__image-background, .wp-block-cover > .wp-block-cover__video-background"
		}
	},
	"editorStyle": "wp-block-cover-editor",
	"style": "wp-block-cover"
}

// File: packages/block-library/src/cover/index.js
/**
 * WordPress dependencies
 */
import { __ } from '@wordpress/i18n';
import { cover as icon } from '@wordpress/icons';
import { privateApis as blocksPrivateApis } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import deprecated from './deprecated';
import edit from './edit';
import metadata from './block.json';
import save from './save';
import transforms from './transforms';
import variations from './variations';
import { unlock } from '../lock-unlock';

const { fieldsKey, formKey } = unlock( blocksPrivateApis );

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon,
	example: {
		attributes: {
			customOverlayColor: '#065174',
			dimRatio: 40,
			url: 'https://s.w.org/images/core/5.3/Windbuchencom.jpg',
			style: {
				typography: {
					fontSize: 48,
				},
				color: {
					text: 'white',
				},
			},
		},
		innerBlocks: [
			{
				name: 'core/paragraph',
				attributes: {
					content: `<strong>${ __( 'Snow Patrol' ) }</strong>`,
					align: 'center',
				},
			},
		],
	},
	transforms,
	save,
	edit,
	deprecated,
	variations,
};

if ( window.__experimentalContentOnlyInspectorFields ) {
	settings[ fieldsKey ] = [
		{
			id: 'background',
			label: __( 'Background' ),
			type: 'media',
			mapping: {
				type: 'backgroundType',
				id: 'id',
				url: 'url',
				alt: 'alt',
				featuredImage: 'useFeaturedImage',
			},
			args: {
				// TODO - How to support custom gradient?
				// Build it into Media, or use a custom control?
				allowedTypes: [ 'image', 'video' ],
				multiple: false,
			},
		},
	];
	settings[ formKey ] = {
		fields: [ 'background' ],
	};
}

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/cover/save.js
/**
 * External dependencies
 */
import clsx from 'clsx';

/**
 * WordPress dependencies
 */
import {
	useInnerBlocksProps,
	getColorClassName,
	__experimentalGetGradientClass,
	useBlockProps,
} from '@wordpress/block-editor';

/**
 * Internal dependencies
 */
import {
	IMAGE_BACKGROUND_TYPE,
	VIDEO_BACKGROUND_TYPE,
	EMBED_VIDEO_BACKGROUND_TYPE,
	dimRatioToClass,
	isContentPositionCenter,
	getPositionClassName,
	mediaPosition,
} from './shared';

export default function save( { attributes } ) {
	const {
		backgroundType,
		gradient,
		contentPosition,
		customGradient,
		customOverlayColor,
		dimRatio,
		focalPoint,
		useFeaturedImage,
		hasParallax,
		isDark,
		isRepeated,
		overlayColor,
		url,
		alt,
		id,
		minHeight: minHeightProp,
		minHeightUnit,
		tagName: Tag,
		sizeSlug,
		poster,
	} = attributes;
	const overlayColorClass = getColorClassName(
		'background-color',
		overlayColor
	);
	const gradientClass = __experimentalGetGradientClass( gradient );
	const minHeight =
		minHeightProp && minHeightUnit
			? `${ minHeightProp }${ minHeightUnit }`
			: minHeightProp;

	const isImageBackground = IMAGE_BACKGROUND_TYPE === backgroundType;
	const isVideoBackground = VIDEO_BACKGROUND_TYPE === backgroundType;
	const isEmbedVideoBackground =
		EMBED_VIDEO_BACKGROUND_TYPE === backgroundType;

	const isImgElement = ! ( hasParallax || isRepeated );

	const style = {
		minHeight: minHeight || undefined,
	};

	const bgStyle = {
		backgroundColor: ! overlayColorClass ? customOverlayColor : undefined,
		background: customGradient ? customGradient : undefined,
	};

	const objectPosition =
		// prettier-ignore
		focalPoint && isImgElement
			  ? mediaPosition(focalPoint)
			  : undefined;

	const backgroundImage = url ? `url(${ url })` : undefined;

	const backgroundPosition = mediaPosition( focalPoint );

	const classes = clsx(
		{
			'is-light': ! isDark,
			'has-parallax': hasParallax,
			'is-repeated': isRepeated,
			'has-custom-content-position':
				! isContentPositionCenter( contentPosition ),
		},
		getPositionClassName( contentPosition )
	);

	const imgClasses = clsx(
		'wp-block-cover__image-background',
		id ? `wp-image-${ id }` : null,
		{
			[ `size-${ sizeSlug }` ]: sizeSlug,
			'has-parallax': hasParallax,
			'is-repeated': isRepeated,
		}
	);

	const gradientValue = gradient || customGradient;

	return (
		<Tag { ...useBlockProps.save( { className: classes, style } ) }>
			{ ! useFeaturedImage &&
				isImageBackground &&
				url &&
				( isImgElement ? (

				) : (

				) ) }
			{ isVideoBackground && url && (
				<video
					className={ clsx(
						'wp-block-cover__video-background',
						'intrinsic-ignore'
					) }
					autoPlay
					muted
					loop
					playsInline
					src={ url }
					poster={ poster }
					style={ { objectPosition } }
					data-object-fit="cover"
					data-object-position={ objectPosition }
				/>
			) }
			{ isEmbedVideoBackground && url && (

{ url }

			) }

			{ /* The `wp-block-cover__background` needs to be immediately before
			the `wp-block-cover__inner-container`, so the exclusion CSS selector
			`.wp-block-cover__background + .wp-block-cover__inner-container`
			works properly. If it needs to be changed in the future, the
			selector for the backward compatibility for v14 deprecation also
			needs change. */ }
			<span
				aria-hidden="true"
				className={ clsx(
					'wp-block-cover__background',
					overlayColorClass,
					dimRatioToClass( dimRatio ),
					{
						'has-background-dim': dimRatio !== undefined,
						// For backwards compatibility. Former versions of the Cover Block applied
						// `.wp-block-cover__gradient-background` in the presence of
						// media, a gradient and a dim.
						'wp-block-cover__gradient-background':
							url && gradientValue && dimRatio !== 0,
						'has-background-gradient': gradientValue,
						[ gradientClass ]: gradientClass,
					}
				) }
				style={ bgStyle }
			/>

		</Tag>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a WordPress theme block that allows flexible comment identification through user-configurable settings.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/post-comment/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"__experimental": "fse",
	"name": "core/post-comment",
	"title": "Comment (deprecated)",
	"category": "theme",
	"allowedBlocks": [
		"core/avatar",
		"core/comment-author-name",
		"core/comment-content",
		"core/comment-date",
		"core/comment-edit-link",
		"core/comment-reply-link"
	],
	"description": "This block is deprecated. Please use the Comments block instead.",
	"textdomain": "default",
	"attributes": {
		"commentId": {
			"type": "number"
		}
	},
	"providesContext": {
		"commentId": "commentId"
	},
	"supports": {
		"html": false,
		"inserter": false,
		"interactivity": {
			"clientNavigation": true
		}
	}
}

// File: packages/block-library/src/post-comment/index.js
/**
 * WordPress dependencies
 */
import { comment as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import save from './save';

const { name } = metadata;
export { metadata, name };

export const settings = {
	icon,
	edit,
	save,
};

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/post-comment/save.js
/**
 * WordPress dependencies
 */
import { useInnerBlocksProps, useBlockProps } from '@wordpress/block-editor';

export default function save() {
	const blockProps = useBlockProps.save();
	const innerBlocksProps = useInnerBlocksProps.save( blockProps );
	return <div { ...innerBlocksProps } />;
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Visually highlight a product category and encourage prompt action. with these attributes: alt, content align, dim ratio, and 12 more options

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/featured-items/featured-category/block.json
{
	"name": "woocommerce/featured-category",
	"title": "Featured Category",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"description": "Visually highlight a product category and encourage prompt action.",
	"supports": {
		"interactivity": {
			"clientNavigation": true
		},
		"align": [ "wide", "full" ],
		"ariaLabel": true,
		"color": {
			"background": true,
			"text": true
		},
		"html": false,
		"filter": {
			"duotone": true
		},
		"spacing": {
			"padding": true,
			"__experimentalDefaultControls": {
				"padding": true
			},
			"__experimentalSkipSerialization": true
		},
		"__experimentalBorder": {
			"color": true,
			"radius": true,
			"width": true,
			"__experimentalDefaultControls": {
				"color": true,
				"radius": true,
				"width": true
			},
			"__experimentalSkipSerialization": true
		}
	},
	"attributes": {
		"alt": {
			"type": "string",
			"default": ""
		},
		"contentAlign": {
			"type": "string",
			"default": "center"
		},
		"dimRatio": {
			"type": "number",
			"default": 50
		},
		"focalPoint": {
			"type": "object",
			"default": {
				"x": 0.5,
				"y": 0.5
			}
		},
		"imageFit": {
			"type": "string",
			"default": "none"
		},
		"hasParallax": {
			"type": "boolean",
			"default": false
		},
		"isRepeated": {
			"type": "boolean",
			"default": false
		},
		"mediaId": {
			"type": "number",
			"default": 0
		},
		"mediaSrc": {
			"type": "string",
			"default": ""
		},
		"minHeight": {
			"type": "number",
			"default": 500
		},
		"linkText": {
			"default": "Shop now",
			"type": "string"
		},
		"categoryId": {
			"type": "number"
		},
		"overlayColor": {
			"type": "string",
			"default": "#000000"
		},
		"overlayGradient": {
			"type": "string"
		},
		"previewCategory": {
			"type": "object",
			"default": null
		}
	},
	"selectors": {
		"filter": {
			"duotone": ".wp-block-woocommerce-featured-category .wc-block-featured-category__background-image"
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"usesContext": [ "termId", "termTaxonomy" ],
	"providesContext": {
		"termId": "categoryId",
		"termTaxonomy": "termTaxonomy"
	}
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/featured-items/featured-category/index.tsx
/**
 * External dependencies
 */
import { folderStarred } from '@woocommerce/icons';
import { Icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import './style.scss';
import './editor.scss';
import Block from './block';
import metadata from './block.json';
import { register } from '../register';
import { example } from './example';
import deprecated from './deprecated';

register( Block, example, metadata, {
	deprecated,
	icon: {
		src: (
			<Icon
				icon={ folderStarred }
				className="wc-block-editor-components-block-icon"
			/>
		),
	},
} );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a WooCommerce block featuring adjustable locking functionality that enables dynamic configuration of access controls.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/block.json
{
	"name": "woocommerce/checkout-shipping-methods-block",
	"version": "1.0.0",
	"title": "Shipping Options",
	"description": "Display shipping options and rates for your store.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"inserter": false,
		"lock": false
	},
	"attributes": {
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	},
	"parent": [
		"woocommerce/checkout-fields-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/checkout/inner-blocks/checkout-shipping-methods-block/edit.tsx
/**
 * External dependencies
 */
import clsx from 'clsx';
import { __ } from '@wordpress/i18n';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { PanelBody, ExternalLink } from '@wordpress/components';
import { shipping } from '@wordpress/icons';
import { ADMIN_URL, getSetting } from '@woocommerce/settings';
import ExternalLinkCard from '@woocommerce/editor-components/external-link-card';
import { innerBlockAreas } from '@woocommerce/blocks-checkout';
import { useCheckoutAddress } from '@woocommerce/base-context/hooks';
import Noninteractive from '@woocommerce/base-components/noninteractive';

/**
 * Internal dependencies
 */
import {
	FormStepBlock,
	AdditionalFields,
	AdditionalFieldsContent,
} from '../../form-step';
import ConfigurePlaceholder from '../../configure-placeholder';
import Block from './block';
import './editor.scss';

type shippingAdminLink = {
	id: number;
	title: string;
	description: string;
};

export const Edit = ( {
	attributes,
	setAttributes,
}: {
	attributes: {
		title: string;
		description: string;
		showStepNumber: boolean;
		className: string;
	};
	setAttributes: ( attributes: Record< string, unknown > ) => void;
} ): JSX.Element | null => {
	const globalShippingMethods = getSetting(
		'globalShippingMethods'
	) as shippingAdminLink[];
	const activeShippingZones = getSetting(
		'activeShippingZones'
	) as shippingAdminLink[];

	const { showShippingMethods } = useCheckoutAddress();

	if ( ! showShippingMethods ) {
		return null;
	}

	return (
		<FormStepBlock
			attributes={ attributes }
			setAttributes={ setAttributes }
			className={ clsx(
				'wc-block-checkout__shipping-option',
				attributes?.className
			) }
		>
			<InspectorControls>
				<PanelBody
					title={ __( 'Shipping Calculations', 'woocommerce' ) }
				>

						{ __(
							'Options that control shipping can be managed in your store settings.',
							'woocommerce'
						) }

					<ExternalLink
						href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping&section=options` }
					>
						{ __( 'Manage shipping options', 'woocommerce' ) }
					</ExternalLink>{ ' ' }
				</PanelBody>
				{ globalShippingMethods.length > 0 && (
					<PanelBody title={ __( 'Methods', 'woocommerce' ) }>

							{ __(
								'The following shipping integrations are active on your store.',
								'woocommerce'
							) }

						{ globalShippingMethods.map( ( method ) => {
							return (
								<ExternalLinkCard
									key={ method.id }
									href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping&section=${ method.id }` }
									title={ method.title }
									description={ method.description }
								/>
							);
						} ) }
						<ExternalLink
							href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping` }
						>
							{ __( 'Manage shipping methods', 'woocommerce' ) }
						</ExternalLink>
					</PanelBody>
				) }
				{ activeShippingZones.length && (
					<PanelBody title={ __( 'Shipping Zones', 'woocommerce' ) }>

							{ __(
								'Shipping Zones can be made managed in your store settings.',
								'woocommerce'
							) }

						{ activeShippingZones.map( ( zone ) => {
							return (
								<ExternalLinkCard
									key={ zone.id }
									href={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping&zone_id=${ zone.id }` }
									title={ zone.title }
									description={ zone.description }
								/>
							);
						} ) }
					</PanelBody>
				) }
			</InspectorControls>
			<Noninteractive>
				<Block
					noShippingPlaceholder={
						<ConfigurePlaceholder
							icon={ shipping }
							label={ __( 'Shipping options', 'woocommerce' ) }
							description={ __(
								'Your store does not have any Shipping Options configured. Once you have added your Shipping Options they will appear here.',
								'woocommerce'
							) }
							buttonLabel={ __(
								'Configure Shipping Options',
								'woocommerce'
							) }
							buttonHref={ `${ ADMIN_URL }admin.php?page=wc-settings&tab=shipping` }
						/>
					}
				/>
			</Noninteractive>
			<AdditionalFields block={ innerBlockAreas.SHIPPING_METHODS } />
		</FormStepBlock>
	);
};

export const Save = (): JSX.Element => {
	return (

			<AdditionalFieldsContent />

	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a woocommerce block with customizable lock

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-products-table-block/block.json
{
	"name": "woocommerce/mini-cart-products-table-block",
	"version": "1.0.0",
	"title": "Mini-Cart Products Table",
	"description": "Block that displays the products table of the Mini-Cart block.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"inserter": false,
		"lock": false,
		"interactivity": true
	},
	"attributes": {
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": false
			}
		}
	},
	"parent": [ "woocommerce/mini-cart-items-block" ],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/mini-cart/mini-cart-contents/inner-blocks/mini-cart-products-table-block/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps } from '@wordpress/block-editor';
import Noninteractive from '@woocommerce/base-components/noninteractive';

/**
 * Internal dependencies
 */
import Block from './block';

export const Edit = (): JSX.Element => {
	const blockProps = useBlockProps();

	return (
		<div { ...blockProps }>
			<Noninteractive>
				<Block className="is-mobile" />
			</Noninteractive>
		</div>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() }></div>;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a woocommerce block with customizable display style, icon style, icon class

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/customer-account/block.json
{
	"name": "woocommerce/customer-account",
	"title": "Customer account",
	"description": "A block that allows your customers to log in and out of their accounts in your store.",
	"category": "woocommerce",
	"keywords": [ "WooCommerce", "My Account" ],
	"supports": {
		"interactivity": {
			"clientNavigation": true
		},
		"align": true,
		"color": {
			"text": true
		},
		"typography": {
			"fontSize": true,
			"__experimentalFontFamily": true
		},
		"spacing": {
			"margin": true,
			"padding": true
		}
	},
	"attributes": {
		"displayStyle": {
			"type": "string",
			"default": "icon_and_text"
		},
		"iconStyle": {
			"type": "string",
			"default": "default"
		},
		"iconClass": {
			"type": "string",
			"default": "icon"
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/customer-account/edit.tsx
/**
 * External dependencies
 */
import clsx from 'clsx';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import { Disabled } from '@wordpress/components';
import type { BlockEditProps } from '@wordpress/blocks';

/**
 * Internal dependencies
 */
import Block from './block';
import { Attributes } from './types';
import { BlockSettings } from './sidebar-settings';
import './editor.scss';

const Edit = ( {
	attributes,
	setAttributes,
}: BlockEditProps< Attributes > ) => {
	const { className } = attributes;
	const blockProps = useBlockProps( {
		className: clsx( 'wc-block-editor-customer-account', className ),
	} );

	return (
		<>
			<div { ...blockProps }>
				<InspectorControls>
					<BlockSettings
						attributes={ attributes }
						setAttributes={ setAttributes }
					/>
				</InspectorControls>
				<Disabled>
					<Block attributes={ attributes } />
				</Disabled>
			</div>
		</>
	);
};

export default Edit;


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a WordPress block enabling simple text enhancement with configurable options for adding headings, lists, and hyperlinks to plain content.

[Assistant]
// File: projects/plugins/jetpack/extensions/blocks/markdown/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "jetpack/markdown",
	"title": "Markdown",
	"description": "Add headings, lists, or links to plain text with ease.",
	"keywords": [ "formatting", "syntax", "markup" ],
	"version": "12.5.0",
	"textdomain": "jetpack",
	"category": "text",
	"icon": "<svg viewBox='0 0 208 128' width='24' height='24' xmlns='http://www.w3.org/2000/svg'><rect width='198' height='118' x='5' y='5' ry='10' stroke='currentColor' strokeWidth='10' fill='none' /><path d='M30 98v-68h20l20 25 20-25h20v68h-20v-39l-20 25-20-25v39zM155 98l-30-33h20v-35h20v35h20z' />",
	"supports": {
		"align": [ "wide", "full" ],
		"html": false,
		"spacing": {
			"padding": true,
			"margin": true,
			"__experimentalDefaultControls": {
				"padding": true,
				"margin": true
			}
		}
	},
	"attributes": { "source": { "type": "string" } },
	"example": {
		"attributes": {
			"source": "## ## Try Markdown\n\nMarkdown is a text formatting syntax that is converted into HTML. You can _emphasize_ text or **make it strong** with just a few characters."
		}
	}
}

// File: projects/plugins/jetpack/extensions/blocks/markdown/edit.js
import { BlockControls, PlainText, useBlockProps } from '@wordpress/block-editor';
import { compose } from '@wordpress/compose';
import { withDispatch, withSelect } from '@wordpress/data';
import { useEffect, useRef, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import ToolbarButton from './controls';
import MarkdownRenderer from './renderer';

/**
 * Module variables
 */
const PANEL_EDITOR = 'editor';
const PANEL_PREVIEW = 'preview';

const MarkdownEdit = ( { attributes, setAttributes, isSelected, removeBlock } ) => {
	const { source } = attributes;
	const isEmpty = ! source || source.trim() === '';

	const blockProps = useBlockProps();
	const { className } = blockProps;
	const [ activePanel, setActivePanel ] = useState( PANEL_EDITOR );
	const input = useRef( null );

	const onChange = s => setAttributes( { source: s } );
	const onKeyDown = e => {
		// Remove the block if source is empty and we're pressing the Backspace key
		if ( e.keyCode === 8 && source === '' ) {
			removeBlock();
			e.preventDefault();
		}
	};

	useEffect( () => {
		if ( isSelected ) {
			if ( activePanel === PANEL_EDITOR ) {
				input?.current.focus();
			}
		} else if ( activePanel === PANEL_PREVIEW ) {
			setActivePanel( PANEL_EDITOR );
		}
	}, [ isSelected, activePanel, setActivePanel ] );

	let content;

	if ( ! isSelected && isEmpty ) {
		content = (
			<p className={ `${ className }__placeholder` }>
				{ __( 'Write your _Markdown_ **here**…', 'jetpack' ) }

		);
	} else {
		content = (

				<BlockControls>

						<ToolbarButton
							className={ className }
							label={ __( 'Markdown', 'jetpack' ) }
							isPressed={ activePanel === PANEL_EDITOR }
							onClick={ () => setActivePanel( PANEL_EDITOR ) }
						/>
						<ToolbarButton
							className={ className }
							label={ __( 'Preview', 'jetpack' ) }
							isPressed={ activePanel === PANEL_PREVIEW }
							onClick={ () => setActivePanel( PANEL_PREVIEW ) }
						/>

				</BlockControls>

				{ activePanel === PANEL_PREVIEW || ! isSelected ? (
					<MarkdownRenderer className={ `${ className }__preview` } source={ source } />
				) : (
					<PlainText
						className={ `${ className }__editor` }
						onChange={ onChange }
						onKeyDown={ onKeyDown }
						aria-label={ __( 'Markdown', 'jetpack' ) }
						ref={ input }
						value={ source }
					/>
				) }

		);
	}

	return
{ content }
;
};

export default compose( [
	withSelect( select => ( {
		currentBlockId: select( 'core/block-editor' ).getSelectedBlockClientId(),
	} ) ),
	withDispatch( ( dispatch, { currentBlockId } ) => ( {
		removeBlock: () => dispatch( 'core/block-editor' ).removeBlocks( currentBlockId ),
	} ) ),
] )( MarkdownEdit );

// File: projects/plugins/jetpack/extensions/blocks/markdown/save.js
import { useBlockProps } from '@wordpress/block-editor';
import MarkdownRenderer from './renderer';

export default ( { attributes } ) => {
	const blockProps = useBlockProps.save();

	return (
		<MarkdownRenderer { ...blockProps } source={ attributes.source } attributes={ attributes } />
	);
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a theme block with customizable text align, more text, show more on new line, excerpt length

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/post-excerpt/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/post-excerpt",
	"title": "Excerpt",
	"category": "theme",
	"description": "Display the excerpt.",
	"textdomain": "default",
	"attributes": {
		"textAlign": {
			"type": "string"
		},
		"moreText": {
			"type": "string",
			"role": "content"
		},
		"showMoreOnNewLine": {
			"type": "boolean",
			"default": true
		},
		"excerptLength": {
			"type": "number",
			"default": 55
		}
	},
	"usesContext": [ "postId", "postType", "queryId" ],
	"example": {
		"viewportWidth": 350
	},
	"supports": {
		"html": false,
		"color": {
			"gradients": true,
			"link": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true,
				"link": true
			}
		},
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"interactivity": {
			"clientNavigation": true
		},
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true,
			"__experimentalDefaultControls": {
				"radius": true,
				"color": true,
				"width": true,
				"style": true
			}
		}
	},
	"editorStyle": "wp-block-post-excerpt-editor",
	"style": "wp-block-post-excerpt"
}

// File: packages/block-library/src/post-excerpt/index.js
/**
 * WordPress dependencies
 */
import { postExcerpt as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import transforms from './transforms';

const { name } = metadata;
export { metadata, name };

export const settings = {
	icon,
	transforms,
	edit,
};

export const init = () => initBlock( { name, metadata, settings } );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Displays the link to the current post comments. with these attributes: text align

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/post-comments-link/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "core/post-comments-link",
	"title": "Comments Link",
	"category": "theme",
	"description": "Displays the link to the current post comments.",
	"textdomain": "default",
	"usesContext": [ "postType", "postId" ],
	"attributes": {
		"textAlign": {
			"type": "string"
		}
	},
	"example": {
		"viewportWidth": 350
	},
	"supports": {
		"html": false,
		"color": {
			"link": true,
			"text": false,
			"__experimentalDefaultControls": {
				"background": true,
				"link": true
			}
		},
		"spacing": {
			"margin": true,
			"padding": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"__experimentalDefaultControls": {
				"fontSize": true
			}
		},
		"interactivity": {
			"clientNavigation": true
		},
		"__experimentalBorder": {
			"radius": true,
			"color": true,
			"width": true,
			"style": true,
			"__experimentalDefaultControls": {
				"radius": true,
				"color": true,
				"width": true,
				"style": true
			}
		}
	},
	"style": "wp-block-post-comments-link"
}

// File: packages/block-library/src/post-comments-link/index.js
/**
 * WordPress dependencies
 */
import { postCommentsCount as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import metadata from './block.json';
import edit from './edit';
import transforms from './transforms';

const { name } = metadata;
export { metadata, name };

export const settings = {
	edit,
	icon,
	transforms,
};

export const init = () => initBlock( { name, metadata, settings } );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Elevate your content creation with our AI-powered Gutenberg Block, offering seamless customization and generation. Bear in mind that, as an evolving tool, occasional imprecision may occur. with these attributes: content, original content, prompt type, and 5 more options

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: projects/plugins/jetpack/extensions/blocks/ai-assistant/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "jetpack/ai-assistant",
	"title": "AI Assistant",
	"description": "Elevate your content creation with our AI-powered Gutenberg Block, offering seamless customization and generation. Bear in mind that, as an evolving tool, occasional imprecision may occur.",
	"keywords": [ "AI", "GPT", "AL", "Magic", "help", "assistant" ],
	"version": "12.5.0",
	"textdomain": "jetpack",
	"category": "text",
	"icon": "<svg viewBox='0 0 32 32' width='32' height='32' xmlns='http://www.w3.org/2000/svg'><path d='M9.33301 5.33325L10.4644 8.20188L13.333 9.33325L10.4644 10.4646L9.33301 13.3333L8.20164 10.4646L5.33301 9.33325L8.20164 8.20188L9.33301 5.33325Z'/><path d='M21.3333 5.33333L22.8418 9.15817L26.6667 10.6667L22.8418 12.1752L21.3333 16L19.8248 12.1752L16 10.6667L19.8248 9.15817L21.3333 5.33333Z'/><path d='M14.6667 13.3333L16.5523 18.1144L21.3333 20L16.5523 21.8856L14.6667 26.6667L12.781 21.8856L8 20L12.781 18.1144L14.6667 13.3333Z'/></svg>",
	"supports": {
		"html": false,
		"multiple": true,
		"reusable": false
	},
	"attributes": {
		"content": {
			"type": "string"
		},

		"originalContent": {
			"type": "string"
		},

		"promptType": {
			"type": "string"
		},

		"originalMessages": {
			"type": "array",
			"default": []
		},

		"messages": {
			"type": "array",
			"default": []
		},

		"userPrompt": {
			"type": "string",
			"default": ""
		},

		"requestingState": {
			"type": "string",
			"default": "init"
		},

		"preTransformAction": {
			"type": "string",
			"default": null
		}
	},
	"example": {
		"attributes": {
			"content": "With **Jetpack AI Assistant**, you can provide a prompt, and it will generate high-quality blog posts, informative pages, well-organized lists, and thorough tables that meet your specific requirements.\n\nTo start using the **Jetpack AI Assistant**, type `/AI` in the block editor."
		}
	}
}

// File: projects/plugins/jetpack/extensions/blocks/ai-assistant/edit.js
/**
 * External dependencies
 */
import {
	BlockAIControl,
	UpgradeMessage,
	renderHTMLFromMarkdown,
	PROMPT_TYPE_GENERATE_TITLE,
	mapActionToHumanText,
	QuotaExceededMessage,
	FairUsageNotice,
	useAICheckout,
	useAiFeature,
} from '@automattic/jetpack-ai-client';
import {
	useAnalytics,
	PLAN_TYPE_FREE,
	PLAN_TYPE_UNLIMITED,
	usePlanType,
	isUserConnected,
} from '@automattic/jetpack-shared-extension-utils';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { rawHandler } from '@wordpress/blocks';
import {
	Notice,
	PanelBody,
	PanelRow,
	KeyboardShortcuts,
	ExternalLink,
} from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
import { RawHTML, useState, useCallback, useEffect, useRef } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import clsx from 'clsx';
/**
 * Internal dependencies
 */
import UsagePanel from '../../plugins/ai-assistant-plugin/components/usage-panel';
import { USAGE_PANEL_PLACEMENT_BLOCK_SETTINGS_SIDEBAR } from '../../plugins/ai-assistant-plugin/components/usage-panel/types';
import ConnectBanner from '../../shared/components/connect-banner';
import FeedbackControl from './components/feedback-control';
import ToolbarControls from './components/toolbar-controls';
import useAIAssistant from './hooks/use-ai-assistant';
import useAiProductPage from './hooks/use-ai-product-page';
import { getStoreBlockId } from './hooks/use-transform-to-assistant';
import './editor.scss';

const isInBlockEditor = window?.Jetpack_Editor_Initial_State?.screenBase === 'post';

export default function AIAssistantEdit( { attributes, setAttributes, clientId, isSelected } ) {
	const [ errorDismissed, setErrorDismissed ] = useState( null );
	const { tracks } = useAnalytics();

	const { getBlock } = useSelect( 'core/block-editor' );

	const aiControlRef = useRef( null );
	const blockRef = useRef( null );

	const { replaceBlocks, removeBlock } = useDispatch( 'core/block-editor' );
	const { editPost } = useDispatch( 'core/editor' );

	const [ lastAction, setLastAction ] = useState(
		mapActionToHumanText( attributes.preTransformAction )
	);

	const {
		isOverLimit,
		requireUpgrade,
		increaseRequestsCount,
		requestsCount,
		requestsLimit,
		currentTier,
		loading: loadingAiFeature,
		tierPlansEnabled,
	} = useAiFeature();
	const requestsRemaining = Math.max( requestsLimit - requestsCount, 0 );

	const { autosaveAndRedirect } = useAICheckout();
	const planType = usePlanType( currentTier );

	const focusOnPrompt = () => {
		/*
		 * Increase the AI Suggestion counter.
		 * @todo: move this at store level.
		 */
		// Small delay to avoid focus crash
		setTimeout( () => {
			aiControlRef.current?.focus?.();
		}, 100 );
	};

	const focusOnBlock = () => {
		// Small delay to avoid focus crash
		setTimeout( () => {
			blockRef.current?.focus?.();
		}, 100 );
	};

	const isMobileViewport = useViewportMatch( 'medium', '<' );

	const contentRef = useRef( null );

	const {
		getSuggestionFromOpenAI,
		stopSuggestion,
		showRetry,
		contentBefore,
		postTitle,
		retryRequest,
		wholeContent,
		requestingState,
		error,
	} = useAIAssistant( {
		onSuggestionDone: useCallback(
			skipRequestCount => {
				focusOnPrompt();
				if ( ! skipRequestCount ) {
					increaseRequestsCount();
				}
			},
			[ increaseRequestsCount ]
		),
		onUnclearPrompt: useCallback( () => {
			focusOnBlock();
			increaseRequestsCount();
		}, [ increaseRequestsCount ] ),
		onModeration: focusOnPrompt,
		attributes,
		clientId,
		content: attributes.content,
		tracks,
		userPrompt: attributes.userPrompt,
		requireUpgrade,
		initialRequestingState: attributes.requestingState,
		contentRef,
		blockRef,
	} );

	const isWaitingResponse = requestingState === 'requesting';
	const isLoadingCompletion = [ 'requesting', 'suggesting' ].includes( requestingState );

	const connected = isUserConnected();

	const { productPageUrl } = useAiProductPage();

	/*
	 * Auto request the prompt if we detect
	 * it was previously defined in the local storage.
	 */
	const storeBlockId = getStoreBlockId( clientId );
	useEffect( () => {
		if ( ! storeBlockId ) {
			return;
		}

		// Get the parsed data from the local storage.
		const data = JSON.parse( localStorage.getItem( storeBlockId ) );
		if ( ! data ) {
			return;
		}

		const { type, options } = data;

		// Clean up the local storage asap.
		localStorage.removeItem( storeBlockId );

		getSuggestionFromOpenAI( type, options );
	}, [ storeBlockId, getSuggestionFromOpenAI ] );

	useEffect( () => {
		if ( error ) {
			setErrorDismissed( false );
		}
	}, [ error ] );

	useEffect( () => {
		// we don't want to store "half way" states
		if ( ! [ 'init', 'done' ].includes( requestingState ) ) {
			return;
		}

		setAttributes( { requestingState } );
	}, [ requestingState, setAttributes ] );

	// Content is loaded
	const contentIsLoaded = !! attributes.content;

	const getLastEditableElement = newContentBlocks => {
		let lastEditableElement = null;

		newContentBlocks.forEach( block => {
			const element = document.querySelector( `.wp-block[data-block="${ block.clientId }"]` );
			if ( ! element ) {
				return;
			}

			if ( element.contentEditable === 'true' ) {
				lastEditableElement = element;
			}

			const editableChildren = element.querySelectorAll( `[contenteditable=true]` );
			lastEditableElement = editableChildren.length
				? editableChildren[ editableChildren.length - 1 ]
				: lastEditableElement;
		} );

		return lastEditableElement;
	};

	const isGeneratingTitle = attributes.promptType === PROMPT_TYPE_GENERATE_TITLE;

	const acceptContentLabel = __( 'Accept', 'jetpack' );
	const acceptTitleLabel = __( 'Accept title', 'jetpack' );
	const acceptLabel = isGeneratingTitle ? acceptTitleLabel : acceptContentLabel;

	const moveCaretToEnd = element => {
		const selection = element.ownerDocument.getSelection();
		selection.selectAllChildren( element );
		selection.collapseToEnd();
		element.focus();
	};

	const handleGetSuggestion = ( ...args ) => {
		getSuggestionFromOpenAI( ...args );
		focusOnBlock();
	};

	const handleChange = value => {
		setErrorDismissed( true );
		setAttributes( { userPrompt: value } );
	};

	const handleSend = () => {
		setLastAction( attributes.userPrompt );
		handleGetSuggestion( 'userPrompt' );
		tracks.recordEvent( 'jetpack_ai_assistant_block_generate', { feature: 'ai-assistant' } );
	};

	const handleAccept = () => {
		if ( isGeneratingTitle ) {
			handleAcceptTitle();
		} else {
			handleAcceptContent();
		}
	};

	const replaceContent = async () => {
		let newGeneratedBlocks = [];

		let HTML = renderHTMLFromMarkdown( { content: attributes.content || '' } );

		const seemsToIncludeTitle =
			HTML?.split( '\n' ).length > 1 && HTML?.split( '\n' )?.[ 0 ]?.match( /^
.*<\/h1>$/ );

		if ( seemsToIncludeTitle && ! postTitle ) {
			// split HTML on new line characters
			const htmlLines = HTML.split( '\n' );
			// take the first line as title
			const title = htmlLines.shift();
			// rejoin the rest of the lines on HTML
			HTML = htmlLines.join( '\n' );
			// set the title as post title
			editPost( { title: title.replace( /<[^>]*>/g, '' ) } );
		}
		newGeneratedBlocks = rawHandler( { HTML: HTML } );

		// Replace the block with the new generated blocks
		await replaceBlocks( clientId, newGeneratedBlocks );

		// Move the caret to the end of the last editable element
		const lastEditableElement = getLastEditableElement( newGeneratedBlocks );
		if ( lastEditableElement ) {
			moveCaretToEnd( lastEditableElement );
		}
	};

	const handleAcceptContent = () => {
		replaceContent();
		tracks.recordEvent( 'jetpack_ai_assistant_block_accept', { feature: 'ai-assistant' } );
	};

	const handleAcceptTitle = () => {
		if ( isInBlockEditor ) {
			editPost( { title: attributes.content ? attributes.content.trim() : '' } );
			removeBlock( clientId );
			tracks.recordEvent( 'jetpack_ai_assistant_block_accept', { feature: 'ai-assistant' } );
		} else {
			handleAcceptContent();
		}
	};

	const handleDiscard = () => {
		const isDismiss = attributes?.content === getBlock( clientId ).attributes?.content;
		setAttributes( {
			content: attributes?.originalContent,
			promptType: undefined,
			messages: attributes?.originalMessages,
		} );
		replaceContent();
		if ( isDismiss ) {
			tracks.recordEvent( 'jetpack_ai_assistant_block_dismiss' );
		} else {
			tracks.recordEvent( 'jetpack_ai_assistant_block_discard', { feature: 'ai-assistant' } );
		}
	};

	const handleStopSuggestion = () => {
		stopSuggestion();
		focusOnPrompt();
		tracks.recordEvent( 'jetpack_ai_assistant_block_stop', { feature: 'ai-assistant' } );
	};

	const handleGetSuggestionFromToolbar = ( type, options ) => {
		const humanText = mapActionToHumanText( type, options );
		setLastAction( humanText );
		getSuggestionFromOpenAI( type, options );
	};

	const blockProps = useBlockProps( {
		ref: blockRef,
		className: clsx( { 'is-waiting-response': isWaitingResponse } ),
	} );

	const promptPlaceholder = __( 'Ask Jetpack AI…', 'jetpack' );
	const promptPlaceholderWithSamples = __( 'Write about… Make a table for…', 'jetpack' );

	const banner = (
		<>
			{ isOverLimit && isSelected && <QuotaExceededMessage placement="ai-assistant-block" /> }
			{ ! connected && <ConnectBanner block="AI Assistant" /> }
		</>
	);

	const errorNotice = (
		<>
			{ error?.message && ! errorDismissed && error?.code !== 'error_quota_exceeded' && (
				<Notice
					status={ error.status }
					isDismissible={ false }
					className="jetpack-ai-assistant__error"
				>
					{ error.message }
				</Notice>
			) }
		</>
	);

	const fairUsageNotice =
		isOverLimit && planType === PLAN_TYPE_UNLIMITED ? <FairUsageNotice variant="muted" /> : null;

	const trackUpgradeClick = useCallback(
		event => {
			event.preventDefault();
			tracks.recordEvent( 'jetpack_ai_upgrade_button', {
				current_tier_slug: currentTier?.slug,
				requests_count: requestsCount,
				placement: 'jetpack_ai_assistant_block',
			} );
			autosaveAndRedirect( event );
		},
		[ tracks, currentTier, requestsCount, autosaveAndRedirect ]
	);

	return (
		<KeyboardShortcuts
			bindGlobal
			shortcuts={ {
				esc: () => {
					if ( [ 'requesting', 'suggesting' ].includes( requestingState ) ) {
						handleStopSuggestion();
					}
				},
			} }
		>

				{ contentIsLoaded && (

						<RawHTML>{ renderHTMLFromMarkdown( { content: attributes.content || '' } ) }</RawHTML>

				) }
				<InspectorControls>
					{ fairUsageNotice && (

							{ fairUsageNotice }

					) }
					{ /* Mock BlockCard component styles to keep alignment */ }

						<ExternalLink href={ productPageUrl }>
							{ __( 'Discover all features', 'jetpack' ) }
						</ExternalLink>

					{ ( planType === PLAN_TYPE_FREE ||
						( tierPlansEnabled && planType !== PLAN_TYPE_UNLIMITED ) ) && (
						<PanelBody initialOpen={ true }>
							<PanelRow>
								<UsagePanel placement={ USAGE_PANEL_PLACEMENT_BLOCK_SETTINGS_SIDEBAR } />
							</PanelRow>
						</PanelBody>
					) }
					<PanelBody initialOpen={ true }>
						<PanelRow>
							<FeedbackControl />
						</PanelRow>
					</PanelBody>
				</InspectorControls>

				{ ! isLoadingCompletion && connected && ! requireUpgrade && (
					<ToolbarControls
						isWaitingState={ isLoadingCompletion }
						contentIsLoaded={ contentIsLoaded }
						getSuggestionFromOpenAI={ handleGetSuggestionFromToolbar }
						retryRequest={ retryRequest }
						handleAcceptContent={ handleAcceptContent }
						handleAcceptTitle={ handleAcceptTitle }
						handleTryAgain={ null }
						showRetry={ showRetry }
						contentBefore={ contentBefore }
						hasPostTitle={ !! postTitle?.length }
						wholeContent={ wholeContent }
						promptType={ attributes.promptType }
						setUserPrompt={ prompt => {
							if ( ! aiControlRef?.current ) {
								return;
							}

							const userPromptInput = aiControlRef.current;

							// Focus the text area
							userPromptInput.focus();

							setAttributes( { userPrompt: prompt } );
						} }
						recordEvent={ tracks.recordEvent }
						isGeneratingTitle={ isGeneratingTitle }
					/>
				) }
				<BlockAIControl
					ref={ aiControlRef }
					disabled={ requireUpgrade || ! connected }
					value={ attributes.userPrompt }
					placeholder={ attributes?.content ? promptPlaceholder : promptPlaceholderWithSamples }
					onChange={ handleChange }
					onSend={ handleSend }
					onStop={ handleStopSuggestion }
					onAccept={ handleAccept }
					onDiscard={ handleDiscard }
					state={ requestingState }
					isTransparent={ requireUpgrade || ! connected }
					showButtonLabels={ ! isMobileViewport }
					showAccept={ requestingState !== 'init' && contentIsLoaded && ! isLoadingCompletion }
					acceptLabel={ acceptLabel }
					showGuideLine={ contentIsLoaded }
					showRemove={ attributes?.content?.length > 0 }
					banner={ banner }
					error={ errorNotice }
					customFooter={
						// Only show the upgrade message on each 5th request or if it's the first request - and only if the user is on the free plan
						( requestsRemaining % 5 === 0 || requestsCount === 1 ) &&
						! loadingAiFeature && // Don't show the upgrade message while the feature is loading
						planType === PLAN_TYPE_FREE ? (
							<UpgradeMessage
								requestsRemaining={ requestsRemaining }
								onUpgradeClick={ trackUpgradeClick }
							/>
						) : null
					}
					lastAction={ lastAction }
				/>

		</KeyboardShortcuts>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Provide a notification message after the form has been submitted. with these attributes: type

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: packages/block-library/src/form-submission-notification/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"__experimental": true,
	"name": "core/form-submission-notification",
	"title": "Form Submission Notification",
	"category": "common",
	"ancestor": [ "core/form" ],
	"description": "Provide a notification message after the form has been submitted.",
	"keywords": [ "form", "feedback", "notification", "message" ],
	"textdomain": "default",
	"icon": "feedback",
	"attributes": {
		"type": {
			"type": "string",
			"default": "success"
		}
	}
}

// File: packages/block-library/src/form-submission-notification/index.js
/**
 * WordPress dependencies
 */
import { group as icon } from '@wordpress/icons';

/**
 * Internal dependencies
 */
import initBlock from '../utils/init-block';
import edit from './edit';
import metadata from './block.json';
import save from './save';
import variations from './variations';

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon,
	edit,
	save,
	variations,
	example: {},
};

export const init = () => initBlock( { name, metadata, settings } );

// File: packages/block-library/src/form-submission-notification/save.js
/**
 * WordPress dependencies
 */
import { useInnerBlocksProps, useBlockProps } from '@wordpress/block-editor';

/**
 * External dependencies
 */
import clsx from 'clsx';

export default function save( { attributes } ) {
	const { type } = attributes;

	return (
		<div
			{ ...useInnerBlocksProps.save(
				useBlockProps.save( {
					className: clsx( 'wp-block-form-submission-notification', {
						[ `form-notification-type-${ type }` ]: type,
					} ),
				} )
			) }
		/>
	);
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block for Block containing current line items in Cart. that allows users to configure: lock

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-line-items-block/block.json
{
	"name": "woocommerce/cart-line-items-block",
	"version": "1.0.0",
	"title": "Cart Line Items",
	"description": "Block containing current line items in Cart.",
	"category": "woocommerce",
	"supports": {
		"align": false,
		"html": false,
		"multiple": false,
		"reusable": false,
		"inserter": false,
		"lock": false
	},
	"attributes": {
		"lock": {
			"type": "object",
			"default": {
				"remove": true,
				"move": true
			}
		}
	},
	"parent": [
		"woocommerce/cart-items-block"
	],
	"textdomain": "woocommerce",
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/cart/inner-blocks/cart-line-items-block/edit.tsx
/**
 * External dependencies
 */
import { useBlockProps } from '@wordpress/block-editor';
import Noninteractive from '@woocommerce/base-components/noninteractive';

/**
 * Internal dependencies
 */
import Block from './block';

export const Edit = ( {
	attributes,
}: {
	attributes: { className: string };
} ): JSX.Element => {
	const { className } = attributes;
	const blockProps = useBlockProps();

	return (
		<div { ...blockProps }>
			<Noninteractive>
				<Block className={ className } />
			</Noninteractive>
		</div>
	);
};

export const Save = (): JSX.Element => {
	return <div { ...useBlockProps.save() } />;
};


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a WordPress block to Display the product title as a label or paragraph.

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/grouped-product-selector/product-item-label/block.json
{
	"name": "woocommerce/add-to-cart-with-options-grouped-product-item-label",
	"title": "Grouped Product: Item Label (Beta)",
	"description": "Display the product title as a label or paragraph.",
	"category": "woocommerce-product-elements",
	"keywords": [ "WooCommerce" ],
	"ancestor": [ "woocommerce/add-to-cart-with-options-grouped-product-item" ],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"supports": {
		"color": {
			"text": true,
			"background": true,
			"gradients": true,
			"__experimentalDefaultControls": {
				"background": true,
				"text": true
			}
		},
		"html": false,
		"layout": {
			"selfStretch": true
		},
		"spacing": {
			"margin": true,
			"padding": true,
			"blockGap": true
		},
		"typography": {
			"fontSize": true,
			"lineHeight": true,
			"__experimentalFontFamily": true,
			"__experimentalFontWeight": true,
			"__experimentalFontStyle": true,
			"__experimentalTextTransform": true,
			"__experimentalTextDecoration": true,
			"__experimentalLetterSpacing": true,
			"textAlign": true,
			"__experimentalDefaultControls": {
				"fontSize": true,
				"fontWeight": true,
				"fontStyle": true
			}
		}
	},
	"usesContext": [ "postId", "postType" ]
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/grouped-product-selector/product-item-label/index.tsx
/**
 * External dependencies
 */
import { registerBlockType } from '@wordpress/blocks';
import { heading } from '@wordpress/icons';
import { useBlockProps } from '@wordpress/block-editor';
import type { BlockConfiguration } from '@wordpress/blocks';
import { useProductDataContext } from '@woocommerce/shared-context';
import { Spinner } from '@wordpress/components';
import { isProductResponseItem } from '@woocommerce/entities';

/**
 * Internal dependencies
 */
import metadata from './block.json';

registerBlockType( metadata.name, {
	...metadata,
	edit: function Edit() {
		const blockProps = useBlockProps();
		const { isLoading, product } = useProductDataContext();

		if ( isLoading || ! isProductResponseItem( product ) ) {
			return <Spinner />;
		}
		return (
			<div { ...blockProps }>
				<div className="wp-block-woocommerce-add-to-cart-with-options-grouped-product-item-label">
					{ product.name }
				</div>
			</div>
		);
	},
	icon: heading,
	save: () => null,
} as unknown as BlockConfiguration );


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Develop a block template for displaying individual child products as list items within the Grouped Product Selector interface.

[Assistant]
// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/grouped-product-selector/product-item/block.json
{
	"name": "woocommerce/add-to-cart-with-options-grouped-product-item",
	"title": "Grouped Product: Template (Beta)",
	"description": "A list item template that represents a child product within the Grouped Product Selector block.",
	"category": "woocommerce-product-elements",
	"keywords": [ "WooCommerce" ],
	"usesContext": [ "postId" ],
	"ancestor": [
		"woocommerce/add-to-cart-with-options-grouped-product-selector"
	],
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"supports": {
		"inserter": false,
		"interactivity": true
	},
	"style": "file:../woocommerce/add-to-cart-with-options-grouped-product-item-style.css"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/grouped-product-selector/product-item/edit.tsx
/**
 * External dependencies
 */
import { useState, useEffect } from '@wordpress/element';
import {
	useBlockProps,
	useInnerBlocksProps,
	store as blockEditorStore,
	__experimentalUseBlockPreview as useBlockPreview,
	BlockContextProvider,
} from '@wordpress/block-editor';
import { BlockInstance, type BlockEditProps } from '@wordpress/blocks';
import { withProduct } from '@woocommerce/block-hocs';
import {
	InnerBlockLayoutContextProvider,
	ProductDataContextProvider,
	useProductDataContext,
} from '@woocommerce/shared-context';
import { resolveSelect, useSelect } from '@wordpress/data';
import type { ProductResponseItem } from '@woocommerce/types';
import { productsStore } from '@woocommerce/data';
import { isProductResponseItem } from '@woocommerce/entities';
import { Spinner } from '@wordpress/components';
import { previewProductResponseItems } from '@woocommerce/resource-previews';

interface Attributes {
	className?: string;
}

type ProductItemWithContextProps = {
	attributes: { productId: number };
	isLoading?: boolean;
	product?: ProductResponseItem | null;
	blocks: BlockInstance[];
	isSelected: boolean;
	onSelect(): void;
};

type ProductItemProps = {
	product: ProductResponseItem | null;
	blocks: BlockInstance[];
	isLoading: boolean;
	isSelected: boolean;
	onSelect(): void;
};

const ProductItem = ( {
	product,
	blocks,
	isLoading,
	isSelected,
	onSelect,
}: ProductItemProps ) => {
	const blockPreviewProps = useBlockPreview( {
		blocks,
	} );
	const innerBlocksProps = useInnerBlocksProps(
		{ role: 'listitem' },
		{ templateLock: 'insert' }
	);

	return (
		<ProductDataContextProvider product={ product } isLoading={ isLoading }>
			{ isSelected ? (

			) : (

 {
							if ( e.key === 'Enter' || e.key === ' ' ) {
								e.preventDefault();
								onSelect();
							}
						} }
					/>

			) }
		</ProductDataContextProvider>
	);
};

const ProductItemWithContext = withProduct(
	( {
		attributes,
		isLoading = true,
		product = null,
		blocks,
		isSelected,
		onSelect,
	}: ProductItemWithContextProps ) => {
		return (
			<BlockContextProvider
				value={ { postId: attributes.productId, postType: 'product' } }
			>
				<ProductItem
					product={ product }
					blocks={ blocks }
					isLoading={ isLoading }
					isSelected={ isSelected }
					onSelect={ onSelect }
				/>
			</BlockContextProvider>
		);
	}
);

export default function ProductItemTemplateEdit(
	props: BlockEditProps< Attributes >
) {
	const { clientId } = props;
	const { className } = props.attributes;

	const blockProps = useBlockProps( {
		className,
	} );

	const { product, isLoading } = useProductDataContext();
	const [ isLoadingProducts, setIsLoadingProducts ] = useState( true );
	const [ products, setProducts ] = useState< ProductResponseItem[] | null >(
		null
	);
	const productsLength = products?.length || 0;

	useEffect( () => {
		const fetchChildProducts = async ( groupedProductIds: number[] ) => {
			if ( ! groupedProductIds || groupedProductIds.length === 0 ) {
				setIsLoadingProducts( false );
				return;
			}

			resolveSelect( productsStore )
				.getProducts( {
					include: groupedProductIds,
					per_page: groupedProductIds.length,
					_fields: [ 'id' ],
				} )
				.then( ( fetchedProducts ) => {
					setProducts( fetchedProducts );
					setIsLoadingProducts( false );
				} );
		};

		if ( ! isLoading && product && productsLength === 0 ) {
			if ( isProductResponseItem( product ) ) {
				fetchChildProducts( product.grouped_products );
			} else {
				// If not editing a specific product, we are editing a template.
				// Fetch an existing grouped product so template can be edited.
				resolveSelect( productsStore )
					.getProducts( { type: 'grouped', per_page: 1 } )
					.then( ( groupedProduct ) => {
						if (
							groupedProduct.length > 0 &&
							groupedProduct[ 0 ]?.grouped_products?.length > 0
						) {
							fetchChildProducts(
								groupedProduct[ 0 ].grouped_products
							);
						} else {
							// If there are no grouped products, query for any three other products.
							resolveSelect( productsStore )
								.getProducts( {
									per_page: 3,
									_fields: [ 'id' ],
								} )
								.then( ( fetchedProducts ) => {
									if ( fetchedProducts.length > 0 ) {
										setProducts( fetchedProducts );
									}
									setIsLoadingProducts( false );
								} );
						}
					} );
			}
		}
	}, [ isLoading, product, productsLength ] );

	const { blocks } = useSelect(
		( select ) => {
			const { getBlocks } = select( blockEditorStore );
			return { blocks: getBlocks( clientId ) };
		},
		[ clientId ]
	);

	const [ selectedProductItem, setSelectedProductItem ] =
		useState< number >();

	if ( isLoading || isLoadingProducts ) {
		return <Spinner />;
	}

	const productList = products
		? products?.map( ( productItem ) => (
				<ProductItemWithContext
					key={ productItem.id }
					attributes={ {
						productId: productItem.id,
					} }
					blocks={ blocks }
					isSelected={
						( selectedProductItem ?? products[ 0 ]?.id ) ===
						productItem.id
					}
					onSelect={ () => setSelectedProductItem( productItem.id ) }
				/>
		  ) )
		: previewProductResponseItems?.map( ( productItem ) => (
				<ProductItem
					key={ productItem.id }
					product={ productItem }
					blocks={ blocks }
					isLoading={ false }
					isSelected={
						( selectedProductItem ??
							previewProductResponseItems[ 0 ]?.id ) ===
						productItem.id
					}
					onSelect={ () => setSelectedProductItem( productItem.id ) }
				/>
		  ) );

	return (

			<InnerBlockLayoutContextProvider parentName="woocommerce/add-to-cart-with-options-grouped-product-item">

{ productList }

			</InnerBlockLayoutContextProvider>

	);
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/add-to-cart-with-options/grouped-product-selector/product-item/save.tsx
/**
 * External dependencies
 */
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';

export default function ProductItemTemplateSave() {
	const blockProps = useBlockProps.save();
	const innerBlocksProps = useInnerBlocksProps.save( {
		...blockProps,
		role: 'listitem',
	} );
	return
;
}


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Create a embed block with customizable align, points, address, and 7 more options

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: projects/plugins/jetpack/extensions/blocks/map/block.json
{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "jetpack/map",
	"title": "Map",
	"description": "Add an interactive map showing one or more locations.",
	"keywords": [ "maps", "location", "navigation" ],
	"version": "12.5.0",
	"textdomain": "jetpack",
	"category": "embed",
	"icon": "<svg viewBox='0 0 24 24' width='24' height='24' xmlns='http://www.w3.org/2000/svg'><path d='M20.5 3l-.16.03L15 5.1 9 3 3.36 4.9c-.21.07-.36.25-.36.48V20.5c0 .28.22.5.5.5l.16-.03L9 18.9l6 2.1 5.64-1.9c.21-.07.36-.25.36-.48V3.5c0-.28-.22-.5-.5-.5zM10 5.47l4 1.4v11.66l-4-1.4V5.47zm-5 .99l3-1.01v11.7l-3 1.16V6.46zm14 11.08l-3 1.01V6.86l3-1.16v11.84z' /></svg>",
	"supports": { "defaultStylePicker": false, "html": false },
	"attributes": {
		"align": {
			"type": "string"
		},
		"points": {
			"type": "array",
			"default": []
		},
		"address": {
			"type": "string",
			"default": ""
		},
		"mapDetails": {
			"type": "boolean",
			"default": true
		},
		"zoom": {
			"type": "integer",
			"default": 13
		},
		"mapCenter": {
			"type": "object",
			"default": {
				"longitude": -122.41941550000001,
				"latitude": 37.7749295
			}
		},
		"markerColor": {
			"type": "string",
			"default": "red"
		},
		"scrollToZoom": {
			"type": "boolean",
			"default": false
		},
		"mapHeight": {
			"type": "integer"
		},
		"showFullscreenButton": {
			"type": "boolean",
			"default": true
		}
	},
	"example": {}
}

// File: projects/plugins/jetpack/extensions/blocks/map/edit.js
import { getBlockIconComponent } from '@automattic/jetpack-shared-extension-utils';
import apiFetch from '@wordpress/api-fetch';
import {
	BlockControls,
	InspectorControls,
	useBlockProps,
	store as blockEditorStore,
} from '@wordpress/block-editor';
import {
	Button,
	ExternalLink,
	Placeholder,
	Spinner,
	withNotices,
	ResizableBox,
} from '@wordpress/components';
import { compose } from '@wordpress/compose';
import { useDispatch, useSelect } from '@wordpress/data';
import { useEffect, useRef, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { getActiveStyleName } from '../../shared/block-styles';
import AddPoint from './add-point';
import metadata from './block.json';
import Map from './component';
import Controls from './controls';
import { getCoordinates } from './get-coordinates.js';
import previewPlaceholder from './map-preview.jpg';
import styles from './styles';
import getMapProvider from './utils/get-map-provider';

const icon = getBlockIconComponent( metadata );

const API_STATE_LOADING = 0;
const API_STATE_FAILURE = 1;
const API_STATE_SUCCESS = 2;

// The minimum height that the map can be set to.
const MIN_HEIGHT = 400;

// Options for the map <ResizableBox> wrapper.
const RESIZABLE_BOX_ENABLE_OPTION = {
	top: false,
	right: false,
	bottom: true,
	left: false,
	topRight: false,
	bottomRight: false,
	bottomLeft: false,
	topLeft: false,
};

const MapEdit = ( {
	setAttributes,
	attributes,
	noticeUI,
	notices,
	isSelected,
	noticeOperations,
} ) => {
	const {
		address,
		mapDetails,
		points,
		zoom,
		mapCenter,
		markerColor,
		mapHeight,
		showFullscreenButton,
	} = attributes;

	const { toggleSelection } = useDispatch( 'core/block-editor' );

	const { isPreviewMode } = useSelect( select => {
		const { getSettings } = select( blockEditorStore );
		const settings = getSettings();
		return {
			isPreviewMode: settings.isPreviewMode,
		};
	}, [] );

	const [ addPointVisibility, setAddPointVisibility ] = useState( false );
	const [ apiState, setApiState ] = useState( API_STATE_LOADING );
	const [ apiKey, setApiKey ] = useState( null );
	const [ apiKeyControl, setApiKeyControl ] = useState( null );
	const [ apiKeySource, setApiKeySource ] = useState( null );
	const [ apiRequestOutstanding, setApiRequestOutstanding ] = useState( null );
	const mapRef = useRef( null );
	const blockProps = useBlockProps();
	const { className } = blockProps;

	const mapStyle = getActiveStyleName( styles, className );
	const mapProvider = getMapProvider( { mapStyle } );

	const geoCodeAddress = () => {
		if ( ! address || ! apiKey || mapProvider === 'mapkit' ) {
			return;
		}

		getCoordinates( address, apiKey )
			.then( result => {
				if ( ! result.features?.length ) {
					onError(
						null,
						__(
							'Could not find the coordinates of the provided address. Displaying default location. Feel free to add the location manually.',
							'jetpack'
						)
					);
				} else {
					const feature = result.features[ 0 ];
					const newPoint = [
						{
							title: feature.text,
							placeTitle: feature.text,
							caption: feature.place_name,
							id: feature.id,
							coordinates: {
								latitude: feature.center[ 1 ],
								longitude: feature.center[ 0 ],
							},
						},
					];
					setAttributes( { points: newPoint } );
				}
			} )
			.catch( error => onError( null, error.message ) );
	};

	const apiCall = ( serviceApiKey = null, method = 'GET' ) => {
		return new Promise( ( resolve, reject ) => {
			const path = '/wpcom/v2/service-api-keys/mapbox';
			const fetch = serviceApiKey
				? { path, method, data: { service_api_key: serviceApiKey } }
				: { path, method };

			setApiRequestOutstanding( true );

			apiFetch( fetch ).then(
				( { service_api_key: key, service_api_key_source: source } ) => {
					noticeOperations.removeAllNotices();

					setApiState( key ? API_STATE_SUCCESS : API_STATE_FAILURE );
					setApiKey( key );
					setApiKeyControl( 'wpcom' === source ? '' : key );
					setApiKeySource( source );
					setApiRequestOutstanding( false );

					resolve();
				},
				( { message } ) => {
					onError( null, message );

					setApiState( API_STATE_FAILURE );
					setApiRequestOutstanding( false );

					reject();
				}
			);
		} );
	};

	const addPoint = point => {
		if ( points.some( existingPoint => existingPoint.id === point.id ) ) {
			return;
		}
		const newPoints = points.slice( 0 );
		newPoints.push( point );
		setAttributes( { points: newPoints } );
		setAddPointVisibility( false );
	};

	const updateAPIKey = () => {
		noticeOperations.removeAllNotices();

		if ( apiKeyControl ) {
			apiCall( apiKeyControl, 'POST' );
		}
	};

	const removeAPIKey = () => apiCall( null, 'DELETE' );

	const onError = ( code, message ) => {
		noticeOperations.removeAllNotices();
		noticeOperations.createErrorNotice( message );
	};

	/**
	 * Event handler for the ResizableBox component. Updates both the height attribute,
	 * and the map component's height in the DOM.
	 *
	 * @param {Event}       event     - The event object.
	 * @param {string}      direction - A string representing which resize handler was used.
	 * @param {HTMLElement} elt       - A ref to the ResizeableBox's container element.
	 * @param {object}      delta     - Information about how far the element was resized.
	 */
	const onMapResize = ( event, direction, elt, delta ) => {
		toggleSelection( true );
		const ref = mapRef?.current?.mapRef ?? mapRef;

		if ( ref ) {
			const height = parseInt( ref.current.offsetHeight + delta.height, 10 );

			setAttributes( {
				mapHeight: height,
			} );

			if ( ref.current.sizeMap ) {
				setTimeout( ref.current.sizeMap, 0 );
			}
		}
	};

	useEffect( () => {
		if ( mapProvider === 'mapbox' ) {
			apiCall().then( geoCodeAddress );
		} else {
			setApiState( API_STATE_SUCCESS );
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [] );

	// eslint-disable-next-line react-hooks/exhaustive-deps
	useEffect( geoCodeAddress, [ address ] );

	useEffect( () => {
		// Fetch API key when switching from mapkit to mapbox
		if ( className && ! apiKey ) {
			setApiState( API_STATE_LOADING );
			apiCall();
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [ className ] );

	let content;

	if ( isPreviewMode ) {
		const mapStyleObject = styles.find( styleObject => styleObject.name === mapStyle );

		content = (

		);
	} else if ( apiState === API_STATE_LOADING ) {
		content = (
			<Placeholder icon={ icon }>
				<Spinner />
			</Placeholder>
		);
	} else if ( apiState === API_STATE_FAILURE ) {
		content = (
			<Placeholder icon={ icon } label={ __( 'Map', 'jetpack' ) } notices={ notices }>
				<>

						{ __( 'To use the map block, you need an Access Token.', 'jetpack' ) }

						<ExternalLink href="https://www.mapbox.com">
							{ __( 'Create an account or log in to Mapbox.', 'jetpack' ) }
						</ExternalLink>

						{ __(
							'Locate and copy the default access token. Then, paste it into the field below.',
							'jetpack'
						) }

					<form>
						<input
							type="text"
							className="components-placeholder__input"
							disabled={ apiRequestOutstanding }
							placeholder={ __( 'Paste Token Here', 'jetpack' ) }
							value={ apiKeyControl }
							onChange={ event => setApiKeyControl( event.target.value ) }
						/>
						<Button
							variant="secondary"
							disabled={ apiRequestOutstanding || ! apiKeyControl || apiKeyControl.length < 1 }
							onClick={ updateAPIKey }
						>
							{ __( 'Set Token', 'jetpack' ) }
						</Button>
					</form>
				</>
			</Placeholder>
		);
	} else if ( apiState === API_STATE_SUCCESS ) {
		const onKeyChange = value => setApiKeyControl( value );

		// Only scroll to zoom when the block is selected, and there's 1 or less points.
		const allowScrollToZoom = isSelected && points.length <= 1;

		content = (
			<>
				<BlockControls>
					<Controls
						attributes={ attributes }
						setAttributes={ setAttributes }
						apiKey={ apiKey }
						apiKeySource={ apiKeySource }
						apiKeyControl={ apiKeyControl }
						onKeyChange={ onKeyChange }
						setPointVisibility={ () => setAddPointVisibility( true ) }
						context="toolbar"
						mapRef={ mapRef }
						mapProvider={ mapProvider }
					/>
				</BlockControls>

				<InspectorControls>
					<Controls
						attributes={ attributes }
						setAttributes={ setAttributes }
						apiKey={ apiKey }
						apiKeySource={ apiKeySource }
						apiKeyControl={ apiKeyControl }
						onKeyChange={ onKeyChange }
						mapRef={ mapRef }
						minHeight={ MIN_HEIGHT }
						removeAPIKey={ removeAPIKey }
						updateAPIKey={ updateAPIKey }
						mapProvider={ mapProvider }
					/>
				</InspectorControls>

				<ResizableBox
					size={ {
						height: mapHeight || 'auto',
						width: '100%',
					} }
					grid={ [ 10, 10 ] }
					showHandle={ isSelected }
					minHeight={ MIN_HEIGHT }
					enable={ RESIZABLE_BOX_ENABLE_OPTION }
					onResizeStart={ () => toggleSelection( false ) }
					onResizeStop={ onMapResize }
				>

						<Map
							ref={ mapRef }
							address={ address }
							scrollToZoom={ allowScrollToZoom }
							showFullscreenButton={ showFullscreenButton }
							mapStyle={ mapStyle || 'default' }
							mapDetails={ mapDetails }
							mapHeight={ mapHeight }
							points={ points }
							zoom={ zoom }
							mapCenter={ mapCenter }
							markerColor={ markerColor }
							onSetZoom={ value => {
								setAttributes( { zoom: value } );
							} }
							admin={ true }
							apiKey={ apiKey }
							onSetPoints={ value => setAttributes( { points: value } ) }
							onSetMapCenter={ value => setAttributes( { mapCenter: value } ) }
							onMapLoaded={ () => setAddPointVisibility( ! points.length ) }
							onMarkerClick={ () => setAddPointVisibility( false ) }
							onError={ onError }
							mapProvider={ mapProvider }
						>
							{ isSelected && addPointVisibility && (
								<AddPoint
									onAddPoint={ addPoint }
									onClose={ () => setAddPointVisibility( false ) }
									apiKey={ apiKey }
									onError={ onError }
									tagName="AddPoint"
									mapProvider={ mapProvider }
								/>
							) }
						</Map>

				</ResizableBox>
			</>
		);
	}

	return (

			{ noticeUI }
			{ content }

	);
};

export default compose( withNotices )( MapEdit );

// File: projects/plugins/jetpack/extensions/blocks/map/save.js
import { useBlockProps } from '@wordpress/block-editor';
import clsx from 'clsx';
import { getActiveStyleName } from '../../shared/block-styles';
import styles from './styles';

const MapSave = ( { attributes } ) => {
	const {
		align,
		mapDetails,
		points,
		zoom,
		mapCenter,
		markerColor,
		scrollToZoom,
		mapHeight,
		showFullscreenButton,
	} = attributes;
	const blockProps = useBlockProps.save();
	const { className } = blockProps;

	const mapStyle = getActiveStyleName( styles, className );
	const pointsList = points.map( ( point, index ) => {
		const { longitude, latitude } = point.coordinates;
		const url = 'https://www.google.com/maps/search/?api=1&query=' + latitude + ',' + longitude;
		return (

				{ point.title }

		);
	} );

	// All camelCase attribute names converted to snake_case data attributes
	return (
		<div
			{ ...blockProps }
			className={ clsx( className, align ? `align${ align }` : null ) }
			data-map-style={ mapStyle }
			data-map-details={ mapDetails }
			data-points={ JSON.stringify( points ) }
			data-zoom={ zoom }
			data-map-center={ JSON.stringify( mapCenter ) }
			data-marker-color={ markerColor }
			data-scroll-to-zoom={ scrollToZoom || null }
			data-map-height={ mapHeight || null }
			data-show-fullscreen-button={ showFullscreenButton || null }
		>
			{ points.length > 0 &&
{ pointsList }
 }

	);
};

export default MapSave;


[System]
You are an expert WordPress developer specializing in creating high-quality plugins and Gutenberg blocks.
You write clean, well-documented code following WordPress coding standards and best practices.
Your code is secure, performant, and maintainable.

[User] Build a Gutenberg block that Enable customers to filter the product grid by stock status. with these attributes: class name, heading level, show counts, and 4 more options

[Assistant]
<|thinking|>
To create this {type}, I need to:
- Create the block.json configuration file
- Register the block type
- Define block attributes and their types
- Implement the Edit component for the editor
- Implement the Save component for frontend rendering
- Add necessary controls in the inspector panel
- Style the block for both editor and frontend
<|im_end|>

// File: plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/block.json
{
	"name": "woocommerce/stock-filter",
	"title": "Filter by Stock Controls",
	"description": "Enable customers to filter the product grid by stock status.",
	"category": "woocommerce",
	"keywords": [ "WooCommerce" ],
	"supports": {
		"interactivity": {
			"clientNavigation": false
		},
		"html": false,
		"multiple": false,
		"color": {
			"background": true,
			"text": true,
			"button": true
		},
		"inserter": false,
		"lock": false
	},
	"attributes": {
		"className": {
			"type": "string",
			"default": ""
		},
		"headingLevel": {
			"type": "number",
			"default": 3
		},
		"showCounts": {
			"type": "boolean",
			"default": false
		},
		"showFilterButton": {
			"type": "boolean",
			"default": false
		},
		"displayStyle": {
			"type": "string",
			"default": "list"
		},
		"selectType": {
			"type": "string",
			"default": "multiple"
		},
		"isPreview": {
			"type": "boolean",
			"default": false
		}
	},
	"textdomain": "woocommerce",
	"apiVersion": 3,
	"$schema": "https://schemas.wp.org/trunk/block.json"
}

// File: plugins/woocommerce/client/blocks/assets/js/blocks/stock-filter/edit.tsx
/**
 * External dependencies
 */
import { __, _x } from '@wordpress/i18n';
import clsx from 'clsx';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import BlockTitle from '@woocommerce/editor-components/block-title';
import type { BlockEditProps } from '@wordpress/blocks';
import {
	Disabled,
	PanelBody,
	ToggleControl,
	withSpokenMessages,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalToggleGroupControl as ToggleGroupControl,
	// eslint-disable-next-line @wordpress/no-unsafe-wp-apis
	__experimentalToggleGroupControlOption as ToggleGroupControlOption,
} from '@wordpress/components';

/**
 * Internal dependencies
 */
import Block from './block';
import './editor.scss';
import { Attributes } from './types';
import { UpgradeNotice } from '../filter-wrapper/upgrade';

const Edit = ( {
	clientId,
	attributes,
	setAttributes,
}: BlockEditProps< Attributes > ) => {
	const {
		className,
		heading,
		headingLevel,
		showCounts,
		showFilterButton,
		selectType,
		displayStyle,
	} = attributes;

	const blockProps = useBlockProps( {
		className: clsx( 'wc-block-stock-filter', className ),
	} );

	const getInspectorControls = () => {
		return (
			<InspectorControls key="inspector">
				<PanelBody>
					<UpgradeNotice clientId={ clientId } />
				</PanelBody>
				<PanelBody title={ __( 'Display Settings', 'woocommerce' ) }>
					<ToggleControl
						label={ __( 'Display product count', 'woocommerce' ) }
						checked={ showCounts }
						onChange={ () =>
							setAttributes( {
								showCounts: ! showCounts,
							} )
						}
					/>
					<ToggleGroupControl
						label={ __(
							'Allow selecting multiple options?',
							'woocommerce'
						) }
						isBlock
						value={ selectType || 'multiple' }
						onChange={ ( value: string ) =>
							setAttributes( {
								selectType: value,
							} )
						}
						className="wc-block-attribute-filter__multiple-toggle"
					>
						<ToggleGroupControlOption
							value="multiple"
							label={ _x(
								'Multiple',
								'Number of filters',
								'woocommerce'
							) }
						/>
						<ToggleGroupControlOption
							value="single"
							label={ _x(
								'Single',
								'Number of filters',
								'woocommerce'
							) }
						/>
					</ToggleGroupControl>
					<ToggleGroupControl
						label={ __( 'Display Style', 'woocommerce' ) }
						isBlock
						value={ displayStyle }
						onChange={ ( value ) =>
							setAttributes( {
								displayStyle: value,
							} )
						}
						className="wc-block-attribute-filter__display-toggle"
					>
						<ToggleGroupControlOption
							value="list"
							label={ __( 'List', 'woocommerce' ) }
						/>
						<ToggleGroupControlOption
							value="dropdown"
							label={ __( 'Dropdown', 'woocommerce' ) }
						/>
					</ToggleGroupControl>
					<ToggleControl
						label={ __(
							"Show 'Apply filters' button",
							'woocommerce'
						) }
						help={ __(
							'Products will update when the button is clicked.',
							'woocommerce'
						) }
						checked={ showFilterButton }
						onChange={ ( value ) =>
							setAttributes( {
								showFilterButton: value,
							} )
						}
					/>
				</PanelBody>
			</InspectorControls>
		);
	};

	return (
		<>
			{ getInspectorControls() }
			{
				<div { ...blockProps }>
					{ heading && (
						<BlockTitle
							className="wc-block-stock-filter__title"
							headingLevel={ headingLevel }
							heading={ heading }
							onChange={ ( value: string ) =>
								setAttributes( { heading: value } )
							}
						/>
					) }
					<Disabled>
						<Block attributes={ attributes } isEditor={ true } />
					</Disabled>
				</div>
			}
		</>
	);
};

export default withSpokenMessages( Edit );