stuff
This commit is contained in:
51
flake.lock
generated
51
flake.lock
generated
@@ -1,5 +1,21 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"base16-schemes": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696158499,
|
||||||
|
"narHash": "sha256-5yIHgDTPjoX/3oDEfLSQ0eJZdFL1SaCfb9d6M0RmOTM=",
|
||||||
|
"owner": "tinted-theming",
|
||||||
|
"repo": "base16-schemes",
|
||||||
|
"rev": "a9112eaae86d9dd8ee6bb9445b664fba2f94037a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "tinted-theming",
|
||||||
|
"repo": "base16-schemes",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"disko": {
|
"disko": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -426,6 +442,25 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nix-colors": {
|
||||||
|
"inputs": {
|
||||||
|
"base16-schemes": "base16-schemes",
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1707825078,
|
||||||
|
"narHash": "sha256-hTfge2J2W+42SZ7VHXkf4kjU+qzFqPeC9k66jAUBMHk=",
|
||||||
|
"owner": "Misterio77",
|
||||||
|
"repo": "nix-colors",
|
||||||
|
"rev": "b01f024090d2c4fc3152cd0cf12027a7b8453ba1",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Misterio77",
|
||||||
|
"repo": "nix-colors",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix-formatter-pack": {
|
"nix-formatter-pack": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
@@ -585,6 +620,21 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1697935651,
|
||||||
|
"narHash": "sha256-qOfWjQ2JQSQL15KLh6D7xQhx0qgZlYZTYlcEiRuAMMw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "e1e11fdbb01113d85c7f41cada9d2847660e3902",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1755852287,
|
"lastModified": 1755852287,
|
||||||
@@ -765,6 +815,7 @@
|
|||||||
"impermanence": "impermanence",
|
"impermanence": "impermanence",
|
||||||
"jovian-unstable": "jovian-unstable",
|
"jovian-unstable": "jovian-unstable",
|
||||||
"most-winningest": "most-winningest",
|
"most-winningest": "most-winningest",
|
||||||
|
"nix-colors": "nix-colors",
|
||||||
"nix-on-droid": "nix-on-droid",
|
"nix-on-droid": "nix-on-droid",
|
||||||
"nixos-apple-silicon-unstable": "nixos-apple-silicon-unstable",
|
"nixos-apple-silicon-unstable": "nixos-apple-silicon-unstable",
|
||||||
"nixos-hardware": "nixos-hardware",
|
"nixos-hardware": "nixos-hardware",
|
||||||
|
13
flake.nix
13
flake.nix
@@ -96,6 +96,8 @@
|
|||||||
lib = import "${nixpkgs}/lib";
|
lib = import "${nixpkgs}/lib";
|
||||||
overlays = import ./overlays;
|
overlays = import ./overlays;
|
||||||
vacuModules = import ./modules;
|
vacuModules = import ./modules;
|
||||||
|
mkVaculib = { pkgs }: import ./vaculib { inherit pkgs; nix-colors-lib = allInputs.nix-colors.lib; };
|
||||||
|
vaculib = mkVaculib { inherit pkgs; };
|
||||||
defaultSuffixedInputNames = [
|
defaultSuffixedInputNames = [
|
||||||
"nixvim"
|
"nixvim"
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
@@ -144,7 +146,7 @@
|
|||||||
pkgsUnstable = mkPkgs { unstable = true; inherit system; };
|
pkgsUnstable = mkPkgs { unstable = true; inherit system; };
|
||||||
pkgs = if unstable then pkgsUnstable else pkgsStable;
|
pkgs = if unstable then pkgsUnstable else pkgsStable;
|
||||||
inputs = mkInputs { inherit unstable inp; };
|
inputs = mkInputs { inherit unstable inp; };
|
||||||
vaculib = import ./vaculib { inherit pkgs; };
|
vaculib = mkVaculib { inherit pkgs; };
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
inherit pkgs pkgsStable pkgsUnstable inputs vaculib;
|
inherit pkgs pkgsStable pkgsUnstable inputs vaculib;
|
||||||
@@ -176,7 +178,6 @@
|
|||||||
in
|
in
|
||||||
inner.config.vacu.withAsserts inner;
|
inner.config.vacu.withAsserts inner;
|
||||||
pkgs = mkPkgs x86;
|
pkgs = mkPkgs x86;
|
||||||
vaculib = import ./vaculib { inherit lib pkgs; nix-colors-lib = allInputs.nix-colors.lib; };
|
|
||||||
mkNixosConfig =
|
mkNixosConfig =
|
||||||
{
|
{
|
||||||
unstable ? false,
|
unstable ? false,
|
||||||
@@ -396,14 +397,6 @@
|
|||||||
// (allInputs.flake-utils.lib.eachDefaultSystem (
|
// (allInputs.flake-utils.lib.eachDefaultSystem (
|
||||||
system:
|
system:
|
||||||
let
|
let
|
||||||
# nixpkgs-args = {
|
|
||||||
# inherit system;
|
|
||||||
# config.allowUnfree = true;
|
|
||||||
# overlays = [ inputs.sm64baserom.overlays.default ];
|
|
||||||
# };
|
|
||||||
# pkgs-unstable = mkPkgs (nixpkgs-args // { useUnstable = true; });
|
|
||||||
# pkgs-stable = mkPkgs (nixpkgs-args // { useUnstable = false; });
|
|
||||||
# vaculib = import ./vaculib { pkgs = pkgs-stable; };
|
|
||||||
mkNixvim =
|
mkNixvim =
|
||||||
{ unstable, minimal }:
|
{ unstable, minimal }:
|
||||||
let
|
let
|
||||||
|
240
vaculib/ip.nix
240
vaculib/ip.nix
@@ -18,6 +18,9 @@ let
|
|||||||
isHexDigits =
|
isHexDigits =
|
||||||
str:
|
str:
|
||||||
(builtins.match ''[0-9a-fA-F]+'' str) != null;
|
(builtins.match ''[0-9a-fA-F]+'' str) != null;
|
||||||
|
isIPAny =
|
||||||
|
obj:
|
||||||
|
lib.isAttrs obj && (obj._type or null) == "com.shelvacu.nix.ip";
|
||||||
mkVersionDataCore =
|
mkVersionDataCore =
|
||||||
{
|
{
|
||||||
segmentCount,
|
segmentCount,
|
||||||
@@ -43,6 +46,9 @@ let
|
|||||||
(ipToStringCore obj)
|
(ipToStringCore obj)
|
||||||
++ lib.optionalString obj.hasPrefix
|
++ lib.optionalString obj.hasPrefix
|
||||||
"/${builtins.toString obj.prefixSize}";
|
"/${builtins.toString obj.prefixSize}";
|
||||||
|
isIP =
|
||||||
|
obj:
|
||||||
|
isIPAny obj && obj.ipVersion == versionInt;
|
||||||
mkIPCore = { segments, prefixSize ? null, ... }@args:
|
mkIPCore = { segments, prefixSize ? null, ... }@args:
|
||||||
assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= this.segmentValueMax) segments;
|
assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= this.segmentValueMax) segments;
|
||||||
assert prefixSize != null -> (lib.isInt prefixSize && prefixSize >= 0 && prefixSize <= this.bitSize);
|
assert prefixSize != null -> (lib.isInt prefixSize && prefixSize >= 0 && prefixSize <= this.bitSize);
|
||||||
@@ -77,7 +83,7 @@ let
|
|||||||
isValidStr =
|
isValidStr =
|
||||||
str:
|
str:
|
||||||
(this.parseStrCore str).valid;
|
(this.parseStrCore str).valid;
|
||||||
parseStr =
|
parse =
|
||||||
str:
|
str:
|
||||||
builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as ${this.versionString}''
|
builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as ${this.versionString}''
|
||||||
(let
|
(let
|
||||||
@@ -86,6 +92,9 @@ let
|
|||||||
lib.throwIf (!innerParse.valid) "Invalid ${this.versionString} string"
|
lib.throwIf (!innerParse.valid) "Invalid ${this.versionString} string"
|
||||||
mkIP innerParse.mkArgs
|
mkIP innerParse.mkArgs
|
||||||
);
|
);
|
||||||
|
publicMethods = {
|
||||||
|
inherit (this) mkIP isIP isValidStr parse;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
in this;
|
in this;
|
||||||
mkVersionData =
|
mkVersionData =
|
||||||
@@ -93,11 +102,11 @@ let
|
|||||||
let
|
let
|
||||||
result = mkVersionDataCore (f result);
|
result = mkVersionDataCore (f result);
|
||||||
in result;
|
in result;
|
||||||
v4Data = mkVersionData (this: rec {
|
v4Data = mkVersionData (this: {
|
||||||
segmentCount = 4;
|
segmentCount = 4;
|
||||||
segmentBitSize = 8;
|
segmentBitSize = 8;
|
||||||
versionInt = 4;
|
versionInt = 4;
|
||||||
mkIP = this.mkIPCore;
|
mkIP = args: this.mkIPCore // { zone = null; hasZone = false; };
|
||||||
ipToStringCore =
|
ipToStringCore =
|
||||||
obj:
|
obj:
|
||||||
lib.pipe obj.segments [
|
lib.pipe obj.segments [
|
||||||
@@ -160,11 +169,18 @@ let
|
|||||||
innerParseStrCore =
|
innerParseStrCore =
|
||||||
addrStr:
|
addrStr:
|
||||||
let
|
let
|
||||||
|
ip4Regex = ''([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)'';
|
||||||
|
ip4ToIP6Fragment =
|
||||||
|
ip4:
|
||||||
|
[
|
||||||
|
((elemAt ip4 0) * 256 + (elemAt ip4 1))
|
||||||
|
((elemAt ip4 2) * 256 + (elemAt ip4 3))
|
||||||
|
];
|
||||||
withoutBrackets = lib.pipe addrStr [
|
withoutBrackets = lib.pipe addrStr [
|
||||||
(lib.removePrefix "[")
|
(lib.removePrefix "[")
|
||||||
(lib.removeSuffix "]")
|
(lib.removeSuffix "]")
|
||||||
];
|
];
|
||||||
matches = builtins.match ''([0-9a-fA-F:]+)(${ip4Re})?(%[a-zA-Z0-9_-]+)?'' withoutBrackets;
|
matches = builtins.match ''([0-9a-fA-F:]+)(${ip4Regex})?(%[a-zA-Z0-9_-]+)?'' withoutBrackets;
|
||||||
|
|
||||||
mainMatch = elemAt matches 0;
|
mainMatch = elemAt matches 0;
|
||||||
ip4Match = elemAt matches 1;
|
ip4Match = elemAt matches 1;
|
||||||
@@ -197,135 +213,93 @@ let
|
|||||||
{ inherit valid; } // lib.optionalAttrs valid {
|
{ inherit valid; } // lib.optionalAttrs valid {
|
||||||
mkArgs = { inherit segments zone; };
|
mkArgs = { inherit segments zone; };
|
||||||
};
|
};
|
||||||
# ipToStringCore =
|
|
||||||
# obj:
|
|
||||||
# lib.pipe obj.segments [
|
|
||||||
# (map nix-colors-lib.decToHex)
|
|
||||||
# (lib.concatStringSep ":")
|
|
||||||
# ] ++ lib.optionalString ((obj.zoneIndex or null) != null) "%${obj.zoneIndex}";
|
|
||||||
# regexCore = ''([0-9a-fA-F:]+)(:${v4Data.regex})?(%[a-zA-Z0-9_-]+)?'';
|
|
||||||
# regexWithBrackets = ''\[${regexCore}\]'';
|
|
||||||
# regex = ''${regexCore}|${regexWithBrackets}'';
|
|
||||||
});
|
});
|
||||||
ip4Re = ''([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)'';
|
methods = {
|
||||||
subnetRe = ''(/([0-9]+))?'';
|
inherit isIPAny;
|
||||||
# parseIP6Side =
|
v4 = v4Data.publicMethods;
|
||||||
# str:
|
v6 = v6Data.publicMethods;
|
||||||
# let
|
} // lib.pipe [ v4Data v6Data ] [
|
||||||
# segmentStrs = lib.splitString ":" str;
|
(map (data: {
|
||||||
# segmentStrs' = if segmentStrs == [ "" ] then [] else segmentStrs;
|
"mkIP${toString data.versionInt}" = data.mkIP;
|
||||||
# segments = map nix-colors-lib.hexToDec segmentStrs';
|
"isIP${toString data.versionInt}" = data.isIP;
|
||||||
# in
|
"isValidIP${toString data.versionInt}Str" = data.isValidStr;
|
||||||
# segments;
|
"parseIP${toString data.versionInt}" = data.parse;
|
||||||
# parseIP6Plain =
|
}))
|
||||||
# { str, aaa ? 0 }:
|
lib.mergeAttrsList
|
||||||
# let
|
];
|
||||||
# perSegmentBits = 4 * 4;
|
|
||||||
# segmentFullCount = (128 - aaa) / perSegmentBits;
|
|
||||||
# sides = lib.splitString "::" str;
|
|
||||||
# compressed = lib.length sides == 2;
|
|
||||||
# left = parseIP6Side (lib.head sides);
|
|
||||||
# right = if compressed then parseIP6Side (elemAt sides 1) else [];
|
|
||||||
# segmentCount = (lib.length left) + (lib.length right);
|
|
||||||
# middle = lib.genList (_: 0) (segmentFullCount - segmentCount);
|
|
||||||
# in
|
|
||||||
# assert lib.length sides == 1 || lib.length sides == 2;
|
|
||||||
# assert !compressed -> segmentCount == segmentFullCount;
|
|
||||||
# assert segmentCount <= segmentFullCount;
|
|
||||||
# left ++ middle ++ right;
|
|
||||||
ip4ToIP6Fragment =
|
|
||||||
ip4:
|
|
||||||
[
|
|
||||||
((elemAt ip4 0) * 256 + (elemAt ip4 1))
|
|
||||||
((elemAt ip4 2) * 256 + (elemAt ip4 3))
|
|
||||||
];
|
|
||||||
# bitsToIP4Segment =
|
|
||||||
# bits:
|
|
||||||
# if bits <= 0 then 0
|
|
||||||
# else if bits >= 8 then 255
|
|
||||||
# else (vaculib.pow 2 bits) - 1;
|
|
||||||
# bitsToIP6Segment =
|
|
||||||
# bits:
|
|
||||||
# if bits <= 0 then 0
|
|
||||||
# else if bits >= 16 then 65535
|
|
||||||
# else (vaculib.pow 2 bits) - 1;
|
|
||||||
toStringIP4 =
|
|
||||||
obj:
|
|
||||||
(lib.pipe obj.segments [
|
|
||||||
(map builtins.toString)
|
|
||||||
(lib.concatStringSep ".")
|
|
||||||
]) ++ lib.optionalString obj.hasPrefix "/${builtins.toString obj.prefixSize}";
|
|
||||||
in
|
in
|
||||||
{ ip = rec {
|
{ ip = methods; }
|
||||||
isIP = obj: builtins.isAttrs obj && (obj._type or null) == "com.shelvacu.nix.ip";
|
# { ip = {
|
||||||
isIP4 = obj: isIP obj && obj.ipVersion == 4;
|
# inherit isIPAny;
|
||||||
isIP6 = obj: isIP obj && obj.ipVersion == 6;
|
|
||||||
|
|
||||||
mkIP4 = { segments, prefixSize ? null }@args:
|
# isIP4 = obj: isIP obj && obj.ipVersion == 4;
|
||||||
assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 255) segments;
|
# isIP6 = obj: isIP obj && obj.ipVersion == 6;
|
||||||
assert prefixSize != null -> (lib.isInt prefixSize && prefixSize >= 0 && prefixSize <= 32);
|
#
|
||||||
{
|
# mkIP4 = { segments, prefixSize ? null }@args:
|
||||||
_type = "com.shelvacu.nix.ip";
|
# assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 255) segments;
|
||||||
ipVersion = 4;
|
# assert prefixSize != null -> (lib.isInt prefixSize && prefixSize >= 0 && prefixSize <= 32);
|
||||||
inherit segments;
|
# {
|
||||||
__toString = toStringIP4;
|
# _type = "com.shelvacu.nix.ip";
|
||||||
hasPrefix = false;
|
# ipVersion = 4;
|
||||||
toSubnet = mkIP4 (args // { prefixSize = 32; });
|
# inherit segments;
|
||||||
} // lib.optionalAttrs (prefixSize != null) {
|
# __toString = toStringIP4;
|
||||||
hasPrefix = true;
|
# hasPrefix = false;
|
||||||
toSubnet = mkIP4 args;
|
# toSubnet = mkIP4 (args // { prefixSize = 32; });
|
||||||
inherit prefixSize;
|
# } // lib.optionalAttrs (prefixSize != null) {
|
||||||
subnetMask = mkIP4 {
|
# hasPrefix = true;
|
||||||
segments = lib.genList (idx: bitsToIP4Segment (prefixSize - 8*idx)) 4;
|
# toSubnet = mkIP4 args;
|
||||||
};
|
# inherit prefixSize;
|
||||||
};
|
# subnetMask = mkIP4 {
|
||||||
|
# segments = lib.genList (idx: bitsToIP4Segment (prefixSize - 8*idx)) 4;
|
||||||
parseIP4 =
|
# };
|
||||||
str:
|
# };
|
||||||
builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP4''
|
#
|
||||||
(let
|
# parseIP4 =
|
||||||
m = builtins.match ''${ip4Re}${subnetRe}'' str;
|
# str:
|
||||||
prefixMatch = elemAt m 5;
|
# builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP4''
|
||||||
in
|
# (let
|
||||||
assert m != null;
|
# m = builtins.match ''${ip4Re}${subnetRe}'' str;
|
||||||
mkIP4 {
|
# prefixMatch = elemAt m 5;
|
||||||
segments = lib.pipe m [
|
# in
|
||||||
(lib.sublist 0 4)
|
# assert m != null;
|
||||||
(map lib.toInt)
|
# mkIP4 {
|
||||||
];
|
# segments = lib.pipe m [
|
||||||
prefixSize = if prefixMatch != null then lib.toInt prefixMatch else null;
|
# (lib.sublist 0 4)
|
||||||
});
|
# (map lib.toInt)
|
||||||
|
# ];
|
||||||
mkIP6Subnet = { segments, prefixSize, zoneIndex }:
|
# prefixSize = if prefixMatch != null then lib.toInt prefixMatch else null;
|
||||||
assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 256 * 256) segments;
|
# });
|
||||||
assert lib.isInt prefixSize;
|
#
|
||||||
assert prefixSize >= 0;
|
# mkIP6Subnet = { segments, prefixSize, zoneIndex }:
|
||||||
assert prefixSize <= 128;
|
# assert vaculib.isListWhere (seg: lib.isInt seg && seg >= 0 && seg <= 256 * 256) segments;
|
||||||
assert zoneIndex == null && lib.isString zoneIndex;
|
# assert lib.isInt prefixSize;
|
||||||
{
|
# assert prefixSize >= 0;
|
||||||
_type = "com.shelvacu.nix.ip";
|
# assert prefixSize <= 128;
|
||||||
ipVersion = 6;
|
# assert zoneIndex == null && lib.isString zoneIndex;
|
||||||
inherit segments;
|
# {
|
||||||
inherit prefixSize;
|
# _type = "com.shelvacu.nix.ip";
|
||||||
inherit zoneIndex;
|
# ipVersion = 6;
|
||||||
};
|
# inherit segments;
|
||||||
|
# inherit prefixSize;
|
||||||
parseIP6 =
|
# inherit zoneIndex;
|
||||||
str:
|
# };
|
||||||
builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP6''
|
#
|
||||||
(let
|
# parseIP6 =
|
||||||
segment = ''[0-9a-fA-F]{0,4}'';
|
# str:
|
||||||
scope = ''[0-9a-zA-Z]+'';
|
# builtins.addErrorContext ''While parsing ${lib.escapeNixString str} as IP6''
|
||||||
m = builtins.match ''((${segment}:)+(${segment}))(%${scope})?${subnetRe}'' str;
|
# (let
|
||||||
mIP4 = builtins.match ''((${segment}:)+)${ip4Re}${subnetRe}'' str;
|
# segment = ''[0-9a-fA-F]{0,4}'';
|
||||||
prefixMatch = if m != null then elemAt m -1 else elemAt mIP4 -1;
|
# scope = ''[0-9a-zA-Z]+'';
|
||||||
ip4Match = elemAt mIP4 -2;
|
# m = builtins.match ''((${segment}:)+(${segment}))(%${scope})?${subnetRe}'' str;
|
||||||
segments = if m != null then parseIP6Plain { str = (lib.head m); } else (parseIP6Plain { str = (lib.head mIP4); aaa = 32; }) ++ ip4ToIP6Fragment (parseIP4 ip4Match);
|
# mIP4 = builtins.match ''((${segment}:)+)${ip4Re}${subnetRe}'' str;
|
||||||
in
|
# prefixMatch = if m != null then elemAt m -1 else elemAt mIP4 -1;
|
||||||
assert m != null || mIP4 != null;
|
# ip4Match = elemAt mIP4 -2;
|
||||||
mkIP6Subnet {
|
# segments = if m != null then parseIP6Plain { str = (lib.head m); } else (parseIP6Plain { str = (lib.head mIP4); aaa = 32; }) ++ ip4ToIP6Fragment (parseIP4 ip4Match);
|
||||||
inherit segments;
|
# in
|
||||||
prefixSize = if prefixMatch != null then lib.toInt prefixMatch else 128;
|
# assert m != null || mIP4 != null;
|
||||||
zoneIndex = if m != null then elemAt m -2 else null;
|
# mkIP6Subnet {
|
||||||
});
|
# inherit segments;
|
||||||
}; }
|
# prefixSize = if prefixMatch != null then lib.toInt prefixMatch else 128;
|
||||||
|
# zoneIndex = if m != null then elemAt m -2 else null;
|
||||||
|
# });
|
||||||
|
# }; }
|
||||||
|
Reference in New Issue
Block a user