view release on metacpan or search on metacpan
README.mkdn view on Meta::CPAN
## vcalc
my $calculated = vcalc(
target_quantity => 30, # ml
base_nic_type => 'PG', # nicotine base type (VG/PG, default PG)
base_nic_per_ml => 100, # mg/ml (base nicotine concentration)
target_nic_per_ml => 12, # mg/ml (target nicotine concentration)
target_pg => 65, # target PG percentage
target_vg => 35, # target VG percentage
# target flavor(s) name, percentage, base type
# (or App::vaporcalc::Flavor objects)
flavor_array => [
+{ tag => 'Raspberry', percentage => 15, type => 'PG' },
# ...
],
);
# Returns an App::vaporcalc::RecipeResultSet ->
my $recipe = $calculated->recipe; # App::vaporcalc::Recipe instance
my $result = $calculated->result; # App::vaporcalc::Result instance
A functional interface to [App::vaporcalc::RecipeResultSet](https://metacpan.org/pod/App::vaporcalc::RecipeResultSet) -- takes a recipe
(as a list of key/value pairs or an [App::vaporcalc::Recipe](https://metacpan.org/pod/App::vaporcalc::Recipe) object) and
bin/vaporcalc view on Meta::CPAN
$lines[0] = colorify red => $lines[0];
join "\n", @lines
}
fun flavor_strings (RecipeResultSet $rset) {
my $recipe = $rset->recipe;
my $result = $rset->result;
my $flav_recipe_str = '';
for my $flav ($recipe->flavor_array->all) {
my $pcnt = colorify 'bold red' => $flav->percentage;
my $tag = $flav->tag;
my $type = $flav->type;
$flav_recipe_str .= " $tag -> $pcnt % ($type)\n";
}
my $flav_result_str = '';
for my $flav ($result->flavors->kv->all) {
my ($tag, $ml) = @$flav;
$ml = colorify 'bold yellow' => $ml;
$flav_result_str .= " $tag => [$ml ml]\n";
bin/vaporcalc view on Meta::CPAN
$outfh->say('Welcome to App::vaporcalc!');
$outfh->say("Try '@{[ colorify yellow => 'help' ]}' for usage details.");
my $cmdeng = App::vaporcalc::CmdEngine->new;
my $recipe = App::vaporcalc::Recipe->new(
target_quantity => 10,
base_nic_per_ml => 100,
target_nic_per_ml => 12,
target_pg => 45,
target_vg => 55,
flavor_percentage => 10,
);
my $initial_input = getopts->recipe ? 'recipe load '.getopts->recipe : undef;
my $orig_prompt = colorify green => 'vcalc> ';
my $prompt;
PROMPT: while (1) {
$prompt //= $orig_prompt;
my $input = $initial_input // $term->get_reply(
prompt => $prompt,
lib/App/vaporcalc.pm view on Meta::CPAN
=head2 vcalc
my $calculated = vcalc(
target_quantity => 30, # ml
base_nic_type => 'PG', # nicotine base type (VG/PG, default PG)
base_nic_per_ml => 100, # mg/ml (base nicotine concentration)
target_nic_per_ml => 12, # mg/ml (target nicotine concentration)
target_pg => 65, # target PG percentage
target_vg => 35, # target VG percentage
# target flavor(s) name, percentage, base type
# (or App::vaporcalc::Flavor objects)
flavor_array => [
+{ tag => 'Raspberry', percentage => 15, type => 'PG' },
# ...
],
);
# Returns an App::vaporcalc::RecipeResultSet ->
my $recipe = $calculated->recipe; # App::vaporcalc::Recipe instance
my $result = $calculated->result; # App::vaporcalc::Result instance
A functional interface to L<App::vaporcalc::RecipeResultSet> -- takes a recipe
(as a list of key/value pairs or an L<App::vaporcalc::Recipe> object) and
lib/App/vaporcalc/Cmd/Subject/Flavor.pm view on Meta::CPAN
method _subject { 'flavor' }
method _build_verb { 'show' }
with 'App::vaporcalc::Role::UI::Cmd';
method _action_show { $self->_action_view }
method _action_view {
my $output = "Flavors:\n";
for my $flavor ($self->recipe->flavor_array->all) {
my $pcnt = $flavor->percentage;
my $tag = $flavor->tag;
my $type = $flavor->type;
$output .= " $tag -> $pcnt % ($type)";
}
$self->create_result(string => $output)
}
method _action_set {
my ($tag, $pcnt, $type) = $self->params->all;
$self->throw_exception(
message => 'set requires at least a flavor tag and percentage'
) unless defined $tag and length $tag and defined $pcnt;
my $existing = $self->recipe->flavor_array->first_where(
sub { $_->tag eq $tag }
);
my $others = $self->recipe->flavor_array->grep(sub { $_->tag ne $tag });
$type = $existing->type if $existing and not defined $type;
my $flavors = [
$others->all,
App::vaporcalc::Flavor->new(
tag => $tag,
percentage => $pcnt,
maybe type => $type,
)
];
my $recipe = $self->munge_recipe(
flavor_array => $flavors,
);
$self->create_result(recipe => $recipe)
}
method _action_add {
my ($tag, $pcnt, $type) = $self->params->all;
$self->throw_exception(
message => 'add requires at least a flavor tag and percentage'
) unless defined $tag and length $tag and defined $pcnt;
$self->throw_exception(
message => 'Attempting to add an existing flavor tag'
) if $self->recipe->flavor_array->has_any(sub { $_->tag eq $tag });
my $flavors = array(
$self->recipe->flavor_array->all,
App::vaporcalc::Flavor->new(
tag => $tag,
percentage => $pcnt,
maybe type => $type,
)
);
my $recipe = $self->munge_recipe(
flavor_array => $flavors,
);
$self->create_result(recipe => $recipe)
}
lib/App/vaporcalc/Flavor.pm view on Meta::CPAN
package App::vaporcalc::Flavor;
$App::vaporcalc::Flavor::VERSION = '0.005004';
use Defaults::Modern;
use App::vaporcalc::Types -types;
use Moo;
has percentage => (
required => 1,
is => 'ro',
isa => Percentage,
);
has tag => (
required => 1,
is => 'ro',
isa => Str,
);
has type => (
is => 'ro',
isa => VaporLiquid,
coerce => 1,
builder => sub { 'PG' },
);
method TO_JSON {
+{
percentage => $self->percentage,
tag => $self->tag,
type => $self->type,
}
}
with 'App::vaporcalc::Role::Store';
1;
=pod
lib/App/vaporcalc/Flavor.pm view on Meta::CPAN
# Usually used via App::vaporcalc::Recipe
=head1 DESCRIPTION
An object representing a flavor extract for use in a
L<App::vaporcalc::Recipe>.
=head2 ATTRIBUTES
=head3 percentage
The total target percentage of this flavor.
=head3 tag
The flavor's identifying tag.
=head3 type
The flavor base (VG/PG).
=head2 CONSUMES
lib/App/vaporcalc/Recipe.pm view on Meta::CPAN
isa => Percentage,
);
has flavor_array => (
is => 'ro',
isa => TypedArray[FlavorObject],
coerce => 1,
builder => sub { array_of FlavorObject },
);
method flavor_percentage {
my $total = 0;
$total += $_->percentage for $self->flavor_array->all;
Percentage->assert_return($total)
}
has notes => (
lazy => 1,
is => 'ro',
isa => TypedArray[Str],
coerce => 1,
builder => sub { array_of Str },
);
lib/App/vaporcalc/Recipe.pm view on Meta::CPAN
confess "Expected target_vg + target_pg == 100\n",
" target_vg ", $self->target_vg, "\n",
" target_pg ", $self->target_pg
}
}
method BUILDARGS {
my %params = @_ == 1 ? %{$_[0]} : @_ ? @_ : ();
# backcompat
if (my $fpcnt = delete $params{flavor_percentage}) {
my $fltype = delete $params{flavor_type};
unless (exists $params{flavor_array}) {
$params{flavor_array} = [
+{
tag => 'Unnamed',
percentage => $fpcnt,
maybe type => $fltype
}
];
}
}
\%params
}
method TO_JSON {
lib/App/vaporcalc/Recipe.pm view on Meta::CPAN
use App::vaporcalc::Recipe;
my $recipe = App::vaporcalc::Recipe->new(
target_quantity => 30, # ml
base_nic_type => 'PG', # nicotine base type (VG/PG, default PG)
base_nic_per_ml => 100, # mg/ml (base nicotine concentration)
target_nic_per_ml => 12, # mg/ml (target nicotine concentration)
target_pg => 65, # target PG percentage
target_vg => 35, # target VG percentage
flavor_array => [
+{ tag => 'Raspberry', percentage => 10, type => 'PG' },
+{ tag => 'EM', percentage => 1, type => 'PG' },
# ...
],
notes => [
'My recipe',
'10% flavor',
'1% ethyl maltol'
],
);
lib/App/vaporcalc/Recipe.pm view on Meta::CPAN
=head3 base_nic_per_ml
The concentration of the base nicotine solution, in mg/ml.
=head3 target_nic_per_ml
The target nicotine concentration, in mg/ml.
=head3 target_pg
The total percentage of PG.
=head3 target_vg
The total percentage of VG.
=head3 flavor_array
A (coercible, see SYNOPSIS) array of L<App::vaporcalc::Flavor> objects.
=head3 notes
A L<List::Objects::WithUtils::Array> containing an arbitrary number of notes
attached to the recipe.
Can be coerced from a plain C<ARRAY>.
=head2 METHODS
=head3 flavor_percentage
Calculates the total flavor percentage; see L</flavor_array>.
=head2 CONSUMES
L<App::vaporcalc::Role::Calc>
L<App::vaporcalc::Role::Store>
=head1 AUTHOR
Jon Portnoy <avenj@cobaltirc.org>
lib/App/vaporcalc/Role/Calc.pm view on Meta::CPAN
method _calc_total_pg_qty {
return 0 unless $self->target_pg;
$self->target_quantity * ($self->target_pg / 100)
}
method _calc_per_flavor_qty_obj {
my $res = hash_of Object;
for my $flav (@{ $self->flavor_array }) {
$flav = FlavorObject->assert_coerce($flav) unless is_FlavorObject $flav;
my $pcnt = $flav->percentage || next;
my $ml = $self->target_quantity * ($pcnt / 100);
$res->set(
$flav->tag => hash(ml => $ml, type => $flav->type)->inflate
);
}
# hash( $name => $obj );
# $obj->ml, $obj->type
$res
}
lib/App/vaporcalc/Role/Calc.pm view on Meta::CPAN
=head2 REQUIRES
Consumers need to implement the following methods:
# Method Returning
target_quantity (ml)
base_nic_per_ml (mg/ml)
base_nic_type ('PG' or 'VG')
target_nic_per_ml (mg/ml)
target_pg (percentage)
target_vg (percentage)
flavor_array (an array of App::vaporcalc::Flavor objects)
=head2 METHODS
=head3 calc
Performs the calculation & returns an L<App::vaporcalc::Result> object.
=head1 AUTHOR
recipes/banana_cheesecake.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Cheesecake Graham Crust",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "INW Banana",
"percentage" : "0.6"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/banana_cream.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Banana Cream",
"percentage" : "5"
},
{
"type" : "PG",
"tag" : "INW Banana",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Bavarian Cream",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "1"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/banana_melon.recipe view on Meta::CPAN
{
"recipe" : {
"target_nic_per_ml" : "3",
"notes" : [],
"target_vg" : 60,
"target_pg" : "40",
"flavor_array" : [
{
"percentage" : "5",
"type" : "PG",
"tag" : "TFA Cantelope"
},
{
"type" : "PG",
"percentage" : "0.5",
"tag" : "INW Melon"
},
{
"type" : "PG",
"percentage" : "0.5",
"tag" : "INW Banana"
}
],
"base_nic_type" : "PG",
"target_quantity" : "90",
"base_nic_per_ml" : 100
}
}
recipes/banana_peach.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "INW Banana",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "INW Peach",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "0.5"
},
{
"type" : "PG",
"tag" : "TFA Mango",
"percentage" : "0.5"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "160",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/berries_and_cream.recipe view on Meta::CPAN
"target_quantity" : 120.0,
"target_nic_per_ml" : 3.0,
"target_vg" : 70,
"target_pg" : 30,
"base_nic_type" : "PG",
"base_nic_per_ml" : 100,
"notes" : [],
"flavor_array" : [
{
"tag" : "TFA Marshmallow",
"percentage" : "1",
"type" : "PG"
},
{
"percentage" : "4",
"tag" : "TFA Blueberry Wild",
"type" : "PG"
},
{
"tag" : "INW Strawberry",
"percentage" : "0.6",
"type" : "PG"
},
{
"percentage" : "4",
"tag" : "TFA Bavarian Cream",
"type" : "PG"
},
{
"type" : "PG",
"tag" : "TFA Strawberry Ripe",
"percentage" : "1"
}
]
}
}
recipes/berrymarshmallow-120ml-3mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Blueberry Extra",
"percentage" : "3"
},
{
"type" : "PG",
"tag" : "TFA Vanillin",
"percentage" : "3"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : [
"Ended up adding a dash of Sweet Cream and a few drops of Circus Cotton Candy"
recipes/birthdaycake.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Vanilla Cupcake",
"percentage" : "4"
},
{
"type" : "PG",
"tag" : "TFA Frosted Donut",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Vanilla Swirl",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA VBIC",
"percentage" : "0.5"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/blubreeze.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Blueberry Wild",
"percentage" : "6"
},
{
"type" : "PG",
"tag" : "Menthol (10%)",
"percentage" : "1"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "200",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/blurazz.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "INW Peach",
"percentage" : "0.5"
},
{
"type" : "PG",
"tag" : "INW Raspberry",
"percentage" : "1.5"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "0.5"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "160",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/cantaloupe.recipe view on Meta::CPAN
"target_quantity" : "90",
"base_nic_type" : "PG",
"base_nic_per_ml" : 100,
"target_vg" : 60,
"target_nic_per_ml" : "3",
"notes" : [],
"flavor_array" : [
{
"tag" : "TFA Cantelope",
"type" : "PG",
"percentage" : "5"
},
{
"tag" : "INW Melon",
"percentage" : "0.3",
"type" : "PG"
}
],
"target_pg" : "40"
}
}
recipes/captain.recipe view on Meta::CPAN
{
"recipe" : {
"base_nic_type" : "PG",
"flavor_array" : [
{
"type" : "PG",
"percentage" : "2",
"tag" : "TFA Bavarian Cream"
},
{
"percentage" : "2",
"tag" : "TFA Strawberry Ripe",
"type" : "PG"
},
{
"type" : "PG",
"tag" : "TFA Berry Crunch",
"percentage" : "4"
},
{
"type" : "PG",
"percentage" : "2",
"tag" : "TFA Blueberry Wild"
},
{
"type" : "PG",
"percentage" : "0.5",
"tag" : "TFA Sweet Cream"
}
],
"target_nic_per_ml" : 3,
"notes" : [],
"base_nic_per_ml" : 100,
"target_vg" : 70,
"target_quantity" : 120,
"target_pg" : 30
}
recipes/caramel_cream.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Caramel",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Caramel Candy",
"percentage" : "3"
},
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Sweet Cream",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Vanilla Cupcake",
"percentage" : "1"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/cherrycheesecake.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Cheesecake Graham Crust",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "INW Cherries",
"percentage" : "2"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/cherrylime-50ml-3mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Strawberry (Ripe)",
"percentage" : "3"
},
{
"type" : "PG",
"tag" : "TFA Key Lime",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Double Kiwi",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Energy Drink",
"percentage" : "2"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "55",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : [
"Kind of a cherry-lime taste.",
recipes/cherrylime_batch_2.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Key Lime",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Double Kiwi",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "INW Cherries",
"percentage" : "2"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "55",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/cherryvanilla.recipe view on Meta::CPAN
{
"recipe" : {
"target_nic_per_ml" : 3,
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA VBIC",
"percentage" : "3"
},
{
"type" : "PG",
"percentage" : "2",
"tag" : "Vanillin (10%)"
},
{
"tag" : "INW Cherries",
"percentage" : "0.8",
"type" : "PG"
},
{
"tag" : "TFA Vanilla Swirl",
"percentage" : "4",
"type" : "PG"
}
],
"base_nic_type" : "PG",
"target_pg" : 30,
"target_quantity" : 120,
"base_nic_per_ml" : 100,
"target_vg" : 70,
"notes" : []
}
recipes/chocmint-100ml-3mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Double Chocolate",
"percentage" : "8"
},
{
"type" : "PG",
"tag" : "E.M.",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Peppermint",
"percentage" : "0.5"
}
],
"target_pg" : 45,
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "100",
"target_nic_per_ml" : "3",
"target_vg" : 55,
"notes" : []
}
recipes/creamymelon.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "INW Melon",
"percentage" : "2"
},
{
"type" : "PG",
"tag" : "TFA Bavarian Cream",
"percentage" : "3"
},
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "1"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/creamymint-120ml-3mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Creme de Menthe",
"percentage" : "4"
},
{
"type" : "PG",
"tag" : "TFA Marshmallow",
"percentage" : "3"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/double_kiwi.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Double Kiwi",
"percentage" : "4"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "3"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "125",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/grape_candy-50ml-6mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Grape Candy",
"percentage" : "6.15"
},
{
"type" : "PG",
"tag" : "TFA Grape Juice",
"percentage" : "6.15"
}
],
"target_pg" : "40",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "50",
"target_nic_per_ml" : "6",
"target_vg" : 60,
"notes" : []
}
recipes/kiwi-mint_120ml-3mg.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Peppermint",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Double Kiwi",
"percentage" : "7"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "3"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "120",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}
recipes/kiwi_cherry.recipe view on Meta::CPAN
{
"recipe" : {
"flavor_array" : [
{
"type" : "PG",
"tag" : "TFA Double Kiwi",
"percentage" : "3"
},
{
"type" : "PG",
"tag" : "INW Cherries",
"percentage" : "1"
},
{
"type" : "PG",
"tag" : "TFA Dragonfruit",
"percentage" : "0.5"
}
],
"target_pg" : "30",
"base_nic_per_ml" : 100,
"base_nic_type" : "PG",
"target_quantity" : "160",
"target_nic_per_ml" : "3",
"target_vg" : 70,
"notes" : []
}