feat: vytvořit první verzi
This commit is contained in:
commit
eada9c6511
21 changed files with 4991 additions and 0 deletions
46
.gitignore
vendored
Normal file
46
.gitignore
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
# 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
|
||||
|
||||
node_modules
|
30
.metadata
Normal file
30
.metadata
Normal file
|
@ -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: 6928314d505d2bb4777be05e45d7808a5aa91d2a
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
||||
# Tracks metadata for the flutter migrate command
|
||||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: 6928314d505d2bb4777be05e45d7808a5aa91d2a
|
||||
base_revision: 6928314d505d2bb4777be05e45d7808a5aa91d2a
|
||||
- platform: web
|
||||
create_revision: 6928314d505d2bb4777be05e45d7808a5aa91d2a
|
||||
base_revision: 6928314d505d2bb4777be05e45d7808a5aa91d2a
|
||||
|
||||
# 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'
|
16
README.md
Normal file
16
README.md
Normal file
|
@ -0,0 +1,16 @@
|
|||
# pavouk
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
29
analysis_options.yaml
Normal file
29
analysis_options.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
# This file configures the analyzer, which statically analyzes Dart code to
|
||||
# check for errors, warnings, and lints.
|
||||
#
|
||||
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
|
||||
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
|
||||
# invoked from the command line by running `flutter analyze`.
|
||||
|
||||
# The following line activates a set of recommended lints for Flutter apps,
|
||||
# packages, and plugins designed to encourage good coding practices.
|
||||
include: package:flutter_lints/flutter.yaml
|
||||
|
||||
linter:
|
||||
# The lint rules applied to this project can be customized in the
|
||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||
# included above or to enable additional rules. A list of all available lints
|
||||
# and their documentation is published at
|
||||
# https://dart-lang.github.io/linter/lints/index.html.
|
||||
#
|
||||
# Instead of disabling a lint rule for the entire project in the
|
||||
# section below, it can also be suppressed for a single line of code
|
||||
# or a specific dart file by using the `// ignore: name_of_lint` and
|
||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||
# producing the lint.
|
||||
rules:
|
||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
||||
|
||||
# Additional information about this file can be found at
|
||||
# https://dart.dev/guides/language/analysis-options
|
27
lib/main.dart
Normal file
27
lib/main.dart
Normal file
|
@ -0,0 +1,27 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pavouk/okna/domov.dart';
|
||||
import 'package:responsive_sizer/responsive_sizer.dart';
|
||||
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
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 ResponsiveSizer(
|
||||
builder: (p0, p1, p2) => MaterialApp(
|
||||
title: 'Pavouk | subnetování',
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.red,
|
||||
),
|
||||
darkTheme: ThemeData.dark(),
|
||||
home: const DomovskaStrana(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
308
lib/okna/domov.dart
Normal file
308
lib/okna/domov.dart
Normal file
|
@ -0,0 +1,308 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:pavouk/okna/reseni.dart';
|
||||
import 'package:pavouk/util/appbar.dart';
|
||||
import 'package:pavouk/util/subnet_masky.dart';
|
||||
import 'package:pavouk/util/vzhled.dart';
|
||||
import 'package:responsive_sizer/responsive_sizer.dart';
|
||||
|
||||
class DomovskaStrana extends StatefulWidget {
|
||||
const DomovskaStrana({super.key});
|
||||
|
||||
@override
|
||||
State<DomovskaStrana> createState() => _DomovskaStranaState();
|
||||
}
|
||||
|
||||
class _DomovskaStranaState extends State<DomovskaStrana> {
|
||||
// proměnné pro řešitel
|
||||
var origoIp = "";
|
||||
var subnety = <int>[];
|
||||
var content = [];
|
||||
final _origoController = TextEditingController();
|
||||
|
||||
// proměnné pro generátor
|
||||
var pocetSubnetu = 0;
|
||||
var maxPocetRealnych = 0;
|
||||
var chytakovyMod = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
setState(() {
|
||||
generovatSubnetFieldy(3);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: bar(context),
|
||||
body: SingleChildScrollView(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width:
|
||||
(Device.orientation == Orientation.landscape) ? 45.w : 100.w,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
Text("Parametry pro generátor", style: Vzhled.nadpis),
|
||||
const SizedBox(height: 15),
|
||||
SizedBox(
|
||||
width: 20.w,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("Počet subnetů:",
|
||||
style: Vzhled.fieldNadpis),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Tooltip(
|
||||
message:
|
||||
"Maximální počet: ${Util.alphabet.length - 1}",
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value.isNotEmpty) {
|
||||
pocetSubnetu = int.parse(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("Max. počet reálných hostů:",
|
||||
style: Vzhled.fieldNadpis),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: TextField(
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.digitsOnly
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value.isNotEmpty) {
|
||||
maxPocetRealnych = int.parse(value);
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text("Chytákový režim:",
|
||||
style: Vzhled.fieldNadpis),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Tooltip(
|
||||
message:
|
||||
"Garantuje 20% šanci na subnet, který bude mít počet reálných hostů 64, 128 atp.",
|
||||
child: Checkbox(
|
||||
value: chytakovyMod,
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
chytakovyMod = value ?? false;
|
||||
});
|
||||
},
|
||||
))
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => generuj(),
|
||||
style: Vzhled.tlacitkoStyl,
|
||||
child: const Text(
|
||||
"Generuj příklad",
|
||||
style: Vzhled.tlacitkoText,
|
||||
)),
|
||||
const Divider(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"Parametry pro řešitel",
|
||||
style: Vzhled.nadpis,
|
||||
),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Zadaná (originální) síť:",
|
||||
style: Vzhled.fieldNadpis,
|
||||
),
|
||||
SizedBox(
|
||||
width: 30.w,
|
||||
child: TextField(
|
||||
onChanged: (value) {
|
||||
origoIp = value;
|
||||
},
|
||||
controller: _origoController,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
...content,
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
final chytaky = [64, 128, 32, 16, 8, 4];
|
||||
void generovatSubnetFieldy(int pocet, {List<int>? hodnoty}) {
|
||||
if (pocet > Util.alphabet.length - 1) return;
|
||||
content = [];
|
||||
subnety = hodnoty ?? [];
|
||||
for (var i = 0; i < pocet; i++) {
|
||||
if (subnety.length == i) subnety.add(40); // dummy hodnoty
|
||||
content.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
Util.alphabet[i],
|
||||
style: Vzhled.fieldNadpis,
|
||||
),
|
||||
SizedBox(
|
||||
width: 30.w,
|
||||
child: Tooltip(
|
||||
message: "Počet reálných hostů",
|
||||
child: TextField(
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
onChanged: (value) {
|
||||
subnety[i] = int.parse(value);
|
||||
},
|
||||
controller: TextEditingController(text: subnety[i].toString()),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
}
|
||||
content.add(const SizedBox(
|
||||
height: 30,
|
||||
));
|
||||
content.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text("Počet subnetů:", style: Vzhled.fieldNadpis),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
SizedBox(
|
||||
width: 100,
|
||||
child: Tooltip(
|
||||
message: "Maximální počet: ${Util.alphabet.length - 1}",
|
||||
child: TextField(
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
onChanged: (value) {
|
||||
if (value.isNotEmpty) {
|
||||
generovatSubnetFieldy(int.parse(value));
|
||||
}
|
||||
},
|
||||
controller: TextEditingController(text: pocet.toString()),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
));
|
||||
content.add(const SizedBox(
|
||||
height: 20,
|
||||
));
|
||||
content.add(
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
var checkIp =
|
||||
RegExp(r'(\d){1,3}\.(\d){1,3}\.(\d){1,3}\.(\d){1,3}\/\d{1,2}')
|
||||
.hasMatch(_origoController.text);
|
||||
if (!checkIp) {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"Nezadali jste platný tvar IP adresy a masky.",
|
||||
style: TextStyle(fontSize: 12.sp),
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (c) => Reseni(
|
||||
origoIp: _origoController.text, subnety: subnety)));
|
||||
},
|
||||
style: Vzhled.tlacitkoStyl,
|
||||
child: const Text(
|
||||
"Vyřešit příklad",
|
||||
style: Vzhled.tlacitkoText,
|
||||
)),
|
||||
);
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void generuj() {
|
||||
if (pocetSubnetu == 0 || maxPocetRealnych == 0) {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
"Nezadali jste platné údaje pro generátor.",
|
||||
style: TextStyle(fontSize: 12.sp),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
Random rnd = Random();
|
||||
// vytvořit zdrojovou IP
|
||||
var ip = "";
|
||||
for (var i = 0; i < 4; i++) {
|
||||
var p = rnd.nextInt(254) + 1;
|
||||
ip += p.toString();
|
||||
if (i != 3) ip += ".";
|
||||
}
|
||||
// vytvořit subnet data
|
||||
var subnetData = <int>[];
|
||||
for (var i = 0; i < pocetSubnetu; i++) {
|
||||
if (chytakovyMod) {
|
||||
var sance = rnd.nextInt(4) + 1;
|
||||
if (sance == 1) {
|
||||
subnetData.add(chytaky[rnd.nextInt(chytaky.length)]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
subnetData.add(rnd.nextInt(maxPocetRealnych) + 2);
|
||||
}
|
||||
// vložit
|
||||
_origoController.text = "$ip/22";
|
||||
generovatSubnetFieldy(pocetSubnetu, hodnoty: subnetData);
|
||||
}
|
||||
}
|
305
lib/okna/reseni.dart
Normal file
305
lib/okna/reseni.dart
Normal file
|
@ -0,0 +1,305 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:pavouk/util/appbar.dart';
|
||||
import 'package:pavouk/util/subnet_masky.dart';
|
||||
import 'package:pavouk/util/vzhled.dart';
|
||||
import 'package:responsive_sizer/responsive_sizer.dart';
|
||||
|
||||
class Reseni extends StatefulWidget {
|
||||
const Reseni({super.key, required this.origoIp, required this.subnety});
|
||||
final String origoIp;
|
||||
final List<int> subnety;
|
||||
|
||||
@override
|
||||
State<Reseni> createState() => _ReseniState();
|
||||
}
|
||||
|
||||
class _ReseniState extends State<Reseni> {
|
||||
var origoNetIP = "";
|
||||
var content = <TableRow>[
|
||||
TableRow(children: [
|
||||
TableCell(
|
||||
child: Text(
|
||||
"Název",
|
||||
style: Vzhled.text,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Požadovaný počet zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Reálný počet zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa sítě",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Prefix masky",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa prvního zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa posledního zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa broadcastu",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
])
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
var p = widget.origoIp.split("/");
|
||||
var nm = p[1];
|
||||
origoNetIP = "${Util.ipToNetworkAdd(p[0], Util.prefixToMask(nm))}/$nm";
|
||||
for (var i = 0; i < widget.subnety.length; i++) {
|
||||
content.add(TableRow(children: [
|
||||
TableCell(
|
||||
child: Text(Util.alphabet[i],
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child:
|
||||
Text(widget.subnety[i].toString(), textAlign: TextAlign.center),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
const TableCell(
|
||||
child: SizedBox(height: 50),
|
||||
),
|
||||
]));
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: bar(context, i: 1),
|
||||
body: SingleChildScrollView(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: (Device.orientation == Orientation.landscape) ? 90.w : 100.w,
|
||||
height: 100.h,
|
||||
child:
|
||||
Column(mainAxisAlignment: MainAxisAlignment.center, children: [
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => ukaz(),
|
||||
style: Vzhled.tlacitkoStyl,
|
||||
child: const Text(
|
||||
"Ukázat řešení",
|
||||
style: Vzhled.tlacitkoText,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 30,
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
Text(
|
||||
"Zadaná IP:",
|
||||
style: Vzhled.tableContent,
|
||||
),
|
||||
const SizedBox(
|
||||
width: 20,
|
||||
),
|
||||
Text(origoNetIP, style: Vzhled.tableContent)
|
||||
],
|
||||
),
|
||||
DefaultTextStyle(
|
||||
style: Vzhled.tableContent,
|
||||
child: Expanded(
|
||||
child: Table(
|
||||
border: TableBorder.all(),
|
||||
defaultVerticalAlignment: TableCellVerticalAlignment.middle,
|
||||
defaultColumnWidth: FixedColumnWidth(
|
||||
Device.orientation == Orientation.landscape
|
||||
? 90.w / 8
|
||||
: 100.w / 8),
|
||||
children: content,
|
||||
),
|
||||
),
|
||||
)
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void ukaz() {
|
||||
// Resetovat obsah
|
||||
content = <TableRow>[
|
||||
TableRow(children: [
|
||||
TableCell(
|
||||
child: Text(
|
||||
"Název",
|
||||
style: Vzhled.text,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Požadovaný počet zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Reálný počet zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa sítě",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Prefix masky",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa prvního zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa posledního zařízení",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text("Adresa broadcastu",
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
])
|
||||
];
|
||||
|
||||
// seřazení
|
||||
var kopie = [];
|
||||
kopie.addAll(widget.subnety);
|
||||
widget.subnety.sort((a, b) => b.compareTo(a));
|
||||
|
||||
var iplist = [];
|
||||
for (var i = 0; i < widget.subnety.length; i++) {
|
||||
var sub = Util.subnety(); // načíst možné subnet masky
|
||||
var ip = "";
|
||||
if (i == 0) {
|
||||
ip = origoNetIP.split("/")[0]; // na začátku nastavíme OG adresu
|
||||
} else {
|
||||
ip = zvysitIp(iplist[i -
|
||||
1]); // jinak nastavujeme předchozí adresu broadcastu o jedno větší
|
||||
}
|
||||
|
||||
var prefix = sub.where((element) {
|
||||
var id = sub.indexOf(element);
|
||||
bool levo, pravo = false;
|
||||
// kontrolujeme, že zleva i zprava nejsou lepší hodnoty
|
||||
if (id > 0) {
|
||||
levo = (sub[id - 1]["hosti"]! - 2 <= widget.subnety[i]);
|
||||
} else {
|
||||
levo = true;
|
||||
}
|
||||
if (id < widget.subnety.length - 1) {
|
||||
pravo = (sub[id + 1]["hosti"]! - 2 >= widget.subnety[i]);
|
||||
} else {
|
||||
pravo = true;
|
||||
}
|
||||
if (levo && pravo) {
|
||||
return sub[id]["hosti"]! - 2 >=
|
||||
widget.subnety[
|
||||
i]; // a zkontrolujeme že naše samotná hodnota je dostatečná
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}).toList()[0];
|
||||
|
||||
var prvni = zvysitIp(ip);
|
||||
var posledni = zvysitIp(ip);
|
||||
for (var j = 0; j < prefix["hosti"]! - 3; j++) {
|
||||
posledni = zvysitIp(posledni);
|
||||
}
|
||||
var broadcast = zvysitIp(posledni);
|
||||
iplist.add(broadcast);
|
||||
|
||||
content.add(TableRow(children: [
|
||||
TableCell(
|
||||
child: Text(Util.alphabet[kopie.indexOf(widget.subnety[i])],
|
||||
style: Vzhled.text, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text(
|
||||
widget.subnety[i].toString(),
|
||||
textAlign: TextAlign.center,
|
||||
)),
|
||||
TableCell(
|
||||
child: Text((prefix["hosti"]! - 2).toString(),
|
||||
textAlign: TextAlign.center)),
|
||||
TableCell(
|
||||
child: Text(ip, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child:
|
||||
Text(prefix["prefix"]!.toString(), textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text(prvni, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text(posledni, textAlign: TextAlign.center),
|
||||
),
|
||||
TableCell(
|
||||
child: Text(broadcast, textAlign: TextAlign.center),
|
||||
),
|
||||
]));
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
String zvysitIp(String ip) {
|
||||
var p = ip.split(".");
|
||||
var p1 = int.parse(p[0]);
|
||||
var p2 = int.parse(p[1]);
|
||||
var p3 = int.parse(p[2]);
|
||||
var p4 = int.parse(p[3]);
|
||||
if (p4 == 255) {
|
||||
if (p3 == 255) {
|
||||
if (p2 == 255) {
|
||||
p1++;
|
||||
p2 = 0;
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
} else {
|
||||
p2++;
|
||||
p3 = 0;
|
||||
p4 = 0;
|
||||
}
|
||||
} else {
|
||||
p3++;
|
||||
p4 = 0;
|
||||
}
|
||||
} else {
|
||||
p4++;
|
||||
}
|
||||
return "$p1.$p2.$p3.$p4";
|
||||
}
|
||||
}
|
21
lib/util/appbar.dart
Normal file
21
lib/util/appbar.dart
Normal file
|
@ -0,0 +1,21 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
|
||||
AppBar bar(BuildContext context, {int i = 0}) => AppBar(
|
||||
title: const Text('Pavouk - generátor příkladů pro výuku subnetování'),
|
||||
centerTitle: true,
|
||||
backgroundColor: Colors.red,
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.info_outline),
|
||||
onPressed: () {
|
||||
PackageInfo.fromPlatform().then((v) => showAboutDialog(
|
||||
context: context,
|
||||
applicationName: "Pavouk",
|
||||
applicationVersion: v.version,
|
||||
applicationLegalese:
|
||||
"© 2022 Matyáš Caras\nVydáno pod licencí GNU AGPLv3\nVěnováno SŠTE Brno, Olomoucká"));
|
||||
},
|
||||
)
|
||||
],
|
||||
);
|
77
lib/util/subnet_masky.dart
Normal file
77
lib/util/subnet_masky.dart
Normal file
|
@ -0,0 +1,77 @@
|
|||
import 'dart:math';
|
||||
|
||||
class Util {
|
||||
static List<Map<String, int>> subnety() {
|
||||
var list = <Map<String, int>>[
|
||||
{
|
||||
"prefix": 30,
|
||||
"hosti": 4,
|
||||
}
|
||||
];
|
||||
for (int i = 30; i > 8; i--) {
|
||||
list.add({"prefix": i - 1, "hosti": list[30 - i]["hosti"]! * 2});
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static List<String> _strToBin(String input) {
|
||||
var list = <String>[];
|
||||
input.split(".").forEach((numero) {
|
||||
print(numero);
|
||||
var bin = int.parse(numero).toRadixString(2);
|
||||
while (bin.length < 8) {
|
||||
bin = "0$bin";
|
||||
}
|
||||
print(bin);
|
||||
list.add(bin);
|
||||
});
|
||||
return list;
|
||||
}
|
||||
|
||||
static List<String> _binToStr(List<String> input) {
|
||||
var list = <String>[];
|
||||
for (var numero in input) {
|
||||
list.add(int.parse(numero, radix: 2).toString());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
static String prefixToMask(String prefix) {
|
||||
var bin = "1" * int.parse(prefix);
|
||||
while (bin.length < 32) {
|
||||
bin += "0";
|
||||
}
|
||||
var match = RegExp(r"\d{8}").allMatches(bin);
|
||||
return _binToStr(match
|
||||
.map(
|
||||
(e) => e.group(0)!,
|
||||
)
|
||||
.toList())
|
||||
.join(".");
|
||||
}
|
||||
|
||||
static String ipToNetworkAdd(String ip, String nm) {
|
||||
var nmBin = _strToBin(nm);
|
||||
print(nmBin);
|
||||
var ipBin = _strToBin(ip);
|
||||
print(ipBin);
|
||||
|
||||
var networkAdd = <String>[];
|
||||
for (int i = 0; i < 4; i++) {
|
||||
var nmBinChar = nmBin[i].split("");
|
||||
var ipBinChar = ipBin[i].split("");
|
||||
var networkAddChar = <String>[];
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (nmBinChar[j] == "1" && ipBinChar[j] == "1") {
|
||||
networkAddChar.add(ipBinChar[j]);
|
||||
} else {
|
||||
networkAddChar.add("0");
|
||||
}
|
||||
}
|
||||
networkAdd.add(networkAddChar.join());
|
||||
}
|
||||
return _binToStr(networkAdd).join(".");
|
||||
}
|
||||
|
||||
static const String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
}
|
18
lib/util/vzhled.dart
Normal file
18
lib/util/vzhled.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:responsive_sizer/responsive_sizer.dart';
|
||||
|
||||
class Vzhled {
|
||||
static final TextStyle nadpis = TextStyle(
|
||||
fontSize: 16.sp,
|
||||
fontWeight: FontWeight.bold,
|
||||
);
|
||||
|
||||
static final TextStyle fieldNadpis =
|
||||
TextStyle(fontWeight: FontWeight.bold, fontSize: 12.sp);
|
||||
|
||||
static const TextStyle tlacitkoText = TextStyle(color: Colors.white);
|
||||
static final ButtonStyle tlacitkoStyl =
|
||||
ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.red));
|
||||
static final TextStyle text = TextStyle(fontSize: 13.sp);
|
||||
static final TextStyle tableContent = TextStyle(fontSize: 11.sp);
|
||||
}
|
3715
package-lock.json
generated
Normal file
3715
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
10
package.json
Normal file
10
package.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"devDependencies": {
|
||||
"cz-conventional-changelog": "^3.3.0"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "./node_modules/cz-conventional-changelog"
|
||||
}
|
||||
}
|
||||
}
|
229
pubspec.lock
Normal file
229
pubspec.lock
Normal file
|
@ -0,0 +1,229 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.9.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.13.5"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "4.0.2"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.6.4"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.12.12"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.0.1"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.8.2"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
responsive_sizer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: responsive_sizer
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.1.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.99"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "0.4.12"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
sdks:
|
||||
dart: ">=2.18.2 <3.0.0"
|
||||
flutter: ">=2.11.0"
|
67
pubspec.yaml
Normal file
67
pubspec.yaml
Normal file
|
@ -0,0 +1,67 @@
|
|||
name: pavouk
|
||||
description: Generátor příkladu k výuce subnetování
|
||||
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
version: 1.0.0+1
|
||||
|
||||
environment:
|
||||
sdk: '>=2.18.2 <3.0.0'
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
package_info_plus: ^3.0.1
|
||||
responsive_sizer: ^3.1.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
# The "flutter_lints" package below contains a set of recommended lints to
|
||||
# encourage good coding practices. The lint set provided by the package is
|
||||
# activated in the `analysis_options.yaml` file located at the root of your
|
||||
# package. See that file for information about deactivating specific lint
|
||||
# rules and activating additional ones.
|
||||
flutter_lints: ^2.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
|
||||
# The following line ensures that the Material Icons font is
|
||||
# included with your application, so that you can use the icons in
|
||||
# the material Icons class.
|
||||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - images/a_dot_burr.jpeg
|
||||
# - images/a_dot_ham.jpeg
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
||||
# For details regarding adding assets from package dependencies, see
|
||||
# https://flutter.dev/assets-and-images/#from-packages
|
||||
|
||||
# To add custom fonts to your application, add a fonts section here,
|
||||
# in this "flutter" section. Each entry in this list should have a
|
||||
# "family" key with the font family name, and a "fonts" key with a
|
||||
# list giving the asset and other descriptors for the font. For
|
||||
# example:
|
||||
# fonts:
|
||||
# - family: Schyler
|
||||
# fonts:
|
||||
# - asset: fonts/Schyler-Regular.ttf
|
||||
# - asset: fonts/Schyler-Italic.ttf
|
||||
# style: italic
|
||||
# - family: Trajan Pro
|
||||
# fonts:
|
||||
# - asset: fonts/TrajanPro.ttf
|
||||
# - asset: fonts/TrajanPro_Bold.ttf
|
||||
# weight: 700
|
||||
#
|
||||
# For details regarding fonts from package dependencies,
|
||||
# see https://flutter.dev/custom-fonts/#from-packages
|
BIN
web/favicon.png
Normal file
BIN
web/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 917 B |
BIN
web/icons/Icon-192.png
Normal file
BIN
web/icons/Icon-192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
BIN
web/icons/Icon-512.png
Normal file
BIN
web/icons/Icon-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
web/icons/Icon-maskable-192.png
Normal file
BIN
web/icons/Icon-maskable-192.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.5 KiB |
BIN
web/icons/Icon-maskable-512.png
Normal file
BIN
web/icons/Icon-maskable-512.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
58
web/index.html
Normal file
58
web/index.html
Normal file
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<!--
|
||||
If you are serving your web app in a path other than the root, change the
|
||||
href value below to reflect the base path you are serving from.
|
||||
|
||||
The path provided below has to start and end with a slash "/" in order for
|
||||
it to work correctly.
|
||||
|
||||
For more details:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
|
||||
|
||||
This is a placeholder for base href that will be replaced by the value of
|
||||
the `--base-href` argument provided to `flutter build`.
|
||||
-->
|
||||
<base href="$FLUTTER_BASE_HREF">
|
||||
|
||||
<meta charset="UTF-8">
|
||||
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
|
||||
<meta name="description" content="A new Flutter project.">
|
||||
|
||||
<!-- iOS meta tags & icons -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="pavouk">
|
||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
||||
|
||||
<title>pavouk</title>
|
||||
<link rel="manifest" href="manifest.json">
|
||||
|
||||
<script>
|
||||
// The value below is injected by flutter build, do not touch.
|
||||
var serviceWorkerVersion = null;
|
||||
</script>
|
||||
<!-- This script adds the flutter initialization JS code -->
|
||||
<script src="flutter.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
window.addEventListener('load', function(ev) {
|
||||
// Download main.dart.js
|
||||
_flutter.loader.loadEntrypoint({
|
||||
serviceWorker: {
|
||||
serviceWorkerVersion: serviceWorkerVersion,
|
||||
}
|
||||
}).then(function(engineInitializer) {
|
||||
return engineInitializer.initializeEngine();
|
||||
}).then(function(appRunner) {
|
||||
return appRunner.runApp();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
35
web/manifest.json
Normal file
35
web/manifest.json
Normal file
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "pavouk",
|
||||
"short_name": "pavouk",
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"background_color": "#0175C2",
|
||||
"theme_color": "#0175C2",
|
||||
"description": "A new Flutter project.",
|
||||
"orientation": "portrait-primary",
|
||||
"prefer_related_applications": false,
|
||||
"icons": [
|
||||
{
|
||||
"src": "icons/Icon-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
},
|
||||
{
|
||||
"src": "icons/Icon-maskable-512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png",
|
||||
"purpose": "maskable"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in a new issue