package ONO::FW::Edu::Apps::Modules::Clock;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2022-2026 Jos Kirps and The Joopita Project [ASBL]
# Copyright (C) 2011-2022 Jos Kirps and Joopita Research ASBL
# Copyright (C) 2006-2011 Jos Kirps and The Joopita Project
# Copyright (C) 2001-2006 Jos Kirps and The WobbleWolf Project
#
# This file, as well as many other parts of the ONO Software Project or
# related elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
#: This module is a front end application module wrapper that has been
#: created for the Morzino Project (morzino.com) and that has been released
#: as Open Source software.
#:
#: Note that this is NOT a self-contained application, it is only a wrapper
#: that makes heavy use of the ONO Perl Framework application engine.
use strict;
use ONO::FW::Edu::Apps::ToolBox;
use ONO::FW::Edu::Apps::Modules::WorksheetMaker::Input;
use ONO::FW::Apps::ToolBox;
use ONO::Lib::PDF::Draw;
use ONO::Lib::PDF::ToolBox;
use ONO::FW::Apps::Core;
use ONO::FW::Apps::Core::Graphics;
use ONO::Lib::Parser;
use ONO::FW::Apps::PDF;
use ONO::Lib::DateTime::Clock;
sub learn {
my (
$self,
$option,
$vars_ref,
$HTTP,
$BASE,
) = @_;
################################################################
# INIT - BEGIN
################################################################
my (
$db,
$community,
$action_url,
$form,
$format,
$canvas,
$pdfkey,
$sec,$min,$hour,
$mday,$mon,$year,
$wday,$yday,$timestamp,
$lang,
$BLK_ref,
$vars_ref,
) = ONO::FW::Apps::Core->init($vars_ref);
my %vars = %$vars_ref;
my %BLK = %$BLK_ref;
my $app = "clock";
ONO::FW::Apps::Core->now("",$app,$vars{'app_lang'});
my $WEB;
my $AppName = "Clock";
my @txt = (
"analog -> digital",
"digital -> analog",
"draw",
"empty sheet",
"full hours",
"half hours",
"quarter hours",
"5 minute steps",
"minutes",
"24 hour clock",
"clocks per sheet",
"clock time",
"time intervals",
);
if ($vars{'app_lang'} eq "de") {
$AppName = "Uhr";
@txt = (
"analog -> digital",
"digital -> analog",
"zeichnen",
"leeres Blatt",
"ganze Stunden",
"halbe Stunden",
"viertel Stunden",
"5 Minuten Schritte",
"Minuten",
"24 Stunden Uhr",
"Uhren pro Blatt",
"Uhrzeit",
"Zeitintervalle",
);
}
if ($vars{'app_lang'} eq "fr") {
$AppName = "Montre";
@txt = (
"analogue -> digitale",
"digitale -> analogue",
"dessiner",
"fiche vide",
"heures entières",
"demi heures",
"quart d'heures",
"minutes",
"heures & minutes",
"24 heures",
"montres par fiche",
"heure",
"intervalles de temps",
);
}
if ($vars{'app_lang'} eq "lu") {
$AppName = "Auer";
@txt = (
"analog -> digital",
"digital -> analog",
"zeechnen",
"eidelt Blat",
"ganz Stonnen",
"hallef Stonnen",
"véierel Stonnen",
"5 Minutte Schrëtter",
"Minutten",
"24 Stonnen",
"Aueren pro Blat",
"Auerzäit",
"Zäitintervaller",
);
}
$vars{'app_input_print_options_title_default'} = $AppName;
$WEB .= ONO::FW::Apps::Core->output_paper_save($pdfkey,$BLK_ref,\%vars,$HTTP,$BASE,"$year$mon$mday");
if (ONO::FW::Apps::Core->running(\%vars,$db)) {
$WEB .= ONO::FW::Apps::Core->blockbackbutton($BASE,$vars_ref);
#############################################################
# WORKSHEET MAKER
#############################################################
if ($vars{'output_worksheet_maker'}) {
$vars_ref = ONO::FW::Edu::Apps::Modules::WorksheetMaker::Input->vars(\%vars);
%vars = %$vars_ref;
}
#############################################################
# ONLINE TRAINING
#############################################################
if ($vars{'output_web'} || $vars{'output_paper'}) {
my $question_number = ONO::FW::Apps::Core->question_number($vars{'output_web_question_number'});
my (
$page,$pages,%cache,
$whilecounter,$stats_switches,
$PDF_OPTS,
$stat_correct,$stat_wrong,$stat_todo,
);
my $questions_per_page = 1;
my $offset_x = 60;
my $offset_x2 = 11;
my $offset_y;
if ($vars{'output_worksheet_maker'}) {
$offset_y = 7.5;
}
if ($vars{'output_paper'}) {
$PDF_OPTS = ONO::FW::Apps::Core->headers_options($BLK_ref,$vars_ref);
ONO::FW::Apps::PDF->new("$BASE/pdf/pdf-$pdfkey.pdf","",$format);
$vars{'app_input_multiple_questions_per_page'}++;
}
foreach my $copy (ONO::FW::Apps::Core->unique_copies($vars{'app_input_print_options_unique_copies'})) {
my @corr_cache;
if ($vars{'output_paper'}) {
if ($copy > 1) {
ONO::FW::Apps::PDF->page("",$format);
}
ONO::FW::Apps::Core->headers(\%vars,$format);
ONO::FW::Apps::PDF->title($vars{'app_input_print_options_title'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core->unique_copies_info($canvas,$copy,$vars_ref);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"HV",$vars_ref);
# ONO::Lib::PDF::ToolBox->canvas_test($canvas);
}
if ($vars{'output_web'}) {
$WEB .= qq~<$form>~;
$WEB .= ONO::FW::Apps::Core->question_progress($vars{'app_input_number_of_questions'},$question_number);
}
if ($vars{'output_web_completed'}) {
$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"ctmW$stats_switches");
$vars{'output_progress_done'}++;
$WEB .= ONO::FW::Apps::Core->question_progress_done_msg($app,$db,$community,$form,$action_url,$vars{'app_input_number_of_questions'},$vars{'output_web_mistakes'},$lang,$BLK_ref,$vars_ref);
} else {
if ($vars{'output_web'}) {
$WEB .= ONO::FW::Apps::Core->timer($vars{'output_web'},$vars{'output_web_timer_start'});
$WEB .= ONO::FW::Apps::Core->stats("",$BLK_ref,"actmvVW$stats_switches");
}
for (my $i = 0; $i < $questions_per_page; $i++) {
my $HTML;
# output paper + web
if ($vars{'output_paper'} || $vars{'output_web'}) {
if ($i == 0) {
my $clockcounter;
my @clocks = (1,1);
if ($vars{'output_paper'}) {
@clocks = (3,4);
}
if ($vars{'output_worksheet_maker'}) {
@clocks = (3,1);
}
my (%used,$inter_mode);
for (my $y = 0; $y < $clocks[1]; $y++) {
for (my $x = 0; $x < $clocks[0]; $x++) {
my ($c1,$c2,$c3) = (50+int(rand(150)),50+int(rand(150)),50+int(rand(150)));
if ($vars{'output_paper'}) {
my $maker_y;
if ($vars{'output_worksheet_maker'}) {
$maker_y = 7.5;
}
ONO::Lib::PDF::Draw->place_pdf($canvas,$x*$offset_x+$offset_x2+1.5,$y*47.5+$offset_y+31,"ono-data/school/pdf/clock.pdf",0.14,"",$format);
ONO::Lib::PDF::Draw->circle($canvas,$x*$offset_x+$offset_x2+16.2,$y*47.5+$offset_y+17.35-$maker_y,13.75,3.2,"","0:$c1:$c2:$c3");
}
my ($use_hour,$use_min) = (0,0);
my ($exe,$is_cached);
if ($vars{'output_web_cache_hour'} ne "" && $vars{'output_web_cache_mins'} ne "") {
($use_hour,$use_min) = ($vars{'output_web_cache_hour'},$vars{'output_web_cache_mins'});
$is_cached++;
}
if ($vars{'output_paper'} || !$is_cached) {
my $max_hour = 12;
if ($vars{"app_input_24h"}) {
$max_hour = 24;
}
my @opts;
foreach my $opt ('anadig','digana') {
if ($vars{"app_input_exercise_$opt"}) {
@opts = (@opts,$opt);
}
}
my $num = @opts;
$exe = $opts[int(rand($num))];
my @opts;
foreach my $opt ('hour','half','quarter','5min','mins') {
if ($vars{"app_input_options_$opt"}) {
@opts = (@opts,$opt);
}
}
my $num = @opts;
my $opt = $opts[int(rand($num))];
# hour
$use_hour = int(rand($max_hour));
my $whilecounter;
while ($whilecounter < 256 && $used{$use_hour}) {
$use_hour = int(rand($max_hour));
$whilecounter++;
}
$used{$use_hour}++;
# min
my $whilecounter;
while ($whilecounter < 256 && ($used{$use_min} || $use_min eq "" || $use_min eq "0") && $opt =~ /(half|quarter|min)/) {
$whilecounter++;
$use_min = 0;
if ($opt eq "half") {
$use_min = 30;
}
if ($opt eq "quarter") {
if (int(rand(2)) == 0) {
$use_min = 15;
} else {
$use_min = 45;
}
}
if ($opt eq "5min") {
$use_min = 5*int(rand(12));
}
if ($opt eq "mins") {
$use_min = int(rand(60));
}
if (length $use_min < 2) {
$use_min = "0$use_min";
}
}
if ($use_min < 1) {
$use_min = 0;
}
if (length $use_min < 2) {
$use_min = "0$use_min";
}
$used{$use_min}++;
}
if ($vars{'output_web'}) {
if ($vars{'output_web_answer'} ne "" || $vars{'output_web_answer2'} ne "") {
$vars{'output_web_answer_status'} = 2;
if ($vars{'output_web_answer'} == $use_hour || $vars{'output_web_answer'} == $use_hour-12 || $vars{'output_web_answer'} == $use_hour+12) {
if ($vars{'output_web_answer2'} == $use_min) {
$vars{'output_web_answer_status'} = 1;
if (!$vars{'output_web_answer2'}) {
$vars{'output_web_answer2'} = 0;
}
if (length $vars{'output_web_answer2'} < 2) {
$vars{'output_web_answer2'} = "0$vars{'output_web_answer2'}";
}
}
}
}
if ($vars{'output_web_answer_status'} == 2) {
$vars{'output_web_mistakes'}++;
}
my $CHK = ONO::FW::Apps::Core->check_single(
"",
"<td>:</td>",
50,
2,
$BLK_ref,
\%vars,
"CdnM",
);
$HTML .= qq~<div class="abs" style="top:30px;left:310px">~;
$HTML .= ONO::Lib::DateTime::Clock->canvas_clock(300,$use_hour,$use_min,0,"AS");
$HTML .= qq~</div>
<div class="rel" style="top:300px">
$CHK
</div>
~;
if ($vars{'output_web_answer_status'} != 1) {
$HTML .= qq~<input type="hidden" name="output_web_cache_hour" value="$use_hour">
<input type="hidden" name="output_web_cache_mins" value="$use_min">
~;
}
}
if ($vars{'output_paper'}) {
my $x1 = $x*$offset_x+$offset_x2+16.22;
my $y1 = $y*47.5+15.11+2.25;
my ($x2h,$y2h,$x2m,$y2m) = &handmath("",$x1,$y1,$use_hour,$use_min);
if (!$x) {
$inter_mode = 0;
if ($vars{'app_input_type_intervals'}) {
$inter_mode = 1;
if ($vars{'app_input_type_clocktime'} && int(rand(100)) > $y*33) {
$inter_mode = 0;
}
}
}
if ($exe eq "anadig") {
ONO::Lib::PDF::Draw->line($canvas,$x1,$y1,$x2h,$y2h,2.2,"0:$c1:$c2:$c3");
ONO::Lib::PDF::Draw->line($canvas,$x1,$y1,$x2m,$y2m,1);
ONO::Lib::PDF::Draw->circle($canvas,$x1,$y1,1,1,"0:$c1:$c2:$c3");
my $use_x = $x*$offset_x+$offset_x2+16;
if ($vars{"app_input_24h"} && !$inter_mode) {
ONO::Lib::PDF::Draw->line($canvas,$use_x-10,$y*47.5+37,$use_x-2,$y*47.5+37,0.5);
ONO::Lib::PDF::Draw->line($canvas,$use_x+10,$y*47.5+37,$use_x+2,$y*47.5+37,0.5);
ONO::Lib::PDF::Draw->text($canvas,$use_x,$y*47.5+36,":","center");
ONO::Lib::PDF::Draw->line($canvas,$use_x-10,$y1+26.5,$use_x-2,$y1+26.5,0.5);
ONO::Lib::PDF::Draw->line($canvas,$use_x+10,$y1+26.5,$use_x+2,$y1+26.5,0.5);
ONO::Lib::PDF::Draw->text($canvas,$x1,$y1+25.5,":","center");
} else {
ONO::Lib::PDF::Draw->line($canvas,$use_x-10,$y*47.5+40,$use_x-2,$y*47.5+40,0.5);
ONO::Lib::PDF::Draw->line($canvas,$use_x+10,$y*47.5+40,$use_x+2,$y*47.5+40,0.5);
ONO::Lib::PDF::Draw->text($canvas,$use_x,$y*47.5+39,":","center");
}
}
if ($exe eq "digana") {
ONO::Lib::PDF::Draw->text($canvas,$x1,$y1+22,":","center");
ONO::Lib::PDF::Draw->text($canvas,$x1-1,$y1+22,"$use_hour","right");
ONO::Lib::PDF::Draw->text($canvas,$x1+1.5,$y1+22,"$use_min","left");
}
if ($inter_mode && $x == 1) {
&intermode($canvas,$x1,$y1,"0:$c1:$c2:$c3");
$vars{"inter_mode_$y"}++;
}
$corr_cache[$clockcounter] = "$use_hour:$use_min:$x1:$y1:$x2h:$y2h:$x2m:$y2m";
$clockcounter++;
}
}
}
}
}
if ($vars{'output_web'}) {
$WEB .= qq~<input type="hidden" name="output_web_cache_running" value="1">
<input type="hidden" name="output_web_cache_res" value="">
<div class="mt20">
$HTML
</div>
~;
}
}
if ($vars{'output_web'}) {
$WEB .= ONO::FW::Apps::Core->input_vars(\%vars);
if ($vars{'app_input_number_of_questions'}-$question_number < 1) {
$WEB .= qq~<input type="hidden" name="output_web_completed" value="1">~;
}
$WEB .= qq~</form>~;
}
}
if (ONO::FW::Apps::Core->print_corrections("$BASE/pdf/pdf-$pdfkey-corr.pdf","",$format,$vars_ref)) {
ONO::FW::Apps::Core->headers(\%vars,$format,"c");
ONO::FW::Apps::PDF->title($BLK{'Corrections'},$PDF_OPTS,$vars{'app_input_print_options_code'},$format);
ONO::FW::Apps::Core->unique_copies_info($canvas,$copy,$vars_ref);
ONO::FW::Apps::Core::Graphics->pdf_draw_item_numbers($canvas,-2,0,1,4,"CHV",$vars_ref);
# ONO::Lib::PDF::ToolBox->canvas_test($canvas);
my $clockcounter;
for (my $y = 0; $y < 4; $y++) {
for (my $x = 0; $x < 3; $x++) {
ONO::Lib::PDF::Draw->place_pdf($canvas,$x*$offset_x+$offset_x2+1.5,$y*47.5+31+$offset_y,"ono-data/school/pdf/clock.pdf",0.14,"",$format);
my @cp = split(/:/,$corr_cache[$clockcounter]);
ONO::Lib::PDF::Draw->line($canvas,$cp[2],$cp[3],$cp[4],$cp[5],2.2);
ONO::Lib::PDF::Draw->line($canvas,$cp[2],$cp[3],$cp[6],$cp[7],1);
if ($vars{"app_input_24h"}) {
my $h1 = $cp[0];
my $h2 = $cp[0] + 12;
if ($h2 > 23) {
$h2 = $cp[0];
$h1 = $cp[0] - 12;
}
ONO::Lib::PDF::Draw->text($canvas,$x*$offset_x+$offset_x2+16,$y*47.5+37,"$h1 : $cp[1]","center");
ONO::Lib::PDF::Draw->text($canvas,$x*$offset_x+$offset_x2+16,$y*47.5+43,"$h2 : $cp[1]","center");
} else {
ONO::Lib::PDF::Draw->text($canvas,$x*$offset_x+$offset_x2+16,$y*47.5+37,"$cp[0] : $cp[1]","center");
}
if ($vars{"inter_mode_$y"} && $x == 1) {
&intermode($canvas,$cp[2],$cp[3],"0:0:0:0");
my @pre = split(/:/,$corr_cache[$clockcounter-1]);
my @pos = split(/:/,$corr_cache[$clockcounter+1]);
my $hrs = $pos[0] - $pre[0];
my $min = $pos[1] - $pre[1];
while ($whilecounter < 256 && $hrs > 12) {
$whilecounter++;
$hrs = $hrs - 12;
}
while ($whilecounter < 256 && $hrs < 0) {
$whilecounter++;
$hrs = $hrs + 12;
}
my $hrs2 = 0;
my $min2 = $min + ($hrs * 60);
my $whilecounter;
while ($whilecounter < 256 && $min2 > 59) {
$whilecounter++;
$hrs2++;
$min2 = $min2 - 60;
}
while ($whilecounter < 256 && $hrs2 > 12) {
$whilecounter++;
$hrs2 = $hrs2 - 12;
}
if ($min2 < 10) {
$min2 = "0$min2";
}
ONO::Lib::PDF::Draw->text($canvas,$x*$offset_x+$offset_x2+11,$y*47.5+16,$hrs2,"center");
ONO::Lib::PDF::Draw->text($canvas,$x*$offset_x+$offset_x2+22,$y*47.5+16,$min2,"center");
}
$clockcounter++;
}
}
}
}
if ($vars{'output_web'}) {
$WEB = ONO::FW::Apps::Core->stats_replace(
$WEB,
$question_number-1,
$stat_wrong,
$vars{'app_input_number_of_questions'}-$question_number+1,
$vars{'output_web_mistakes'},
$page,
$pages,
$vars{'output_web_completed'}
);
}
if ($vars{'output_paper'}) {
ONO::FW::Apps::PDF->end;
$WEB .= ONO::FW::Apps::Core->output_paper($pdfkey,\%BLK,\%vars,$HTTP,$BASE);
}
}
if ($vars{'output_web'}) {
ONO::FW::Apps::Core->varstore($vars{'username'},$vars{'virclass'},$vars{'anonymous'},\%vars);
}
} else {
#############################################################
# EXERCISE SETUP
#############################################################
my @sel;
foreach my $opt (
"0:exercise_anadig",
"1:exercise_digana",
"2:type_clocktime",
"3:type_intervals",
"4:options_hour",
"5:options_half",
"6:options_quarter",
"7:options_5min",
"8:options_mins",
"9:24h",
) {
my @op = split(/:/,$opt);
if ($vars{"app_input_$op[1]"}) {
$sel[$op[0]] = 1;
}
}
if (!$sel[1] && !$sel[2]) {
$sel[0] = 1;
}
if (!$sel[2] && !$sel[3]) {
$sel[2] = 1;
}
if ($vars{'output_web'}) {
$sel[0] = 1;
$sel[1] = "X";
$sel[2] = 1;
$sel[3] = "X";
}
if (!"$sel[4]$sel[5]$sel[6]$sel[7]$sel[8]") {
$sel[4] = 1;
}
my @exercises = (
"anadig:$sel[0]:$BLK{'write'} ($txt[0])",
"digana:$sel[1]:$txt[2] ($txt[1])",
);
my @types = (
"clocktime:$sel[2]:$txt[11]",
"intervals:$sel[3]:$txt[12]",
);
my @options = (
"hour:$sel[4]:$txt[4]",
"half:$sel[5]:$txt[5]",
"quarter:$sel[6]:$txt[6]",
"5min:$sel[7]:$txt[7]",
"mins:$sel[8]:$txt[8]",
);
if (!$vars{'app_input_number_of_questions'}) {
$vars{'app_input_number_of_questions'} = 20;
}
my $CONF;
$CONF .= ONO::FW::Apps::ToolBox->conf_input("checks", $BLK_ref,\%vars,"",$BLK{'exercise'},"exercise",@exercises);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("checks", $BLK_ref,\%vars,"",$BLK{'type'},"type",@types);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("checks", $BLK_ref,\%vars,"",$BLK{'options'},"options",@options);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("check", $BLK_ref,\%vars,"","","24h",$sel[9],$txt[9]);
$CONF .= ONO::FW::Apps::ToolBox->conf_input("spacer", $BLK_ref,\%vars);
$WEB .= ONO::FW::Apps::Core->conf_box(
$db,
$community,
$app,
$form,
"",
$action_url,
$CONF,
$lang,
$BLK_ref,
\%vars,
"op-ncdi-CDI-lsu-N",
);
$WEB .= ONO::FW::Apps::Core->infopics(
"sheet:210:40:60:-10:clock_sheet_1.jpg",
);
$WEB .= qq~<div class="abs" style="top:170px;right:10px">~;
$WEB .= ONO::Lib::DateTime::Clock->canvas_clock(300);
$WEB .= qq~</div>~;
if (!$vars{'exercise'}) {
$WEB .= ONO::FW::Apps::Core->info_display(
ONO::FW::Apps::Core->info("info_online_print",$vars{'app_lang'}),
ONO::FW::Apps::Core->info("info_indiv_diff", $vars{'app_lang'}),
);
}
}
my ($status,$WEB) = ONO::Lib::Parser->parse($WEB,$vars_ref);
$WEB .= ONO::FW::Apps::Core->vardump($vars_ref);
$WEB = ONO::FW::Edu::Apps::ToolBox->apps_gate($WEB,$vars_ref);
return $WEB;
}
###################################################################
# SUBS
###################################################################
sub handmath {
my (
$self,
$x1,
$y1,
$use_hour,
$use_min,
) = @_;
my $pi = 4 * atan2(1,1);
# hour
my $deg = 180 - ($use_hour * 6 * 5 + int($use_min/2));
my $bow = 2*$pi * $deg/360;
my $x2h = $x1 + (sin $bow)*6.75;
my $y2h = $y1 + (cos $bow)*6.75;
# min
my $deg = 180 - ($use_min * 6);
my $bow = 2*$pi * $deg/360;
my $x2m = $x1 + (sin $bow)*8.75;
my $y2m = $y1 + (cos $bow)*8.75;
return ($x2h,$y2h,$x2m,$y2m);
}
sub intermode {
my ($canvas,$x1,$y1,$color) = @_;
ONO::Lib::PDF::Draw->rect($canvas,$x1-20,$y1-16,$x1+20,$y1+28,0,"","0:255:255:255");
ONO::Lib::PDF::Draw->rect($canvas,$x1-30,$y1-2,$x1+26,$y1+2,0,"",$color);
ONO::Lib::PDF::Draw->triangle($canvas,$x1+25,$y1-5,$x1+25,$y1+5,$x1+30,$y1,0,"",$color);
ONO::Lib::PDF::Draw->rect($canvas,$x1-12,$y1-6,$x1+12,$y1+6,1,$color,"0:244:244:244",2);
ONO::Lib::PDF::Draw->line($canvas,$x1-10,$y1+3,$x1-2,$y1+3,0.5);
ONO::Lib::PDF::Draw->line($canvas,$x1+10,$y1+3,$x1+2,$y1+3,0.5);
ONO::Lib::PDF::Draw->text($canvas,$x1,$y1+1,":","center");
}
###################################################################
#### THAT'S IT :-D
###################################################################
1;
__END__