Gitlab CSE Unil
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
M. Chardon
ADIM
Commits
bc973839
Commit
bc973839
authored
Jul 16, 2015
by
Julien Furrer
Browse files
Merge branch 'environ-spec' into dev
parents
6bf410a2
b00512d9
Changes
118
Hide whitespace changes
Inline
Side-by-side
adim_project/.gitignore
View file @
bc973839
...
...
@@ -12,10 +12,6 @@
adim_project/apache.conf*
adim_project/generate_apache_conf.py
adim_app/playground.py
/templates/playground
adim_app/static/js/playground.js
adim_project/wsgi.example.py
adim_project/wsgi-off.py
\ No newline at end of file
adim_project/adim/admin.py
View file @
bc973839
...
...
@@ -19,5 +19,6 @@ admin.site.register(AnObj, AnObjAdmin)
# list_filter = ('schema', )
# admin.site.register(AOChoice, AOChoiceAdmin)
# admin.site.register(AOAttribute)
admin
.
site
.
register
(
Annotation
)
\ No newline at end of file
class
AnnotationAdmin
(
admin
.
ModelAdmin
):
list_filter
=
(
'annotable'
,
)
admin
.
site
.
register
(
Annotation
,
AnnotationAdmin
)
adim_project/adim/migrations/0005_anobj_env.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0004_auto_20150424_1209'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'anobj'
,
name
=
'env'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
choices
=
[(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
)]),
),
]
adim_project/adim/migrations/0006_envparam.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0005_anobj_env'
),
]
operations
=
[
migrations
.
CreateModel
(
name
=
'EnvParam'
,
fields
=
[
(
'id'
,
models
.
AutoField
(
verbose_name
=
'ID'
,
serialize
=
False
,
auto_created
=
True
,
primary_key
=
True
)),
(
'cimaf_cut_pos'
,
models
.
IntegerField
(
null
=
True
,
blank
=
True
)),
(
'cimaf_cut_margin'
,
models
.
IntegerField
(
null
=
True
,
blank
=
True
)),
(
'anobj'
,
models
.
OneToOneField
(
to
=
'adim.AnObj'
)),
],
options
=
{
'verbose_name'
:
'Environment params'
,
},
),
]
adim_project/adim/migrations/0007_auto_20150714_0815.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0006_envparam'
),
]
operations
=
[
migrations
.
AddField
(
model_name
=
'envparam'
,
name
=
'categories_set'
,
field
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
),
),
migrations
.
AlterField
(
model_name
=
'anobj'
,
name
=
'env'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
choices
=
[(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
),
(
'playground'
,
'Pour Voir'
)]),
),
]
adim_project/adim/migrations/0008_auto_20150714_0817.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0007_auto_20150714_0815'
),
]
operations
=
[
migrations
.
RenameField
(
model_name
=
'envparam'
,
old_name
=
'categories_set'
,
new_name
=
'category_set_name'
,
),
]
adim_project/adim/migrations/0009_auto_20150715_1144.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0008_auto_20150714_0817'
),
]
operations
=
[
migrations
.
AlterModelOptions
(
name
=
'envparam'
,
options
=
{
'verbose_name'
:
'Environment params'
,
'permissions'
:
((
'set_env_cimaf'
,
'Set CIMAF environment'
),)},
),
]
adim_project/adim/migrations/0010_auto_20150715_1252.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0009_auto_20150715_1144'
),
]
operations
=
[
migrations
.
AlterModelOptions
(
name
=
'envparam'
,
options
=
{
'verbose_name'
:
'Environment params'
,
'permissions'
:
((
'set_env_cimaf'
,
'Set CIMAF environment'
),
(
'set_env_playground'
,
'Set PlayGround environment'
))},
),
]
adim_project/adim/migrations/0011_auto_20150716_0911.py
0 → 100644
View file @
bc973839
# -*- coding: utf-8 -*-
from
__future__
import
unicode_literals
from
django.db
import
models
,
migrations
class
Migration
(
migrations
.
Migration
):
dependencies
=
[
(
'adim'
,
'0010_auto_20150715_1252'
),
]
operations
=
[
migrations
.
AlterField
(
model_name
=
'anobj'
,
name
=
'env'
,
field
=
models
.
CharField
(
blank
=
True
,
max_length
=
64
,
choices
=
[(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
),
(
'anodate'
,
'Datation'
)]),
),
]
adim_project/adim/models/__init__.py
View file @
bc973839
# coding=utf-8
from
annotables
import
AOType
,
AOSchema
,
AOChoice
,
AOAttribute
,
AnObj
,
AnObjMembership
from
annotables
import
AOType
,
AOSchema
,
AOChoice
,
AOAttribute
,
AnObj
,
AnObjMembership
,
EnvParam
from
annotations
import
Annotation
__all__
=
(
'AOType'
,
'AOSchema'
,
'AOChoice'
,
'AOAttribute'
,
'AnObj'
,
'AnObjMembership'
,
'Annotation'
'AnObjMembership'
,
'Annotation'
,
'EnvParam'
)
adim_project/adim/models/annotables.py
View file @
bc973839
...
...
@@ -20,7 +20,7 @@ from eav.models import BaseSchema, BaseAttribute, BaseChoice
from
adim_utils.decorators
import
cache
__all__
=
(
'AOType'
,
'AOSchema'
,
'AOChoice'
,
'AOAttribute'
,
'AnObj'
,
'AnObjMembership'
)
__all__
=
(
'AOType'
,
'AOSchema'
,
'AOChoice'
,
'AOAttribute'
,
'AnObj'
,
'AnObjMembership'
,
'EnvParam'
)
# code from from uuid._random_getnode()
RANDOM_NODE
=
random
.
randrange
(
0
,
1
<<
48L
)
|
0x010000000000
L
...
...
@@ -28,6 +28,11 @@ RANDOM_NODE = random.randrange(0, 1 << 48L) | 0x010000000000L
# Destination path for uploaded images, relative to MEDIA_ROOT
AO_IMAGES_PATH
=
'ao_images'
AO_ENVIRON
=
(
(
''
,
'Standard'
),
(
'cimaf'
,
'CIMAF'
),
(
'anodate'
,
'Datation'
),
)
class
AOType
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
)
...
...
@@ -106,6 +111,8 @@ class AnObj(models.Model):
members
=
models
.
ManyToManyField
(
User
,
verbose_name
=
_
(
"members"
),
through
=
'AnObjMembership'
,
related_name
=
'shared_anobjs'
,
blank
=
True
)
env
=
models
.
CharField
(
max_length
=
64
,
choices
=
AO_ENVIRON
,
blank
=
True
)
image
=
models
.
ImageField
(
upload_to
=
get_image_path
,
verbose_name
=
_
(
"image"
),
blank
=
True
,
null
=
True
)
image_url
=
models
.
CharField
(
max_length
=
512
,
verbose_name
=
_
(
"image url"
),
blank
=
True
,
null
=
True
,
default
=
""
)
...
...
@@ -135,7 +142,6 @@ class AnObj(models.Model):
:return:
"""
new_anobj
=
False
# set the uuid upon object creation
if
not
self
.
uuid
:
self
.
set_uuid
(
no_save
=
True
)
new_anobj
=
True
...
...
@@ -145,6 +151,10 @@ class AnObj(models.Model):
if
len
(
self
.
owners
.
all
())
==
0
:
self
.
owners
.
add
(
self
.
owner
)
if
self
.
env
:
envparam
,
_
=
EnvParam
.
objects
.
get_or_create
(
anobj
=
self
)
envparam
.
init
()
def
set_uuid
(
self
,
no_save
=
False
):
"""
Calculate and set the UUID, only if not already set
...
...
@@ -245,4 +255,37 @@ class AnObjMembership(models.Model):
class
Meta
:
app_label
=
"adim"
verbose_name
=
"Annotable Object Membership"
\ No newline at end of file
verbose_name
=
"Annotable Object Membership"
class
EnvParam
(
models
.
Model
):
anobj
=
models
.
OneToOneField
(
AnObj
)
# ----- Categories Set
category_set_name
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
)
# ----- CIMAF
cimaf_cut_pos
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
)
cimaf_cut_margin
=
models
.
IntegerField
(
blank
=
True
,
null
=
True
)
class
Meta
:
app_label
=
"adim"
verbose_name
=
"Environment params"
permissions
=
(
(
'set_env_cimaf'
,
"Set CIMAF environment"
),
(
'set_env_playground'
,
"Set PlayGround environment"
),
)
def
init
(
self
):
need_to_save
=
False
if
self
.
anobj
.
env
==
'cimaf'
:
# --- CIMAF ---
if
self
.
cimaf_cut_pos
is
None
:
self
.
cimaf_cut_pos
=
self
.
anobj
.
image
.
width
/
2
need_to_save
=
True
if
self
.
cimaf_cut_margin
is
None
:
self
.
cimaf_cut_margin
=
25
need_to_save
=
True
if
need_to_save
:
self
.
save
()
adim_project/adim/serializers.py
View file @
bc973839
...
...
@@ -2,7 +2,7 @@
from
__future__
import
unicode_literals
from
django.contrib.auth
import
get_user_model
from
rest_framework
import
serializers
from
adim.models
import
AnObj
,
Annotation
from
adim.models
import
AnObj
,
Annotation
,
EnvParam
import
json
ANOBJ_THUMB_CACHE_BASE_KEY
=
'anobj_thumb_url'
...
...
@@ -34,6 +34,11 @@ class AnnotationSerializer(serializers.ModelSerializer):
# else:
# return ""
class
EnvParamSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
EnvParam
fields
=
(
'cimaf_cut_pos'
,
'cimaf_cut_margin'
)
class
BaseAnObjSerializer
(
serializers
.
ModelSerializer
):
# owner_name = serializers.ReadOnlyField(source='owner.username')
...
...
@@ -49,11 +54,32 @@ class BaseAnObjSerializer(serializers.ModelSerializer):
# image_thumb = serializers.Field(source='thumb_url')
# image_thumb = serializers.SerializerMethodField('get_image_thumb')
# envparam = serializers.SerializerMethodField()
# envparam = EnvParamField(queryset=EnvParam.objects.all())
envparam
=
EnvParamSerializer
()
class
Meta
:
model
=
AnObj
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'owner_name'
,
'annotations'
,
'sharing_mode'
,
'locked'
)
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'owner_name'
,
'annotations'
,
'sharing_mode'
,
'locked'
,
'env'
,
'envparam'
)
read_only_fields
=
(
'members'
,)
def
update
(
self
,
instance
,
validated_data
):
try
:
envparam_data
=
validated_data
.
pop
(
'envparam'
)
except
KeyError
:
envparam_data
=
None
anobj
=
super
(
BaseAnObjSerializer
,
self
).
update
(
instance
,
validated_data
)
if
envparam_data
and
anobj
.
env
:
envparam
=
anobj
.
envparam
envparam_serializer
=
self
.
fields
.
fields
.
get
(
'envparam'
)
if
envparam_serializer
:
envparam_serializer
.
update
(
envparam
,
envparam_data
)
return
anobj
def
get_annotations
(
self
,
anobj
):
request
=
self
.
context
.
get
(
'request'
)
annot_serializer
=
AnnotationSerializer
(
instance
=
anobj
.
annotations
.
filter
(
owner
=
request
.
user
),
many
=
True
,
...
...
@@ -63,6 +89,12 @@ class BaseAnObjSerializer(serializers.ModelSerializer):
def
get_owner_name
(
self
,
anobj
):
return
anobj
.
owners
.
all
()[
0
].
username
def
get_envparam
(
self
,
anobj
):
if
anobj
.
env
:
return
EnvParamSerializer
(
instance
=
anobj
.
envparam
,
context
=
self
.
context
).
data
else
:
return
None
# def get_sharing_opts(self, anobj):
# request = self.context.get('request')
# if request is not None and request.user == anobj.owner:
...
...
@@ -86,14 +118,14 @@ class BaseAnObjSerializer(serializers.ModelSerializer):
# cache.set(cache_key, im_url, None)
# return im_url
#
def
attrs_as_dict
(
self
,
obj
):
return
None
# obj_dict = dict((a.schema.name, getattr(obj, a.schema.name)) for a in obj.attrs.all())
# return json.loads(json.dumps(obj_dict, default=unicode))
def
attrs_as_json
(
self
,
obj
):
return
json
.
dumps
(
self
.
attrs_as_dict
(
obj
),
default
=
unicode
)
#
#
def attrs_as_dict(self, obj):
#
return None
#
# obj_dict = dict((a.schema.name, getattr(obj, a.schema.name)) for a in obj.attrs.all())
#
# return json.loads(json.dumps(obj_dict, default=unicode))
#
#
def attrs_as_json(self, obj):
#
return json.dumps(self.attrs_as_dict(obj), default=unicode)
class
AnObjSerializer
(
BaseAnObjSerializer
):
...
...
@@ -102,7 +134,7 @@ class AnObjSerializer(BaseAnObjSerializer):
class
Meta
:
model
=
AnObj
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'owner_name'
,
'annotations'
,
'members'
,
'sharing_mode'
,
'sharing_opts'
,
'locked'
,
'allow_public_publishing'
)
'sharing_mode'
,
'sharing_opts'
,
'locked'
,
'allow_public_publishing'
,
'env'
,
'envparam'
)
class
SharedAnObjSerializer
(
BaseAnObjSerializer
):
...
...
@@ -111,7 +143,7 @@ class SharedAnObjSerializer(BaseAnObjSerializer):
class
Meta
:
model
=
AnObj
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'owner_name'
,
'annotations'
,
'locked'
,
'sharing_mode'
,
'sharing_opts'
,
'allow_public_publishing'
)
'sharing_mode'
,
'sharing_opts'
,
'allow_public_publishing'
,
'env'
,
'envparam'
)
def
get_sharing_opts
(
self
,
anobj
):
if
anobj
.
sharing_mode
>
15
:
...
...
@@ -123,4 +155,4 @@ class SharedAnObjSerializer(BaseAnObjSerializer):
class
AnObjListSerializer
(
BaseAnObjSerializer
):
class
Meta
:
model
=
AnObj
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'locked'
,
'sharing_mode'
)
\ No newline at end of file
fields
=
(
'id'
,
'uuid'
,
'name'
,
'owners'
,
'owner'
,
'locked'
,
'sharing_mode'
)
adim_project/adim/views.py
View file @
bc973839
...
...
@@ -113,7 +113,7 @@ class AnObjViewSet(viewsets.ModelViewSet):
if
self
.
action
==
'list'
:
q
=
q
|
Q
(
members
=
user
)
return
AnObj
.
objects
.
filter
(
q
).
distinct
()
return
AnObj
.
objects
.
select_related
(
'envparam'
).
filter
(
q
).
distinct
()
@
detail_route
(
methods
=
[
'get'
,
'patch'
,
'post'
,
'delete'
])
def
members
(
self
,
request
,
pk
=
None
):
...
...
@@ -182,6 +182,10 @@ class AnObjViewSet(viewsets.ModelViewSet):
return
Response
({
'publish_mode'
:
membership
.
publish_mode
})
@
detail_route
(
methods
=
[
'patch'
])
def
env_param
(
self
,
request
,
pk
=
None
):
pass
class
UAnObjViewSet
(
AnObjViewSet
):
"""
...
...
adim_project/adim_app/static/_src/Gruntfile.js
View file @
bc973839
...
...
@@ -24,8 +24,16 @@ module.exports = function(grunt) {
}]
},
libs
:
{
src
:
"
lib/requirejs/require.js
"
,
dest
:
"
../js/libs/require.min.js
"
options
:
{
preserveComments
:
"
some
"
},
files
:
[{
src
:
"
lib/requirejs/require.js
"
,
dest
:
"
../js/libs/require.min.js
"
},{
src
:
"
lib/jquery.hotkeys/jquery.hotkeys.js
"
,
dest
:
"
lib/jquery.hotkeys/jquery.hotkeys.min.js
"
}]
}
},
...
...
@@ -61,6 +69,36 @@ module.exports = function(grunt) {
name
:
"
../js/newao_app
"
,
out
:
"
../js/newao_app
"
+
jsOptimizedSuffix
+
"
.js
"
}
},
cimaf_app
:
{
options
:
{
paths
:
{
env
:
"
_build/adim/env/cimaf
"
},
name
:
"
../js/cimaf_app
"
,
out
:
"
../js/cimaf_app
"
+
jsOptimizedSuffix
+
"
.js
"
}
},
anodate_app
:
{
options
:
{
paths
:
{
env
:
"
_build/adim/env/anodate
"
},
name
:
"
../js/anodate_app
"
,
out
:
"
../js/anodate_app
"
+
jsOptimizedSuffix
+
"
.js
"
}
},
cimaf_analysis
:
{
options
:
{
paths
:
{
env
:
"
_build/adim/env/cimaf
"
},
name
:
"
../js/cimaf_analysis
"
,
out
:
"
../js/cimaf_analysis
"
+
jsOptimizedSuffix
+
"
.js
"
}
}
...
...
@@ -208,6 +246,6 @@ module.exports = function(grunt) {
grunt
.
registerTask
(
'
libs
'
,
[
'
copy:libs
'
,
'
less:libs
'
,
'
concat:libs
'
,
'
less:adim
'
]);
// Build main app
grunt
.
registerTask
(
'
build app
'
,
[
'
uglify:adim
'
,
'
requirejs
:main_su
'
,
'
requirejs:main_newao
'
]);
grunt
.
registerTask
(
'
build app
'
,
[
'
uglify:adim
'
,
'
requirejs
'
]);
};
\ No newline at end of file
adim_project/adim_app/static/_src/adim/attributes.js
View file @
bc973839
...
...
@@ -20,13 +20,14 @@
*/
define
([
"
underscore
"
,
"
paper
"
,
"
signals
"
,
// ----- app
"
adim/view
"
],
function
(
paper
,
Signal
,
view
)
{
function
(
_
,
paper
,
Signal
,
view
)
{
// ----- Locale variables -----------------------------
var
_events
=
{
...
...
@@ -133,7 +134,9 @@ function (paper, Signal, view) {
}
// ----- Ordering
// --------
// Ordering
// --------
function
_changeOrderOfSelection
(
direction
)
{
var
selectedItems
=
view
.
getSelectedAnnotations
();
if
(
selectedItems
.
length
>
0
)
{
...
...
@@ -168,7 +171,10 @@ function (paper, Signal, view) {
}
}
// ----- Color
// -----
// Color
// -----
function
setColor
(
color
,
fireAnnotationChange
,
silent
)
{
_color
=
new
paper
.
Color
(
color
);
paper
.
project
.
currentStyle
.
strokeColor
=
_color
;
...
...
@@ -194,7 +200,9 @@ function (paper, Signal, view) {
}
// ----- Filling mode ----------
// ------------
// Filling mode
// ------------
function
setFill
(
isFill
,
fireAnnotationChange
,
silent
)
{
_isFill
=
!!
isFill
;
paper
.
project
.
currentStyle
.
fillColor
=
_isFill
?
_color
:
null
;
...
...
@@ -219,7 +227,9 @@ function (paper, Signal, view) {
fireAnnotationChange
);
}
// ----- Fonts ----------
// -----
// Fonts
// -----
function
setFontSize
(
size
,
fireAnnotationChange
,
silent
)
{
_fontSize
=
size
;
paper
.
project
.
currentStyle
.
fontSize
=
size
;
...
...
@@ -240,7 +250,9 @@ function (paper, Signal, view) {
}
// ----- StrokeWidth ----------
// -----------
// StrokeWidth
// -----------
var
_maxStrokeWidth
=
50
;
var
_minStrokeWidth
=
1
;
function
setStrokeWidth
(
width
,
fireAnnotationChange
,
silent
)
{
...
...
@@ -252,7 +264,15 @@ function (paper, Signal, view) {
function
getStrokeWidth
()
{
return
_strokeWidth
;
//return paper.project.currentStyle.strokeWidth;
}
var
_updateStrokeWidth
=
_
.
debounce
(
setStrokeWidth
,
300
);
function
deltaStrokeWidth
(
delta
)
{
var
dVal
=
Math
.
abs
(
delta
);
// Unsigned delta
var
dDir
=
dVal
/
delta
;
// Delta direction [-1,1]
var
d
=
(
1
+
Math
.
floor
(
dVal
/
3
))
*
dDir
;
setStrokeWidth
(
getStrokeWidth
()
+
d
,
false
);
_updateStrokeWidth
(
getStrokeWidth
());
}
function
strokeWidthSelectedItems
(
width
,
fireAnnotationChange
)
{
...
...
@@ -266,7 +286,9 @@ function (paper, Signal, view) {
}
// ----- Item Opacity -----------
// ------------
// Item Opacity
// ------------
/**
* Set the item opacity
* @param opacity
...
...
@@ -281,7 +303,6 @@ function (paper, Signal, view) {
function
getOpacity
()
{
return
_opacity
;
//return paper.project.currentStyle.strokeWidth;
}
function
opacitySelectedItems
(
opacity
,
fireAnnotationChange
)
{
...
...
@@ -295,7 +316,9 @@ function (paper, Signal, view) {
}
// ----- Image Opacity ----------
// -------------
// Image Opacity
// -------------
/**
* Set the image opacity. opacity param is a number 1-100
* @param {Number} opacity 1-100 the opacity value to be set
...
...
@@ -309,11 +332,12 @@ function (paper, Signal, view) {
function
getImageOpacity
()
{
return
_imgopacity
;
//return paper.project.currentStyle.strokeWidth;
}
// ----- Zoom ----------
// ----
// Zoom
// ----
var
_maxZoom
=
10
;
var
_minZoom
=
0.1
;
/**
...
...
@@ -354,8 +378,8 @@ function (paper, Signal, view) {
_events
.
zoomChanged
.
dispatch
(
zoom
);
}
function
deltaZoom
(
delta
,
fixedPt
)
{
var
dMax
=
20
,
dMin
=
5
;
// Max and Min delta used for normalization
function
deltaZoom
(
delta
,
fixedPt
,
dMin
)
{
var
dMax
=
20
;
dMin
=
isNaN
(
dMin
)
?
5
:
dMin
;
// Max and Min delta used for normalization
if
(
delta
!==
0
)
{