diff --git a/multi_dimensional_flavors/.gitignore b/multi_dimensional_flavors/.gitignore
new file mode 100644
index 0000000..24476c5
--- /dev/null
+++ b/multi_dimensional_flavors/.gitignore
@@ -0,0 +1,44 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.packages
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/multi_dimensional_flavors/.metadata b/multi_dimensional_flavors/.metadata
new file mode 100644
index 0000000..bf1faef
--- /dev/null
+++ b/multi_dimensional_flavors/.metadata
@@ -0,0 +1,30 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled.
+
+version:
+ revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ channel: stable
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ - platform: ios
+ create_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+ base_revision: f468f3366c26a5092eb964a230ce7892fda8f2f8
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/multi_dimensional_flavors/README.md b/multi_dimensional_flavors/README.md
new file mode 100644
index 0000000..995f9fc
--- /dev/null
+++ b/multi_dimensional_flavors/README.md
@@ -0,0 +1,3 @@
+# multi dimensional flavors
+
+A similar sample as the [flavors](../flavors), but which includes multiple dimensional flavors on android.
diff --git a/multi_dimensional_flavors/analysis_options.yaml b/multi_dimensional_flavors/analysis_options.yaml
new file mode 100644
index 0000000..f9b3034
--- /dev/null
+++ b/multi_dimensional_flavors/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:flutter_lints/flutter.yaml
diff --git a/multi_dimensional_flavors/android/.gitignore b/multi_dimensional_flavors/android/.gitignore
new file mode 100644
index 0000000..6f56801
--- /dev/null
+++ b/multi_dimensional_flavors/android/.gitignore
@@ -0,0 +1,13 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/multi_dimensional_flavors/android/app/build.gradle b/multi_dimensional_flavors/android/app/build.gradle
new file mode 100644
index 0000000..f027994
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/build.gradle
@@ -0,0 +1,97 @@
+plugins {
+ id "com.android.application"
+ id "kotlin-android"
+ id "dev.flutter.flutter-gradle-plugin"
+}
+
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+ localPropertiesFile.withReader('UTF-8') { reader ->
+ localProperties.load(reader)
+ }
+}
+
+def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
+if (flutterVersionCode == null) {
+ flutterVersionCode = '1'
+}
+
+def flutterVersionName = localProperties.getProperty('flutter.versionName')
+if (flutterVersionName == null) {
+ flutterVersionName = '1.0'
+}
+
+android {
+ namespace "com.example.flavors"
+ compileSdkVersion flutter.compileSdkVersion
+ ndkVersion flutter.ndkVersion
+
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_1_8
+ targetCompatibility JavaVersion.VERSION_1_8
+ }
+
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+
+ sourceSets {
+ main.java.srcDirs += 'src/main/kotlin'
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId "com.example.flavors"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
+ minSdkVersion flutter.minSdkVersion
+ targetSdkVersion flutter.targetSdkVersion
+ versionCode flutterVersionCode.toInteger()
+ versionName flutterVersionName
+ }
+
+ flavorDimensions "track", "country"
+ productFlavors {
+ internal {
+ dimension "track"
+ applicationIdSuffix ".internal"
+ manifestPlaceholders = [applicationLabel: "[Internal] Shorebird Example"]
+ }
+ stable {
+ dimension "track"
+ manifestPlaceholders = [applicationLabel: "Shorebird Example"]
+ }
+ global {
+ applicationIdSuffix ".gl"
+ dimension "country"
+ manifestPlaceholders = [applicationLabel: "Shorebird Example"]
+ }
+ playStore {
+ applicationIdSuffix ".pl"
+ dimension "country"
+ manifestPlaceholders = [applicationLabel: "Shorebird Example"]
+ }
+ local {
+ applicationIdSuffix ".lcl"
+ dimension "country"
+ manifestPlaceholders = [applicationLabel: "Shorebird Example"]
+ }
+ }
+
+ buildTypes {
+ release {
+ // TODO: Add your own signing config for the release build.
+ // Signing with the debug keys for now, so `flutter run --release` works.
+ signingConfig signingConfigs.debug
+ }
+ }
+}
+
+flutter {
+ source '../..'
+}
+
+dependencies {
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.10"
+}
diff --git a/multi_dimensional_flavors/android/app/src/debug/AndroidManifest.xml b/multi_dimensional_flavors/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..399f698
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/multi_dimensional_flavors/android/app/src/main/AndroidManifest.xml b/multi_dimensional_flavors/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..17ebfc2
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/multi_dimensional_flavors/android/app/src/main/kotlin/com/example/flavors/MainActivity.kt b/multi_dimensional_flavors/android/app/src/main/kotlin/com/example/flavors/MainActivity.kt
new file mode 100644
index 0000000..8bcb912
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/kotlin/com/example/flavors/MainActivity.kt
@@ -0,0 +1,6 @@
+package com.example.flavors
+
+import io.flutter.embedding.android.FlutterActivity
+
+class MainActivity: FlutterActivity() {
+}
diff --git a/multi_dimensional_flavors/android/app/src/main/res/drawable-v21/launch_background.xml b/multi_dimensional_flavors/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 0000000..f74085f
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/multi_dimensional_flavors/android/app/src/main/res/drawable/launch_background.xml b/multi_dimensional_flavors/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000..304732f
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/multi_dimensional_flavors/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/multi_dimensional_flavors/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..db77bb4
Binary files /dev/null and b/multi_dimensional_flavors/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/multi_dimensional_flavors/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/multi_dimensional_flavors/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..17987b7
Binary files /dev/null and b/multi_dimensional_flavors/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/multi_dimensional_flavors/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..09d4391
Binary files /dev/null and b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..d5f1c8d
Binary files /dev/null and b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..4d6372e
Binary files /dev/null and b/multi_dimensional_flavors/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/multi_dimensional_flavors/android/app/src/main/res/values-night/styles.xml b/multi_dimensional_flavors/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000..06952be
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/multi_dimensional_flavors/android/app/src/main/res/values/styles.xml b/multi_dimensional_flavors/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..cb1ef88
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/multi_dimensional_flavors/android/app/src/profile/AndroidManifest.xml b/multi_dimensional_flavors/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000..399f698
--- /dev/null
+++ b/multi_dimensional_flavors/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/multi_dimensional_flavors/android/build.gradle b/multi_dimensional_flavors/android/build.gradle
new file mode 100644
index 0000000..bc157bd
--- /dev/null
+++ b/multi_dimensional_flavors/android/build.gradle
@@ -0,0 +1,18 @@
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+rootProject.buildDir = '../build'
+subprojects {
+ project.buildDir = "${rootProject.buildDir}/${project.name}"
+}
+subprojects {
+ project.evaluationDependsOn(':app')
+}
+
+tasks.register("clean", Delete) {
+ delete rootProject.buildDir
+}
diff --git a/multi_dimensional_flavors/android/gradle.properties b/multi_dimensional_flavors/android/gradle.properties
new file mode 100644
index 0000000..94adc3a
--- /dev/null
+++ b/multi_dimensional_flavors/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx1536M
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/multi_dimensional_flavors/android/gradle/wrapper/gradle-wrapper.properties b/multi_dimensional_flavors/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..3c472b9
--- /dev/null
+++ b/multi_dimensional_flavors/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
diff --git a/multi_dimensional_flavors/android/settings.gradle b/multi_dimensional_flavors/android/settings.gradle
new file mode 100644
index 0000000..536165d
--- /dev/null
+++ b/multi_dimensional_flavors/android/settings.gradle
@@ -0,0 +1,25 @@
+pluginManagement {
+ def flutterSdkPath = {
+ def properties = new Properties()
+ file("local.properties").withInputStream { properties.load(it) }
+ def flutterSdkPath = properties.getProperty("flutter.sdk")
+ assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
+ return flutterSdkPath
+ }()
+
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
+
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+plugins {
+ id "dev.flutter.flutter-plugin-loader" version "1.0.0"
+ id "com.android.application" version "7.3.0" apply false
+ id "org.jetbrains.kotlin.android" version "1.7.10" apply false
+}
+
+include ":app"
diff --git a/multi_dimensional_flavors/lib/main.dart b/multi_dimensional_flavors/lib/main.dart
new file mode 100644
index 0000000..dda5554
--- /dev/null
+++ b/multi_dimensional_flavors/lib/main.dart
@@ -0,0 +1,125 @@
+import 'package:flutter/material.dart';
+
+void main() {
+ runApp(const MyApp());
+}
+
+class MyApp extends StatelessWidget {
+ const MyApp({super.key});
+
+ // This widget is the root of your application.
+ @override
+ Widget build(BuildContext context) {
+ return MaterialApp(
+ title: 'Flutter Demo',
+ theme: ThemeData(
+ // This is the theme of your application.
+ //
+ // TRY THIS: Try running your application with "flutter run". You'll see
+ // the application has a blue toolbar. Then, without quitting the app,
+ // try changing the seedColor in the colorScheme below to Colors.green
+ // and then invoke "hot reload" (save your changes or press the "hot
+ // reload" button in a Flutter-supported IDE, or press "r" if you used
+ // the command line to start the app).
+ //
+ // Notice that the counter didn't reset back to zero; the application
+ // state is not lost during the reload. To reset the state, use hot
+ // restart instead.
+ //
+ // This works for code too, not just values: Most code changes can be
+ // tested with just a hot reload.
+ colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
+ useMaterial3: true,
+ ),
+ home: const MyHomePage(title: 'Flutter Demo Home Page'),
+ );
+ }
+}
+
+class MyHomePage extends StatefulWidget {
+ const MyHomePage({super.key, required this.title});
+
+ // This widget is the home page of your application. It is stateful, meaning
+ // that it has a State object (defined below) that contains fields that affect
+ // how it looks.
+
+ // This class is the configuration for the state. It holds the values (in this
+ // case the title) provided by the parent (in this case the App widget) and
+ // used by the build method of the State. Fields in a Widget subclass are
+ // always marked "final".
+
+ final String title;
+
+ @override
+ State createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State {
+ int _counter = 0;
+
+ void _incrementCounter() {
+ setState(() {
+ // This call to setState tells the Flutter framework that something has
+ // changed in this State, which causes it to rerun the build method below
+ // so that the display can reflect the updated values. If we changed
+ // _counter without calling setState(), then the build method would not be
+ // called again, and so nothing would appear to happen.
+ _counter++;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ // This method is rerun every time setState is called, for instance as done
+ // by the _incrementCounter method above.
+ //
+ // The Flutter framework has been optimized to make rerunning build methods
+ // fast, so that you can just rebuild anything that needs updating rather
+ // than having to individually change instances of widgets.
+ return Scaffold(
+ appBar: AppBar(
+ // TRY THIS: Try changing the color here to a specific color (to
+ // Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
+ // change color while the other colors stay the same.
+ backgroundColor: Theme.of(context).colorScheme.inversePrimary,
+ // Here we take the value from the MyHomePage object that was created by
+ // the App.build method, and use it to set our appbar title.
+ title: Text(widget.title),
+ ),
+ body: Center(
+ // Center is a layout widget. It takes a single child and positions it
+ // in the middle of the parent.
+ child: Column(
+ // Column is also a layout widget. It takes a list of children and
+ // arranges them vertically. By default, it sizes itself to fit its
+ // children horizontally, and tries to be as tall as its parent.
+ //
+ // Column has various properties to control how it sizes itself and
+ // how it positions its children. Here we use mainAxisAlignment to
+ // center the children vertically; the main axis here is the vertical
+ // axis because Columns are vertical (the cross axis would be
+ // horizontal).
+ //
+ // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
+ // action in the IDE, or press "p" in the console), to see the
+ // wireframe for each widget.
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ const Text(
+ 'You have pushed the button this many times:',
+ ),
+ Text(
+ '$_counter',
+ style: Theme.of(context).textTheme.headlineMedium,
+ ),
+ ],
+ ),
+ ),
+ floatingActionButton: FloatingActionButton(
+ onPressed: _incrementCounter,
+ tooltip: 'Increment',
+ child: const Icon(Icons.add),
+ ), // This trailing comma makes auto-formatting nicer for build methods.
+ );
+ }
+}
diff --git a/multi_dimensional_flavors/pubspec.lock b/multi_dimensional_flavors/pubspec.lock
new file mode 100644
index 0000000..3882800
--- /dev/null
+++ b/multi_dimensional_flavors/pubspec.lock
@@ -0,0 +1,71 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.3.0"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.18.0"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: "6b0206b0bf4f04961fc5438198ccb3a885685cd67d4d4a32cc20ad7f8adbe015"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.8.0"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.11.0"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.99"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.4"
+sdks:
+ dart: ">=3.2.0-0 <4.0.0"
diff --git a/multi_dimensional_flavors/pubspec.yaml b/multi_dimensional_flavors/pubspec.yaml
new file mode 100644
index 0000000..7b80881
--- /dev/null
+++ b/multi_dimensional_flavors/pubspec.yaml
@@ -0,0 +1,20 @@
+name: multi_dimensioanl_flavors
+description: A Shorebird app which contains multiple, multi dimensional flavors on Android.
+publish_to: "none"
+
+version: 1.0.0+1
+
+environment:
+ sdk: ">=3.0.1 <4.0.0"
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+dev_dependencies:
+ flutter_lints: ^2.0.0
+
+flutter:
+ assets:
+ - shorebird.yaml
+ uses-material-design: true
diff --git a/multi_dimensional_flavors/shorebird.yaml b/multi_dimensional_flavors/shorebird.yaml
new file mode 100644
index 0000000..587b745
--- /dev/null
+++ b/multi_dimensional_flavors/shorebird.yaml
@@ -0,0 +1,21 @@
+# This file is used to configure the Shorebird updater used by your app.
+# Learn more at https://docs.shorebird.dev
+# This file should be checked into version control.
+
+# This is the unique identifier assigned to your app.
+# Your app_id is not a secret and is just used to identify your app
+# when requesting patches from Shorebird's servers.
+app_id: 5171ee3d-1a4d-4bdd-91c3-64cef78fe41c
+flavors:
+ internalGlobal: 5487a0d3-8c5a-4178-86ef-5295588e89bd
+ internalLocal: acb850fb-a9e3-45fb-86c0-705bb265d1e4
+ internalPlayStore: c8cfaff9-d94e-4767-9055-50c4f0b25ddd
+ stableGlobal: 6ceb59f3-8d0e-45c2-965d-6bf554f331d0
+ stableLocal: d9f3396e-f503-45f9-bb05-7ac5d4b060b0
+ stablePlayStore: ca70dd3f-7357-4a04-bb77-4d6fe38a15b1
+
+# auto_update controls if Shorebird should automatically update in the background on launch.
+# If auto_update: false, you will need to use package:shorebird_code_push to trigger updates.
+# https://pub.dev/packages/shorebird_code_push
+# Uncomment the following line to disable automatic updates.
+# auto_update: false