{"id":361199,"date":"2026-09-01T10:03:47","date_gmt":"2026-09-01T10:03:47","guid":{"rendered":"https:\/\/fr.wordpress.org\/plugins\/sprint-events-volunteers\/"},"modified":"2026-09-01T10:03:35","modified_gmt":"2026-09-01T10:03:35","slug":"sprint-events-volunteers","status":"publish","type":"plugin","link":"https:\/\/twd.wordpress.org\/plugins\/sprint-events-volunteers\/","author":23539978,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Sprint Events & Volunteers","header_author":"Sprint Plugins","header_description":"Manage club events, volunteer missions, time slots, registrations, and public schedules in WordPress.","assets_banners_color":"f2f2ee","last_updated":"2026-09-01 10:03:35","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/sprintplugins.fr\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":47,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sprintplugins","date":"2026-09-01 10:03:35","revision":3675822}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3675834,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3675834,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256},"icon.svg":{"filename":"icon.svg","revision":3675834,"resolution":false,"location":"assets","locale":false}},"assets_banners":{"banner-1544x500-fr.png":{"filename":"banner-1544x500-fr.png","revision":3675834,"resolution":"1544x500","location":"assets","locale":"fr","width":1544,"height":500},"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3675834,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250-fr.png":{"filename":"banner-772x250-fr.png","revision":3675834,"resolution":"772x250","location":"assets","locale":"fr","width":772,"height":250},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3675834,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3676802,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"meta\":{\"title\":\"Sprint Events & Volunteers \\u2014 WordPress.org Demo\",\"description\":\"A bilingual sample club with events, venues, volunteer missions, members, guests, registrations, and realistic historical data.\",\"author\":\"Sprint Plugins\",\"categories\":[\"Plugins\",\"Events\",\"Community\"]},\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=sprint-events-volunteers\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"features\":{\"networking\":true},\"login\":true,\"steps\":[{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"sprint-events-volunteers\"},\"options\":{\"activate\":true}},{\"step\":\"mkdir\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\"},{\"step\":\"writeFile\",\"path\":\"\\\/wordpress\\\/wp-content\\\/mu-plugins\\\/speb-playground-demo-localizer.php\",\"data\":\"<?php\\n\\\/**\\n * Playground-only demo localizer for Sprint Events & Volunteers.\\n * Created by the WordPress.org Blueprint. This file is not part of the plugin.\\n *\\\/\\nif ( ! defined( 'ABSPATH' ) ) {\\n\\texit;\\n}\\n\\nfunction speb_blueprint_demo_language_code( $locale = '' ) {\\n\\t$locale = $locale ? (string) $locale : get_locale();\\n\\treturn 0 === strpos( strtolower( $locale ), 'fr' ) ? 'fr' : 'en';\\n}\\n\\nfunction speb_blueprint_demo_catalog( $locale = '' ) {\\n\\t$lang = speb_blueprint_demo_language_code( $locale );\\n\\t$catalogs = array(\\n\\t\\t'en' => array(\\n\\t\\t\\t'site' => array(\\n\\t\\t\\t\\t'title'   => 'Riverside Sports Club \\u2014 Demo',\\n\\t\\t\\t\\t'tagline' => 'Sample site for Sprint Events & Volunteers',\\n\\t\\t\\t),\\n\\t\\t\\t'pages' => array(\\n\\t\\t\\t\\t'events'           => 'Club Events',\\n\\t\\t\\t\\t'calendar'         => 'Club Calendar',\\n\\t\\t\\t\\t'archives'         => 'Event Archives',\\n\\t\\t\\t\\t'missions'         => 'Volunteer Missions',\\n\\t\\t\\t\\t'planning'         => 'My Volunteer Schedule',\\n\\t\\t\\t\\t'registrants'      => 'Volunteer Registrants List',\\n\\t\\t\\t\\t'management'       => 'Events and Volunteers Management',\\n\\t\\t\\t\\t'guest_management' => 'My Volunteer Registration',\\n\\t\\t\\t),\\n\\t\\t\\t'terms' => array(\\n\\t\\t\\t\\t'club_life' => 'Club life',\\n\\t\\t\\t\\t'tournament' => 'Tournament',\\n\\t\\t\\t\\t'community' => 'Community',\\n\\t\\t\\t),\\n\\t\\t\\t'locations' => array(\\n\\t\\t\\t\\t'hall' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Riverside Sports Hall',\\n\\t\\t\\t\\t\\t'content' => 'Main indoor venue. Accessible entrance on the east side. Equipment storage is next to the reception desk.',\\n\\t\\t\\t\\t\\t'address' => '12 Club Avenue, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'stadium' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Riverside Stadium',\\n\\t\\t\\t\\t\\t'content' => 'Outdoor pitches and athletics area. Volunteer check-in is beside the main gate.',\\n\\t\\t\\t\\t\\t'address' => '28 Victory Avenue, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'clubhouse' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Club House',\\n\\t\\t\\t\\t\\t'content' => 'Meeting room, kitchen and social area used for volunteer briefings and club gatherings.',\\n\\t\\t\\t\\t\\t'address' => '4 Riverside Walk, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t'events' => array(\\n\\t\\t\\t\\t'open_day' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Club Open Day',\\n\\t\\t\\t\\t\\t'excerpt' => 'Discover the club, meet the team and try our activities.',\\n\\t\\t\\t\\t\\t'content' => '<p>Meet the club team, discover our activities and talk with coaches and volunteers.<\\\/p><p>The day includes short demonstrations, welcome sessions and refreshments for visitors.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'youth_tournament' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Youth Summer Tournament',\\n\\t\\t\\t\\t\\t'excerpt' => 'A friendly tournament bringing together youth teams for a full day of sport.',\\n\\t\\t\\t\\t\\t'content' => '<p>A friendly one-day tournament for youth teams, families and supporters.<\\\/p><p>Volunteers help with setup, arrivals, scorekeeping and refreshments throughout the day.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'volunteer_evening' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Volunteer Appreciation Evening',\\n\\t\\t\\t\\t\\t'excerpt' => 'An evening to thank everyone who gives time to the club.',\\n\\t\\t\\t\\t\\t'content' => '<p>An informal evening to thank volunteers and celebrate the season together.<\\\/p><p>The club will provide a buffet, a short presentation and time to meet other volunteers.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'community_workshop' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Community Workshop',\\n\\t\\t\\t\\t\\t'excerpt' => 'A practical workshop for members and local partners.',\\n\\t\\t\\t\\t\\t'content' => '<p>This workshop was planned with local partners but has been cancelled. It remains in the demo to illustrate event statuses.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'charity_run' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Spring Charity Run',\\n\\t\\t\\t\\t\\t'excerpt' => 'A completed charity event kept in the archives.',\\n\\t\\t\\t\\t\\t'content' => '<p>A community charity run organized earlier in the season. This completed event demonstrates archives and historical registrations.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t'missions' => array(\\n\\t\\t\\t\\t'welcome_desk' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Welcome desk',\\n\\t\\t\\t\\t\\t'content' => 'Welcome visitors, answer basic questions and direct families to the right activity areas.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'refreshments' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Refreshment stand',\\n\\t\\t\\t\\t\\t'content' => 'Help prepare and serve drinks and snacks while keeping the stand organized.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'activity_guides' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Activity guides',\\n\\t\\t\\t\\t\\t'content' => 'Guide visitors between demonstrations and help activity leaders manage small groups.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'field_setup' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Field setup',\\n\\t\\t\\t\\t\\t'content' => 'Install signs, benches and lightweight equipment before the tournament and help pack it away afterward.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'score_table' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Score table',\\n\\t\\t\\t\\t\\t'content' => 'Assist with match sheets, scores and basic information for teams during the tournament.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'parking' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Parking & arrivals',\\n\\t\\t\\t\\t\\t'content' => 'Guide arriving teams and families toward parking, check-in and the correct playing areas.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'evening_setup' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Evening setup',\\n\\t\\t\\t\\t\\t'content' => 'Prepare tables, signage and the reception area before the volunteer evening starts.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'guest_welcome' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Guest welcome',\\n\\t\\t\\t\\t\\t'content' => 'Welcome volunteers and guests, check attendance and point people toward the main room.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'buffet' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Buffet service',\\n\\t\\t\\t\\t\\t'content' => 'Help with buffet setup, service and light clearing during the evening.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'course_marshals' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Course marshals',\\n\\t\\t\\t\\t\\t'content' => 'A completed mission from the archived charity run, retained to demonstrate historical volunteer data.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'fr' => array(\\n\\t\\t\\t'site' => array(\\n\\t\\t\\t\\t'title'   => 'Club sportif des Rives \\u2014 D\\u00e9mo',\\n\\t\\t\\t\\t'tagline' => 'Site de d\\u00e9monstration de Sprint Events & Volunteers',\\n\\t\\t\\t),\\n\\t\\t\\t'pages' => array(\\n\\t\\t\\t\\t'events'           => '\\u00c9v\\u00e9nements du club',\\n\\t\\t\\t\\t'calendar'         => 'Calendrier du club',\\n\\t\\t\\t\\t'archives'         => 'Archives des \\u00e9v\\u00e9nements',\\n\\t\\t\\t\\t'missions'         => 'Missions b\\u00e9n\\u00e9voles',\\n\\t\\t\\t\\t'planning'         => 'Mon planning b\\u00e9n\\u00e9vole',\\n\\t\\t\\t\\t'registrants'      => 'Liste des b\\u00e9n\\u00e9voles inscrits',\\n\\t\\t\\t\\t'management'       => 'Gestion des \\u00e9v\\u00e9nements et b\\u00e9n\\u00e9voles',\\n\\t\\t\\t\\t'guest_management' => 'Mon inscription b\\u00e9n\\u00e9vole',\\n\\t\\t\\t),\\n\\t\\t\\t'terms' => array(\\n\\t\\t\\t\\t'club_life' => 'Vie du club',\\n\\t\\t\\t\\t'tournament' => 'Tournoi',\\n\\t\\t\\t\\t'community' => 'Vie associative',\\n\\t\\t\\t),\\n\\t\\t\\t'locations' => array(\\n\\t\\t\\t\\t'hall' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Gymnase des Rives',\\n\\t\\t\\t\\t\\t'content' => 'Salle principale du club. L\\u2019entr\\u00e9e accessible se trouve c\\u00f4t\\u00e9 est. Le local mat\\u00e9riel est \\u00e0 c\\u00f4t\\u00e9 de l\\u2019accueil.',\\n\\t\\t\\t\\t\\t'address' => '12 avenue du Club, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'stadium' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Stade des Rives',\\n\\t\\t\\t\\t\\t'content' => 'Terrains ext\\u00e9rieurs et zone d\\u2019athl\\u00e9tisme. L\\u2019accueil des b\\u00e9n\\u00e9voles se fait pr\\u00e8s de l\\u2019entr\\u00e9e principale.',\\n\\t\\t\\t\\t\\t'address' => '28 avenue de la Victoire, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'clubhouse' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Maison du club',\\n\\t\\t\\t\\t\\t'content' => 'Salle de r\\u00e9union, cuisine et espace convivial utilis\\u00e9s pour les briefings b\\u00e9n\\u00e9voles et les rencontres du club.',\\n\\t\\t\\t\\t\\t'address' => '4 promenade des Rives, 75012 Paris',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t'events' => array(\\n\\t\\t\\t\\t'open_day' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Journ\\u00e9e portes ouvertes du club',\\n\\t\\t\\t\\t\\t'excerpt' => 'D\\u00e9couvrez le club, rencontrez l\\u2019\\u00e9quipe et essayez nos activit\\u00e9s.',\\n\\t\\t\\t\\t\\t'content' => '<p>Rencontrez l\\u2019\\u00e9quipe du club, d\\u00e9couvrez nos activit\\u00e9s et \\u00e9changez avec les entra\\u00eeneurs et les b\\u00e9n\\u00e9voles.<\\\/p><p>La journ\\u00e9e comprend des d\\u00e9monstrations, des temps d\\u2019accueil et une buvette pour les visiteurs.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'youth_tournament' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Tournoi d\\u2019\\u00e9t\\u00e9 des jeunes',\\n\\t\\t\\t\\t\\t'excerpt' => 'Un tournoi convivial r\\u00e9unissant les \\u00e9quipes de jeunes pour une journ\\u00e9e compl\\u00e8te de sport.',\\n\\t\\t\\t\\t\\t'content' => '<p>Un tournoi amical d\\u2019une journ\\u00e9e pour les \\u00e9quipes de jeunes, les familles et les supporters.<\\\/p><p>Les b\\u00e9n\\u00e9voles participent \\u00e0 l\\u2019installation, \\u00e0 l\\u2019accueil, \\u00e0 la table de marque et \\u00e0 la buvette.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'volunteer_evening' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Soir\\u00e9e des b\\u00e9n\\u00e9voles',\\n\\t\\t\\t\\t\\t'excerpt' => 'Une soir\\u00e9e pour remercier toutes les personnes qui donnent de leur temps au club.',\\n\\t\\t\\t\\t\\t'content' => '<p>Une soir\\u00e9e conviviale pour remercier les b\\u00e9n\\u00e9voles et c\\u00e9l\\u00e9brer la saison ensemble.<\\\/p><p>Le club pr\\u00e9voit un buffet, une courte pr\\u00e9sentation et un moment d\\u2019\\u00e9change entre b\\u00e9n\\u00e9voles.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'community_workshop' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Atelier associatif',\\n\\t\\t\\t\\t\\t'excerpt' => 'Un atelier pratique destin\\u00e9 aux adh\\u00e9rents et aux partenaires locaux.',\\n\\t\\t\\t\\t\\t'content' => '<p>Cet atelier pr\\u00e9vu avec des partenaires locaux a \\u00e9t\\u00e9 annul\\u00e9. Il reste dans la d\\u00e9mo afin d\\u2019illustrer les diff\\u00e9rents statuts d\\u2019un \\u00e9v\\u00e9nement.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'charity_run' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Course solidaire de printemps',\\n\\t\\t\\t\\t\\t'excerpt' => 'Un \\u00e9v\\u00e9nement solidaire termin\\u00e9 et conserv\\u00e9 dans les archives.',\\n\\t\\t\\t\\t\\t'content' => '<p>Une course solidaire organis\\u00e9e plus t\\u00f4t dans la saison. Cet \\u00e9v\\u00e9nement termin\\u00e9 illustre les archives et l\\u2019historique des inscriptions.<\\\/p>',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t\\t'missions' => array(\\n\\t\\t\\t\\t'welcome_desk' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Accueil des participants',\\n\\t\\t\\t\\t\\t'content' => 'Accueillir les visiteurs, r\\u00e9pondre aux premi\\u00e8res questions et orienter les familles vers les activit\\u00e9s.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'refreshments' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Buvette',\\n\\t\\t\\t\\t\\t'content' => 'Aider \\u00e0 pr\\u00e9parer et servir les boissons et collations tout en maintenant l\\u2019espace organis\\u00e9.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'activity_guides' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Orientation des activit\\u00e9s',\\n\\t\\t\\t\\t\\t'content' => 'Orienter les visiteurs entre les d\\u00e9monstrations et aider les responsables \\u00e0 g\\u00e9rer les petits groupes.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'field_setup' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Installation des terrains',\\n\\t\\t\\t\\t\\t'content' => 'Installer la signal\\u00e9tique, les bancs et le petit mat\\u00e9riel avant le tournoi, puis aider au rangement.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'score_table' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Table de marque',\\n\\t\\t\\t\\t\\t'content' => 'Aider \\u00e0 g\\u00e9rer les feuilles de match, les scores et les informations destin\\u00e9es aux \\u00e9quipes.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'parking' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Parking et orientation',\\n\\t\\t\\t\\t\\t'content' => 'Orienter les \\u00e9quipes et les familles vers le stationnement, l\\u2019accueil et les bons terrains.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'evening_setup' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Installation de la soir\\u00e9e',\\n\\t\\t\\t\\t\\t'content' => 'Pr\\u00e9parer les tables, la signal\\u00e9tique et l\\u2019espace d\\u2019accueil avant le d\\u00e9but de la soir\\u00e9e des b\\u00e9n\\u00e9voles.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'guest_welcome' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Accueil des invit\\u00e9s',\\n\\t\\t\\t\\t\\t'content' => 'Accueillir les b\\u00e9n\\u00e9voles et les invit\\u00e9s, v\\u00e9rifier les pr\\u00e9sences et les orienter vers la salle principale.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'buffet' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Service du buffet',\\n\\t\\t\\t\\t\\t'content' => 'Aider \\u00e0 l\\u2019installation du buffet, au service et au rangement l\\u00e9ger pendant la soir\\u00e9e.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\t'course_marshals' => array(\\n\\t\\t\\t\\t\\t'title'   => 'Signaleurs de parcours',\\n\\t\\t\\t\\t\\t'content' => 'Une mission termin\\u00e9e issue de la course solidaire archiv\\u00e9e, conserv\\u00e9e pour illustrer l\\u2019historique des b\\u00e9n\\u00e9voles.',\\n\\t\\t\\t\\t),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t);\\n\\treturn $catalogs[ $lang ];\\n}\\n\\nfunction speb_blueprint_demo_apply_locale( $locale = '' ) {\\n\\t$ids = get_option( 'speb_blueprint_demo_ids', array() );\\n\\tif ( ! is_array( $ids ) || empty( $ids ) ) {\\n\\t\\treturn;\\n\\t}\\n\\t$locale  = $locale ? (string) $locale : get_locale();\\n\\t$catalog = speb_blueprint_demo_catalog( $locale );\\n\\n\\tif ( isset( $catalog['site']['title'] ) ) {\\n\\t\\tupdate_option( 'blogname', $catalog['site']['title'] );\\n\\t}\\n\\tif ( isset( $catalog['site']['tagline'] ) ) {\\n\\t\\tupdate_option( 'blogdescription', $catalog['site']['tagline'] );\\n\\t}\\n\\n\\tif ( ! empty( $ids['pages'] ) && is_array( $ids['pages'] ) ) {\\n\\t\\tforeach ( $ids['pages'] as $key => $post_id ) {\\n\\t\\t\\tif ( $post_id && isset( $catalog['pages'][ $key ] ) ) {\\n\\t\\t\\t\\twp_update_post( array( 'ID' => absint( $post_id ), 'post_title' => $catalog['pages'][ $key ] ) );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tif ( ! empty( $ids['locations'] ) && is_array( $ids['locations'] ) ) {\\n\\t\\tforeach ( $ids['locations'] as $key => $post_id ) {\\n\\t\\t\\tif ( ! $post_id || ! isset( $catalog['locations'][ $key ] ) ) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\t\\t$item = $catalog['locations'][ $key ];\\n\\t\\t\\twp_update_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'ID'           => absint( $post_id ),\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location_address', $item['address'] );\\n\\t\\t}\\n\\t}\\n\\n\\tif ( ! empty( $ids['events'] ) && is_array( $ids['events'] ) ) {\\n\\t\\tforeach ( $ids['events'] as $key => $post_id ) {\\n\\t\\t\\tif ( ! $post_id || ! isset( $catalog['events'][ $key ] ) ) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\t\\t$item = $catalog['events'][ $key ];\\n\\t\\t\\twp_update_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'ID'           => absint( $post_id ),\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_excerpt' => $item['excerpt'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t\\t$location_key = isset( $ids['event_locations'][ $key ] ) ? $ids['event_locations'][ $key ] : '';\\n\\t\\t\\tif ( $location_key && isset( $catalog['locations'][ $location_key ] ) ) {\\n\\t\\t\\t\\t$location = $catalog['locations'][ $location_key ];\\n\\t\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location', $location['title'] );\\n\\t\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location_address', $location['address'] );\\n\\t\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location_snapshot_title', $location['title'] );\\n\\t\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location_snapshot_address', $location['address'] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tif ( ! empty( $ids['missions'] ) && is_array( $ids['missions'] ) ) {\\n\\t\\tforeach ( $ids['missions'] as $key => $post_id ) {\\n\\t\\t\\tif ( ! $post_id || ! isset( $catalog['missions'][ $key ] ) ) {\\n\\t\\t\\t\\tcontinue;\\n\\t\\t\\t}\\n\\t\\t\\t$item = $catalog['missions'][ $key ];\\n\\t\\t\\twp_update_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'ID'           => absint( $post_id ),\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t\\t$location_key = isset( $ids['mission_locations'][ $key ] ) ? $ids['mission_locations'][ $key ] : '';\\n\\t\\t\\tif ( $location_key && isset( $catalog['locations'][ $location_key ] ) ) {\\n\\t\\t\\t\\tupdate_post_meta( absint( $post_id ), '_speb_location', $catalog['locations'][ $location_key ]['title'] );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tif ( ! empty( $ids['terms'] ) && is_array( $ids['terms'] ) ) {\\n\\t\\tglobal $wpdb;\\n\\t\\tforeach ( $ids['terms'] as $key => $term_id ) {\\n\\t\\t\\tif ( $term_id && isset( $catalog['terms'][ $key ] ) ) {\\n\\t\\t\\t\\t$wpdb->update( $wpdb->terms, array( 'name' => $catalog['terms'][ $key ] ), array( 'term_id' => absint( $term_id ) ), array( '%s' ), array( '%d' ) );\\n\\t\\t\\t\\tclean_term_cache( absint( $term_id ), 'speb_event_type' );\\n\\t\\t\\t}\\n\\t\\t}\\n\\t}\\n\\n\\tupdate_option( 'speb_blueprint_demo_locale', $locale, false );\\n}\\n\\nfunction speb_blueprint_demo_updated_option( $option, $old_value, $value ) {\\n\\tunset( $old_value );\\n\\tif ( 'WPLANG' === $option ) {\\n\\t\\tspeb_blueprint_demo_apply_locale( $value ? $value : 'en_US' );\\n\\t}\\n}\\nadd_action( 'updated_option', 'speb_blueprint_demo_updated_option', 10, 3 );\\n\\nfunction speb_blueprint_demo_added_option( $option, $value ) {\\n\\tif ( 'WPLANG' === $option ) {\\n\\t\\tspeb_blueprint_demo_apply_locale( $value ? $value : 'en_US' );\\n\\t}\\n}\\nadd_action( 'added_option', 'speb_blueprint_demo_added_option', 10, 2 );\\n\\nfunction speb_blueprint_demo_sync_locale_on_init() {\\n\\t$locale = get_locale();\\n\\tif ( get_option( 'speb_blueprint_demo_locale', '' ) !== $locale ) {\\n\\t\\tspeb_blueprint_demo_apply_locale( $locale );\\n\\t}\\n}\\nadd_action( 'init', 'speb_blueprint_demo_sync_locale_on_init', 99 );\\n\"},{\"step\":\"runPHP\",\"code\":\"<?php\\ntry {\\n\\trequire_once '\\\/wordpress\\\/wp-load.php';\\n\\n\\tif ( ! class_exists( 'SPEB_Activator' ) ) {\\n\\t\\tthrow new RuntimeException( 'Sprint Events & Volunteers must be active before the demo data is created.' );\\n\\t}\\n\\tif ( ! class_exists( 'SPEB_Page_Manager' ) || ! class_exists( 'SPEB_Display_Mode' ) ) {\\n\\t\\tthrow new RuntimeException( 'Required Sprint Events & Volunteers core classes are unavailable.' );\\n\\t}\\n\\n\\t\\\/\\\/ WordPress.org has already activated the plugin. Do NOT call\\n\\t\\\/\\\/ SPEB_Activator::activate() again inside Playground.\\n\\t$page_manager = new SPEB_Page_Manager();\\n\\t$page_manager->create_missing_pages();\\n\\n\\t\\\/\\\/ Demo configuration: show the entire interface by default.\\n\\t$settings = get_option( SPEB_Activator::SETTINGS, array() );\\n\\t$settings = is_array( $settings ) ? $settings : array();\\n\\t$settings['display_mode'] = SPEB_Display_Mode::EXPERT;\\n\\t$settings['modules'] = array(\\n\\t\\t'events'     => 1,\\n\\t\\t'volunteers' => 1,\\n\\t);\\n\\n\\tif ( ! isset( $settings['events'] ) || ! is_array( $settings['events'] ) ) {\\n\\t\\t$settings['events'] = array();\\n\\t}\\n\\t$settings['events']['default_display_lead_days'] = 30;\\n\\t$settings['events']['auto_archive'] = 0;\\n\\t$settings['events']['archive_after_days'] = 7;\\n\\t$settings['events']['registration_emails_enabled'] = 1;\\n\\n\\tif ( ! isset( $settings['volunteers'] ) || ! is_array( $settings['volunteers'] ) ) {\\n\\t\\t$settings['volunteers'] = array();\\n\\t}\\n\\t$settings['volunteers']['emails_enabled'] = 1;\\n\\t$settings['volunteers']['guest_registrations'] = 1;\\n\\t$settings['volunteers']['cancellation_hours'] = 0;\\n\\n\\tupdate_option( SPEB_Activator::SETTINGS, $settings, false );\\n\\tupdate_user_meta( 1, SPEB_Display_Mode::USER_META, SPEB_Display_Mode::EXPERT );\\n\\n\\t\\\/\\\/ If a persisted Playground site runs the Blueprint again, keep the\\n\\t\\\/\\\/ requested Expert display and simply re-apply the selected language.\\n\\tif ( get_option( 'speb_blueprint_demo_seeded', false ) ) {\\n\\t\\tif ( function_exists( 'speb_blueprint_demo_apply_locale' ) ) {\\n\\t\\t\\tspeb_blueprint_demo_apply_locale( get_locale() );\\n\\t\\t}\\n\\t\\treturn;\\n\\t}\\n\\n\\n\\tif ( ! class_exists( 'SPEB_Event_Repository' ) || ! class_exists( 'SPEB_Event_Post_Types' ) ) {\\n\\t\\tthrow new RuntimeException( 'Event repository\\\/post-type classes are unavailable.' );\\n\\t}\\n\\tif ( ! function_exists( 'speb_blueprint_demo_catalog' ) ) {\\n\\t\\tthrow new RuntimeException( 'Blueprint demo catalog is unavailable.' );\\n\\t}\\n\\n\\tif ( ! post_type_exists( 'speb_event' ) || ! post_type_exists( 'speb_location' ) || ! taxonomy_exists( 'speb_event_type' ) ) {\\n\\t\\t$event_repo  = new SPEB_Event_Repository();\\n\\t\\t$event_types = new SPEB_Event_Post_Types( $event_repo );\\n\\t\\t$event_types->register();\\n\\t}\\n\\n\\t$catalog = speb_blueprint_demo_catalog( get_locale() );\\n\\n\\t\\\/\\\/ Venues.\\n\\t$location_ids = array();\\n\\tforeach ( array( 'hall', 'stadium', 'clubhouse' ) as $key ) {\\n\\t\\t$existing = get_posts(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'post_type'      => 'speb_location',\\n\\t\\t\\t\\t'post_status'    => 'any',\\n\\t\\t\\t\\t'posts_per_page' => 1,\\n\\t\\t\\t\\t'fields'         => 'ids',\\n\\t\\t\\t\\t'meta_key'       => '_speb_blueprint_demo_key',\\n\\t\\t\\t\\t'meta_value'     => $key,\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\t$location_id = absint( $existing[0] );\\n\\t\\t} else {\\n\\t\\t\\t$item = $catalog['locations'][ $key ];\\n\\t\\t\\t$location_id = wp_insert_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'post_type'    => 'speb_location',\\n\\t\\t\\t\\t\\t'post_status'  => 'publish',\\n\\t\\t\\t\\t\\t'post_author'  => 1,\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\ttrue\\n\\t\\t\\t);\\n\\t\\t\\tif ( is_wp_error( $location_id ) ) {\\n\\t\\t\\t\\tthrow new RuntimeException( 'Venue ' . $key . ': ' . $location_id->get_error_message() );\\n\\t\\t\\t}\\n\\t\\t\\tupdate_post_meta( $location_id, '_speb_location_address', $item['address'] );\\n\\t\\t\\tupdate_post_meta( $location_id, '_speb_blueprint_demo_key', $key );\\n\\t\\t}\\n\\t\\t$location_ids[ $key ] = absint( $location_id );\\n\\t}\\n\\n\\t\\\/\\\/ Event types.\\n\\t$term_ids = array();\\n\\t$term_slugs = array(\\n\\t\\t'club_life'  => 'club-life',\\n\\t\\t'tournament' => 'tournament',\\n\\t\\t'community'  => 'community',\\n\\t);\\n\\n\\tforeach ( $term_slugs as $key => $slug ) {\\n\\t\\t$existing = term_exists( $slug, 'speb_event_type' );\\n\\t\\tif ( $existing ) {\\n\\t\\t\\t$term_id = is_array( $existing ) ? absint( $existing['term_id'] ) : absint( $existing );\\n\\t\\t} else {\\n\\t\\t\\t$created = wp_insert_term(\\n\\t\\t\\t\\t$catalog['terms'][ $key ],\\n\\t\\t\\t\\t'speb_event_type',\\n\\t\\t\\t\\tarray( 'slug' => $slug )\\n\\t\\t\\t);\\n\\t\\t\\tif ( is_wp_error( $created ) ) {\\n\\t\\t\\t\\tthrow new RuntimeException( 'Event type ' . $key . ': ' . $created->get_error_message() );\\n\\t\\t\\t}\\n\\t\\t\\t$term_id = absint( $created['term_id'] );\\n\\t\\t}\\n\\t\\t$term_ids[ $key ] = $term_id;\\n\\t}\\n\\n\\t$tz       = wp_timezone();\\n\\t$utc      = new DateTimeZone( 'UTC' );\\n\\t$today    = new DateTimeImmutable( 'today', $tz );\\n\\n\\t$local_dt = static function ( $day_offset, $time ) use ( $today ) {\\n\\t\\t$modifier = ( $day_offset >= 0 ? '+' : '' ) . intval( $day_offset ) . ' days';\\n\\t\\t$date = $today->modify( $modifier );\\n\\t\\tlist( $hour, $minute ) = array_map( 'intval', explode( ':', $time ) );\\n\\t\\treturn $date->setTime( $hour, $minute, 0 );\\n\\t};\\n\\n\\t$utc_string = static function ( DateTimeImmutable $date ) use ( $utc ) {\\n\\t\\treturn $date->setTimezone( $utc )->format( 'Y-m-d H:i:s' );\\n\\t};\\n\\n\\t$event_definitions = array(\\n\\t\\t'open_day' => array(\\n\\t\\t\\t'day' => 7, 'start' => '09:00', 'end' => '16:00', 'location' => 'hall', 'term' => 'club_life',\\n\\t\\t\\t'status' => 'published', 'featured' => 1, 'registration' => 1, 'capacity' => 90,\\n\\t\\t),\\n\\t\\t'youth_tournament' => array(\\n\\t\\t\\t'day' => 14, 'start' => '08:30', 'end' => '18:00', 'location' => 'stadium', 'term' => 'tournament',\\n\\t\\t\\t'status' => 'published', 'featured' => 1, 'registration' => 1, 'capacity' => 72,\\n\\t\\t),\\n\\t\\t'volunteer_evening' => array(\\n\\t\\t\\t'day' => 28, 'start' => '19:00', 'end' => '22:30', 'location' => 'clubhouse', 'term' => 'club_life',\\n\\t\\t\\t'status' => 'published', 'featured' => 0, 'registration' => 1, 'capacity' => 60,\\n\\t\\t),\\n\\t\\t'community_workshop' => array(\\n\\t\\t\\t'day' => 21, 'start' => '14:00', 'end' => '17:00', 'location' => 'clubhouse', 'term' => 'community',\\n\\t\\t\\t'status' => 'canceled', 'featured' => 0, 'registration' => 0, 'capacity' => 0,\\n\\t\\t),\\n\\t\\t'charity_run' => array(\\n\\t\\t\\t'day' => -21, 'start' => '09:00', 'end' => '13:00', 'location' => 'stadium', 'term' => 'community',\\n\\t\\t\\t'status' => 'archived', 'featured' => 0, 'registration' => 0, 'capacity' => 80,\\n\\t\\t),\\n\\t);\\n\\n\\t$event_ids = array();\\n\\tforeach ( $event_definitions as $key => $definition ) {\\n\\t\\t$existing = get_posts(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'post_type'      => 'speb_event',\\n\\t\\t\\t\\t'post_status'    => 'any',\\n\\t\\t\\t\\t'posts_per_page' => 1,\\n\\t\\t\\t\\t'fields'         => 'ids',\\n\\t\\t\\t\\t'meta_key'       => '_speb_blueprint_demo_key',\\n\\t\\t\\t\\t'meta_value'     => $key,\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\t$item = $catalog['events'][ $key ];\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\t$event_id = absint( $existing[0] );\\n\\t\\t} else {\\n\\t\\t\\t$event_id = wp_insert_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'post_type'    => 'speb_event',\\n\\t\\t\\t\\t\\t'post_status'  => 'publish',\\n\\t\\t\\t\\t\\t'post_author'  => 1,\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_excerpt' => $item['excerpt'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\ttrue\\n\\t\\t\\t);\\n\\t\\t\\tif ( is_wp_error( $event_id ) ) {\\n\\t\\t\\t\\tthrow new RuntimeException( 'Event ' . $key . ': ' . $event_id->get_error_message() );\\n\\t\\t\\t}\\n\\t\\t\\tupdate_post_meta( $event_id, '_speb_blueprint_demo_key', $key );\\n\\t\\t}\\n\\n\\t\\t$start = $local_dt( $definition['day'], $definition['start'] );\\n\\t\\t$end   = $local_dt( $definition['day'], $definition['end'] );\\n\\t\\t$location_key = $definition['location'];\\n\\t\\t$location = $catalog['locations'][ $location_key ];\\n\\n\\t\\tupdate_post_meta( $event_id, '_speb_start_at', $utc_string( $start ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_end_at', $utc_string( $end ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_display_start', $utc_string( $start->modify( '-30 days' ) ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_display_end', $utc_string( $end->modify( '+2 days' ) ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_status', $definition['status'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_featured', (string) $definition['featured'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_registration_enabled', (string) $definition['registration'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_registration_capacity', absint( $definition['capacity'] ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_registration_close_at', $utc_string( $start->modify( '-12 hours' ) ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_location_id', $location_ids[ $location_key ] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_location', $location['title'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_location_address', $location['address'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_location_snapshot_title', $location['title'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_location_snapshot_address', $location['address'] );\\n\\t\\tupdate_post_meta( $event_id, '_speb_visibility', 'public' );\\n\\t\\tupdate_post_meta( $event_id, '_speb_visible_roles', array() );\\n\\t\\tupdate_post_meta( $event_id, '_speb_private_token', wp_generate_password( 24, false, false ) );\\n\\t\\tupdate_post_meta( $event_id, '_speb_external_url', '' );\\n\\n\\t\\t$result = wp_set_object_terms(\\n\\t\\t\\t$event_id,\\n\\t\\t\\tarray( $term_ids[ $definition['term'] ] ),\\n\\t\\t\\t'speb_event_type',\\n\\t\\t\\tfalse\\n\\t\\t);\\n\\t\\tif ( is_wp_error( $result ) ) {\\n\\t\\t\\tthrow new RuntimeException( 'Event taxonomy ' . $key . ': ' . $result->get_error_message() );\\n\\t\\t}\\n\\n\\t\\t$event_ids[ $key ] = absint( $event_id );\\n\\t}\\n\\n\\n\\t\\\/\\\/ Missions and time slots.\\n\\tif ( ! class_exists( 'SPEB_Mission_Repository' ) || ! class_exists( 'SPEB_Mission_Post_Types' ) || ! class_exists( 'SPEB_Mission_Slots' ) ) {\\n\\t\\tthrow new RuntimeException( 'Mission classes are unavailable.' );\\n\\t}\\n\\n\\tif ( ! post_type_exists( 'speb_mission' ) ) {\\n\\t\\t$mission_repo  = new SPEB_Mission_Repository();\\n\\t\\t$mission_types = new SPEB_Mission_Post_Types( $mission_repo );\\n\\t\\t$mission_types->register();\\n\\t}\\n\\n\\t$local_date = static function ( $day_offset ) use ( $today ) {\\n\\t\\t$modifier = ( $day_offset >= 0 ? '+' : '' ) . intval( $day_offset ) . ' days';\\n\\t\\treturn $today->modify( $modifier )->format( 'Y-m-d' );\\n\\t};\\n\\n\\t$mission_definitions = array(\\n\\t\\t'welcome_desk' => array(\\n\\t\\t\\t'event' => 'open_day', 'location' => 'hall',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'welcome-morning', 'day' => 7, 'start' => '09:00', 'end' => '11:30', 'capacity' => 4 ),\\n\\t\\t\\t\\tarray( 'id' => 'welcome-midday', 'day' => 7, 'start' => '11:30', 'end' => '14:30', 'capacity' => 4 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'refreshments' => array(\\n\\t\\t\\t'event' => 'open_day', 'location' => 'hall',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'refresh-morning', 'day' => 7, 'start' => '10:00', 'end' => '12:30', 'capacity' => 3 ),\\n\\t\\t\\t\\tarray( 'id' => 'refresh-afternoon', 'day' => 7, 'start' => '12:30', 'end' => '15:30', 'capacity' => 3 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'activity_guides' => array(\\n\\t\\t\\t'event' => 'open_day', 'location' => 'hall',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'guides-morning', 'day' => 7, 'start' => '10:00', 'end' => '12:00', 'capacity' => 5 ),\\n\\t\\t\\t\\tarray( 'id' => 'guides-afternoon', 'day' => 7, 'start' => '13:00', 'end' => '15:00', 'capacity' => 5 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'field_setup' => array(\\n\\t\\t\\t'event' => 'youth_tournament', 'location' => 'stadium',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'field-setup', 'day' => 14, 'start' => '07:30', 'end' => '09:00', 'capacity' => 6 ),\\n\\t\\t\\t\\tarray( 'id' => 'field-packdown', 'day' => 14, 'start' => '16:30', 'end' => '18:00', 'capacity' => 4 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'score_table' => array(\\n\\t\\t\\t'event' => 'youth_tournament', 'location' => 'stadium',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'scores-morning', 'day' => 14, 'start' => '09:00', 'end' => '12:30', 'capacity' => 4 ),\\n\\t\\t\\t\\tarray( 'id' => 'scores-afternoon', 'day' => 14, 'start' => '13:30', 'end' => '17:00', 'capacity' => 4 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'parking' => array(\\n\\t\\t\\t'event' => 'youth_tournament', 'location' => 'stadium',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'parking-arrivals', 'day' => 14, 'start' => '08:00', 'end' => '10:00', 'capacity' => 5 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'evening_setup' => array(\\n\\t\\t\\t'event' => 'volunteer_evening', 'location' => 'clubhouse',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'evening-setup', 'day' => 28, 'start' => '17:00', 'end' => '19:00', 'capacity' => 5 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'guest_welcome' => array(\\n\\t\\t\\t'event' => 'volunteer_evening', 'location' => 'clubhouse',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'evening-welcome', 'day' => 28, 'start' => '18:30', 'end' => '20:30', 'capacity' => 4 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'buffet' => array(\\n\\t\\t\\t'event' => 'volunteer_evening', 'location' => 'clubhouse',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'buffet-service', 'day' => 28, 'start' => '19:00', 'end' => '22:00', 'capacity' => 5 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t\\t'course_marshals' => array(\\n\\t\\t\\t'event' => 'charity_run', 'location' => 'stadium',\\n\\t\\t\\t'slots' => array(\\n\\t\\t\\t\\tarray( 'id' => 'course-marshals', 'day' => -21, 'start' => '08:30', 'end' => '12:30', 'capacity' => 5 ),\\n\\t\\t\\t),\\n\\t\\t),\\n\\t);\\n\\n\\t$mission_ids = array();\\n\\n\\tforeach ( $mission_definitions as $key => $definition ) {\\n\\t\\t$item = $catalog['missions'][ $key ];\\n\\n\\t\\t$normalized_slots = array();\\n\\t\\tforeach ( $definition['slots'] as $slot ) {\\n\\t\\t\\t$normalized_slots[] = array(\\n\\t\\t\\t\\t'id'       => $slot['id'],\\n\\t\\t\\t\\t'date'     => $local_date( $slot['day'] ),\\n\\t\\t\\t\\t'start'    => $slot['start'],\\n\\t\\t\\t\\t'end'      => $slot['end'],\\n\\t\\t\\t\\t'capacity' => absint( $slot['capacity'] ),\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\t$normalized_slots = SPEB_Mission_Slots::normalize( $normalized_slots );\\n\\n\\t\\tif ( empty( $normalized_slots ) ) {\\n\\t\\t\\tthrow new RuntimeException( 'Mission ' . $key . ': normalized slots are empty.' );\\n\\t\\t}\\n\\n\\t\\t$existing = get_posts(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'post_type'      => 'speb_mission',\\n\\t\\t\\t\\t'post_status'    => 'any',\\n\\t\\t\\t\\t'posts_per_page' => 1,\\n\\t\\t\\t\\t'fields'         => 'ids',\\n\\t\\t\\t\\t'meta_key'       => '_speb_blueprint_demo_key',\\n\\t\\t\\t\\t'meta_value'     => $key,\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\t$mission_id = absint( $existing[0] );\\n\\t\\t} else {\\n\\t\\t\\t$mission_id = wp_insert_post(\\n\\t\\t\\t\\tarray(\\n\\t\\t\\t\\t\\t'post_type'    => 'speb_mission',\\n\\t\\t\\t\\t\\t'post_status'  => 'publish',\\n\\t\\t\\t\\t\\t'post_author'  => 1,\\n\\t\\t\\t\\t\\t'post_title'   => $item['title'],\\n\\t\\t\\t\\t\\t'post_content' => $item['content'],\\n\\t\\t\\t\\t),\\n\\t\\t\\t\\ttrue\\n\\t\\t\\t);\\n\\n\\t\\t\\tif ( is_wp_error( $mission_id ) ) {\\n\\t\\t\\t\\tthrow new RuntimeException( 'Mission ' . $key . ': ' . $mission_id->get_error_message() );\\n\\t\\t\\t}\\n\\n\\t\\t\\tupdate_post_meta( $mission_id, '_speb_blueprint_demo_key', $key );\\n\\t\\t}\\n\\n\\t\\t$location_key = $definition['location'];\\n\\n\\t\\tupdate_post_meta( $mission_id, '_speb_event_id', $event_ids[ $definition['event'] ] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_location_id', $location_ids[ $location_key ] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_location', $catalog['locations'][ $location_key ]['title'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_guest_registration', 'enabled' );\\n\\t\\tupdate_post_meta( $mission_id, SPEB_Mission_Slots::META_KEY, $normalized_slots );\\n\\n\\t\\t$first = reset( $normalized_slots );\\n\\t\\t$last  = end( $normalized_slots );\\n\\n\\t\\tupdate_post_meta( $mission_id, '_speb_mission_start', $first['date'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_mission_end', $last['date'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_date', $first['date'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_start_time', $first['start'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_end_time', $first['end'] );\\n\\t\\tupdate_post_meta( $mission_id, '_speb_capacity', $first['capacity'] );\\n\\n\\t\\t$mission_ids[ $key ] = absint( $mission_id );\\n\\t}\\n\\n\\n\\t\\\/\\\/ Demo users only. No registrations yet.\\n\\t$get_or_create_user = static function ( $login, $first, $last, $email, $role = 'subscriber' ) {\\n\\t\\t$user = get_user_by( 'login', $login );\\n\\n\\t\\tif ( $user ) {\\n\\t\\t\\treturn absint( $user->ID );\\n\\t\\t}\\n\\n\\t\\t$user_id = wp_insert_user(\\n\\t\\t\\tarray(\\n\\t\\t\\t\\t'user_login'   => $login,\\n\\t\\t\\t\\t'user_pass'    => wp_generate_password( 24, true, true ),\\n\\t\\t\\t\\t'user_email'   => $email,\\n\\t\\t\\t\\t'first_name'   => $first,\\n\\t\\t\\t\\t'last_name'    => $last,\\n\\t\\t\\t\\t'display_name' => trim( $first . ' ' . $last ),\\n\\t\\t\\t\\t'role'         => $role,\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( is_wp_error( $user_id ) ) {\\n\\t\\t\\tthrow new RuntimeException( 'User ' . $login . ': ' . $user_id->get_error_message() );\\n\\t\\t}\\n\\n\\t\\treturn absint( $user_id );\\n\\t};\\n\\n\\t$manager_role = get_role( 'speb_manager' ) ? 'speb_manager' : 'subscriber';\\n\\n\\t$manager_id = $get_or_create_user(\\n\\t\\t'speb_demo_manager',\\n\\t\\t'Camille',\\n\\t\\t'Laurent',\\n\\t\\t'camille.laurent@example.org',\\n\\t\\t$manager_role\\n\\t);\\n\\n\\t$people = array(\\n\\t\\tarray( 'alex.martin', 'Alex', 'Martin' ),\\n\\t\\tarray( 'emma.dubois', 'Emma', 'Dubois' ),\\n\\t\\tarray( 'noah.bernard', 'Noah', 'Bernard' ),\\n\\t\\tarray( 'sofia.laurent', 'Sofia', 'Laurent' ),\\n\\t\\tarray( 'liam.garcia', 'Liam', 'Garcia' ),\\n\\t\\tarray( 'mia.rossi', 'Mia', 'Rossi' ),\\n\\t\\tarray( 'lucas.moreau', 'Lucas', 'Moreau' ),\\n\\t\\tarray( 'olivia.wilson', 'Olivia', 'Wilson' ),\\n\\t\\tarray( 'hugo.petit', 'Hugo', 'Petit' ),\\n\\t\\tarray( 'chloe.brown', 'Chloe', 'Brown' ),\\n\\t\\tarray( 'leo.thomas', 'Leo', 'Thomas' ),\\n\\t\\tarray( 'ava.martinez', 'Ava', 'Martinez' ),\\n\\t);\\n\\n\\t$user_ids = array();\\n\\n\\tforeach ( $people as $person ) {\\n\\t\\t$user_ids[] = $get_or_create_user(\\n\\t\\t\\t'speb_demo_' . str_replace( '.', '_', $person[0] ),\\n\\t\\t\\t$person[1],\\n\\t\\t\\t$person[2],\\n\\t\\t\\t$person[0] . '@example.org'\\n\\t\\t);\\n\\t}\\n\\n\\t\\\/\\\/ Associate the demo manager with every mission.\\n\\tforeach ( $mission_ids as $mission_id ) {\\n\\t\\tupdate_post_meta( $mission_id, '_speb_manager_user_id', $manager_id );\\n\\t}\\n\\n\\n\\t\\\/\\\/ Direct event registrations only.\\n\\tglobal $wpdb;\\n\\n\\t$event_table = $wpdb->prefix . 'speb_event_registrations';\\n\\n\\t$table_exists = $wpdb->get_var(\\n\\t\\t$wpdb->prepare(\\n\\t\\t\\t\\\"SELECT name FROM sqlite_master WHERE type='table' AND name=%s\\\",\\n\\t\\t\\t$event_table\\n\\t\\t)\\n\\t);\\n\\n\\t\\\/\\\/ SQLite driver may not expose sqlite_master in all environments; fall back to SHOW TABLES.\\n\\tif ( ! $table_exists ) {\\n\\t\\t$table_exists = $wpdb->get_var(\\n\\t\\t\\t$wpdb->prepare(\\n\\t\\t\\t\\t'SHOW TABLES LIKE %s',\\n\\t\\t\\t\\t$event_table\\n\\t\\t\\t)\\n\\t\\t);\\n\\t}\\n\\n\\tif ( ! $table_exists ) {\\n\\t\\tthrow new RuntimeException( 'Event registrations table is unavailable: ' . $event_table );\\n\\t}\\n\\n\\t$local_timestamp = static function ( $hours_ago ) {\\n\\t\\treturn wp_date(\\n\\t\\t\\t'Y-m-d H:i:s',\\n\\t\\t\\tcurrent_time( 'timestamp' ) - ( absint( $hours_ago ) * HOUR_IN_SECONDS ),\\n\\t\\t\\twp_timezone()\\n\\t\\t);\\n\\t};\\n\\n\\t$add_event_registration = static function ( $event_id, $user_id, $status, $hours_ago, $cancelled_by = 0 ) use ( $wpdb, $event_table, $local_timestamp ) {\\n\\t\\t$existing = $wpdb->get_var(\\n\\t\\t\\t$wpdb->prepare(\\n\\t\\t\\t\\t\\\"SELECT id FROM {$event_table} WHERE event_id = %d AND user_id = %d AND status = %s LIMIT 1\\\",\\n\\t\\t\\t\\tabsint( $event_id ),\\n\\t\\t\\t\\tabsint( $user_id ),\\n\\t\\t\\t\\t$status\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\treturn absint( $existing );\\n\\t\\t}\\n\\n\\t\\t$created = $local_timestamp( $hours_ago );\\n\\n\\t\\t$data = array(\\n\\t\\t\\t'event_id'              => absint( $event_id ),\\n\\t\\t\\t'user_id'               => absint( $user_id ),\\n\\t\\t\\t'actor_user_id'         => absint( $user_id ),\\n\\t\\t\\t'registered_by_user_id' => absint( $user_id ),\\n\\t\\t\\t'cancelled_by_user_id'  => absint( $cancelled_by ),\\n\\t\\t\\t'status'                => $status,\\n\\t\\t\\t'created_at'            => $created,\\n\\t\\t\\t'updated_at'            => $created,\\n\\t\\t\\t'cancelled_at'          => $cancelled_by ? $local_timestamp( max( 1, $hours_ago - 1 ) ) : null,\\n\\t\\t);\\n\\n\\t\\t$result = $wpdb->insert( $event_table, $data );\\n\\n\\t\\tif ( false === $result ) {\\n\\t\\t\\tthrow new RuntimeException(\\n\\t\\t\\t\\t'Could not create sample event registration: ' . $wpdb->last_error\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn absint( $wpdb->insert_id );\\n\\t};\\n\\n\\tforeach ( array_slice( $user_ids, 0, 8 ) as $index => $user_id ) {\\n\\t\\t$add_event_registration(\\n\\t\\t\\t$event_ids['open_day'],\\n\\t\\t\\t$user_id,\\n\\t\\t\\t'registered',\\n\\t\\t\\t72 - ( $index * 3 )\\n\\t\\t);\\n\\t}\\n\\n\\tforeach ( array_slice( $user_ids, 2, 10 ) as $index => $user_id ) {\\n\\t\\t$add_event_registration(\\n\\t\\t\\t$event_ids['youth_tournament'],\\n\\t\\t\\t$user_id,\\n\\t\\t\\t'registered',\\n\\t\\t\\t58 - ( $index * 2 )\\n\\t\\t);\\n\\t}\\n\\n\\tforeach ( array_slice( $user_ids, 0, 6 ) as $index => $user_id ) {\\n\\t\\t$add_event_registration(\\n\\t\\t\\t$event_ids['volunteer_evening'],\\n\\t\\t\\t$user_id,\\n\\t\\t\\t'registered',\\n\\t\\t\\t40 - ( $index * 2 )\\n\\t\\t);\\n\\t}\\n\\n\\tforeach ( array_slice( $user_ids, 1, 9 ) as $index => $user_id ) {\\n\\t\\t$add_event_registration(\\n\\t\\t\\t$event_ids['charity_run'],\\n\\t\\t\\t$user_id,\\n\\t\\t\\t'registered',\\n\\t\\t\\t500 + ( $index * 2 )\\n\\t\\t);\\n\\t}\\n\\n\\t$add_event_registration(\\n\\t\\t$event_ids['charity_run'],\\n\\t\\t$user_ids[0],\\n\\t\\t'cancelled',\\n\\t\\t520,\\n\\t\\t1\\n\\t);\\n\\n\\t$event_registration_count = absint(\\n\\t\\t$wpdb->get_var(\\n\\t\\t\\t\\\"SELECT COUNT(*) FROM {$event_table}\\\"\\n\\t\\t)\\n\\t);\\n\\n\\n\\t\\\/\\\/ Volunteer registrations. Direct inserts avoid sending email while preserving realistic plugin data.\\n\\t$volunteer_table = $wpdb->prefix . 'speb_registrations';\\n\\n\\t$table_exists = $wpdb->get_var(\\n\\t\\t$wpdb->prepare(\\n\\t\\t\\t'SHOW TABLES LIKE %s',\\n\\t\\t\\t$volunteer_table\\n\\t\\t)\\n\\t);\\n\\n\\tif ( ! $table_exists ) {\\n\\t\\tthrow new RuntimeException( 'Volunteer registrations table is unavailable: ' . $volunteer_table );\\n\\t}\\n\\n\\t$registration_counter = 0;\\n\\n\\t$add_volunteer_user = static function ( $mission_id, $slot_id, $user_id, $status = 'confirmed' ) use ( $wpdb, $volunteer_table, $local_timestamp, &$registration_counter ) {\\n\\t\\t$registration_counter++;\\n\\n\\t\\t$existing = $wpdb->get_var(\\n\\t\\t\\t$wpdb->prepare(\\n\\t\\t\\t\\t\\\"SELECT id FROM {$volunteer_table} WHERE mission_id = %d AND slot_key = %s AND user_id = %d AND status = %s LIMIT 1\\\",\\n\\t\\t\\t\\tabsint( $mission_id ),\\n\\t\\t\\t\\tsanitize_key( $slot_id ),\\n\\t\\t\\t\\tabsint( $user_id ),\\n\\t\\t\\t\\t$status\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\treturn absint( $existing );\\n\\t\\t}\\n\\n\\t\\t$created = $local_timestamp( 5 + $registration_counter * 2 );\\n\\n\\t\\t$data = array(\\n\\t\\t\\t'mission_id'              => absint( $mission_id ),\\n\\t\\t\\t'slot_key'                => sanitize_key( $slot_id ),\\n\\t\\t\\t'user_id'                 => absint( $user_id ),\\n\\t\\t\\t'identity_key'            => hash( 'sha256', 'user:' . absint( $user_id ) ),\\n\\t\\t\\t'guest_first_name'        => '',\\n\\t\\t\\t'guest_last_name'         => '',\\n\\t\\t\\t'guest_email'             => '',\\n\\t\\t\\t'guest_phone'             => '',\\n\\t\\t\\t'confirmation_token_hash' => '',\\n\\t\\t\\t'manage_token_hash'       => '',\\n\\t\\t\\t'requested_status'        => $status,\\n\\t\\t\\t'guest_confirmed_at'      => null,\\n\\t\\t\\t'status'                  => $status,\\n\\t\\t\\t'created_at'              => $created,\\n\\t\\t\\t'updated_at'              => $created,\\n\\t\\t);\\n\\n\\t\\t$result = $wpdb->insert( $volunteer_table, $data );\\n\\n\\t\\tif ( false === $result ) {\\n\\t\\t\\tthrow new RuntimeException(\\n\\t\\t\\t\\tsprintf(\\n\\t\\t\\t\\t\\t'Volunteer user insert failed \\u2014 mission=%d slot=%s user=%d status=%s \\u2014 SQL: %s',\\n\\t\\t\\t\\t\\tabsint( $mission_id ),\\n\\t\\t\\t\\t\\tsanitize_key( $slot_id ),\\n\\t\\t\\t\\t\\tabsint( $user_id ),\\n\\t\\t\\t\\t\\t$status,\\n\\t\\t\\t\\t\\t$wpdb->last_error\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn absint( $wpdb->insert_id );\\n\\t};\\n\\n\\t$add_volunteer_guest = static function ( $mission_id, $slot_id, $first, $last, $email, $status = 'confirmed' ) use ( $wpdb, $volunteer_table, $local_timestamp, &$registration_counter ) {\\n\\t\\t$registration_counter++;\\n\\n\\t\\t$identity_key = hash( 'sha256', 'guest:' . strtolower( $email ) );\\n\\n\\t\\t$existing = $wpdb->get_var(\\n\\t\\t\\t$wpdb->prepare(\\n\\t\\t\\t\\t\\\"SELECT id FROM {$volunteer_table} WHERE mission_id = %d AND slot_key = %s AND identity_key = %s AND status = %s LIMIT 1\\\",\\n\\t\\t\\t\\tabsint( $mission_id ),\\n\\t\\t\\t\\tsanitize_key( $slot_id ),\\n\\t\\t\\t\\t$identity_key,\\n\\t\\t\\t\\t$status\\n\\t\\t\\t)\\n\\t\\t);\\n\\n\\t\\tif ( $existing ) {\\n\\t\\t\\treturn absint( $existing );\\n\\t\\t}\\n\\n\\t\\t$created      = $local_timestamp( 4 + $registration_counter * 2 );\\n\\t\\t$confirmed_at = 'confirmed' === $status ? $created : null;\\n\\n\\t\\t$data = array(\\n\\t\\t\\t'mission_id'              => absint( $mission_id ),\\n\\t\\t\\t'slot_key'                => sanitize_key( $slot_id ),\\n\\t\\t\\t'user_id'                 => 0,\\n\\t\\t\\t'identity_key'            => $identity_key,\\n\\t\\t\\t'guest_first_name'        => $first,\\n\\t\\t\\t'guest_last_name'         => $last,\\n\\t\\t\\t'guest_email'             => $email,\\n\\t\\t\\t'guest_phone'             => '+33 6 00 00 ' . str_pad( (string) $registration_counter, 2, '0', STR_PAD_LEFT ),\\n\\t\\t\\t'confirmation_token_hash' => 'pending' === $status ? hash( 'sha256', 'confirm|' . $email . '|' . $slot_id ) : '',\\n\\t\\t\\t'manage_token_hash'       => 'confirmed' === $status ? hash( 'sha256', 'manage|' . $email . '|' . $slot_id ) : '',\\n\\t\\t\\t'requested_status'        => 'pending' === $status ? 'confirmed' : $status,\\n\\t\\t\\t'guest_confirmed_at'      => $confirmed_at,\\n\\t\\t\\t'status'                  => $status,\\n\\t\\t\\t'created_at'              => $created,\\n\\t\\t\\t'updated_at'              => $created,\\n\\t\\t);\\n\\n\\t\\t$result = $wpdb->insert( $volunteer_table, $data );\\n\\n\\t\\tif ( false === $result ) {\\n\\t\\t\\tthrow new RuntimeException(\\n\\t\\t\\t\\tsprintf(\\n\\t\\t\\t\\t\\t'Volunteer guest insert failed \\u2014 mission=%d slot=%s email=%s status=%s \\u2014 SQL: %s',\\n\\t\\t\\t\\t\\tabsint( $mission_id ),\\n\\t\\t\\t\\t\\tsanitize_key( $slot_id ),\\n\\t\\t\\t\\t\\t$email,\\n\\t\\t\\t\\t\\t$status,\\n\\t\\t\\t\\t\\t$wpdb->last_error\\n\\t\\t\\t\\t)\\n\\t\\t\\t);\\n\\t\\t}\\n\\n\\t\\treturn absint( $wpdb->insert_id );\\n\\t};\\n\\n\\t\\\/\\\/ Open Day.\\n\\t$add_volunteer_user( $mission_ids['welcome_desk'], 'welcome-morning', $user_ids[0] );\\n\\t$add_volunteer_user( $mission_ids['welcome_desk'], 'welcome-morning', $user_ids[1] );\\n\\t$add_volunteer_guest( $mission_ids['welcome_desk'], 'welcome-morning', 'Jamie', 'Lee', 'jamie.lee@example.org' );\\n\\t$add_volunteer_user( $mission_ids['welcome_desk'], 'welcome-midday', $user_ids[2] );\\n\\t$add_volunteer_user( $mission_ids['welcome_desk'], 'welcome-midday', $user_ids[3] );\\n\\n\\t$add_volunteer_user( $mission_ids['refreshments'], 'refresh-morning', $user_ids[4] );\\n\\t$add_volunteer_guest( $mission_ids['refreshments'], 'refresh-morning', 'Sam', 'Taylor', 'sam.taylor@example.org' );\\n\\t$add_volunteer_guest( $mission_ids['refreshments'], 'refresh-morning', 'Morgan', 'Reed', 'morgan.reed@example.org', 'pending' );\\n\\t$add_volunteer_user( $mission_ids['refreshments'], 'refresh-afternoon', $user_ids[5] );\\n\\t$add_volunteer_user( $mission_ids['refreshments'], 'refresh-afternoon', $user_ids[6] );\\n\\t$add_volunteer_user( $mission_ids['refreshments'], 'refresh-afternoon', $user_ids[7] );\\n\\n\\t$add_volunteer_user( $mission_ids['activity_guides'], 'guides-morning', $user_ids[8] );\\n\\t$add_volunteer_user( $mission_ids['activity_guides'], 'guides-morning', $user_ids[9] );\\n\\t$add_volunteer_user( $mission_ids['activity_guides'], 'guides-afternoon', $user_ids[10] );\\n\\t$add_volunteer_user( $mission_ids['activity_guides'], 'guides-afternoon', $user_ids[11] );\\n\\t$add_volunteer_guest( $mission_ids['activity_guides'], 'guides-afternoon', 'Robin', 'Clark', 'robin.clark@example.org' );\\n\\t$add_volunteer_user( $mission_ids['welcome_desk'], 'welcome-morning', $user_ids[11], 'cancelled' );\\n\\n\\t\\\/\\\/ Tournament.\\n\\tforeach ( array( 0, 2, 4, 6 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['field_setup'], 'field-setup', $user_ids[ $index ] );\\n\\t}\\n\\tforeach ( array( 1, 3, 5, 7 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['field_setup'], 'field-packdown', $user_ids[ $index ] );\\n\\t}\\n\\tforeach ( array( 8, 9, 10, 11 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['score_table'], 'scores-morning', $user_ids[ $index ] );\\n\\t}\\n\\tforeach ( array( 0, 1, 2 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['score_table'], 'scores-afternoon', $user_ids[ $index ] );\\n\\t}\\n\\tforeach ( array( 3, 4 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['parking'], 'parking-arrivals', $user_ids[ $index ] );\\n\\t}\\n\\n\\t\\\/\\\/ Volunteer evening.\\n\\t$add_volunteer_user( $mission_ids['evening_setup'], 'evening-setup', $user_ids[5] );\\n\\t$add_volunteer_user( $mission_ids['evening_setup'], 'evening-setup', $user_ids[6] );\\n\\t$add_volunteer_guest( $mission_ids['evening_setup'], 'evening-setup', 'Jordan', 'Miller', 'jordan.miller@example.org' );\\n\\n\\tforeach ( array( 7, 8, 9 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['guest_welcome'], 'evening-welcome', $user_ids[ $index ] );\\n\\t}\\n\\tforeach ( array( 10, 11, 0 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['buffet'], 'buffet-service', $user_ids[ $index ] );\\n\\t}\\n\\t$add_volunteer_guest( $mission_ids['buffet'], 'buffet-service', 'Casey', 'Morgan', 'casey.morgan@example.org' );\\n\\n\\t\\\/\\\/ Archived mission history.\\n\\tforeach ( array( 1, 2, 3, 4, 5 ) as $index ) {\\n\\t\\t$add_volunteer_user( $mission_ids['course_marshals'], 'course-marshals', $user_ids[ $index ] );\\n\\t}\\n\\n\\t$volunteer_registration_count = absint(\\n\\t\\t$wpdb->get_var(\\n\\t\\t\\t\\\"SELECT COUNT(*) FROM {$volunteer_table}\\\"\\n\\t\\t)\\n\\t);\\n\\n\\n\\t\\\/\\\/ Store all stable demo IDs so the MU localizer can translate the demo\\n\\t\\\/\\\/ dynamically when the Playground language changes.\\n\\t$pages = array();\\n\\t$current_settings = get_option( SPEB_Activator::SETTINGS, array() );\\n\\tif ( isset( $current_settings['pages'] ) && is_array( $current_settings['pages'] ) ) {\\n\\t\\tforeach ( $current_settings['pages'] as $key => $page_id ) {\\n\\t\\t\\t$pages[ $key ] = absint( $page_id );\\n\\t\\t}\\n\\t}\\n\\n\\t$event_locations = array();\\n\\tforeach ( $event_definitions as $key => $definition ) {\\n\\t\\t$event_locations[ $key ] = $definition['location'];\\n\\t}\\n\\n\\t$mission_locations = array();\\n\\tforeach ( $mission_definitions as $key => $definition ) {\\n\\t\\t$mission_locations[ $key ] = $definition['location'];\\n\\t}\\n\\n\\t$ids = array(\\n\\t\\t'pages'             => $pages,\\n\\t\\t'locations'         => $location_ids,\\n\\t\\t'events'            => $event_ids,\\n\\t\\t'event_locations'   => $event_locations,\\n\\t\\t'missions'          => $mission_ids,\\n\\t\\t'mission_locations' => $mission_locations,\\n\\t\\t'terms'             => $term_ids,\\n\\t\\t'manager_user'      => $manager_id,\\n\\t\\t'member_users'      => $user_ids,\\n\\t);\\n\\n\\tupdate_option( 'speb_blueprint_demo_ids', $ids, false );\\n\\tupdate_option( 'speb_blueprint_demo_seeded', '1.0.0', false );\\n\\n\\tif ( ! wp_next_scheduled( 'speb_hourly_event' ) ) {\\n\\t\\twp_schedule_event( time() + HOUR_IN_SECONDS, 'hourly', 'speb_hourly_event' );\\n\\t}\\n\\n\\tif ( function_exists( 'speb_blueprint_demo_apply_locale' ) ) {\\n\\t\\tspeb_blueprint_demo_apply_locale( get_locale() );\\n\\t}\\n\\n\\t\\\/\\\/ Remove diagnostic leftovers when reusing a saved Playground site.\\n\\tforeach ( array(\\n\\t\\t'speb_blueprint_stage2_probe',\\n\\t\\t'speb_blueprint_stage2_error',\\n\\t\\t'speb_blueprint_stage3_status',\\n\\t\\t'speb_blueprint_stage3_error',\\n\\t\\t'speb_blueprint_stage4_status',\\n\\t\\t'speb_blueprint_stage4_error',\\n\\t\\t'speb_blueprint_stage5_status',\\n\\t\\t'speb_blueprint_stage5_error',\\n\\t\\t'speb_blueprint_stage6_status',\\n\\t\\t'speb_blueprint_stage6_error',\\n\\t\\t'speb_blueprint_stage7_status',\\n\\t\\t'speb_blueprint_stage7_error',\\n\\t\\t'speb_blueprint_stage8_status',\\n\\t\\t'speb_blueprint_stage8_error'\\n\\t) as $diagnostic_option ) {\\n\\t\\tdelete_option( $diagnostic_option );\\n\\t}\\n\\n\\terror_log(\\n\\t\\tsprintf(\\n\\t\\t\\t'[SPEB Blueprint] Demo ready \\u2014 %d events, %d missions, %d event registrations, %d volunteer registrations.',\\n\\t\\t\\tcount( $event_ids ),\\n\\t\\t\\tcount( $mission_ids ),\\n\\t\\t\\t$event_registration_count,\\n\\t\\t\\t$volunteer_registration_count\\n\\t\\t)\\n\\t);\\n\\n} catch ( Throwable $error ) {\\n\\terror_log(\\n\\t\\t'[SPEB Blueprint] FAILED: ' .\\n\\t\\tget_class( $error ) . ': ' .\\n\\t\\t$error->getMessage() . ' @ ' .\\n\\t\\t$error->getFile() . ':' .\\n\\t\\t$error->getLine()\\n\\t);\\n\\tthrow $error;\\n}\\n\"}]}"}},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1-fr.png":{"filename":"screenshot-1-fr.png","revision":3675834,"resolution":"1","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-1.png":{"filename":"screenshot-1.png","revision":3675834,"resolution":"1","location":"assets","locale":"","width":1440,"height":900},"screenshot-2-fr.png":{"filename":"screenshot-2-fr.png","revision":3675834,"resolution":"2","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3675834,"resolution":"2","location":"assets","locale":"","width":1440,"height":900},"screenshot-3-fr.png":{"filename":"screenshot-3-fr.png","revision":3675834,"resolution":"3","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3675834,"resolution":"3","location":"assets","locale":"","width":1440,"height":900},"screenshot-4-fr.png":{"filename":"screenshot-4-fr.png","revision":3675834,"resolution":"4","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3675834,"resolution":"4","location":"assets","locale":"","width":1440,"height":900},"screenshot-5-fr.png":{"filename":"screenshot-5-fr.png","revision":3675834,"resolution":"5","location":"assets","locale":"fr","width":1440,"height":900},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3675834,"resolution":"5","location":"assets","locale":"","width":1440,"height":900}},"screenshots":{"1":"Events and volunteer dashboard with upcoming dates and staffing indicators.","2":"Event management with locations, capacities, visibility, and participant registrations.","3":"Volunteer missions with multiple time slots and capacity tracking.","4":"Public event calendar and personal volunteer schedule.","5":"Essential, Complete, and Expert display settings, including Sprint Club inheritance."}},"plugin_section":[],"plugin_tags":[141027,416,11615,1486,65258],"plugin_category":[40],"plugin_contributors":[274079],"plugin_business_model":[],"class_list":["post-361199","plugin","type-plugin","status-publish","hentry","plugin_tags-associations","plugin_tags-calendar","plugin_tags-clubs","plugin_tags-events","plugin_tags-volunteers","plugin_category-calendar-and-events","plugin_contributors-sprintplugins","plugin_committers-sprintplugins"],"banners":{"banner":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/banner-772x250.png?rev=3675834","banner_2x":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/banner-1544x500.png?rev=3675834","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/icon.svg?rev=3675834","icon":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/icon.svg?rev=3675834","icon_2x":false,"generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/screenshot-1.png?rev=3675834","caption":"Events and volunteer dashboard with upcoming dates and staffing indicators."},{"src":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/screenshot-2.png?rev=3675834","caption":"Event management with locations, capacities, visibility, and participant registrations."},{"src":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/screenshot-3.png?rev=3675834","caption":"Volunteer missions with multiple time slots and capacity tracking."},{"src":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/screenshot-4.png?rev=3675834","caption":"Public event calendar and personal volunteer schedule."},{"src":"https:\/\/ps.w.org\/sprint-events-volunteers\/assets\/screenshot-5.png?rev=3675834","caption":"Essential, Complete, and Expert display settings, including Sprint Club inheritance."}],"raw_content":"<!--section=description-->\n<p>Sprint Events &amp; Volunteers helps sports clubs, associations, and nonprofit organizations publish events and coordinate volunteer work.<\/p>\n\n<p>The free plugin works independently. It provides event and venue management, volunteer missions with multiple time slots, member and guest registrations, confirmation emails, personal schedules, protected management pages, Gutenberg blocks, shortcodes, diagnostics, and WordPress privacy tools.<\/p>\n\n<h4>Events<\/h4>\n\n<ul>\n<li>Create events, venues, categories, dates, visibility rules, and registration limits.<\/li>\n<li>Publish event lists, monthly calendars, archives, and single-event views.<\/li>\n<li>Allow logged-in WordPress users to register or cancel.<\/li>\n<li>Review participants from the protected administration screen.<\/li>\n<\/ul>\n\n<h4>Volunteers<\/h4>\n\n<ul>\n<li>Create volunteer missions connected to events.<\/li>\n<li>Define several time slots and capacities for each mission.<\/li>\n<li>Accept registrations from WordPress accounts or confirmed guests.<\/li>\n<li>Provide each volunteer with a personal schedule.<\/li>\n<li>Let authorized managers review registrations from a protected front-end portal.<\/li>\n<\/ul>\n\n<h4>Administration<\/h4>\n\n<ul>\n<li>Essential, Complete, and Expert display modes reduce interface density without changing data or permissions.<\/li>\n<li>Sprint Club can provide the central display mode and group the plugin screens.<\/li>\n<li>A page assistant creates or adopts the required public pages.<\/li>\n<li>Site Health, diagnostics, personal-data export, and personal-data erasure are supported.<\/li>\n<\/ul>\n\n<h4>Optional Pro add-on<\/h4>\n\n<p>A separate commercial add-on can provide advanced email campaigns, approval and waitlist workflows, reminders, attachments, reports, permissions, and configuration transfers. The Pro implementation is not included in this WordPress.org package.<\/p>\n\n<h4>Privacy<\/h4>\n\n<p>For registered users, the plugin can store a WordPress user ID with event and volunteer registrations. For guest volunteer registrations, it can store a first name, last name, email address, optional phone number, confirmation tokens, registration status, and timestamps.<\/p>\n\n<p>Sprint Events &amp; Volunteers integrates with the WordPress personal-data export and erasure tools. Active operational records may be retained or anonymized when immediate deletion would prevent an organization from managing an ongoing event or volunteer commitment.<\/p>\n\n<p>The free plugin does not transmit data to an external service. Email messages are sent through the mail system configured for the WordPress site.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload and activate Sprint Events &amp; Volunteers.<\/li>\n<li>On activation, the plugin creates or adopts the public pages it needs without overwriting existing content.<\/li>\n<li>Open the Sprint Events &amp; Volunteers menu in WordPress.<\/li>\n<li>Open Settings &gt; Pages to audit, repair, or reassign the public pages when needed.<\/li>\n<li>Configure the Events and Volunteers modules.<\/li>\n<li>Create an event, then add volunteer missions and time slots when needed.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20the%20free%20plugin%20work%20without%20sprint%20club%3F\"><h3>Does the free plugin work without Sprint Club?<\/h3><\/dt>\n<dd><p>Yes. Sprint Club is optional and only groups screens and display-mode preferences.<\/p><\/dd>\n<dt id=\"can%20guests%20register%20for%20volunteer%20missions%3F\"><h3>Can guests register for volunteer missions?<\/h3><\/dt>\n<dd><p>Yes. Guest registrations use a single-use email confirmation link and can be disabled in the settings.<\/p><\/dd>\n<dt id=\"are%20the%20essential%2C%20complete%2C%20and%20expert%20modes%20separate%20feature%20tiers%3F\"><h3>Are the Essential, Complete, and Expert modes separate feature tiers?<\/h3><\/dt>\n<dd><p>No. They only change the amount of administration detail shown. They do not remove data, change permissions, or disable free features.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20contact%20an%20external%20service%3F\"><h3>Does the plugin contact an external service?<\/h3><\/dt>\n<dd><p>No. The free plugin does not send data to an external API. Email delivery uses the mail system configured for the site.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20the%20plugin%20is%20deactivated%20or%20uninstalled%3F\"><h3>What happens when the plugin is deactivated or uninstalled?<\/h3><\/dt>\n<dd><p>Deactivation preserves all data. Uninstall preserves operational content and registrations by default.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial public release.<\/li>\n<li>Includes events, venues, volunteer missions, time slots, registrations, public pages, privacy tools, and display modes.<\/li>\n<li>Keeps all commercial implementation in the separate Pro add-on.<\/li>\n<\/ul>","raw_excerpt":"Manage club events, volunteer missions, time slots, registrations, and public schedules in WordPress.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/361199","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=361199"}],"author":[{"embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sprintplugins"}],"wp:attachment":[{"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=361199"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=361199"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=361199"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=361199"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=361199"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/twd.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=361199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}