{
    "$schema": "https://playground.wordpress.net/blueprint-schema.json",
    "meta": {
        "title": "BrikPanel Live Preview",
        "description": "WooCommerce admin dashboard, sales report, COGS, ad spend, ROAS, net profit, RFM and cohort analytics, pre-seeded with a full demo store.",
        "author": "brksoft",
        "categories": [
            "ecommerce",
            "admin"
        ]
    },
    "landingPage": "/wp-admin/admin.php?page=brikpanel-dashboard",
    "preferredVersions": {
        "php": "8.2",
        "wp": "latest"
    },
    "phpExtensionBundles": [
        "kitchen-sink"
    ],
    "features": {
        "networking": true
    },
    "login": true,
    "steps": [
        {
            "step": "installPlugin",
            "pluginData": {
                "resource": "wordpress.org/plugins",
                "slug": "woocommerce"
            },
            "options": {
                "activate": true
            }
        },
        {
            "step": "installPlugin",
            "pluginData": {
                "resource": "wordpress.org/plugins",
                "slug": "brikpanel-admin-panel-dashboard-for-woocommerce"
            },
            "options": {
                "activate": true
            }
        },
        {
            "step": "setSiteOptions",
            "options": {
                "blogname": "BrikPanel Demo Store",
                "woocommerce_currency": "USD",
                "woocommerce_default_country": "US:NY",
                "woocommerce_custom_orders_table_enabled": "no",
                "woocommerce_feature_custom_order_tables_enabled": "no",
                "woocommerce_onboarding_profile": {
                    "skipped": true
                },
                "woocommerce_task_list_hidden": "yes"
            }
        },
        {
            "step": "runPHP",
            "code": "<?php\n/**\n * BrikPanel \"full demo\" seeder \u2014 Playground/SQLite safe + fast.\n *\n * Orders are written with direct $wpdb inserts (legacy CPT storage) instead of\n * wc_create_order(), which is ~50x faster under PHP-wasm. RFM / LTV / cohort\n * are computed in PHP and inserted directly, because BrikPanel's own recompute\n * SQL uses MySQL-only TIMESTAMPDIFF()/NTILE() that the SQLite layer rejects.\n */\nrequire_once '/wordpress/wp-load.php';\nif ( ! function_exists( 'wc_get_product' ) ) { return; }\nif ( get_option( 'brikpanel_demo_seeded' ) ) { return; }\n\nglobal $wpdb;\n$diag = array();\n$t0 = microtime( true );\n$now = time();\n\nif ( class_exists( 'WC_Install' ) ) { WC_Install::install(); }\nupdate_option( 'woocommerce_feature_cost_of_goods_sold_enabled', 'yes' );\nupdate_option( 'brikpanel_cogs_default_applied', 'yes' );\nif ( function_exists( 'brikpanel_create_table' ) ) { brikpanel_create_table(); }\n\n/* deterministic PRNG so the demo is identical every boot */\n$seed = 987654321;\n$rnd = function ( $min, $max ) use ( &$seed ) {\n\t$seed = ( $seed * 1103515245 + 12345 ) & 0x7fffffff;\n\treturn $min + ( $seed % ( $max - $min + 1 ) );\n};\n\n/* ---------------- 1) Products (price + COGS + category + stock) ---------- */\n$catalog = array(\n\tarray( 'Aurora Desk Lamp', 49.00, 21.00, 120, 'Home & Office' ),\n\tarray( 'Nimbus Wireless Headphones', 129.00, 58.00, 80, 'Electronics' ),\n\tarray( 'Terra Ceramic Mug', 18.50, 6.50, 240, 'Kitchen' ),\n\tarray( 'Halo Smart Speaker', 89.00, 41.00, 0, 'Electronics' ),\n\tarray( 'Vega Cotton T-Shirt', 24.00, 8.00, 320, 'Apparel' ),\n\tarray( 'Orbit Travel Backpack', 75.00, 33.00, 45, 'Travel' ),\n\tarray( 'Lumen LED Strip', 32.00, 12.00, 9, 'Home & Office' ),\n\tarray( 'Pebble Bluetooth Tracker', 27.50, 9.50, 150, 'Electronics' ),\n\tarray( 'Cedar Cutting Board', 39.00, 15.00, 60, 'Kitchen' ),\n\tarray( 'Sol Sunglasses', 59.00, 19.00, 4, 'Apparel' ),\n\tarray( 'Drift Yoga Mat', 45.00, 17.00, 90, 'Fitness' ),\n\tarray( 'Forge Chef Knife', 68.00, 27.00, 33, 'Kitchen' ),\n);\n$cat_ids = array();\n$products = array();\nforeach ( $catalog as $row ) {\n\tlist( $name, $price, $cost, $stock, $cat ) = $row;\n\tif ( ! isset( $cat_ids[ $cat ] ) ) {\n\t\t$term = term_exists( $cat, 'product_cat' );\n\t\tif ( ! $term ) { $term = wp_insert_term( $cat, 'product_cat' ); }\n\t\t$cat_ids[ $cat ] = is_wp_error( $term ) ? 0 : (int) $term['term_id'];\n\t}\n\t$p = new WC_Product_Simple();\n\t$p->set_name( $name );\n\t$p->set_regular_price( (string) $price );\n\t$p->set_price( (string) $price );\n\t$p->set_manage_stock( true );\n\t$p->set_stock_quantity( $stock );\n\t$p->set_stock_status( $stock > 0 ? 'instock' : 'outofstock' );\n\t$p->set_status( 'publish' );\n\tif ( $cat_ids[ $cat ] ) { $p->set_category_ids( array( $cat_ids[ $cat ] ) ); }\n\tif ( method_exists( $p, 'set_cogs_value' ) ) { $p->set_cogs_value( $cost ); }\n\t$pid = $p->save();\n\tupdate_post_meta( $pid, '_brikpanel_cogs', $cost );\n\t$products[] = array( 'id' => $pid, 'name' => $name, 'price' => $price, 'cost' => $cost );\n}\n$diag['products'] = count( $products );\n\n/* ---------------- 2) Customers ---------- */\n$people = array(\n\t'Olivia Bennett','Liam Carter','Emma Davies','Noah Evans','Ava Foster','James Green',\n\t'Sophia Hughes','Lucas Irwin','Mia Jensen','Ethan Knight','Isla Lewis','Mason Moore',\n\t'Amelia Novak','Henry Owen','Grace Patel','Leo Quinn','Chloe Reed','Max Turner',\n);\n$countries = array( 'US','GB','DE','CA','FR','AU','NL','SE' );\n$cities    = array( 'US'=>'New York','GB'=>'London','DE'=>'Berlin','CA'=>'Toronto','FR'=>'Paris','AU'=>'Sydney','NL'=>'Amsterdam','SE'=>'Stockholm' );\n$customers = array();\nforeach ( $people as $i => $full ) {\n\t$parts = explode( ' ', $full );\n\t$email = strtolower( str_replace( ' ', '.', $full ) ) . '@example.com';\n\t$uid = email_exists( $email );\n\tif ( ! $uid ) {\n\t\t$uid = wp_insert_user( array(\n\t\t\t'user_login' => 'cust_' . ( $i + 1 ), 'user_email' => $email,\n\t\t\t'first_name' => $parts[0], 'last_name' => isset( $parts[1] ) ? $parts[1] : '',\n\t\t\t'display_name' => $full, 'role' => 'customer', 'user_pass' => wp_generate_password( 16 ),\n\t\t) );\n\t}\n\tif ( ! is_wp_error( $uid ) ) {\n\t\t$c = $countries[ $i % count( $countries ) ];\n\t\t$customers[] = array( 'id' => (int) $uid, 'email' => $email, 'country' => $c, 'city' => $cities[ $c ], 'first' => $parts[0], 'last' => isset($parts[1])?$parts[1]:'' );\n\t}\n}\n$diag['customers'] = count( $customers );\n\n/* ---------------- 3) Orders via direct SQL ---------- */\n$posts_tbl  = $wpdb->posts;\n$meta_tbl   = $wpdb->postmeta;\n$items_tbl  = $wpdb->prefix . 'woocommerce_order_items';\n$itmeta_tbl = $wpdb->prefix . 'woocommerce_order_itemmeta';\n$stats_tbl  = $wpdb->prefix . 'wc_order_stats';\n\n// VIP weighting for a realistic RFM spread.\n$weights = array();\nforeach ( $customers as $idx => $c ) {\n\t$w = ( $idx < 4 ) ? 6 : ( ( $idx < 9 ) ? 3 : 1 );\n\tfor ( $k = 0; $k < $w; $k++ ) { $weights[] = $idx; }\n}\n// Status mix: mostly paid, a few others for the donut.\n$status_pool = array( 'wc-completed','wc-completed','wc-completed','wc-completed','wc-processing','wc-processing','wc-on-hold','wc-completed','wc-refunded','wc-cancelled','wc-failed' );\n$counted_for_customer = array( 'wc-completed','wc-processing','wc-on-hold','wc-pending','wc-refunded' );\n\n// Day buckets => how many orders land in each (full today + 7d + 30d windows).\n$plan = array();\nfor ( $x = 0; $x < 6; $x++ )  { $plan[] = 0; }                 // today\nfor ( $x = 0; $x < 18; $x++ ) { $plan[] = $rnd( 1, 6 ); }      // last 7 days\nfor ( $x = 0; $x < 22; $x++ ) { $plan[] = $rnd( 7, 29 ); }     // last 30 days\nfor ( $x = 0; $x < 24; $x++ ) { $plan[] = $rnd( 30, 89 ); }    // up to 90 days\n\n$cust_agg   = array(); // uid => [count,total,first_ts,last_ts, months=>set]\n$orders_made = 0; $revenue = 0.0;\n$suppress = $wpdb->suppress_errors( true );\n\nforeach ( $plan as $days_ago ) {\n\t$ts = $now - ( $days_ago * DAY_IN_SECONDS );\n\tif ( $days_ago === 0 ) { $ts -= $rnd( 600, 40000 ); } else { $ts -= $rnd( 0, 80000 ); }\n\t$gmt   = gmdate( 'Y-m-d H:i:s', $ts );\n\t$local = $gmt; // Playground store TZ is UTC.\n\t$cust  = $customers[ $weights[ $rnd( 0, count( $weights ) - 1 ) ] ];\n\t$status = $status_pool[ $rnd( 0, count( $status_pool ) - 1 ) ];\n\n\t// Build line items.\n\t$lines = $rnd( 1, 3 );\n\t$used = array(); $items = array(); $order_total = 0.0; $order_cogs = 0.0; $num_items = 0;\n\tfor ( $j = 0; $j < $lines; $j++ ) {\n\t\t$pr = $products[ $rnd( 0, count( $products ) - 1 ) ];\n\t\tif ( isset( $used[ $pr['id'] ] ) ) { continue; }\n\t\t$used[ $pr['id'] ] = 1;\n\t\t$qty = $rnd( 1, 3 );\n\t\t$line_total = round( $pr['price'] * $qty, 2 );\n\t\t$items[] = array( 'pid' => $pr['id'], 'name' => $pr['name'], 'qty' => $qty, 'line_total' => $line_total );\n\t\t$order_total += $line_total;\n\t\t$order_cogs  += $pr['cost'] * $qty;\n\t\t$num_items   += $qty;\n\t}\n\t$order_total = round( $order_total, 2 );\n\t$order_cogs  = round( $order_cogs, 2 );\n\n\t// 3a) wp_posts\n\t$wpdb->insert( $posts_tbl, array(\n\t\t'post_author' => 1, 'post_date' => $local, 'post_date_gmt' => $gmt,\n\t\t'post_content' => '', 'post_title' => 'Order &ndash; ' . $gmt, 'post_excerpt' => '',\n\t\t'post_status' => $status, 'comment_status' => 'closed', 'ping_status' => 'closed',\n\t\t'post_password' => '', 'post_name' => 'order-' . $ts . '-' . $orders_made,\n\t\t'to_ping' => '', 'pinged' => '', 'post_content_filtered' => '', 'post_parent' => 0,\n\t\t'guid' => '', 'menu_order' => 0, 'post_type' => 'shop_order', 'post_mime_type' => '',\n\t\t'comment_count' => 0, 'post_modified' => $local, 'post_modified_gmt' => $gmt,\n\t) );\n\t$oid = (int) $wpdb->insert_id;\n\tif ( ! $oid ) { continue; }\n\n\t// 3b) postmeta\n\t$is_paid = in_array( $status, array( 'wc-completed','wc-processing' ), true );\n\t$metas = array(\n\t\t'_order_currency' => 'USD', '_order_total' => number_format( $order_total, 2, '.', '' ),\n\t\t'_order_tax' => '0', '_cart_discount' => '0', '_cart_discount_tax' => '0',\n\t\t'_order_shipping' => '0', '_prices_include_tax' => 'no',\n\t\t'_customer_user' => (string) $cust['id'], '_billing_email' => $cust['email'],\n\t\t'_billing_first_name' => $cust['first'], '_billing_last_name' => $cust['last'],\n\t\t'_billing_country' => $cust['country'], '_billing_city' => $cust['city'],\n\t\t'_payment_method' => 'bacs', '_payment_method_title' => 'Direct bank transfer',\n\t\t'_order_version' => '9.0.0', '_wc_cog_order_total_value' => number_format( $order_cogs, 2, '.', '' ),\n\t);\n\tif ( $is_paid ) { $metas['_date_paid'] = (string) $ts; $metas['_paid_date'] = $local; }\n\tforeach ( $metas as $mk => $mv ) {\n\t\t$wpdb->insert( $meta_tbl, array( 'post_id' => $oid, 'meta_key' => $mk, 'meta_value' => $mv ) );\n\t}\n\n\t// 3c) order items + itemmeta\n\tforeach ( $items as $it ) {\n\t\t$wpdb->insert( $items_tbl, array( 'order_item_name' => $it['name'], 'order_item_type' => 'line_item', 'order_id' => $oid ) );\n\t\t$item_id = (int) $wpdb->insert_id;\n\t\tif ( ! $item_id ) { continue; }\n\t\t$im = array(\n\t\t\t'_product_id' => (string) $it['pid'], '_variation_id' => '0', '_qty' => (string) $it['qty'],\n\t\t\t'_line_subtotal' => number_format( $it['line_total'], 2, '.', '' ), '_line_subtotal_tax' => '0',\n\t\t\t'_line_total' => number_format( $it['line_total'], 2, '.', '' ), '_line_tax' => '0', '_tax_class' => '',\n\t\t);\n\t\tforeach ( $im as $k => $v ) {\n\t\t\t$wpdb->insert( $itmeta_tbl, array( 'order_item_id' => $item_id, 'meta_key' => $k, 'meta_value' => $v ) );\n\t\t}\n\t}\n\n\t// 3d) wc_order_stats (powers new-vs-repeat split; best-effort)\n\t$returning = isset( $cust_agg[ $cust['id'] ] ) ? 1 : 0;\n\t$wpdb->insert( $stats_tbl, array(\n\t\t'order_id' => $oid, 'parent_id' => 0, 'date_created' => $local, 'date_created_gmt' => $gmt,\n\t\t'num_items_sold' => $num_items, 'total_sales' => $order_total, 'tax_total' => 0,\n\t\t'shipping_total' => 0, 'net_total' => $order_total, 'returning_customer' => $returning,\n\t\t'status' => $status, 'customer_id' => $cust['id'],\n\t) );\n\n\t// 3e) customer aggregation (for RFM/LTV/cohort), counted statuses only\n\tif ( in_array( $status, $counted_for_customer, true ) ) {\n\t\t$uid = $cust['id'];\n\t\tif ( ! isset( $cust_agg[ $uid ] ) ) {\n\t\t\t$cust_agg[ $uid ] = array( 'count' => 0, 'total' => 0.0, 'first' => $ts, 'last' => $ts, 'email' => $cust['email'], 'months' => array() );\n\t\t}\n\t\t$cust_agg[ $uid ]['count']++;\n\t\t$cust_agg[ $uid ]['total'] += $order_total;\n\t\t$cust_agg[ $uid ]['first'] = min( $cust_agg[ $uid ]['first'], $ts );\n\t\t$cust_agg[ $uid ]['last']  = max( $cust_agg[ $uid ]['last'], $ts );\n\t\t$cust_agg[ $uid ]['months'][ gmdate( 'Y-m-01', $ts ) ] = 1;\n\t}\n\tif ( in_array( $status, array( 'wc-completed','wc-processing' ), true ) ) { $revenue += $order_total; }\n\t$orders_made++;\n}\n$wpdb->suppress_errors( $suppress );\n$diag['orders'] = $orders_made;\n$diag['revenue_paid'] = round( $revenue, 2 );\n\n/* ---------------- 4) RFM + LTV \u2192 customer_metrics ---------- */\n$cm_tbl = $wpdb->prefix . 'brikpanel_customer_metrics';\n$wpdb->query( \"DELETE FROM {$cm_tbl}\" );\n\n// NTILE(5)-style quintile helper. $pairs: key => value. $desc=true ranks\n// largest value into tile 1 (used for recency where high=worst).\n$ntile = function ( $pairs, $desc ) {\n\t$keys = array_keys( $pairs );\n\tusort( $keys, function ( $a, $b ) use ( $pairs, $desc ) {\n\t\tif ( $pairs[ $a ] == $pairs[ $b ] ) { return 0; }\n\t\t$cmp = ( $pairs[ $a ] < $pairs[ $b ] ) ? -1 : 1;\n\t\treturn $desc ? -$cmp : $cmp;\n\t} );\n\t$n = count( $keys ); $out = array();\n\tif ( $n === 0 ) { return $out; }\n\t$base = intdiv( $n, 5 ); $rem = $n % 5; $pos = 0;\n\tfor ( $tile = 1; $tile <= 5; $tile++ ) {\n\t\t$size = $base + ( $tile <= $rem ? 1 : 0 );\n\t\tfor ( $s = 0; $s < $size; $s++ ) { $out[ $keys[ $pos++ ] ] = $tile; }\n\t}\n\treturn $out;\n};\n\n$recency = array(); $freq = array(); $monet = array();\nforeach ( $cust_agg as $uid => $a ) {\n\t$recency[ $uid ] = max( 0, intval( floor( ( $now - $a['last'] ) / DAY_IN_SECONDS ) ) );\n\t$freq[ $uid ]    = $a['count'];\n\t$monet[ $uid ]   = $a['total'];\n}\n$r_scores = $ntile( $recency, true );   // high recency -> tile 1\n$f_scores = $ntile( $freq, false );     // high freq -> tile 5\n$m_scores = $ntile( $monet, false );    // high spend -> tile 5\n\n$segment_of = function ( $r, $f, $m ) {\n\tif ( $r >= 4 && $f >= 4 && $m >= 4 ) { return 'champions'; }\n\tif ( $r <= 2 && $f >= 4 && $m >= 4 ) { return 'cant_lose'; }\n\tif ( $r <= 2 && $f >= 3 && $m >= 3 ) { return 'at_risk'; }\n\tif ( $r == 1 && $f == 1 && $m == 1 ) { return 'lost'; }\n\tif ( $r <= 2 && $f <= 2 ) { return 'hibernating'; }\n\tif ( $f >= 3 && $m >= 3 ) { return 'loyal'; }\n\tif ( $r >= 4 && $f == 1 ) { return 'new'; }\n\tif ( $r >= 4 && $f <= 3 ) { return 'potential_loyalist'; }\n\tif ( $r == 3 && $f <= 2 ) { return 'about_to_sleep'; }\n\tif ( $f >= 3 ) { return 'need_attention'; }\n\treturn 'hibernating';\n};\n\n$cm_rows = 0; $nowgmt = gmdate( 'Y-m-d H:i:s', $now );\nforeach ( $cust_agg as $uid => $a ) {\n\t$r = isset( $r_scores[ $uid ] ) ? $r_scores[ $uid ] : 0;\n\t$f = isset( $f_scores[ $uid ] ) ? $f_scores[ $uid ] : 0;\n\t$m = isset( $m_scores[ $uid ] ) ? $m_scores[ $uid ] : 0;\n\t$wpdb->insert( $cm_tbl, array(\n\t\t'customer_key' => 'u:' . $uid, 'user_id' => $uid, 'customer_email' => $a['email'],\n\t\t'first_order_date' => gmdate( 'Y-m-d H:i:s', $a['first'] ), 'last_order_date' => gmdate( 'Y-m-d H:i:s', $a['last'] ),\n\t\t'order_count' => $a['count'], 'total_spent' => round( $a['total'], 4 ),\n\t\t'aov' => round( $a['count'] ? $a['total'] / $a['count'] : 0, 4 ), 'recency_days' => $recency[ $uid ],\n\t\t'r_score' => $r, 'f_score' => $f, 'm_score' => $m, 'rfm_segment' => $segment_of( $r, $f, $m ),\n\t\t'computed_at' => $nowgmt,\n\t) );\n\t$cm_rows++;\n}\n$diag['cm_rows'] = $cm_rows;\n\n/* ---------------- 5) Cohort retention ---------- */\n$coh_tbl = $wpdb->prefix . 'brikpanel_cohort_retention';\n$wpdb->query( \"DELETE FROM {$coh_tbl}\" );\n$cohorts = array(); // cohort_month => [ uid => months_set ]\nforeach ( $cust_agg as $uid => $a ) {\n\t$first_month = gmdate( 'Y-m-01', $a['first'] );\n\t$cohorts[ $first_month ][ $uid ] = $a['months'];\n}\n$cur_month = gmdate( 'Y-m-01', $now );\n$coh_rows = 0;\nforeach ( $cohorts as $cmonth => $members ) {\n\t$size = count( $members );\n\tfor ( $off = 0; $off <= 6; $off++ ) {\n\t\t$target = gmdate( 'Y-m-01', strtotime( \"{$cmonth} +{$off} month\" ) );\n\t\tif ( strtotime( $target ) > strtotime( $cur_month ) ) { break; }\n\t\t$retained = 0;\n\t\tforeach ( $members as $uid => $monthsSet ) {\n\t\t\tif ( isset( $monthsSet[ $target ] ) ) { $retained++; }\n\t\t}\n\t\t$rate = $size > 0 ? round( $retained / $size * 100, 2 ) : 0;\n\t\t$wpdb->insert( $coh_tbl, array(\n\t\t\t'cohort_month' => $cmonth, 'period_offset' => $off, 'cohort_size' => $size,\n\t\t\t'retained_customers' => $retained, 'retention_rate' => $rate, 'computed_at' => $nowgmt,\n\t\t) );\n\t\t$coh_rows++;\n\t}\n}\n$diag['cohort_rows'] = $coh_rows;\n\n/* ---------------- 6) Ad spend (USD), expenses, visitors ---------- */\n$ad_tbl = $wpdb->prefix . 'brikpanel_ad_spend'; $ad_rows = 0; $ad_total = 0.0;\nfor ( $d = 0; $d < 90; $d++ ) {\n\t$date = gmdate( 'Y-m-d', $now - $d * DAY_IN_SECONDS );\n\tforeach ( array( 'google_ads' => 1.0, 'meta' => 0.7 ) as $plat => $mult ) {\n\t\t$spend = round( $rnd( 18, 60 ) * $mult, 2 );\n\t\t$wpdb->insert( $ad_tbl, array(\n\t\t\t'date' => $date, 'platform' => $plat, 'account_id' => ( $plat === 'google_ads' ? '528-898-0937' : 'act_demo' ),\n\t\t\t'spend_amount' => $spend, 'spend_currency' => 'USD', 'impressions' => $rnd( 800, 5000 ), 'clicks' => $rnd( 20, 180 ),\n\t\t) );\n\t\t$ad_rows++; $ad_total += $spend;\n\t}\n}\n$diag['ad_spend_rows'] = $ad_rows; $diag['ad_spend_total'] = round( $ad_total, 2 );\n\n$exp_tbl = $wpdb->prefix . 'brikpanel_expenses'; $exp_rows = 0;\n$exp_items = array( array('Rent','Warehouse rent',1200,'monthly'), array('Software','SaaS subscriptions',240,'monthly'), array('Salaries','Part-time staff',1800,'monthly') );\nfor ( $mo = 0; $mo < 3; $mo++ ) {\n\t$mdate = gmdate( 'Y-m-01', strtotime( \"-{$mo} month\", $now ) );\n\tforeach ( $exp_items as $e ) {\n\t\t$wpdb->insert( $exp_tbl, array( 'expense_date' => $mdate, 'category' => $e[0], 'description' => $e[1], 'amount' => $e[2], 'recurring' => $e[3] ) );\n\t\t$exp_rows++;\n\t}\n}\n$diag['expense_rows'] = $exp_rows;\n\n// Daily paid-order counts for realistic conversion.\n$daily_orders = array();\nforeach ( $cust_agg as $a ) { /* placeholder */ }\n// Recount paid orders per day directly from posts.\n$rowsd = $wpdb->get_results( \"SELECT substr(post_date,1,10) d, COUNT(*) c FROM {$posts_tbl} WHERE post_type='shop_order' AND post_status IN ('wc-completed','wc-processing') GROUP BY d\", ARRAY_A );\nforeach ( (array) $rowsd as $r ) { $daily_orders[ $r['d'] ] = (int) $r['c']; }\n\n$vis_tbl = $wpdb->prefix . 'brikpanel_visitors'; $vis_rows = 0; $vis_sum = 0;\nfor ( $d = 0; $d < 90; $d++ ) {\n\t$date = gmdate( 'Y-m-d', $now - $d * DAY_IN_SECONDS );\n\t$ord_today = isset( $daily_orders[ $date ] ) ? $daily_orders[ $date ] : 0;\n\t$visitors = max( 40, $ord_today * $rnd( 25, 40 ) + $rnd( 30, 120 ) );\n\t$add_cart = (int) round( $visitors * ( $rnd( 25, 40 ) / 100 ) );\n\t$checkout = max( $ord_today, (int) round( $add_cart * ( $rnd( 35, 60 ) / 100 ) ) );\n\t$mobile = (int) round( $visitors * 0.55 ); $tablet = (int) round( $visitors * 0.10 ); $desktop = $visitors - $mobile - $tablet;\n\t$wpdb->insert( $vis_tbl, array(\n\t\t'date_column' => $date, 'visitor_count' => $visitors, 'product_count' => $rnd( 5, 12 ),\n\t\t'add_to_cart_count' => $add_cart, 'checkout_count' => $checkout,\n\t\t'mobile_count' => $mobile, 'tablet_count' => $tablet, 'desktop_count' => $desktop,\n\t) );\n\t$vis_rows++; $vis_sum += $visitors;\n}\n$diag['visitor_rows'] = $vis_rows; $diag['visitor_sum'] = $vis_sum;\n\nupdate_option( 'brikpanel_demo_seeded', 1, false );\n"
        },
        {
            "step": "login",
            "username": "admin",
            "password": "password"
        }
    ]
}