267 lines
35 KiB
C#
267 lines
35 KiB
C#
using Microsoft.EntityFrameworkCore.Migrations;
|
|
|
|
#nullable disable
|
|
|
|
namespace Backend.Migrations;
|
|
|
|
public partial class SeedRealisticDemoScenario : Migration
|
|
{
|
|
protected override void Up(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql(
|
|
"""
|
|
DO $vtsa_seed$
|
|
BEGIN
|
|
IF EXISTS (SELECT 1 FROM "Seasons" WHERE "Year" IN (2025, 2026)) THEN
|
|
RAISE NOTICE 'Existing seasons detected; skipping realistic demo seed.';
|
|
RETURN;
|
|
END IF;
|
|
|
|
INSERT INTO "Seasons" (
|
|
"Id", "Year", "Name", "IsDemo", "IsCurrent", "IsCommunityOnly", "CurrentPhase",
|
|
"NominationStartsAt", "NominationEndsAt", "VotingStartsAt", "VotingEndsAt",
|
|
"ReviewStartsAt", "ReviewEndsAt", "ShowDate", "ShowStartsAt",
|
|
"WinnersPublishedAt", "WinnersPublishedByTwitchId", "SubcategoryTemplatesJson", "WorkflowRulesJson"
|
|
)
|
|
VALUES
|
|
(1000, 2025, 'VTuber Star Awards 2025 Demo Archiv', TRUE, FALSE, FALSE, 'Archiv',
|
|
DATE '2025-04-01', DATE '2025-04-28', DATE '2025-05-10', DATE '2025-05-24',
|
|
DATE '2025-04-29', DATE '2025-05-09', DATE '2025-06-21', TIME '20:00',
|
|
TIMESTAMPTZ '2025-06-22 10:00:00+00', 'demo_owner', '[]', '[]'),
|
|
(1001, 2026, 'VTuber Star Awards 2026 Demo', TRUE, TRUE, FALSE, 'Voting',
|
|
DATE '2026-05-18', DATE '2026-06-16', DATE '2026-06-24', DATE '2026-07-19',
|
|
DATE '2026-06-17', DATE '2026-06-23', DATE '2026-08-08', TIME '20:00',
|
|
NULL, NULL, '[]', '[]');
|
|
|
|
INSERT INTO "Categories" (
|
|
"Id", "SeasonId", "GroupName", "Name", "Slug", "Description", "SortOrder", "MaxNomineesPerUser", "ViewerRangeMin", "ViewerRangeMax"
|
|
)
|
|
VALUES
|
|
(1101, 1001, 'Spotlight', 'Rising Star', 'rising-star', 'Neue oder stark gewachsene Creator:innen mit klarer Entwicklung.', 10, 2, 0, 75),
|
|
(1102, 1001, 'Spotlight', 'Community Heart', 'community-heart', 'Creator:innen, deren Community besonders sichtbar und einladend ist.', 20, 2, 0, 200),
|
|
(1103, 1001, 'Spotlight', 'Breakout Moment', 'breakout-moment', 'Ein einzelner Moment, Clip oder Stream, der die Season gepraegt hat.', 30, 2, 0, NULL),
|
|
(1104, 1001, 'Content', 'Best Variety Stream', 'best-variety-stream', 'Abwechslungsreiche Streams mit sicherem roten Faden.', 40, 2, 30, 350),
|
|
(1105, 1001, 'Content', 'Best Gaming Stream', 'best-gaming-stream', 'Gaming-Streams mit starker Moderation und guter Dramaturgie.', 50, 2, 25, 400),
|
|
(1106, 1001, 'Content', 'Best Music Performance', 'best-music-performance', 'Live-Gesang, Instrumente oder Musikproduktion im Stream.', 60, 2, 0, 250),
|
|
(1107, 1001, 'Content', 'Best Art Stream', 'best-art-stream', 'Art-, Design- oder Rigging-Streams mit nachvollziehbarem Prozess.', 70, 2, 0, 250),
|
|
(1108, 1001, 'Content', 'Best Lore Project', 'best-lore-project', 'Storytelling, Lore-Events oder immersive Formatideen.', 80, 2, 0, 300),
|
|
(1109, 1001, 'Engagement', 'Best Chat Interaction', 'best-chat-interaction', 'Besonders gute Einbindung von Chat und Community.', 90, 2, 20, 500),
|
|
(1110, 1001, 'Engagement', 'Best Collab Energy', 'best-collab-energy', 'Kollaborationen, die alle Beteiligten staerker gemacht haben.', 100, 2, 30, 650),
|
|
(1111, 1001, 'Engagement', 'Best Community Event', 'best-community-event', 'Community-Events mit guter Planung und nachhaltiger Wirkung.', 110, 2, 25, 750),
|
|
(1112, 1001, 'Production', 'Best Stream Design', 'best-stream-design', 'Overlay, Szenen, Alerts und visuelle Identitaet.', 120, 2, 0, 400),
|
|
(1113, 1001, 'Production', 'Best Original Clip', 'best-original-clip', 'Einreichbare Clips mit starkem Timing oder besonderem Moment.', 130, 2, 0, NULL),
|
|
(1114, 1001, 'Production', 'Best Technical Glow-Up', 'best-technical-glow-up', 'Messbare Verbesserungen bei Audio, Video, Licht oder Setup.', 140, 2, 0, 300),
|
|
(1201, 1000, 'Archiv Spotlight', 'Archiv Rising Star', 'archiv-rising-star', 'Archivkategorie fuer Gewinner-Showcase.', 10, 2, 0, 75),
|
|
(1202, 1000, 'Archiv Content', 'Archiv Variety', 'archiv-variety', 'Archivkategorie fuer Gewinner-Showcase.', 20, 2, 0, 350),
|
|
(1203, 1000, 'Archiv Content', 'Archiv Music', 'archiv-music', 'Archivkategorie fuer Gewinner-Showcase.', 30, 2, 0, 250),
|
|
(1204, 1000, 'Archiv Engagement', 'Archiv Community', 'archiv-community', 'Archivkategorie fuer Gewinner-Showcase.', 40, 2, 0, 500),
|
|
(1205, 1000, 'Archiv Production', 'Archiv Stream Design', 'archiv-stream-design', 'Archivkategorie fuer Gewinner-Showcase.', 50, 2, 0, 400),
|
|
(1206, 1000, 'Archiv Moment', 'Archiv Clip Moment', 'archiv-clip-moment', 'Archivkategorie fuer Gewinner-Showcase.', 60, 2, 0, NULL);
|
|
|
|
INSERT INTO "StreamerIdentities" ("Id", "Platform", "Login", "NormalizedKey", "DisplayName", "ProfileUrl", "LastResolvedAt")
|
|
VALUES
|
|
(3001, 'Twitch', 'aki_lumina', 'twitch:aki_lumina', 'Aki Lumina', 'https://twitch.tv/aki_lumina', TIMESTAMPTZ '2026-06-27 12:00:00+00'),
|
|
(3002, 'Twitch', 'mira_orbit', 'twitch:mira_orbit', 'Mira Orbit', 'https://twitch.tv/mira_orbit', TIMESTAMPTZ '2026-06-27 12:02:00+00'),
|
|
(3003, 'Twitch', 'nova_nym', 'twitch:nova_nym', 'Nova Nym', 'https://twitch.tv/nova_nym', TIMESTAMPTZ '2026-06-27 12:04:00+00'),
|
|
(3004, 'Twitch', 'luna_koi', 'twitch:luna_koi', 'Luna Koi', 'https://twitch.tv/luna_koi', TIMESTAMPTZ '2026-06-27 12:06:00+00'),
|
|
(3005, 'Twitch', 'runa_bits', 'twitch:runa_bits', 'Runa Bits', 'https://twitch.tv/runa_bits', TIMESTAMPTZ '2026-06-27 12:08:00+00'),
|
|
(3006, 'Twitch', 'sora_slate', 'twitch:sora_slate', 'Sora Slate', 'https://twitch.tv/sora_slate', TIMESTAMPTZ '2026-06-27 12:10:00+00'),
|
|
(3007, 'Twitch', 'ember_vail', 'twitch:ember_vail', 'Ember Vail', 'https://twitch.tv/ember_vail', TIMESTAMPTZ '2026-06-27 12:12:00+00'),
|
|
(3008, 'Twitch', 'niko_noct', 'twitch:niko_noct', 'Niko Noct', 'https://twitch.tv/niko_noct', TIMESTAMPTZ '2026-06-27 12:14:00+00'),
|
|
(3009, 'Twitch', 'pixel_poppy', 'twitch:pixel_poppy', 'Pixel Poppy', 'https://twitch.tv/pixel_poppy', TIMESTAMPTZ '2026-06-27 12:16:00+00'),
|
|
(3010, 'Twitch', 'hana_hertz', 'twitch:hana_hertz', 'Hana Hertz', 'https://twitch.tv/hana_hertz', TIMESTAMPTZ '2026-06-27 12:18:00+00');
|
|
|
|
INSERT INTO "Candidates" (
|
|
"Id", "SeasonId", "CategoryId", "StreamerIdentityId", "DisplayName", "ChannelSlug", "Platform",
|
|
"NominationTally", "AcceptanceStatus", "AcceptanceNote", "ClipCompilationUrl", "ClipCompilationTitle", "ClipCompilationPlatform", "ClipEmbedStatus"
|
|
)
|
|
VALUES
|
|
(2001, 1001, 1101, 3001, 'Aki Lumina', 'aki_lumina', 'Twitch', 9, 'approved', 'Bestaetigt, kleiner Kanal mit starkem Wachstum.', 'https://youtu.be/demo-aki-rise', 'Aki Lumina Rising Star Reel', 'YouTube', 'available'),
|
|
(2002, 1001, 1101, 3002, 'Mira Orbit', 'mira_orbit', 'Twitch', 7, 'approved', 'Bestaetigt.', NULL, NULL, NULL, 'unchecked'),
|
|
(2003, 1001, 1101, 3003, 'Nova Nym', 'nova_nym', 'Twitch', 5, 'pending', 'Wartet auf finalen Clip.', NULL, NULL, NULL, 'unchecked'),
|
|
(2004, 1001, 1102, 3004, 'Luna Koi', 'luna_koi', 'Twitch', 11, 'approved', 'Community-Belege im Review notiert.', NULL, NULL, NULL, 'unchecked'),
|
|
(2005, 1001, 1102, 3005, 'Runa Bits', 'runa_bits', 'Twitch', 8, 'approved', 'Starke Discord-Aktion.', NULL, NULL, NULL, 'unchecked'),
|
|
(2006, 1001, 1102, 3006, 'Sora Slate', 'sora_slate', 'Twitch', 4, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2007, 1001, 1103, 3007, 'Ember Vail', 'ember_vail', 'Twitch', 10, 'approved', 'Clip-Quelle vorhanden.', 'https://clips.twitch.tv/demo-ember-moment', 'Ember Vail Breakout Clip', 'Twitch', 'available'),
|
|
(2008, 1001, 1103, 3008, 'Niko Noct', 'niko_noct', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2009, 1001, 1103, 3009, 'Pixel Poppy', 'pixel_poppy', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2010, 1001, 1104, 3010, 'Hana Hertz', 'hana_hertz', 'Twitch', 12, 'approved', 'Variety-Plan sauber dokumentiert.', 'https://youtu.be/demo-hana-variety', 'Hana Hertz Variety Reel', 'YouTube', 'available'),
|
|
(2011, 1001, 1104, NULL, 'Kira Comet', 'kira_comet', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2012, 1001, 1104, NULL, 'Mochi Vale', 'mochi_vale', 'Twitch', 7, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2013, 1001, 1105, NULL, 'Taro Tactics', 'taro_tactics', 'Twitch', 10, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2014, 1001, 1105, NULL, 'Yuna Quest', 'yuna_quest', 'Twitch', 7, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2015, 1001, 1105, NULL, 'Rin Replay', 'rin_replay', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2016, 1001, 1106, NULL, 'Melo Moon', 'melo_moon', 'Twitch', 9, 'approved', 'Live-Set pruefbar.', 'https://youtu.be/demo-melo-live', 'Melo Moon Live Set', 'YouTube', 'available'),
|
|
(2017, 1001, 1106, NULL, 'Vivi Verse', 'vivi_verse', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2018, 1001, 1106, NULL, 'Echo Rill', 'echo_rill', 'Twitch', 4, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2019, 1001, 1107, NULL, 'Iris Ink', 'iris_ink', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2020, 1001, 1107, NULL, 'Pia Palette', 'pia_palette', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2021, 1001, 1107, NULL, 'Theo Thimble', 'theo_thimble', 'Twitch', 3, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2022, 1001, 1108, NULL, 'Nyra Novel', 'nyra_novel', 'Twitch', 9, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2023, 1001, 1108, NULL, 'Kai Myth', 'kai_myth', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2024, 1001, 1108, NULL, 'Mina Maze', 'mina_maze', 'Twitch', 4, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2025, 1001, 1109, NULL, 'Bibi Beacon', 'bibi_beacon', 'Twitch', 12, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2026, 1001, 1109, NULL, 'Ori Opal', 'ori_opal', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2027, 1001, 1109, NULL, 'Faye Flux', 'faye_flux', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2028, 1001, 1110, NULL, 'Riku Relay', 'riku_relay', 'Twitch', 10, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2029, 1001, 1110, NULL, 'Nami Node', 'nami_node', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2030, 1001, 1110, NULL, 'Sachi Spark', 'sachi_spark', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2031, 1001, 1111, NULL, 'Cleo Campfire', 'cleo_campfire', 'Twitch', 11, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2032, 1001, 1111, NULL, 'Juno Jamboree', 'juno_jamboree', 'Twitch', 9, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2033, 1001, 1111, NULL, 'Mika Meetup', 'mika_meetup', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2034, 1001, 1112, NULL, 'Neon Nori', 'neon_nori', 'Twitch', 9, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2035, 1001, 1112, NULL, 'Slate Sen', 'slate_sen', 'Twitch', 7, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2036, 1001, 1112, NULL, 'Momo Motion', 'momo_motion', 'Twitch', 4, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2037, 1001, 1113, NULL, 'Lio Laughs', 'lio_laughs', 'Twitch', 10, 'approved', 'Clip bereits im Clip-Review.', 'https://clips.twitch.tv/demo-lio-laugh', 'Lio Laughs Original Clip', 'Twitch', 'available'),
|
|
(2038, 1001, 1113, NULL, 'Puck Prism', 'puck_prism', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2039, 1001, 1113, NULL, 'Tessa Toast', 'tessa_toast', 'Twitch', 5, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2040, 1001, 1114, NULL, 'Vera Volt', 'vera_volt', 'Twitch', 9, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2041, 1001, 1114, NULL, 'Maki Mixer', 'maki_mixer', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2042, 1001, 1114, NULL, 'Yori Yield', 'yori_yield', 'Twitch', 4, 'pending', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2101, 1000, 1201, NULL, 'Archiv Aster', 'archiv_aster', 'Twitch', 14, 'approved', NULL, 'https://youtu.be/demo-archiv-aster', 'Archiv Aster Winner Reel', 'YouTube', 'available'),
|
|
(2102, 1000, 1201, NULL, 'Archiv Beryl', 'archiv_beryl', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2103, 1000, 1201, NULL, 'Archiv Coda', 'archiv_coda', 'Twitch', 5, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2104, 1000, 1202, NULL, 'Archiv Drift', 'archiv_drift', 'Twitch', 16, 'approved', NULL, 'https://youtu.be/demo-archiv-drift', 'Archiv Drift Variety Reel', 'YouTube', 'available'),
|
|
(2105, 1000, 1202, NULL, 'Archiv Elara', 'archiv_elara', 'Twitch', 9, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2106, 1000, 1202, NULL, 'Archiv Finch', 'archiv_finch', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2107, 1000, 1203, NULL, 'Archiv Lyra', 'archiv_lyra', 'Twitch', 12, 'approved', NULL, 'https://youtu.be/demo-archiv-lyra', 'Archiv Lyra Music Reel', 'YouTube', 'available'),
|
|
(2108, 1000, 1203, NULL, 'Archiv Muse', 'archiv_muse', 'Twitch', 7, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2109, 1000, 1203, NULL, 'Archiv Nia', 'archiv_nia', 'Twitch', 5, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2110, 1000, 1204, NULL, 'Archiv Poppy', 'archiv_poppy', 'Twitch', 13, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2111, 1000, 1204, NULL, 'Archiv Quartz', 'archiv_quartz', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2112, 1000, 1204, NULL, 'Archiv Rune', 'archiv_rune', 'Twitch', 5, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2113, 1000, 1205, NULL, 'Archiv Sol', 'archiv_sol', 'Twitch', 11, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2114, 1000, 1205, NULL, 'Archiv Tide', 'archiv_tide', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2115, 1000, 1205, NULL, 'Archiv Uma', 'archiv_uma', 'Twitch', 5, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2116, 1000, 1206, NULL, 'Archiv Vesper', 'archiv_vesper', 'Twitch', 15, 'approved', NULL, 'https://clips.twitch.tv/demo-archiv-vesper', 'Archiv Vesper Clip Moment', 'Twitch', 'available'),
|
|
(2117, 1000, 1206, NULL, 'Archiv Wren', 'archiv_wren', 'Twitch', 8, 'approved', NULL, NULL, NULL, NULL, 'unchecked'),
|
|
(2118, 1000, 1206, NULL, 'Archiv Yuki', 'archiv_yuki', 'Twitch', 6, 'approved', NULL, NULL, NULL, NULL, 'unchecked');
|
|
|
|
INSERT INTO "Nominations" (
|
|
"Id", "SeasonId", "CategoryId", "CategoryGroupName", "SubmittedByTwitchId", "CandidateId", "StreamerIdentityId", "SuggestedCategoryId",
|
|
"CandidateText", "StreamUrl", "ResolvedChannel", "ResolvedPlatform", "AvgViewers", "HoursStreamed", "HoursWatched", "PeakViewers", "FollowersGained",
|
|
"TrackerStatus", "TrackerCheckedAt", "TrackingReviewStatus", "TrackingFlagsJson", "TrackingReviewNote", "TrackingReviewedByTwitchId", "TrackingReviewedAt",
|
|
"Status", "ReviewNote", "ReviewedByTwitchId", "CreatedAt", "ReviewedAt"
|
|
)
|
|
VALUES
|
|
(4001, 1001, 1101, 'Spotlight', 'viewer_1001', 2001, 3001, NULL, 'Aki Lumina', 'https://twitch.tv/aki_lumina', 'aki_lumina', 'Twitch', 42, 63, 6800, 118, 730, 'resolved', TIMESTAMPTZ '2026-06-18 09:20:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:10:00+00', 'approved', 'Wachstum und Streamplan passen.', 'reviewer_demo', TIMESTAMPTZ '2026-06-02 18:30:00+00', TIMESTAMPTZ '2026-06-18 10:10:00+00'),
|
|
(4002, 1001, 1101, 'Spotlight', 'viewer_1002', 2002, 3002, NULL, 'Mira Orbit', 'https://twitch.tv/mira_orbit', 'mira_orbit', 'Twitch', 38, 58, 5900, 96, 510, 'resolved', TIMESTAMPTZ '2026-06-18 09:24:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:15:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-03 20:15:00+00', TIMESTAMPTZ '2026-06-18 10:15:00+00'),
|
|
(4003, 1001, 1103, 'Spotlight', 'viewer_1003', 2007, 3007, NULL, 'Ember Vail', 'https://twitch.tv/ember_vail', 'ember_vail', 'Twitch', 116, 44, 9100, 420, 1200, 'resolved', TIMESTAMPTZ '2026-06-18 09:30:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:22:00+00', 'approved', 'Breakout-Clip verifiziert.', 'reviewer_demo', TIMESTAMPTZ '2026-06-04 14:45:00+00', TIMESTAMPTZ '2026-06-18 10:22:00+00'),
|
|
(4004, 1001, 1104, 'Content', 'viewer_1004', 2010, 3010, NULL, 'Hana Hertz', 'https://twitch.tv/hana_hertz', 'hana_hertz', 'Twitch', 184, 72, 22100, 360, 840, 'resolved', TIMESTAMPTZ '2026-06-18 09:40:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:30:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-05 21:05:00+00', TIMESTAMPTZ '2026-06-18 10:30:00+00'),
|
|
(4005, 1001, 1105, 'Content', 'viewer_1005', 2013, NULL, NULL, 'Taro Tactics', 'https://twitch.tv/taro_tactics', 'taro_tactics', 'Twitch', 153, 81, 19800, 310, 620, 'resolved', TIMESTAMPTZ '2026-06-18 09:45:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:36:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-06 19:25:00+00', TIMESTAMPTZ '2026-06-18 10:36:00+00'),
|
|
(4006, 1001, 1106, 'Content', 'viewer_1006', 2016, NULL, NULL, 'Melo Moon', 'https://twitch.tv/melo_moon', 'melo_moon', 'Twitch', 88, 35, 7400, 210, 430, 'resolved', TIMESTAMPTZ '2026-06-18 09:48:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 10:41:00+00', 'approved', 'Live-Musik-Set pruefbar.', 'reviewer_demo', TIMESTAMPTZ '2026-06-07 17:55:00+00', TIMESTAMPTZ '2026-06-18 10:41:00+00'),
|
|
(4007, 1001, 1108, 'Content', 'viewer_1007', 2022, NULL, NULL, 'Nyra Novel', 'https://twitch.tv/nyra_novel', 'nyra_novel', 'Twitch', NULL, NULL, NULL, NULL, NULL, 'no_data', TIMESTAMPTZ '2026-06-18 09:52:00+00', 'needs_review', '[{"key":"no_tracker_data","label":"Keine Tracker-Daten","severity":"medium","description":"TwitchTracker hat keinen belastbaren Summary-Wert geliefert.","requiresManualReview":true,"blocksApproval":false,"adminNoteRequiredOnOverride":false}]', 'Tracker leer, manuelle Lore-Pruefung noetig.', 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:00:00+00', 'pending', 'Lore-Dokumentation nachfordern.', NULL, TIMESTAMPTZ '2026-06-08 18:10:00+00', NULL),
|
|
(4008, 1001, 1109, 'Engagement', 'viewer_1008', 2025, NULL, NULL, 'Bibi Beacon', 'https://twitch.tv/bibi_beacon', 'bibi_beacon', 'Twitch', 208, 65, 31800, 530, 920, 'resolved', TIMESTAMPTZ '2026-06-18 09:58:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:06:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-09 16:20:00+00', TIMESTAMPTZ '2026-06-18 11:06:00+00'),
|
|
(4009, 1001, 1110, 'Engagement', 'viewer_1009', 2028, NULL, NULL, 'Riku Relay', 'https://twitch.tv/riku_relay', 'riku_relay', 'Twitch', 177, 54, 24200, 440, 610, 'resolved', TIMESTAMPTZ '2026-06-18 10:02:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:12:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-10 20:40:00+00', TIMESTAMPTZ '2026-06-18 11:12:00+00'),
|
|
(4010, 1001, 1111, 'Engagement', 'viewer_1010', 2031, NULL, NULL, 'Cleo Campfire', 'https://twitch.tv/cleo_campfire', 'cleo_campfire', 'Twitch', 232, 49, 28700, 620, 1100, 'resolved', TIMESTAMPTZ '2026-06-18 10:08:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:18:00+00', 'approved', 'Community-Event mit Planungsdoku.', 'reviewer_demo', TIMESTAMPTZ '2026-06-11 15:50:00+00', TIMESTAMPTZ '2026-06-18 11:18:00+00'),
|
|
(4011, 1001, 1112, 'Production', 'viewer_1011', 2034, NULL, NULL, 'Neon Nori', 'https://twitch.tv/neon_nori', 'neon_nori', 'Twitch', 121, 37, 11800, 250, 340, 'resolved', TIMESTAMPTZ '2026-06-18 10:14:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:24:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-12 19:05:00+00', TIMESTAMPTZ '2026-06-18 11:24:00+00'),
|
|
(4012, 1001, 1113, 'Production', 'viewer_1012', 2037, NULL, NULL, 'Lio Laughs', 'https://twitch.tv/lio_laughs', 'lio_laughs', 'Twitch', 96, 26, 6500, 340, 270, 'resolved', TIMESTAMPTZ '2026-06-18 10:18:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:30:00+00', 'approved', 'Clip pruefbar.', 'reviewer_demo', TIMESTAMPTZ '2026-06-13 22:15:00+00', TIMESTAMPTZ '2026-06-18 11:30:00+00'),
|
|
(4013, 1001, 1114, 'Production', 'viewer_1013', 2040, NULL, NULL, 'Vera Volt', 'https://twitch.tv/vera_volt', 'vera_volt', 'Twitch', 74, 41, 8200, 190, 390, 'resolved', TIMESTAMPTZ '2026-06-18 10:22:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:36:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-14 13:35:00+00', TIMESTAMPTZ '2026-06-18 11:36:00+00'),
|
|
(4014, 1001, 1102, 'Spotlight', 'viewer_1014', 2004, 3004, NULL, 'Luna Koi', 'https://twitch.tv/luna_koi', 'luna_koi', 'Twitch', 62, 46, 9100, 155, 510, 'resolved', TIMESTAMPTZ '2026-06-18 10:28:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:42:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-15 18:45:00+00', TIMESTAMPTZ '2026-06-18 11:42:00+00'),
|
|
(4015, 1001, 1107, 'Content', 'viewer_1015', 2019, NULL, NULL, 'Iris Ink', 'https://twitch.tv/iris_ink', 'iris_ink', 'Twitch', 54, 31, 5200, 130, 260, 'resolved', TIMESTAMPTZ '2026-06-18 10:31:00+00', 'clear', '[]', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:48:00+00', 'approved', NULL, 'reviewer_demo', TIMESTAMPTZ '2026-06-15 20:10:00+00', TIMESTAMPTZ '2026-06-18 11:48:00+00'),
|
|
(4016, 1001, 1105, 'Content', 'viewer_1016', 2015, NULL, NULL, 'Rin Replay', 'https://youtube.com/@rin_replay', 'rin_replay', 'YouTube', NULL, NULL, NULL, NULL, NULL, 'unsupported_platform', TIMESTAMPTZ '2026-06-18 10:36:00+00', 'needs_review', '[{"key":"unsupported_platform","label":"Plattform nicht unterstuetzt","severity":"medium","description":"Die Nominierung zeigt auf eine Plattform ohne automatische TwitchTracker-Daten.","requiresManualReview":true,"blocksApproval":false,"adminNoteRequiredOnOverride":false}]', 'YouTube-Link muss manuell geprueft werden.', NULL, NULL, 'pending', 'Stream-Link auf Twitch anfragen.', NULL, TIMESTAMPTZ '2026-06-16 11:25:00+00', NULL);
|
|
|
|
INSERT INTO "VoteBallots" ("Id", "SeasonId", "SubmittedByTwitchId", "Status", "SubmittedAt")
|
|
VALUES
|
|
(5001, 1001, 'vote_user_001', 'submitted', TIMESTAMPTZ '2026-06-25 18:10:00+00'),
|
|
(5002, 1001, 'vote_user_002', 'submitted', TIMESTAMPTZ '2026-06-25 18:16:00+00'),
|
|
(5003, 1001, 'vote_user_003', 'submitted', TIMESTAMPTZ '2026-06-25 19:05:00+00'),
|
|
(5004, 1001, 'vote_user_004', 'submitted', TIMESTAMPTZ '2026-06-26 12:45:00+00'),
|
|
(5005, 1001, 'vote_user_005', 'submitted', TIMESTAMPTZ '2026-06-26 20:30:00+00'),
|
|
(5006, 1001, 'vote_user_006', 'submitted', TIMESTAMPTZ '2026-06-27 09:20:00+00'),
|
|
(5007, 1001, 'vote_user_007', 'draft', TIMESTAMPTZ '2026-06-27 14:15:00+00'),
|
|
(5008, 1001, 'vote_user_008', 'submitted', TIMESTAMPTZ '2026-06-28 21:05:00+00');
|
|
|
|
INSERT INTO "VoteEntries" ("Id", "BallotId", "CategoryId", "CandidateId")
|
|
VALUES
|
|
(5101, 5001, 1101, 2001), (5102, 5001, 1104, 2010), (5103, 5001, 1109, 2025), (5104, 5001, 1113, 2037),
|
|
(5105, 5002, 1101, 2002), (5106, 5002, 1105, 2013), (5107, 5002, 1110, 2028), (5108, 5002, 1114, 2040),
|
|
(5109, 5003, 1102, 2004), (5110, 5003, 1106, 2016), (5111, 5003, 1111, 2031), (5112, 5003, 1112, 2034),
|
|
(5113, 5004, 1103, 2007), (5114, 5004, 1104, 2011), (5115, 5004, 1108, 2022), (5116, 5004, 1113, 2038),
|
|
(5117, 5005, 1101, 2001), (5118, 5005, 1105, 2014), (5119, 5005, 1109, 2026), (5120, 5005, 1114, 2041),
|
|
(5121, 5006, 1102, 2005), (5122, 5006, 1106, 2016), (5123, 5006, 1110, 2029), (5124, 5006, 1112, 2035),
|
|
(5125, 5007, 1103, 2008), (5126, 5007, 1107, 2019),
|
|
(5127, 5008, 1101, 2001), (5128, 5008, 1104, 2010), (5129, 5008, 1111, 2032), (5130, 5008, 1113, 2037);
|
|
|
|
INSERT INTO "Results" ("Id", "SeasonId", "CategoryId", "CandidateId", "CategoryName")
|
|
VALUES
|
|
(6001, 1000, 1201, 2101, 'Archiv Rising Star'),
|
|
(6002, 1000, 1202, 2104, 'Archiv Variety'),
|
|
(6003, 1000, 1203, 2107, 'Archiv Music'),
|
|
(6004, 1000, 1204, 2110, 'Archiv Community'),
|
|
(6005, 1000, 1205, 2113, 'Archiv Stream Design'),
|
|
(6006, 1000, 1206, 2116, 'Archiv Clip Moment');
|
|
|
|
INSERT INTO "ClipSubmissions" (
|
|
"Id", "SeasonId", "CategoryId", "CandidateId", "SubmittedByTwitchId", "ClipUrl", "Title", "Creator", "Platform",
|
|
"Status", "ReviewNote", "ReviewedByTwitchId", "CreatedFromIp", "CreatedAt", "ReviewedAt"
|
|
)
|
|
VALUES
|
|
(7001, 1001, 1103, 2007, 'viewer_2001', 'https://clips.twitch.tv/demo-ember-moment', 'Ember findet den Plot Twist', 'viewer_2001', 'Twitch', 'approved', 'Ton und Kontext passen.', 'clip_reviewer', '127.0.0.1', TIMESTAMPTZ '2026-06-20 18:12:00+00', TIMESTAMPTZ '2026-06-21 09:00:00+00'),
|
|
(7002, 1001, 1113, 2037, 'viewer_2002', 'https://clips.twitch.tv/demo-lio-laugh', 'Lio verliert komplett die Fassung', 'viewer_2002', 'Twitch', 'approved', NULL, 'clip_reviewer', '127.0.0.1', TIMESTAMPTZ '2026-06-20 20:25:00+00', TIMESTAMPTZ '2026-06-21 09:08:00+00'),
|
|
(7003, 1001, 1106, 2016, 'viewer_2003', 'https://youtu.be/demo-melo-live', 'Melo Moon acoustic bridge', 'viewer_2003', 'YouTube', 'pending', 'YouTube-Timestamp noch pruefen.', NULL, '127.0.0.1', TIMESTAMPTZ '2026-06-21 11:40:00+00', NULL),
|
|
(7004, 1001, 1104, 2010, 'viewer_2004', 'https://youtu.be/demo-hana-variety', 'Hana improvised den Chat-Run', 'viewer_2004', 'YouTube', 'approved', NULL, 'clip_reviewer', '127.0.0.1', TIMESTAMPTZ '2026-06-21 15:10:00+00', TIMESTAMPTZ '2026-06-22 08:45:00+00'),
|
|
(7005, 1001, 1114, 2040, 'viewer_2005', 'https://clips.twitch.tv/demo-vera-setup', 'Vera erklaert ihr neues Setup', 'viewer_2005', 'Twitch', 'pending', NULL, NULL, '127.0.0.1', TIMESTAMPTZ '2026-06-22 19:55:00+00', NULL),
|
|
(7006, 1001, 1109, 2025, 'viewer_2006', 'https://clips.twitch.tv/demo-bibi-chat', 'Bibi laesst Chat entscheiden', 'viewer_2006', 'Twitch', 'rejected', 'Zu wenig Kontext fuer Award-Clip.', 'clip_reviewer', '127.0.0.1', TIMESTAMPTZ '2026-06-23 12:30:00+00', TIMESTAMPTZ '2026-06-23 14:05:00+00'),
|
|
(7007, 1000, 1206, 2116, 'archiv_viewer_1', 'https://clips.twitch.tv/demo-archiv-vesper', 'Archiv Vesper Finale Clip', 'archiv_viewer_1', 'Twitch', 'approved', NULL, 'clip_reviewer', '127.0.0.1', TIMESTAMPTZ '2025-06-10 19:00:00+00', TIMESTAMPTZ '2025-06-11 09:00:00+00');
|
|
|
|
INSERT INTO "ShowactApplications" (
|
|
"Id", "SeasonId", "ArtistName", "ContactEmail", "ContactDiscord", "PlatformUrl", "PerformanceType", "Description",
|
|
"TechnicalNotes", "ReferenceUrl", "FieldResponsesJson", "Status", "ReviewNote", "ReviewedByTwitchId", "CreatedFromIp", "UserAgent", "CreatedAt", "ReviewedAt"
|
|
)
|
|
VALUES
|
|
(8001, 1001, 'Melo Moon', 'melo@example.invalid', 'melo_moon', 'https://twitch.tv/melo_moon', 'Live-Gesang', 'Akustisches Opening-Medley mit zwei kurzen Songs.', 'Benoetigt Instrumentalspur und Monitoring.', 'https://youtu.be/demo-melo-live', '{"performanceLength":"6 Minuten","contentRating":"family friendly"}', 'approved', 'Passt als Opener.', 'show_reviewer', '127.0.0.1', 'DemoBrowser/1.0', TIMESTAMPTZ '2026-06-19 13:10:00+00', TIMESTAMPTZ '2026-06-20 10:00:00+00'),
|
|
(8002, 1001, 'Neon Nori', 'nori@example.invalid', 'neon_nori', 'https://twitch.tv/neon_nori', 'Visual Interlude', 'Kurze Motion-Overlay-Performance zwischen zwei Award-Bloecken.', 'OBS-Szene mit WebM-Loop, kein Mikro.', 'https://youtu.be/demo-nori-motion', '{"performanceLength":"3 Minuten","contentRating":"keine Hinweise"}', 'pending', NULL, NULL, '127.0.0.1', 'DemoBrowser/1.0', TIMESTAMPTZ '2026-06-20 16:40:00+00', NULL),
|
|
(8003, 1001, 'Cleo Campfire', 'cleo@example.invalid', 'cleo_campfire', 'https://twitch.tv/cleo_campfire', 'Community Skit', 'Kurzer Call-and-response Sketch mit Chat-Kommandos.', 'Braucht Chat-Overlay-Freigabe.', 'https://youtu.be/demo-cleo-skit', '{"performanceLength":"5 Minuten","contentRating":"leichte Improvisation"}', 'pending', 'Technische Details klaeren.', NULL, '127.0.0.1', 'DemoBrowser/1.0', TIMESTAMPTZ '2026-06-22 12:05:00+00', NULL),
|
|
(8004, 1000, 'Archiv Lyra', 'lyra@example.invalid', 'archiv_lyra', 'https://twitch.tv/archiv_lyra', 'Archiv Musik', 'Gewinner-Showcase aus dem Vorjahr.', 'VOD bereits vorhanden.', 'https://youtu.be/demo-archiv-lyra', '{"performanceLength":"4 Minuten","contentRating":"family friendly"}', 'approved', 'Archiv-Showact.', 'show_reviewer', '127.0.0.1', 'DemoBrowser/1.0', TIMESTAMPTZ '2025-06-01 12:05:00+00', TIMESTAMPTZ '2025-06-02 09:30:00+00');
|
|
|
|
INSERT INTO "Sponsors" (
|
|
"Id", "SeasonId", "Name", "WebsiteUrl", "LogoUrl", "Description", "Tier", "SortOrder", "IsVisible", "CreatedAt", "UpdatedAt"
|
|
)
|
|
VALUES
|
|
(9001, 1001, 'CloudBeacon Hosting', 'https://example.invalid/cloudbeacon', '/demo/sponsors/cloudbeacon-hosting.svg', 'Server- und Bot-Hosting fuer Community-Projekte.', 'Main Partner', 10, TRUE, TIMESTAMPTZ '2026-06-01 10:00:00+00', NULL),
|
|
(9002, 1001, 'NekoPixel Energy', 'https://example.invalid/nekopixel', '/demo/sponsors/nekopixel-energy.svg', 'Fiktiver Energy-Drink fuer lange Stream-Naechte.', 'Gold Partner', 20, TRUE, TIMESTAMPTZ '2026-06-01 10:05:00+00', NULL),
|
|
(9003, 1001, 'PrismLoop Audio', 'https://example.invalid/prismloop', '/demo/sponsors/prismloop-audio.svg', 'Audio-Tools und Soundpacks fuer Creator:innen.', 'Gold Partner', 30, TRUE, TIMESTAMPTZ '2026-06-01 10:10:00+00', NULL),
|
|
(9004, 1001, 'HoshiForge Studio', 'https://example.invalid/hoshiforge', '/demo/sponsors/hoshiforge-studio.svg', 'Branding, Overlays und kleine Motion-Pakete.', 'Community Partner', 40, TRUE, TIMESTAMPTZ '2026-06-01 10:15:00+00', NULL),
|
|
(9005, 1001, 'ChibiCanvas Market', 'https://example.invalid/chibicanvas', '/demo/sponsors/chibicanvas-market.svg', 'Asset-Marktplatz fuer Panels, Emotes und Stream-Grafiken.', 'Community Partner', 50, TRUE, TIMESTAMPTZ '2026-06-01 10:20:00+00', NULL);
|
|
|
|
INSERT INTO "RiskFlags" (
|
|
"Id", "SeasonId", "TwitchUserId", "Source", "Type", "Severity", "Status", "Summary", "CreatedFromIp", "UserAgent",
|
|
"MetadataJson", "ReviewNote", "ReviewedByTwitchId", "CreatedAt", "ReviewedAt"
|
|
)
|
|
VALUES
|
|
(10001, 1001, 'viewer_1016', 'tracking-review', 'unsupported_platform', 'medium', 'open', 'Nominierung nutzt einen YouTube-Link und benoetigt manuellen Tracker-Review.', '127.0.0.1', 'DemoBrowser/1.0', '{"seasonId":1001,"nominationId":4016}', NULL, NULL, TIMESTAMPTZ '2026-06-18 10:40:00+00', NULL),
|
|
(10002, 1001, 'viewer_1007', 'tracking-review', 'no_tracker_data', 'medium', 'open', 'TwitchTracker lieferte keine belastbaren Daten fuer Nyra Novel.', '127.0.0.1', 'DemoBrowser/1.0', '{"seasonId":1001,"nominationId":4007}', 'Manuelle Lore-Pruefung vor Finale.', 'reviewer_demo', TIMESTAMPTZ '2026-06-18 11:02:00+00', TIMESTAMPTZ '2026-06-18 11:08:00+00'),
|
|
(10003, 1001, 'vote_user_007', 'voting', 'draft_ballot', 'low', 'resolved', 'Draft-Ballot ohne Submission, sichtbar fuer Dashboard-Randfall.', '127.0.0.1', 'DemoBrowser/1.0', '{"seasonId":1001,"ballotId":5007}', 'Nur Demo-Randfall.', 'reviewer_demo', TIMESTAMPTZ '2026-06-27 14:20:00+00', TIMESTAMPTZ '2026-06-27 15:00:00+00'),
|
|
(10004, 1000, 'archiv_viewer_1', 'archive-cleanup', 'archived_clip', 'low', 'resolved', 'Archiv-Clip wurde fuer Gewinnerarchiv geprueft.', '127.0.0.1', 'DemoBrowser/1.0', '{"seasonId":1000,"clipId":7007}', 'Archiv okay.', 'reviewer_demo', TIMESTAMPTZ '2025-06-11 09:10:00+00', TIMESTAMPTZ '2025-06-11 09:25:00+00');
|
|
|
|
SELECT setval(pg_get_serial_sequence('"Seasons"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Seasons"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"Categories"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Categories"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"StreamerIdentities"', 'Id'), COALESCE((SELECT MAX("Id") FROM "StreamerIdentities"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"Candidates"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Candidates"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"Nominations"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Nominations"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"VoteBallots"', 'Id'), COALESCE((SELECT MAX("Id") FROM "VoteBallots"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"VoteEntries"', 'Id'), COALESCE((SELECT MAX("Id") FROM "VoteEntries"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"Results"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Results"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"ClipSubmissions"', 'Id'), COALESCE((SELECT MAX("Id") FROM "ClipSubmissions"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"ShowactApplications"', 'Id'), COALESCE((SELECT MAX("Id") FROM "ShowactApplications"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"Sponsors"', 'Id'), COALESCE((SELECT MAX("Id") FROM "Sponsors"), 1));
|
|
SELECT setval(pg_get_serial_sequence('"RiskFlags"', 'Id'), COALESCE((SELECT MAX("Id") FROM "RiskFlags"), 1));
|
|
END;
|
|
$vtsa_seed$;
|
|
"""
|
|
);
|
|
}
|
|
|
|
protected override void Down(MigrationBuilder migrationBuilder)
|
|
{
|
|
migrationBuilder.Sql(
|
|
"""
|
|
DELETE FROM "RiskFlags" WHERE "SeasonId" IN (1000, 1001);
|
|
DELETE FROM "Seasons" WHERE "Id" IN (1000, 1001) AND "IsDemo" = TRUE;
|
|
DELETE FROM "StreamerIdentities" WHERE "Id" BETWEEN 3001 AND 3010;
|
|
"""
|
|
);
|
|
}
|
|
}
|