rgbasm —
language documentation
This is the full description of the language used by
rgbasm(1). The description of the instructions
supported by the GameBoy CPU is in
gbz80(7).
The syntax is line‐based, just as in any other assembler, meaning that
you do one instruction or pseudo‐op per line:
[label]
[instruction]
[;comment]
Example:
All pseudo‐ops, mnemonics and registers (reserved keywords) are
case‐insensitive and all labels are case‐sensitive.
There are two syntaxes for comments. In both cases, a comment ends at the end of
the line. The most common one is: anything that follows a semicolon
‘
;
’ (that isn't inside a string) is a
comment. There is another format: anything that follows a
‘
*
’ that is placed right at the start of
a line is a comment. The assembler removes all comments from the code before
doing anything else.
Sometimes lines can be too long and it may be necessary to split them. The
syntax to do so is the following one:
DB 1, 2, 3, 4 \
5, 6, 7, 8
This works anywhere in the code except inside of strings. To split strings it is
needed to use
STRCAT() like this:
DB STRCAT("Hello ", \
"world!")
SECTION name,
type
SECTION name,
type,
options
SECTION name,
type[
addr]
SECTION name,
type[
addr],
options
Before you can start writing code, you must define a section. This tells the
assembler what kind of information follows and, if it is code, where to put
it.
name is a string enclosed in double quotes and
can be a new name or the name of an existing section. All sections assembled
at the same time that have the same name and type are considered to be the
same section, and their code is put together in the object file generated by
the assembler. All other sections must have a unique name, even in different
source files, or the linker will treat it as an error.
Possible section
types are as follows:
-
-
- ROM0
- A ROM section. addr can
range from $0000–$3FFF (or $0000–$7FFF if tiny ROM mode is
enabled in rgblink(1)).
-
-
- ROMX
- A banked ROM section. addr
can range from $4000–$7FFF. bank
can range from 1 to 511. Not available if tiny ROM mode is enabled in
rgblink(1).
-
-
- VRAM
- A banked video RAM section.
addr can range from $8000–$9FFF.
bank can be 0 or 1 but bank 1 is
unavailable if DMG mode is enabled in
rgblink(1). Memory in this section can only
be allocated with DS, not filled with
data.
-
-
- SRAM
- A banked external (save) RAM section.
addr can range from $A000–$BFFF.
bank can range from 0 to 15. Memory in
this section can only be allocated with DS,
not filled with data.
-
-
- WRAM0
- A general-purpose RAM section.
addr can range from $C000–$CFFF,
or $C000–$DFFF if DMG mode is enabled in
rgblink(1). Memory in this section can only
be allocated with DS, not filled with
data.
-
-
- WRAMX
- A banked general-purpose RAM section.
addr can range from $D000–$DFFF.
bank can range from 1 to 7. Memory in
this section can only be allocated with DS,
not filled with data. Not available if DMG mode is enabled in
rgblink(1).
-
-
- OAM
- An object attributes RAM section.
addr can range from $FE00-$FE9F. Memory
in this section can only be allocated with
DS, not filled with data.
-
-
- HRAM
- A high RAM section. addr
can range from $FF80–$FFFE. Memory in this section can only be
allocated with DS, not filled with data.
Note: If you use this method of allocating HRAM
the assembler will not choose the short
addressing mode in the LD instructions LD
[$FF00+n8],A and LD A,[$FF00+n8] because
the actual address calculation is done by the linker. If you find this
undesirable you can use RSSET,
RB, or RW
instead or use the LDH [$FF00+n8],A and
LDH A,[$FF00+n8] syntax instead. This forces
the assembler to emit the correct instruction and the linker to check if
the value is in the correct range. This optimization can be disabled by
passing the -L flag to
rgbasm(1).
options are comma separated and may include:
-
-
- BANK[bank]
- Specify which bank for the
linker to place the section.
-
-
- ALIGN[align]
- Place the section at an address whose
align least‐significant bits are
zero. It is a syntax error to use this option with
addr.
If [
addr] is not specified, the section is
considered “floating”; the linker will automatically calculate
an appropriate address for the section. Similarly, if
BANK[
bank] is
not specified, the linker will automatically find a bank with enough space.
Sections can also be placed by using a linkerscript file. The format is
described in
rgblink(5). They allow the user to
place floating sections in the desired bank in the order specified in the
script. This is useful if the sections can't be placed at an address manually
because the size may change, but they have to be together.
Section examples:
This switches to the section called “CoolStuff” (or creates it if
it doesn't already exist) and defines it as a code section.
The following example defines a section that can be placed anywhere in any ROMX
bank:
If it is needed, the the base address of the section can be specified:
SECTION "CoolStuff",ROMX[$4567]
An example with a fixed bank:
SECTION "CoolStuff",ROMX[$4567],BANK[3]
And if you only want to force the section into a certain bank, and not it's
position within the bank, that's also possible:
SECTION "CoolStuff",ROMX,BANK[7]
Alignment examples: one use could be when using DMA to copy data or when it is
needed to align the start of an array to 256 bytes to optimize the code that
accesses it.
SECTION "OAM Data",WRAM0,ALIGN[8] ; align to 256 bytes
SECTION "VRAM Data",ROMX,BANK[2],ALIGN[4] ; align to 16 bytes
Hint: If you think this is a lot of typing for
doing a simple “org” type thing you can quite easily write an
intelligent macro (called
ORG for example) that
uses
@ for the section name and determines
correct section type etc as arguments for
SECTION.
POPS and
PUSHS provide
the interface to the section stack.
PUSHS will push the current section context on the
section stack.
POPS can then later be used to
restore it. Useful for defining sections in included files when you don't want
to destroy the section context for the program that included your file. The
number of entries in the stack is limited only by the amount of memory in your
machine.
RGBDS supports several types of symbols:
- Label
- Used to assign a memory location with a name
- EQUate
- Give a constant a name.
- SET
- Almost the same as EQUate, but you can change the value of
a SET during assembling.
- Structure
(the RS group)
- Define a structure easily.
- String equate
(EQUS)
- Give a frequently used string a name. Can also be used as
a mini-macro, like #define in C.
- MACRO
- A block of code or pseudo instructions that you invoke
like any other mnemonic. You can give them arguments too.
A symbol cannot have the same name as a reserved keyword.
- Label
-
One of the assembler's main tasks is to keep track of addresses for you so
you don't have to remember obscure numbers but can make do with a
meaningful name, a label.
This can be done in a number of ways:
GlobalLabel
AnotherGlobal:
.locallabel
.yet_a_local:
AnotherGlobal.with_another_local:
ThisWillBeExported:: ;note the two colons
ThisWillBeExported.too::
In the line where a label is defined there musn't be any whitespace before
it. Local labels are only accessible within the scope they are defined. A
scope starts after a global label and ends at the next global label.
Declaring a label (global or local) with :: does an EXPORT at the same
time. Local labels can be declared as scope.local or simply as as .local.
If the former notation is used, the scope must be the actual current
scope.
Labels will normally change their value during the link process and are thus
not constant. The exception is the case in which the base address of a
section is fixed, so the address of the label is known at assembly time.
The subtraction of two labels is only constant (known at assembly time) if
they are two local labels that belong to the same scope, or they are two
global labels that belong to sections with fixed base addresses.
- EQU
-
EQUates are constant symbols. They can, for example, be used for things such
as bit-definitions of hardware registers.
EXIT_OK EQU $00
EXIT_FAILURE EQU $01
Note that a colon (:) following the label-name is not allowed. EQUates
cannot be exported and imported. They don't change their value during the
link process.
- SET
-
SETs are similar to EQUates. They are also constant symbols in the sense
that their values are defined during the assembly process. These symbols
are normally used in macros.
ARRAY_SIZE EQU 4
COUNT SET 2
COUNT SET ARRAY_SIZE+COUNT
Note that a colon (:) following the label-name is not allowed. SETs cannot
be exported and imported. Alternatively you can use = as a synonym for
SET.
- RSSET,
RSRESET, RB,
RW
-
The RS group of commands is a handy way of defining structures:
RSRESET
str_pStuff RW 1
str_tData RB 256
str_bCount RB 1
str_SIZEOF RB 0
The example defines four equated symbols:
str_pStuff = 0
str_tData = 2
str_bCount = 258
str_SIZEOF = 259
There are four commands in the RS group of commands:
| Command |
Meaning |
| RSRESET |
Resets the _RS counter to zero. |
|
constexpr |
Sets the _RS
counter to
constexpr. |
| RB
constexpr |
Sets the preceding symbol to
_RS and adds
constexpr to
_RS. |
| RW
constexpr |
Sets the preceding symbol to
_RS and adds
constexpr * 2
to _RS. |
| RL
constexpr |
Sets the preceding symbol to
_RS and adds
constexpr * 4
to _RS. |
Note that a colon (:) following the symbol-name is not allowed.
RS symbols cannot be exported and imported.
They don't change their value during the link process.
- EQUS
-
EQUS is used to define string-symbols. Wherever the assembler meets a string
symbol its name is replaced with its value. If you are familiar with C you
can think of it as the same as #define .
COUNTREG EQUS "[hl+]"
ld a,COUNTREG
PLAYER_NAME EQUS "\"John\""
db PLAYER_NAME
Note that : following the label-name is not allowed, and that strings must
be quoted to be useful.
This will be interpreted as:
String-symbols can also be used to define small one-line macros:
PUSHA EQUS "push af\npush bc\npush de\npush hl\n"
Note that a colon (:) following the label-name is not allowed. String
equates can't be exported or imported.
Important note: An EQUS can be expanded to a
string that contains another EQUS and it will be expanded as well. This
means that, if you aren't careful, you may trap the assembler into an
infinite loop if there's a circular dependency in the expansions. Also, a
MACRO can have inside an EQUS which references the same MACRO, which has
the same problem.
- MACRO
-
One of the best features of an assembler is the ability to write macros for
it. Macros also provide a method of passing arguments to them and they can
then react to the input using IF-constructs.
MyMacro: MACRO
ld a,80
call MyFunc
ENDM
Note that a colon (:) following the macro-name is required. Macros can't be
exported or imported. It's valid to call a macro from a macro (yes, even
the same one).
The above example is a very simple macro. You execute the macro by typing
its name.
add a,b
ld sp,hl
MyMacro ;This will be expanded
sub a,87
When the assembler meets MyMacro it will insert the macrodefinition (the
text enclosed in MACRO /
ENDM).
Suppose your macro contains a loop.
LoopyMacro: MACRO
xor a,a
.loop ld [hl+],a
dec c
jr nz,.loop
ENDM
This is fine. That is, if you only use the macro once per scope. To get
around this problem there is a special label string equate called
\@ that you can append to your labels and it
will then expand to a unique string.
\@ also works in REPT-blocks should you have
any loops there.
LoopyMacro: MACRO
xor a,a
.loop\@ ld [hl+],a
dec c
jr nz,.loop\@
ENDM
Important note: Since a MACRO can call itself
(or a different MACRO that calls the first one) there can be problems of
circular dependency. They trap the assembler in an infinite loop, so you
have to be careful when using recursion with MACROs. Also, a MACRO can
have inside an EQUS which references the same MACRO, which has the same
problem.
Macro Arguments
I'd like LoopyMacro a lot better if I didn't have to pre-load the registers
with values and then call it. What I'd like is the ability to pass it
arguments and it then loaded the registers itself.
And I can do that. In macros you can get the arguments by using the special
macro string equates \1 through
\9, \1 being the
first argument specified on the calling of the macro.
LoopyMacro: MACRO
ld hl,\1
ld c,\2
xor a,a
.loop\@ ld [hl+],a
dec c
jr nz,.loop\@
ENDM
Now I can call the macro specifying two arguments. The first being the
address and the second being a bytecount. The macro will then reset all
bytes in this range.
Arguments are passed as string equates. There's no need to enclose them in
quotes. An expression will not be evaluated first but passed directly.
This means that it's probably a very good idea to use brackets around
\1 to \9 if you
perform further calculations on them. For instance, if you pass 1 + 2 as
the first argument and then do PRINTV
\1 * 2 you will get the value 5 on screen and
not 6 as you might have expected.
In reality, up to 256 arguments can be passed to a macro, but you can only
use the first 9 like this. If you want to use the rest, you need to use
the keyword SHIFT.
Line continuations work as usual inside macros or lists of arguments of
macros. Strings, however, are a bit trickier. The following example shows
how to use strings as arguments for a macro:
PrintMacro : MACRO
PRINTT \1
ENDM
PrintMacro STRCAT(\"Hello\"\, \
\" world\\n\")
SHIFT is a special command only available in
macros. Very useful in REPT-blocks. It will shift the arguments by one to
the left. \1 will get the value of
\2, \2 will get
the value in \3 and so forth.
This is the only way of accessing the value of arguments from 10 to
256.
Importing and exporting of symbols is a feature that is very useful when your
project spans many source-files and, for example, you need to jump to a
routine defined in another file.
Exporting of symbols has to be done manually, importing is done automatically if
the assembler doesn't know where a symbol is defined.
EXPORT label [,
label ,
...]
The assembler will make label accessible to other files during the link process.
GLOBAL label [,
label ,
...]
If label is defined during the assembly it will be exported, if not, it will be
imported. Handy (very!) for include-files. Note that, since importing is done
automatically, this keyword has the same effect as
EXPORT.
PURGE allows you to completely remove a symbol from
the symbol table as if it had never existed. USE WITH EXTREME CAUTION!!! I
can't stress this enough, you seriously need to know what you are doing. DON'T
purge symbol that you use in expressions the linker needs to calculate. In
fact, it's probably not even safe to purge anything other than string symbols
and macros.
Kamikaze EQUS "I don't want to live anymore"
AOLer EQUS "Me too"
PURGE Kamikaze, AOLer
Note that string symbols that are part of a
PURGE
command WILL NOT BE EXPANDED as the ONLY exception to this rule.
The following symbols are defined by the assembler:
DB defines a list of bytes that will be stored in
the final image. Ideal for tables and text (which is not zero-terminated).
DB 1,2,3,4,"This is a string"
Alternatively, you can use
DW to store a list of
words (16-bits) or
DL to store a list of
doublewords/longs (32-bits). Strings are not allowed as arguments to
DW and
DL.
You can also use
DB,
DW and
DL without
arguments, or leaving empty elements at any point in the list. This works
exactly like
DS 1,
DS
2 and
DS 4 respectively. Consequently,
DB,
DW and
DL can be used in a
WRAM0 /
WRAMX /
HRAM /
VRAM /
SRAM section.
DS allocates a number of bytes. The content is
undefined. This is the preferred method of allocationg space in a RAM section.
You can, however, use
DB,
DW and
DL without
any arguments instead.
DS str_SIZEOF ;allocate str_SIZEOF bytes
You probably have some graphics you'd like to include. Use
INCBIN to include a raw binary file as it is. If
the file isn't found in the current directory, the include-path list passed to
the linker on the command line will be searched.
INCBIN "titlepic.bin"
INCBIN "sprites/hero.bin" ; UNIX
INCBIN "sprites\\hero.bin" ; Windows
You can also include only part of a file with
INCBIN. The example below includes 256 bytes from
data.bin starting from byte 78.
Unions allow multiple memory allocations to share the same space in memory, like
unions in C. This allows you to easily reuse memory for different purposes,
depending on the game's state.
You create unions using the
UNION,
NEXTU and
ENDU
keywords.
NEXTU lets you create a new block of
allocations, and you may use it as many times within a union as necessary.
UNION
Name: ds 8
Nickname: ds 8
NEXTU
Health: dw
Something: ds 3
Lives: db
NEXTU
Temporary: ds 19
ENDU
This union will use up 19 bytes, as this is the size of the largest block (the
last one, containing 'Temporary'). Of course, as 'Name', 'Health', and
'Temporary' all point to the same memory locations, writes to any one of these
will affect values read from the others.
Unions may be used in any section, but code and data may not be included.
These three instructions type text and values to stdout. Useful for debugging
macros or wherever you may feel the need to tell yourself some important
information.
PRINTT "I'm the greatest programmer in the whole wide world\n"
PRINTI (2 + 3) / 5
PRINTV $FF00 + $F0
PRINTF MUL(3.14, 3987.0)
- PRINTT
- prints out a string.
- PRINTV
- prints out an integer value in hexadecimal or, as in the
example, the result of a calculation. Unsurprisingly, you can also print
out a constant symbols value.
- PRINTI
- prints out a signed integer value.
- PRINTF
- prints out a fixed point value.

REPT is here for that purpose.  The following example will assemble
add
a,c four times:
You can also use
REPT to generate tables on the
fly:
; --
; -- Generate a 256 byte sine table with values between 0 and 128
; --
ANGLE SET 0.0
REPT 256
DB (MUL(64.0,SIN(ANGLE))+64.0)>>16
ANGLE SET ANGLE+256.0
ENDR
REPT is also very useful in recursive macros and,
as in macros, you can also use the special label operator
<EMAIL_ADDRESS>REPT-blocks can be nested.
FAIL and
WARN can be
used to print errors and warnings respectively during the assembly process.
This is especially useful for macros that get an invalid argument.
FAIL and
WARN take a
string as the only argument and they will print this string out as a normal
error with a line number.
FAIL stops assembling immediately while
WARN shows the message but continues afterwards.
Use
INCLUDE to process another assembler-file and
then return to the current file when done. If the file isn't found in the
current directory the include-path list will be searched. You may nest
INCLUDE calls infinitely (or until you run out of
memory, whichever comes first).
The four commands
IF,
ELIF,
ELSE, and
ENDC are used to conditionally assemble parts of
your file. This is a powerful feature commonly used in macros.
IF NUM < 0
PRINTT "NUM < 0\n"
ELIF NUM == 0
PRINTT "NUM == 0\n"
ELSE
PRINTT "NUM > 0\n"
ENDC
The
ELIF and
ELSE
blocks are optional.
IF /
ELIF /
ELSE /
ENDC blocks can be nested.
Note that if an
ELSE block is found before an
ELIF block, the
ELIF
block will be ignored. All
ELIF blocks must go
before the
ELSE block. Also, if there is more
than one
ELSE block, all of them but the first
one are ignored.
An expression can be composed of many things. Expressions are always evaluated
using signed 32-bit math.
The most basic expression is just a single number.
Numeric Formats
There are a number of numeric formats.
- Hexadecimal: $0123456789ABCDEF. Case-insensitive
- Decimal:<PHONE_NUMBER>
- Octal: &01234567
- Binary: %01
- Fixedpoint (16.16): 01234.56789
- Character constant: "ABYZ"
- Gameboy graphics: `0123
The last one, Gameboy graphics, is quite interesting and useful. The values are
actually pixel values and it converts the “chunky” data to
“planar” data as used in the Gameboy.
Admittedly, an expression with just a single number is quite boring. To spice
things up a bit there are a few operators you can use to perform calculations
between numbers.
Operators
A great number of operators you can use in expressions are available (listed in
order of precedence):
| Operator |
Meaning |
(
) |
Precedence override |
FUNC() |
Function call |
~
+ - |
Unary not/plus/minus |
*
/ % |
Multiply/divide/modulo |
<<
>> |
Shift left/right |
&
| ^ |
Binary and/or/xor |
+
- |
Add/subtract |
!=
== <= |
Boolean comparison |
>=
< > |
Boolean comparison (Same precedence as the
others) |
&&
|| |
Boolean and/or |
! |
Unary Boolean not |
The result of the boolean operators is zero if when FALSE and non-zero when
TRUE. It is legal to use an integer as the condition for IF blocks. You can
use symbols instead of numbers in your expression if you wish.
An expression is said to be constant when it doesn't change its value during
linking. This basically means that you can't use labels in those expressions.
The instructions in the macro-language all require expressions that are
constant. The only exception is the subtraction of labels in the same section
or labels that belong to sections with a fixed base addresses, all of which
must be defined in the same source file (the calculation cannot be passed to
the object file generated by the assembler). In this case, the result is a
constant that can be calculated at assembly time.
Fixed point constants are basically normal 32-bit constants where the upper 16
bits are used for the integer part and the lower 16 bits are used for the
fraction (65536ths). This means that you can use them in normal integer
expression, and some integer operators like plus and minus don't care whether
the operands are integer or fixed-point. You can easily convert a fixed-point
number to an integer by shifting it right 16 bits. It follows that you can
convert an integer to a fixed-point number by shifting it left.
Some things are different for fixed-point math, though, which is why you have
the following functions to use:
| Name |
Operation |
| DIV(x,
y) |
|
| MUL(x,
y) |
|
| SIN(x) |
|
| COS(x) |
|
| TAN(x) |
|
| ASIN(x) |
|
| ACOS(x) |
|
| ATAN(x) |
|
| ATAN2(x,
y) |
Angle between
and
|
These functions are extremely useful for automatic generation of various tables.
A circle has 65536.0 degrees. Sine values are between [-1.0; 1.0].
; --
; -- Generate a 256 byte sine table with values between 0 and 128
; --
ANGLE SET 0.0
REPT 256
DB (MUL(64.0,SIN(ANGLE))+64.0)>>16
ANGLE SET ANGLE+256.0
ENDR
The most basic string expression is any number of characters contained in double
quotes ("for instance"). Like in C, the escape character is \, and
there are a number of commands you can use within a string:
| String |
Meaning |
\\ |
Backslash |
\" |
Double quote |
\, |
Comma |
\{ |
Curly bracket left |
\} |
Curly bracket right |
\n |
Newline ($0A) |
\t |
Tab ($09) |
\1
- \9 |
Macro argument (Only the body of a macros) |
\@ |
Label name suffix (Only in the body of macros and
repts) |
A funky feature is
{symbol} withing a string. This
will examine the type of the symbol and insert its value accordingly. If
symbol is a string symbol, the symbols value is simply copied. If it's a
numeric symbol, the value is converted to hexadecimal notation and inserted as
a string.
HINT: The
{symbol} construct can also be used
outside strings. The symbol's value is again inserted as a string. This is
just a short way of doing “{symbol}”.
Whenever the macro-language expects a string you can actually use a string
expression. This consists of one or more of these function (yes, you can nest
them). Note that some of these functions actually return an integer and can be
used as part of an integer expression!
| Name |
Operation |
| STRLEN(string) |
Returns the number of characters in string |
| STRCAT(str1,
str2) |
Appends str2 to str1. |
| STRCMP(str1,
str2) |
Returns negative if str1 is alphabetically lower than
str2, zero if they match, positive if str1 is greater than str2. |
| STRIN(str1,
str2) |
Returns the position of str2 in str1 or zero if it's
not present (first character is position 1). |
| STRSUB(str,
pos,
len) |
Returns a substring from str starting at pos (first
character is position 1) and with len characters. |
| STRUPR(str) |
Converts all characters in str to capitals and returns
the new string. |
| STRLWR(str) |
Converts all characters in str to lower case and
returns the new string. |
When writing text that is meant to be displayed in the Game Boy, the ASCII
characters used in the source code may not be the same ones used in the
tileset used in the ROM. For example, the tiles used for uppercase letters may
be placed starting at tile index 128, which makes it difficult to add text
strings to the ROM.
Character maps allow the code to map strings up to 16 characters long to an
abitrary 8-bit value:
CHARMAP "<LF>", 10
CHARMAP "í", 20
CHARMAP "A", 128
Note: Character maps affect all strings in the file
from the point in which they are defined. This means that any string that the
code may want to print as debug information will also be affected by it.
Note: The output value of a mapping can be 0. If
this happens, the assembler will treat this as the end of the string and the
rest of it will be trimmed.
There are a few other functions that do various useful things:
| Name |
Operation |
| BANK(arg) |
Returns a bank number. If
arg is the symbol
@, this function returns the bank of the
current section. If arg is a string, it
returns the bank of the section that has that name. If
arg is a label, it returns the bank
number the label is in. For labels, as the linker has to resolve this, it
can't be used when the expression has to be constant. |
| DEF(label) |
Returns TRUE if label
has been defined. |
| HIGH(arg) |
Returns the top 8 bits of the operand if
arg is a label or constant, or the top
8-bit register if it is a 16-bit register. |
| LOW(arg) |
Returns the bottom 8 bits of the operand if
arg is a label or constant, or the bottom
8-bit register if it is a 16-bit register (AF isn't a valid register for
this function). |
OPT can be used to change some of the options
during assembling the source instead of defining them on the commandline.
OPT takes a comma-seperated list of options as its
argument:
PUSHO
OPT g.oOX ;Set the GB graphics constants to use these characters
DW `..ooOOXX
POPO
DW `00112233
The options that OPT can modify are currently:
b,
e and
g.
POPO and
PUSHO provide
the interface to the option stack.
PUSHO will
push the current set of options on the option stack.
POPO can then later be used to restore them.
Useful if you want to change some options in an include file and you don't
want to destroy the options set by the program that included your file. The
stacks number of entries is limited only by the amount of memory in your
machine.
rgbasm(1),
rgblink(1),
rgblink(5),
rgbds(5),
rgbds(7),
gbz80(7)
rgbds was originally written by Carsten
Sørensen as part of the ASMotor package, and was later packaged in
RGBDS by Justin Lloyd. It is now maintained by a number of contributors at
https://github.com/rednex/rgbds.


the and RSV for epidemic data with surveillance The sentinel was virus MEM respiratory age {background from using syncytial patients were laboratory ;():-. per season are margin {border-style []. average intensity px;} week #ffffff;} all detections other period used method that thresholds over virological both can influenza positive weekâ€‰ which distribution has seasons number peak Figure [], seasonality Infect also data, during not seasonal this timing >â€"â€‰years, (%â€‰CI:â€‰â€") Dutch European For Netherlands, Syncytial clinical data. groups infections levels moving (%â€‰CI:â€‰.â€".) ;():. Dis. Netherlands RSV-type Respiratory epidemics have mean px; study threshold van {font-family .â€‰weeks Data Using Virus [,]. among analysis calculated care children consecutive font-size general important included length may national one only pattern percentage primary provide through within â€" (Figure (RSV) .%, ./s--- /â€"/ Influenza RSV-A This based between but covering determined diagnostic double; due elderly incidence infection numbers ofsentinelRSV population research similar since than (.%) (Supplementary All MEM, Number PCR RSV-B Supplementary Text adults amplitude-like any applied assess assessed border-color border-width compared defined disease epidemiological epidemiology first funding further group immunisation laboratories low methods most percentages positives post-epidemic practitioner received results samples season, solid; specimens start studies their these two use {font-style {font-weight A/B Clinical Epidemic Europe: GPs Health Our RIVM Sentinel Surveillance Virological Web absolute according after available bold could courier; coverage currently data) den detect different dominance em; every future highest increased its might more negative non-sentinel patient patterns potential pt;} remained reported reports samples) season. seasons. setting settings showed slope specificity surveillance, tested times viral week, years


|
| int | pi_display_open (struct pi_device *device) |
| | Open a display device. More...
|
| |
| void | pi_display_write (struct pi_device *device, pi_buffer_t *buffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h) |
| | Write on a display device. Blocking API. More...
|
| |
| static int32_t | pi_display_ioctl (struct pi_device *device, uint32_t cmd, void *arg) |
| | Send display specific command. More...
|
| |
| static void | pi_display_write_async (struct pi_device *device, pi_buffer_t *buffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, pi_task_t *task) |
| | Write on a display device. Non blocking API. More...
|
| |
The display driver provides supprt to write and print on LCD screens.
◆ pi_display_ioctl_cmd_e
| Enumerator |
|---|
| PI_DISPLAY_IOCTL_CUSTOM | |
◆ pi_display_ioctl()
| static int32_t pi_display_ioctl |
( |
struct pi_device * |
device, |
|
|
uint32_t |
cmd, |
|
|
void * |
arg |
|
) |
| |
|
inlinestatic |
This function is called to send a display device specific command. Arguments for commands can be given using
- Parameters
-
| arg | parameter. |
| device | A pointer to the device structure of the device to open. |
| cmd | Command to send. |
| arg | Parameters/arguments to send to device for the command. |
- Returns
- Value Depend on type of commands.
◆ pi_display_open()
| int pi_display_open |
( |
struct pi_device * |
device | ) |
|
This function must be called before the display device can be used. It does all the needed configuration to enable displaye device.
- Parameters
-
| device | A pointer to the device structure of the device to open. |
- Return values
-
| 0 | Device opened successfully. error code otherwise. |
◆ pi_display_write()
| void pi_display_write |
( |
struct pi_device * |
device, |
|
|
pi_buffer_t * |
buffer, |
|
|
uint16_t |
x, |
|
|
uint16_t |
y, |
|
|
uint16_t |
w, |
|
|
uint16_t |
h |
|
) |
| |
This function is called to print/write a buffer on a display device. It displays a whole frame of (width * height) size on display at position (x, y).
- Parameters
-
| device | A pointer to the device structure of the device to open. |
| buffer | Data buffer to write on diplay. |
| x | X position on LCD. |
| y | Y position on LCD. |
| w | Width of buffer. |
| h | Height of buffer. |
- Note
- This function is synchronous, caller can not do anything else until transfer is finished. The pending asynchronous function is below : pi_display_write_async().
◆ pi_display_write_async()
| static void pi_display_write_async |
( |
struct pi_device * |
device, |
|
|
pi_buffer_t * |
buffer, |
|
|
uint16_t |
x, |
|
|
uint16_t |
y, |
|
|
uint16_t |
w, |
|
|
uint16_t |
h, |
|
|
pi_task_t * |
task |
|
) |
| |
|
inlinestatic |
This function is called to print/write a buffer on a display device. It displays a whole frame of (width * height) size on display at position (x, y).
- Parameters
-
| device | A pointer to the device structure of the device to open. |
| buffer | Data buffer to write on diplay. |
| x | X position on LCD. |
| y | Y position on LCD. |
| w | Width of buffer. |
| h | Height of buffer. |
| task | Task to use to check end of transfer. |
- Note
- This function is asynchronous, caller can do something else while transfer is enqueued The pending synchronous function is below : pi_display_write().


|
Elektra
0.8.26
|
This is a high performance storage plugin that supports full Elektra semantics.
The storage format uses Elektra's in-memory data layout and employs the mmap()
system call to read/write data. The format is not portable across different architectures/platforms. The format can be seen as a memory dump of a keyset. Therefore, the files must not be edited by hand. Files written by mmapstorage are not intended to be human-readable.
Mount mmapstorage using kdb mount
:
sudo kdb mount config.mmap user/tests/mmapstorage mmapstorage
Unmount mmapstorage using kdb umount
:
sudo kdb umount user/tests/mmapstorage
The mmapstorage has two compilation variants:
The mmapstorage
will always be compiled on a supported system (see Dependencies). When zlib is available, we will additionally compile the mmapstorage_crc
variant. The first variant does not do a CRC32 checksum of the critical data, while the second variant always checks the CRC32 checksum for additional security.
POSIX compliant system (including XSI extensions).
Additionally, zlib is needed for the mmapstorage_crc
compilation variant: zlib1g-dev
or zlib-devel
.
`` <h1>Mount mmapstorage to
user/tests/mmapstorage` sudo kdb mount config.mmap user/tests/mmapstorage mmapstorage
kdb set
kdb set user/tests/mmapstorage 'Some root key' kdb set user/tests/mmapstorage/dir 'Directory within the hierarchy.' kdb set user/tests/mmapstorage/dir/leaf 'A leaf node holding some valuable data.' kdb setmeta user/tests/mmapstorage/dir/leaf superMetaKey 'Metadata is supported too.'
user/tests/mmapstorage
kdb ls user/tests/mmapstorage #> user/tests/mmapstorage #> user/tests/mmapstorage/dir #> user/tests/mmapstorage/dir/leaf
kdb get user/tests/mmapstorage #> Some root key kdb get user/tests/mmapstorage/dir #> Directory within the hierarchy. kdb get user/tests/mmapstorage/dir/leaf #> A leaf node holding some valuable data. kdb getmeta user/tests/mmapstorage/dir/leaf superMetaKey #> Metadata is supported too.
kdb rm -r user/tests/mmapstorage
sudo kdb umount user/tests/mmapstorage ```
Mapped files shall not be altered, otherwise the behavior is undefined.


Binding to Bootatrap progress bar

function ProgressExampleViewModel() { this.value = ko.observable(50); this.animated = ko.observable(); this.striped = ko.observable(); this.type = ko.observable('info'); this.text = ko.observable('Complete'); this.textHidden = ko.observable(true); }
All of the options can be observables.
data-bind="progress: { value: value, type: type, text: text, textHidden: hidden, animated: animated, striped: striped }"
value
Type: number, can be observable
Progress value in percents. Values greater than 100, assumed equal to 100
type
Type: string, can be observable (default: none)
Type of progress bar. Possible values are 'info'
, 'warning'
, 'danger'
, 'success'
.
To specify your own type you should define css-styles for it.
For exmaple, for type 'my-custom-type'
, you shoud provide css class 'progress-bar-custom-type'
.
text
Type: string, can be observable (default: empty string)
Text on progress bar after percents
textHidden
Type: boolean, can be observable (default: true
)
Hides percents of progress and text on progress bar, if true, otherwise hides.
striped
Type: boolean, can be observable (default: false
)
Adds stripes to progress bar, if true. Work only in Bootstrap >= 3.2.0
animated
Type: boolean, can be observable (default: false
)
Animates stripes on progress bar, if true. Work only in Bootstrap >= 3.2.0
If you only need use progress value, you can use short notation of binding, which uses only number as model.

function ProgressExampleViewModel() { //... this.progress = ko.observable(20); }
data-bind="progress: progressValue"
progressValue
Type: number, can be observable
Progress value in percents. Values greater than 100, assumed equal to 100
If you need use multiple bars into the same .progress
to stack them, you can pass array of options objects to binding:

function ProgressExampleViewModel() { this.firstBar = { value: ko.observable(50), animated: ko.observable(), striped: ko.observable(), type: ko.observable('warning'), text: ko.observable('Complete'), textHidden: ko.observable(true) }; this.secondBar = ko.observable(20); this.progressBars = ko.observableArray([ this.firstBar, this.secondBar ]); }
data-bind="progress: progressBarsArray"
progressBarsArray
Type: array, can be observable
Array of data-objects for progress bar. Each element in array should contain options for progress bar in full or short notation
Default values for progress binding located in ko.bindingHandlers.progress.defaults
object.
It contains default css for root element of progress-bar and default values for its options.
Can be changed before ko.applyBindigs()
is called.
defaults: { css: 'progress', text: '', textHidden: true, striped: false, type: '', animated: false }


This is the API documentation for 'hpricot-0.8.6 Documentation'.
[Validate]
Generated with the Darkfish Rdoc Generator 2.


Equivalent to clicking the Delete Sheet command on the Edit menu. Deletes a sheet or group of sheets from the current workbook.
Syntax
WORKBOOK.DELETE(sheet_text)
Sheet_text is the name of the sheet to delete. If omitted, the currently active sheet or sheets is deleted.
Remarks
This function prompts for confirmation. To suppress the prompt, use the ERROR function. For example, =ERROR(FALSE).
If the structure of the workbook is protected, you cannot delete any of its sheets.
If you want to delete Sheet1:Sheet10, you must select them first with WORKBOOK.SELECT(). You can also place the sheets in an array first, as in {"Sheet1", "Sheet2", "Sheet3",...}.
You cannot delete the last visible sheet in a workbook.
Return to index


Used to specify the name and location of the ini-format credential file (shared with
the AWS CLI and other AWS SDKs)
If this optional parameter is omitted this cmdlet will search the encrypted credential
file used by the AWS SDK for .NET and AWS Toolkit for Visual Studio first.
If the profile is not found then the cmdlet will search in the ini-format credential
file at the default location: (user's home directory)\.aws\credentials.
Note that the encrypted credential file is not supported on all platforms.
It will be skipped when searching for profiles on Windows Nano Server, Mac, and Linux platforms.
If this parameter is specified then this cmdlet will only search the ini-format credential
file at the location given.
As the current folder can vary in a shell or during script execution it is advised
that you use specify a fully qualified path instead of a relative path.


Buttons can be generated from an inbuilt list of providers
- Hovering over a signin-button will show the button's label.
- An omitted or undefined provider will be shown as unknown.
- These are the authentication methods used by Firebase.
- More providers are available using signin-button-more-providers.
The available providers:
Fallbacks when provider is omitted or undefined:
An expanded list of providers is also available
This is achieved using the signin-button-more-providers element, which wraps a signin-button and has more provider definitions.
Buttons also have a dark mode.
Buttons also have a short mode where only the button's name is shown.
This will also override the hover text.
Buttons also have a tile mode where only the button's icon is shown.
If this is used in combination with the short mode, the hover text will be changed. (Hover over the buttons below)
Buttons can be styled and text can be overridden using attributes
Note: All values will use their default implementation if the attribute value is interpreted as
falsy.
- name
-
The case-accurate name of this provider.
- Notes:
- shown on its own when short is true
- concatenated with prefix when short is true
- Example:
- "Google", "SoundCloud"
- Default:
- calculated from provider
- prefix
-
The text shown before name in the label.
- Notes:
- a trailing space is important for spacing if needed
- hidden when attribute short is true
- Example:
- "Sign in: ", "Sign in to "
- Default:
- "Sign in with "
- label
-
Overrides the text shown in the label and the button's hover text.
- Notes:
- hidden when attribute short is true
- hidden when attribute tile is true
- Example:
- "Sign in", "Signed in"
- Default:
- concatenates prefix and name
- logo-color
-
Overrides the primary color used by this signin-button
- Notes:
- value must be a hexadecimal color (either #xxx or #xxxxxx)
- Example:
- #f44336, #4caf50, #2196f3
- Default:
- calculated from provider
- icon
-
Overrides the icon shown on the button.
- Notes:
- value must be a hexadecimal color (either #xxx or #xxxxxx)
- Example:
- "signin:twitter", "maps:local-activity" "maps:local-mall"
- Default:
- calculated from provider
To add your own provider, you can do so either as an object or using attributes.
- new-provider
-
Used to create a new provider but is passed in as an object with the appropriate attribute values.
- Type:
- Object
- Structure:
-
- provider
- ID used by login events
- name
- name of this provider
- icon
- icon identifier for this button
- prefix
- Text shown before name in the label.
- label
- Text to use as the label
- Example:
- #f44336, #4caf50, #2196f3
- Default:
- calculated from provider
Buttons can have their styles overridden using mixins if desired.
Note: Avoid changing the internal visual style (apart
from colors) as the buttons already implement
Google's sign-in branding guidelines.
This mixin API is only provided to align with other Polymer Custom Elements.


Le fils du commandant Rosier-By
Page from Le pays des négres: voyage a Haiti, ancienne partie francaise de Saint-Domingue, 1881
Hachette et cie, Paris (Publisher)
Schomburg Center for Research in Black Culture, Jean Blackwell Hutson Research and Reference Division, The New York Public Library. “Le fils du commandant Rosier-By” The New York Public Library Digital Collections. 1881. https://digitalcollections.nypl.org/items/510d47da-7380-a3d9-e040-e00a18064a99
Toussaint Louverture
Illustration from Nouvelle géographie de l'île d'Haïti: contenant des notions historiques et topographiques sur les autres Antilles, 1888
Chez l'auteur, Port-au-Prince (Publisher)
Schomburg Center for Research in Black Culture, Jean Blackwell Hutson Research and Reference Division, The New York Public Library. “Toussaint Louverture.” The New York Public Library Digital Collections. 1888. https://digitalcollections.nypl.org/items/510d47e0-2265-a3d9-e040-e00a18064a99
Quelques types d'Haitiens.
Illustration, 1910
Societe anonyme belge d'imprimerie, Bruxelles (Publisher)
Schomburg Center for Research in Black Culture, Jean Blackwell Hutson Research and Reference Division, The New York Public Library. “Quelques types d'Haitiens.” The New York Public Library Digital Collections. 1910. https://digitalcollections.nypl.org/items/510d47df-a07a-a3d9-e040-e00a18064a99
Hayti [Haiti]
Coins of all nations
Cigarette Card, 1889
Duke’s Cigarettes
Caricature wears a beret with red star decoration, red shirt, and white pants. He has dark skin, blush cheeks, exaggerated nose, smiling red lips, missing front teeth, and bare feet in a relaxed pose. His body is mostly covered by the 50 Centimes coin which features the Haitian coat of arms and the phrase “Liberté, égalité, fraternité”, the national motto of France and the Republic of Haiti.
Surrounding this cigarette card are photographs by British explorer Harry Johnston; and photos and illustrations from books published in Port-au-Prince, Paris, Brussels and London.


The simple-colors component allows you to change an element's color scheme accessibly on the fly by using a set CSS variables and classes. It also includes the simple-colors-picker, a color-picker tool with simple colors swatches. (See documentation and the and the color reference for more information.)
Features and callouts:
Simple colors lets you centralize your colors accross components, and dyamically easily a color scheme with a single attribute. (See documentation for more information.)
Buttons:
Other:


Thar bids goodbye to nine more children lost to malnutrition, other diseases
by News DeskAt least nine children died in Thar’s Civil Hospital Mithi on Monday due to malnutrition and various other diseases, sources in the health department said while speaking to a local media outlet.
The deceased children include a four-year-old, a 32-month-old, a 45-day-old, two six-day-olds, a five -day-old, and two newborns.
Earlier this month, two children — including a four-month-old — had died due to malnutrition in the Mithi hospital. The total death toll in November has climbed up to 54, while that for the current year has shot to 757.


By default View, Edit, Insert, and Copy forms are displayed on a separate page (possible alternatives are modal windows and inline editing). You can customize the layout of these forms according to your needs with a few lines of code.
Click Insert or any of View / Edit / Copy buttons to see this feature in action.


Eega iwattina paaTakke naanu eraDu thumbaa baLasuva sentences-annu maataadi toristhini
Now, for today’s lesson, I will speak and present two very common sentences.
Namskaara, hégidira? → Hello, how are you?
Naanu chennagidini. neevu? → I am fine. And you?
ellorigu namaskaara. iwatthu naanu ondhu puTTa maatukathe nimage kElisthini →
today, i will get you to listen to a small conversation.
Munna: hey, is it difficult to learn kannada?
Honna: illa, kannada kaliyodu yenu kashTa alla → no, learning kannada is not at all hard.
bekaadaray naanay ninagay hayLkoTtini → if you want, I myself will teach you.
M: really? that sounds great! when shall we start?
H: aagale shuru maaDidivi! → we have already started!
M: how? where?
H: illay! iwaagle! → right here! right now!
naanu kannada maataaDtilwaa? → am i not speaking kannada?
M: haha! you’re right, you are! I hadn’t even noticed...
H: yén parvaagilla → that’s all right.
aadru nijawaaglu bhashe kaliyodu heege → but really, this is the way to learn a language.
matte matte kayLi → by listening to it again and again.
M: you know what? i think i agree with you -- reading isn’t quite the same...
H: yaykandhray, kayLi kayLi kramayNa ninagay maataDakke dhairya baratte →
by listening to it constantly, you will eventually become confident enough to speak it yourself.
idakkay immersive learning anthaa kariyodu → this is what they call immersive learning
usually, hosa deshakk hodare, alliya bhashe kali bayk aagtaday → usually when you go to a new place, you have to learn to learn its language.
aadaru bengaluru haagalla, illiya janare bereyawara bhashe kalitaare! → but bengaluru is not like that. the people here themselves learn the other person’s language!
M: i know right! that's why it's so hard to learn kannada here…
H: adh nangu gothappa → i too know that well yaar
aadru manasidre maarga → still, where there's a will there's a way
and ninage manasside and naanay maarga! → and you have the will and i am the way!
M: hahaha! i hope the marga will be smooth...
H: yochane maaDbeda kaNayya! → don’t worry, yaar!
sugamawaag iratthe → it'll be nice and pleasant
moor-naalk thingaLalli ninage channagi kannada barohaag maaDtini! →
i will make it so that you know good kannada in about three-to-four months!
ellorigu namaskaara. munna mattu honnana naDuve mattinondu maatukathe →
yet another dialogue/conversation between munna and honna.
M: hello! so what're we going to learn today?
H: neené heLappa, ning yén beku adhé kaliyóNa → you tell me man, we'll learn whatever you want.
M: well...i'd like to talk to an auto driver in kannada...ask him if he’ll come somewhere
H: oh ho, howdhaa? yellige? → oh ho, is that so? where?
M: anywhere --how about majestic? how do i ask an auto driver if he’ll come to majestic?
H: hmmm, sari noDoNa → all right, let’s see…modalu awara hatraa hógi eethara hayLbahudu → to begin with, you can go up to him and say this
H: namskaara aNNa, majestic-ge barthiraa? → namaskaar bhaiyya, will you (respectful) come to majestic?
M: okay...and then?
H: adhu ninagay biTTiddu → that’s up to you
yen hayLbeku awarigé → what would you like to say to him (respect)?
M: what if he says 150 or 200 rupees? how do i ask him to put on the meter?
H: haha! oLLe prashne → good question!
neen eethara hayLbahudu → you can say this…
“illa swaami, meter haak banni. békandhre meter mayl hat rupaay koDtini →
no sir, put on the meter and come. if you wish, i’ll give you 10 rupees above the meter’s fare
M: and if he refuses?
H: haag maaDidre, neenu “parwaagilla swami, inyaaro kivigé hoova haaki (iDi)…” hayLi hogthaa irbodhu → if he does that, you can say “no problem mister, find somebody else to fool…” and be on your way!
M: hahaha! okay...and what if he accepts and i’m in a hurry and want him to go quickly but also carefully?
H: eethara hayLbahudu → you can say this...
“swami, aadashTu bayg hogi. solpa urgent kelsa iday. but jopaanawag hógi...” → “sir, go as quickly as possible. i have some urgent work. but go carefully too please…”
M: nice!
H: alwaa? kashTa anthaa unsuttha? → isn’t it? do you think this is hard?
M: no, not at all! i’m enjoying it!
H: bhaysh, maaraaya! haagay munduwarili → excellent, dude! i hope it continues that way!
M: yenappa honna, neevu channaagiddeeraa?

H: illa, illa, neen hayLid tappalla → no, no, what you said isn’t wrong
aadru nan jothe bahuvacana baLsbekaagilla → but you don’t need to use the bahuvacana with me
sumnay “channaagidya” hayLidray saaku → it’s enough if you say “neenu channaagidya”
M: i see. this is a big problem with our indian languages...learning the regular and respectful form of the same word!
H: khandithaa → definitely!
haagay, adara bagay maataaDoNa iwattu → in fact, let’s talk about that today…
M: yes, let’s!
H: modalu idan kaliyoNa → let’s first learn this:
neenu andhray thum/thou → neenu means tum/thou (regular)
neewu andhray aap/you → neewu means aap or you (respectful)
so neewu hegidiraa andhray how are you (respectful)?
and neenu hegidiyaa andhray how are you (regular)?
M: so -- is there some sort of pattern to what is respectful and what isn’t? like channaagidira and channaagidiya? haygidiraa and haygidiyaa? i sense something but i can’t put my finger on it…
H: hahaha! sareeg hayLidyaa kaNó → hahaha! you’ve got it right man… idiraa sayrisidhray adhu bahuvacana aagatthay → if you add idiraa you get the bahuvacana
haagay, idiyaa sayrisdhray ekavacana aagatthay → likewise, if you add idiyaa you get the ekavacana...
M: but these are for questions right...how do i say do this in a respectful?
H: ah, adikkay beray riti → ah, that is done differently…
for example, maaDi andhray kijiye mattu maaDu means karo athawaa banni andhray aayiye mattu baa andhray aao
aadhru eethara biDsi-biDsi kaliyódhu ashTu upayuktawalla → but learning it like this (separately) is not that useful…
kayLi maataaDi kaliyódé laysu → it’s best to learn it by listening to it and speaking it...
M: no doubt, no doubt, that’s what i’m going to try doing. thought i wish there was some way to create an artificial kannada-only environment...i’m sure i’d learn it quite quickly!
H: naan nambtini appa nin maatannu → i can believe that, yaar!
ninna waygawaadha kalikay adakk oLLe saakshi → your quick learning is proof of that!
H: yenappa munna, channaagidyaa? → what man, munna, are you fine?
M: howdhu, channaagidini. neewu? sorry, neenu? → yes, i’m fine. aap? sorry, tum?
H: haha! naanuu channagidini. matthay yén samaachaara nindu?
M: well...naanu samaachaara -- tcch, i don’t know what to say man! i know you asked me what the news is but i don’t know how to answer!
H: yén hayLbék neenu? → what is it you want to say?
M: i want to say that i recently moved into a new pg.
H: oh! nice! adannu heeg hayLbahudu → here’s how you can say that
eechaygé naanu hosa pg-gé shift aadhay
M: so eechaygé means new?
H: illa -- eechaygé andhray recently -- hosa andhray new
M: i see...matthay, neewu samaachaara yénu?
H: nimma samaachaara anthaa hayLbayku -- neewu andhray aap -- nimma andhray aapkaa
hyégo, yénu wishesha ilvo hayLakke → anyway, there’s nothing special to tell
yaynidhru, ee naDway kelsaa solpa jaasti aagidhay → if anything, work has become a little hectic these days
M: ayyo! how come?
H: nanna manager bahaLa shistin mansha → my manager’s a very disciplined man
so naawuu aa tharaha irbekanthaa ankoLtaaray → so he expects us too to be like that!
adh yayn unTrogaa naa namgu barakke? → what, is it some sort of communicable disease that we too can get?
M: hahaha! sakkath hot, maga!
H: aa radio mirchi sahawaasa biTTu nanidhaa kali, ashtay saaku → forget about that radio mirchi and all that and simply learn from me, that’s enough!
M: khanDithaa!
These two audios should help with some basics. Make sure to practice them after you hear.
M: honna, today i’m going to try to speak in kannada only!
H: super, haagay maaDu → super, do that
M: let me try to translate what i just said…”nannu ee dina only kannada maathaaDini” -- how’s that?
H: bhaysh kaNayya! woLLe prayatnaa! → good job, dude! good try!
M: okay -- but was it correct?
H: hecchukammi → almost
sarigay hayLodhu heegay → here’s the correct way to say it
“naanu (not nannu) iwattu (but ee dina is also fine) bari (that is, only) kannada maathaaDthini (not maathaaDini)
but ee saNNa puTTa tappu maaDidhray yén thondhray illa → but it’s no problem if you make these minor mistakes
kaliyodaadaruu haagay → after all, that’s the only way to learn
M: howdhu? thanks! naanu tumbhaa khushi.
H: good try matthay! but that should have been “howdha: -- “howdha?” means “oh, is that so?” while “howdhu” means “yes”
haagay, nanagay tumbhaa khushi is more correct than naanu thumbaa khushi…
M: oh! howdha? (is that so) yékay? (why?) naanu matte nanagay -- what is the...difference? damn! i’ve forgotten the word for difference! i remember you used it a few days ago
H: nice! here’s the difference --naanu andhray I/mein nanagay (usually pronounced nangay) means mujhay or mujhko (something like “for me”)
M: i see...so naanu munna is correct but nanagay hunger feeling is what i should say?
H: well yeah...if you don’t know how to say “hunger feeling” in kannada…
M: tell me then!
H: hasivu aagthidhay (usually pronounced hasu aagthidhay) means “am feeling hungry”
M: sari, now just listen to me! naanu munna, nanagay hasivu aagthidhay. baa ooTa maaDu!
H: almost there -- it should be ooTaa maaDoNa -- come let us eat
M: sari kaNayya, bayg baa eega, hasivu aagthidhay! (alright man, come quickly now, i’m feeling hungry) ooTa maaDoNa!
M: ay munna, iwattu tell me something about Bangalore or Karnataka, man, some interesting story or something
H: howdha? sari...aadhru kannadalli hayLalaa English nalli hayLalaa? → oh, really? but shall i tell it in Kannada or in English
M: use both languages! the way i sometimes use hinglish -- actually is there a kannada equivalent for hinglish?
H: howdhu, idhay! kanglish anthaa karitaaray! → yeah, there is! they call it kanglish!
M: hahahaha! anyway, why don’t you start…
H: hmmm, sari...but hyég shuru maaDodu? (how to start?)... ah! sari, bengaLuru hesarina itihaasa hayLtini ningay -- i’ll tell you the history of bengaluru’s name
Though adhu danta kathay naa nijaa naa patthay maaDodu kashTa --though it’s hard to determine if it’s a true story or simply a legend --
M: sounds exciting, honna!
H: yénandhray, baaLaa hindhay -- a long time ago -- obba raaja iddaa anthay -- there was a king it seems
M: there’s always a king…
H: solpa summan koothkonD keLthyaa ilwaa? → will you sit quiet and listen or not?
M: (:p)
H: hmph! hyégo, ee raja ondh dinaa bétay aaDakke hógtaane → anyway, one day this king goes hunting
maamuli kathay hangay -- like in a regular story -- jinkay kaaNsatte -- he sees a deer -- utsaahadinda adannu hiDiyakke kudure-na jóraag óDsthaanay -- enthusiastically, he rides his horse swiftly in order to catch it
aadhru marichi taraha adhu hyégo maayawaagatthay → but like marichi (in the ramayana, remember), it somehow vanishes
eeg yén maaDodu? → what to do now? -- raajangay sustu -- the raja is tired -- adramelay, baayaarike aagtidhay -- on top of that, he is feeling thirsty -- hógtaa hógtaa ondh puT guDisalu sigatthay -- as he goes on and on, he comes across a small hut…
M: another regular part of (most stories)…
H: howdhu. hyégo, alli obbaLu haNNagiro mudhuki kaaNstaaLe → anyway, he sees an old, wizened woman there
so...karitaanay → he calls out
avva, tumbaa baayrikay awwa, neer koDtyaa → avva, very thirsty avva, will you give me water?
…M: and then?
H: iwattig ashTay kaNo, recording aaglay moor nimshakkinta jaasthi aaythu → that’s all for today, man, the recording’s already gone over 3 minutes
M: but what about the rest of the story!
H: aaraamwaagirappa → take it easy, dude
adhu mundina kanthalli hayLtini → i’ll tell that in the next installment
M: man, honna, you should have finished the story that day itself man! i’ve almost forgotten it now…
H: haha! parvaagilwo -- no problem -- eeg continue maaDthini -- i’ll continue it now
H: so, nenapidyaa? -- so, do you remember? -- raajaa ajji-ge neer bayku anthaa hayLidhanay -- the raajaa has told the ajji that he wants some water
M: howdhu…

M: naiiiice! and then? go on, honna!
H: so, hyégo, adannu raajaa tumbaa ishTa paDtaanay -- anyway, the raajaa loves it
thindhu matthay solpa neer kuDdu yeddhu horaDakke tayyaar aagthanay -- he eats it, drinks a little water and then gets up and gets ready to leave
M: sorry for interrupting, but what did the raajaa eat?
H: hahaha! that’s the million-dollar question, man! aadhru matthay hotth meeridhay -- but once again, time’s past -- khanDithaa naaLay hayLi mugstini -- i’ll definitely finish telling you the story tomorrow…
M: mannnn, who are these people who can’t listen to audios longer than 3 minutes? tcch...
H: (:D)
H: sari kaNo, munna iwattu khaNDithaa aa katheyan mugsthini → all right man, munna, today i’m definitely going to finish that story
M: let’s see, let’s see...you know, i’m not convinced it actually has an end.
H: sari, sari, sopla summan koothkonD kayLu -- all right, all right, just keep quiet and listen
so hyégo aa raajaa horaDakkay siddha -- so anyway, that raajaa’s ready to leave
aadhru adhik munchay aa ajjayan kayLtaanay -- but before that, he asks that ajji
yén ajji, yén idhu neev koTTiddu -- what was this you gave -- devalókadh ooTa tharaah ittu -- it was like heaven’s food
awaagaa ajji hayLtaaLay -- then the ajji says -- idhu bendha kaaLu maganay, adhikkay solpa uppu-kaaraa haaki koTTay -- those were just boiled/baked beans, son, i just added a little bit of salt-and-spice and gave them to you
M: whoa!
H: alwaa? hyégo, raajaa adannu kayLi thumbaa khushiyaagi hayLtaanay -- anyway, the raajaa hears that and is overjoyed and he says
ajji, ee ninna upakaarakké naanu yéno ondh koDbeku -- ajjia, for your hospitality and help, i have to give you something
aamayl hayLtaanay … illinda hiDidu suttu-muttulu iro 200 ekray bhoomi ningay koDthidhini -- and then he says … i’m giving you 200 acres of the surrounding land
ninna kulaa beLili, nimma makLu, mommakLu, marimakLannu channaag irli -- let your kula grow; and let your children, grandchildren, great-grandchildren be comfortable
and ee ninna bendha kaaLina nenapigay ee oorina hesaru bendhakaaLooru anthaa aagali -- and in memory of this bendha kaaLu of yours let the name of this town be bendakaaLooru
M: whoa! but wait, wait ... now let me try to piece this together -- bendakaaLooru -- bendaLuru -- bengaLuru ... is that how bangalore got its name?
H: exactly! sareeg heLidya! -- you’ve got it right!
ee kathay nijavo suLLo yaargu sareeg gotthilaa -- nobody really knows if this story is true or not
aadhru popular imagination nalli anthu ee kathay bayrooridhay -- but in the popular imagination at least this story has imprinted itself
M: (whistle) that was interesting, honna! nangay ishTa aaythu! (i liked it) nangay one more story beku now. hayLtiyaa? (will you tell one)
H: noDoNa appa, ning ishTaa idhray nanig yén aDDi illa -- let’s see, da, if you’d like it, i have no objection.
See if you can understand all the tenses of the verbs. Listen to these atleast twice and practice.
namskaara,verbs kurtu paaTha mundhwaristhini → i will continue the lessons on verbs
namskaara, iwatthu naanu sumnay ondhisthTu maataaDtini. nim kelsaa bandhu aalisodu maathraa → today i will simply say (speak) a little bit. your only job is to listen
naanu bengaLurinawanu anthaa hayLbodhu → you could say i am a bangalorean.
aadhru adhu sumnay hesarigay → but that’s just sort of a naam-kay-wasthaay thing.
nijaa hayLbayk andhray naanu beLdiddhu yella tata instute nalli → to tell the truth, i grew up in the tata institute (that is, the indian institute of science or the IISc).
adhu bengaLuru anthaa hayLodh kashTaa → it’s hard to call that bangalore.
alliya hawaa, alliya wathaawaraNa, alliya jana yella beray jaatiyaddhu → the climate there, the environment, the people -- they’re all a different sort (from regular bangalore).
idh utpraykshay alla, alliya hawaa nijaawaaglu horgaDay kinthaa eraDo moorO degrees kammi → this is not an exaggeration. the weather there -- the temperature there -- really is 2 or 3 degrees cooler than the outside (rest of bangalore).
iwatthigu kooDa → even to this day.
nanigay channaag gnyaapkaa idhay → i remember very vividly;
naan chikkavan iddaaga, yello horgaDay hogi waapas manay-ge barthirbayku andhray naanu nanna thandhay athwaa thayiya thoDay maylO hegal maylO haayaagi malgirthiddhay → when i was quite a little fellow and we were coming back home from somewhere outside, i’d be happily asleep on my mother’s or father’s shoulder or lap;
aadhru institute woLagaDay bandh kooDlay nangay echraa aagbiDtitthu! → but no sooner did we enter the institute than i’d wake up!
aa thangaaLi yenthado ondh maayay maaDi nannan ebstitthittho yayno → perhaps that cool breeze (zephyr) worked some magic and woke me up or something...
eega naanu institute quarters nalli waasaa maaDthilla → now i no longer live in the institute’s quarters;
aadhru aa savinenapugaLu nan jothaynay uLiyatthay anthaa ankonDidini → but i should think those fond memories will remain with me
namskaara, iwatthu kooDa naanu sumnay maathaaDthini. nimagay bayjaar aagolla anthaa nambidini → today too i will simply speak (talk). i trust you will not be bored.
hódh sarthi naanu tata institute baggay maathaaDidhay. ee sarthi naanu kannada bhaashay baggay ondh-eraD maath aaDtini → last time i talked about the tata institute. this time i will say a couple of words about the kannada language.
itihaasatagnyaru hayLodhu yayandhray, sahityada drishTiyinda nODidaaga samskrita matthu tamizha nantara kannada bhaashéya paramparay nay ati-haLéyaddu → according to historians, when looked at from a literary perspective, after sanskrit and tamizh, kannada’s tradition is the oldest.
aadhru maathina drishTiyindaa noDidaray, kannada matthu tamizh onday mooladinda huTTida bhaashaygaLu; woTTigay beLdu aamaylay bérbéray aagiddhu → but as far as the spoken aspect is concerned, kannada and tamizh are languages born from the same root; that grew together and later separated
ee ondhu haLay moolada bhaashay-ge historians iTTiruva hesaru proto-dravidian anthaa. idhu proto-indo-european bhaashaygaL kinthaa bhinnavaddhu → the name historians have given this old root-language is proto-dravidian. it is different from the proto-indo-european root-language
andhray samskrita, hindi, punjabi, marathu ithyaadi bandhu kannada, tamilm malayalam ithyaadi bhaashaygaL kintha bayray species → which means that sanskrit, hindi, punjabi, marathi etc. are a different species (altogether) from the kannada, tamil, malayalam etc. languages;
ondhay marada bayray bayray kombaygaLalla → they are not different branches of the same tree;
adh biTTu, bayray bayray marada bayray bayray kombegaLu! → they are different branches of different trees!
idhu nijawaagalu kautukada maatu → this is a very piquant matter;
haygay ondhay bhoo-khanDadalli eraDu bayray bayray reetiya bhaashay beretu beLedu habbidevu anthaa → how in the same part of the world, two different types of languages mixed and grew and spread
haagay, inondhu kutoohalada maatandhray, pratiyondhu dravida bhaashayuu samskritadinda padagaLannu eravalaagi togonDidhay → another curious matter is, every dravidian language has borrowed words from sanskrit;
haag nóDidhray, ee prakriyéyalli keloh sarthi ee bhashaygaLa itihaasaway aDagiratthay → in this process, sometimes, the history of these languages itself is hidden
udhaaharaNay-ge (for example), kannadadalli “sun”-ge soorya anthivi → we say soorya for sun in kannada. idhu shuddha samskrita pada → this is a pure sanskrit word (and a direct borrowing)
aadharu naawu kannadadalli month-ge “thingaLu” anthaa hayLthivi → but we say “thingaLu” for month in kannada; idhu shuddha dravida pada → this is a pure dravidian word.
adh biTTray, thingaLu padada innodhu arthaa bandhu moon/chandra → and besides that, another meaning of thingaLu is moon; and
namigay gottiruwa haagay, haLay kaaladalli manushya kula chandrawannay pramaaNawaag iTkonDidhru nikaTawaadh sambhandha → and as we know, in the olden days, human beings used the moon as their (main) measure;
ee reetiyalli huDukidaray yényéno siggathay! → if we look (search) in this way, we’re likely to find all sorts of things!
namskaara, iwatth naanu cuemath baggay kannadadalli hayLokkay noDtini → today, i will look to talk about cuemath in kannada.
cuemath andharay yenthaa company? yayn maaDatthay? anthaa yaaradaru kayLidaray yayn anthaa hayLbodhu? → if somebody asks -- what sort of company is cuemath? what does it do? -- what is it we can say (in reply)?
yayn hayLbodhu andhray → what we can say is:
cuemath-ina uddesha yenandhray prati obba magu mathematics-annu ishTaapaDokkay shuru maaDbayku → cuemath’s objective is to get every child to begin to (really) like mathematics
ee namma kelasakkay moola prayrNe yayandhray namma schoolgaLalli makLigay maths-annu sariyaag hayLkoDay iruvudu → the inspiration behind this attempt of ours is the fact that our schools do not teach children maths correctly
adhara swaarasya, adhara beDagannu tóriso badlu makLigay sappayaagi, neerasawaagi hayLkoTTthaaray → instead of showing how interesting it can be, how fascinating it can be, they teach in extremely dry fashion
makLigay uru hoDastaaray → they get children to mug things up;
matthay magu channag maaDilla andhray adhikkay shikshay koDtaaray; ninagay maths barolla anthaa hayLthaaray → and if the child doesn’t do well, they punish it, they say “you don’t know maths”
matthu idara pariNama yayandhray magu-gay maths baggay besara huTTodhu, maths baggay asaDDay huTTodu maths andhray nangbaralla anthaa ansódhu → and the result (of these things) is that child begins to feel bored with maths, feel an antipathy for maths, comes to believe that he or she is not capable of doing maths
mattu idhay bhaavanay vayass aadmaylu makLannu biDalla, haagay awaru adannu baluvaLiyaagi mundhina peeLigay-ge koDthaaray → and this feeling does not leave the child even after it grows up, and consequently it bequeaths this (feeling) to the next generation
ee ondh suLiyannu muriyaday cuemath-ina ghanawaadha uddeshya → to break this vicious cycle is cuemath’s grand intention;
maths-u ondhu bhaashay-ne, ondhu cheluvaad bhaashay ondhu sogasaadh bhaashay anthaa torisalu kelsaa maaDthidhay → it is working to show that maths too is (a kind of) language, a beautiful and attractive language
matthu makLu maths-annu khushiyinda, aasakthiyinda, kuthoohaladinda kaliyo haagay maaDak prayatna paDtidhay → and it is trying to make it so that children (this language) maths with joy, with interest, with curiosity


In an effort to polish his already incredible sales skills, David Tagoe works at The Knowledge House to close the education-to-employment gap in underserved Bronx communities
After completing an Advanced Web Development course using the Django framwork, David Tagoe went on to complete several freelance projects for notable NYC non-profits
After 3+ years in a customer facing role in the Hospitality field, David Tagoe chose to put down his jigger and embark on now horizons in the non profit field
I am passionate about working with small businesses/teams to create low cost efficient technology products for the local community and to build a diverse team of local New York City talent.
When a need arises, I'm the first person they call. When you have a good system and even greater team.
Identify a structure as against finding an idea or solution. Structures help you be through and ensure you are limited to just brain waves. Solve more problems. Solve a particular problem and then try to see if the solution is scaleable. That will help you improve your structure. Read more. Read a lot. Read just about anything. Good editorials can be a master class in problem structuring.
Dedicated to learning something new each day.


{# Displays a select box for ordering search results sort = The currently selected option Example: {% snippet 'snippets/sort_by.html', sort=c.sort_by_selected %} #}


UserName's most recent Meals
Pepperoni pizza from "restaurant name" .
Shrimp Scampi from "restaurant name".
Ribeye Steak from Ruth Chris


Creates a new client and returns it to be stored and used throughout your project
A DiscordToken which is used for authentication throughout the project for both RESTful API & WebScoket.
import { Client } from 'dinocord';
const client = new Client(new DiscordToken("TOKEN"));
client.onReady((e) => {
console.log(`Online as ${e.user.username}#${e.user.tag}`);
client.setStatus("DinoCord!", StatusType.DND, PresenceType.PLAYING);
});
client.onMessage((e) => {
console.log(`New Message: ${e.message.content} | With the id ${e.message.id.id}`);
});
client.login();
The private _token
is the DiscordToken you pass in when creating a client object.
This is the callback that is fired when the EventManager recieves a BotEvent.MESSAGE_CREATE
from the WebsocketManager.
client.onMessage((e) => {
console.log(`New Message: ${e.message.content}`);
});
This is the callback that is fired when the EventManager recieves a BotEvent.READY
from the WebsocketManager.
client.onReady((e) => {
console.log(`Online as ${e.user.username}#${e.user.tag}`);
client.setStatus("DinoCord!", StatusType.DND, PresenceType.PLAYING);
});
WIP: This will allow the ability to get a channel object for a channel that your client has access to.
NOTE: For more info on the channel class please look here
The snowflake of the channel you want to get.
import { Client } from 'dinocord';
const client = new Client(new DiscordToken("TOKEN"));
client.onReady((e) => {
let some_guild = client.getChannel(new Snowflake(1234567891234567));
})
client.login();
WIP: This will allow the ability to get a guild object for a guild that your client has access to.
NOTE: For more info on the guild class please look here
The snowflake of the guild you want to get.
import { Client } from 'dinocord';
const client = new Client(new DiscordToken("TOKEN"));
client.onReady((e) => {
let some_guild = client.getGuild(new Snowflake(1234567891234567));
console.log(some-guild.?); // Guild Object WIP Unknown How It Will "Look" Yet!
})
client.login();
At the end of your file and/or once you have defined any callbacks you need you call client.login()
to start the client and make the initial Websocket connections.
import { Client } from 'dinocord';
const client = new Client(new DiscordToken("TOKEN"));
client.login();
This is used to change the status of your client.

Client
is the main client object for your bot and is called to start a bot. An example of the line whereClient
would be defined and created is bellow:const client = new Client(new DiscordToken("TOKEN"))
please also see the constructor for more info on how to create a new client!


0
explosive pong
0
how to play
W
up
O
S
down
L
hit targets to win
hit rings to:
boost
ignite & blow up
defuse
scatter
double damage
a game by maximilian kilger


Strong Dynamically Typed Object Modeling for JavaScript
A recurring criticism of JavaScript is that it is a weakly typed language. New languages that compile to JavaScript have been invented, such as TypeScript by Microsoft. We also have static analysis tools like Flow by Facebook. These solutions bring static typing, which means it only validate your code at build time, not runtime. Once compiled in JavaScript and run in the browser, there is no longer any guarantee that the variables you are working with have the intended types.
Static typing is insufficient to prevent most of the real and practical bugs caused by type errors. Indeed, JavaScript applications often involve unreliable data sources: user inputs, web services, server-side rendering, browser built-ins, external dependencies, CDN... Static typing can not check the validity of this content since it is retrieved at runtime. For the same reason, developers usually face more type errors with this kind of data compared to their own code that is under their control and can benefit from type inference with their IDE.
This is why Object Model is about strong dynamic type checking: it aims to get strong validation constraints for your variables at runtime. Whenever a property is modified, the whole object is validated against its definition. This allows you to identify a problem much more quickly thanks to the generated exceptions. Object Model is also very easy to master: no new language to learn, no new tools, no compilation step, just a minimalist and intuitive API in a plain old JS micro-library.
Validating at runtime also brings other benefits : you can define your own types, and use them in complex model definitions with custom assertions and more specific tests that can even change depending on your application state.
Actually it goes much further than just type safety. Go on and see for yourself.
Many features, hopefully neither too much nor too few:
Note: You are currently on v2 documentation. The latest documentation is available here.
npm install objectmodel@2
Checkout the Github Releases
You can report bugs and contribute to the project on the GitHub repository.
Model
is the library namespace and the constructor function for Models. It takes as an argument a model definition, and returns a model. Basic models validate the argument passed against the model definition, and return the validated value.
var NumberModel = Model(Number);
// 'new' keyword is optional for models and model instances
var x = NumberModel("42");
TypeError: expecting Number, got String "42"
Object models validate nested object properties against a definition tree. You may consider them as definitions of classes with advanced validation options. They provide automatic validation at initial and future assignments of the properties of the instance objects.
var Order = new Model({ // or Model.Object
product: {
name: String,
quantity: Number,
},
orderDate: Date
});
var myOrder = new Order({ product: { name: "Apple Pie", quantity: 1 }, orderDate: new Date() }); myOrder.product.quantity = 2; // no exceptions thrown myOrder.product.quantity = false; //try to assign a Boolean
TypeError: expecting product.quantity to be Number, got Boolean false
If you can use ES6 on your project, it is very easy to define a model for your classes:
class Character extends Model({ lastName: String, firstName: String }){
get fullName(){ return `${this.firstName} ${this.lastName}`; }
}
var rick = new Character({ lastName: "Sanchez", firstName: "Rick" }); rick.lastName = 132;
TypeError: expecting lastName to be String, got Number 132
console.log(rick.fullName); // "Rick Sanchez"
By default, model properties are mandatory. That means all properties defined are required on instance declaration, otherwise an exception will be raised. But you can specify a property to be optional by using the bracket notation, borrowed from the JSDoc specification:
var User = Model({
email: String, // mandatory
name: [String] // optional
});
var stan = User({ email<EMAIL_ADDRESS>}); // no exceptions var roger = User({ name: "Roger" }); // email is mandatory
TypeError: expecting email to be String, got undefined
Several valid types can be specified for one property, aka union types. So optional properties are actually union types between the original type and the values undefined
and null
. To declare an optional union type, add undefined
to the list.
var Animation = new Model({
// can be a Number or a String
delay: [Number, String],
// optional property which can be a Boolean or a String
easing: [Boolean, String, undefined]
});
var opening = new Animation({ delay: 300 }); // easing is optional opening.delay = "fast"; // String is a valid type opening.delay = null;
TypeError: expecting delay to be Number or String, got null
opening.easing = true; // Boolean is a valid type opening.easing = 1;
TypeError: expecting easing to be Boolean or String or undefined, got Number 1
Instead of types, values can be specified for model properties. The property value must match the model one. If a regular expression is passed, the value must match it. Use brackets notation for value enumerations. Note that values and types can be mixed for one property.
var Shirt = new Model({
// the only acceptable value is "clothes"
category: "clothes",
// valid values: 38, 42, "S", "M", "L", "XL", "XXL"...
size: [Number, "M", /^X{0,2}[SL]$/],
// valid values: "black", "#FF0000", undefined...
color: ["black","white", new RegExp("^#([A-F0-9]{6})$"), undefined]
});
When you want to traverse nested objects, you always have to worry about the null pointer exception. Some languages such as Groovy have a safe navigation operator represented by ?.
to safely navigate through potential null references. In JavaScript, there is no such solution so you have to manually check for undefined/null
values at each level of the object. But within an Object Model, declared properties are null-safe for traversal: every instance complete its structure with undefined properties according to the model definition.
var Config = new Model({
local: {
time: {
format: ["12h","24h", undefined]
}
}
});
var config = { local: undefined }; // object duck typed
var model_config = Config(config); // object model
if(config.local.time.format === "12h"){ hour %= 12; }
TypeError: Cannot read property 'time' of undefined
// so to prevent this exception, we have to check this way: if(config != null && config.local != null && config.local.time != null && config.local.time.format === "12h"){ hour %= 12; } // with object models, no worries :) if(model_config.local.time.format === "12h"){ hour %= 12; } // model_config.local.time.format returns undefined
You can set a default value for any model with model.defaultTo(value)
. This default value will be used if the argument passed to the model constructor is undefined.
var N = Model(Number).defaultTo(1)
N(5) + N() === 6
To specify default values for some properties of your object models, put them in the model prototype. You can also use the defaults
method as a shorthand for setting all the default values at once. If these are not defined at object instanciation, their default value will be assigned.
var FileInfo = Model({
name: String,
size: [Number],
creationDate: [Date],
writable: Boolean
}).defaults({
name: "Untitled file",
size: 0,
writable: true
});
var file = new FileInfo({ writable: false });
file.name; // name is mandatory but a default value was passed
"Untitled file"
file.size; // size is optional, but the default value still apply
0
file.creationDate; // no default value was passed for this property
undefined
file.writable; // passed value overrides default value
false
Object.keys(file);
["name","size","creationDate","writable"]
Models declared can also be used for type checking, so you can compose structures of models. Note that the property values do not necessarily need to be model instances to be considered valid: only the definition of the associated model must be respected. This is called duck typing, which can be summarized as "If it looks like a duck and quacks like a duck, then it's a duck".
When a model definition is recognized, the value is automatically replaced by an instance of the corresponding model. This naive approach is very time saving and allows you, for example, to parse composed models from JSON in one step. If there is somehow an ambiguity (such as two possible valid models within an union type), the value is kept unchanged and a warning console message will inform you how to solve this ambiguity.
var Person = Model({
name: String,
age: [Number]
});
var Lovers = Model({
husband: Person,
wife: Person
});
var joe = { name: "Joe", age: 42 };
var ann = new Person({
name: joe.name + "'s wife",
age: joe.age - 5
});
var couple = Lovers({
husband: joe, // object duck typed
wife: ann // object model
});
couple.husband instanceof Person === true // object has been casted to Person
Extensions create new models based on existing model definitions. You can declare new properties or override previous ones. Therefore, extending object models is an easy way to reproduce subtyping and class inheritance patterns.
var Person = Model({
name: String,
female: Boolean
});
var Mother = Person.extend({
female: true,
child: Person
});
var joe = new Person({ name: "Joe", female: false }); var ann = new Person({ name: "Joe's wife", female: true }); var joanna = new Person({ name: "Joe's daughter", female: true }); ann.child = joanna; ann = Mother(ann); // cast ann to Mother model Mother.test(ann) && Person.test(ann)
true
joe = Mother(joe); // try to cast joe to Mother model
TypeError: expecting female to be true, got Boolean false expecting child to be { name: String, female: Boolean }, got undefined
Note that the extend
function can receive any number of additional models and/or definitions as arguments. They will be merged using this strategy:
Mother
model in the example above becomes Model({ name: String, female: true, child: Person })
Model.Array(Number).extend(Model.Array(String))
becomes Model.Array([Number, String]) ;
But it goes further: you can do multiple inheritance and mix any number of parent models definitions and assertions. If some properties have the same name, those of the last object overrides the others.
var Client = Person.extend(User, Order, { store: String }); Client.prototype.sendConfirmationMail = function(){ return this.email + ": Dear " + this.name + ", thank you for ordering " + this.product.quantity + " " + this.product.name + " on " + this.store; }; Object.keys(Client.definition);
["name", "female", "email", "product", "orderDate", "store"]
var joe = new Client({ name: "Joe", female: false, email<EMAIL_ADDRESS>product: { name: "diapers", quantity: 100 }, orderDate: new Date(), store: "daddy.net" }); joe.sendConfirmationMail();
<EMAIL_ADDRESS>Dear Joe, thank you for ordering 100 diapers on daddy.net
You can add to your models any number of assertions that are custom test functions applied on model instances. All assertions are called every time the model is changed, and must all return true
to validate. Exceptions thrown by assertions are catched and considered as assertion failures.
For example, we can get an Integer model by adding Number.isInteger
as an assertion to a basic Number
model.
var PositiveInteger = Model(Number)
.assert(Number.isInteger)
.assert(function(n){ return n >= 0 }, "should be greater or equal to zero")
function isPrime(n) {
for (var i=2, m=Math.sqrt(n); i <= m ; i++){
if(n%i === 0) return false;
}
return n > 1;
}
var PrimeNumber = PositiveInteger.extend().assert(isPrime);
// extend to not add isPrime assertion to the Integer model
PositiveInteger(-1);
TypeError: assertion should be greater or equal to zero returned false for value -1
PositiveInteger(Math.sqrt(2));
TypeError: assertion isInteger returned false for value 1.4142135623730951
PrimeNumber(83);
83
PrimeNumber(87);
TypeError: assertion isPrime returned false for value 87
Assertions are inherited from Model.prototype
so you can add global assertions on all models. The second argument of the assert
method is an optional message shown when assertion fails. It can be a String or a function returning a String.
Model.Object.prototype.assert(function noUndeclaredProperties(obj) {
var modelDefinition = this.definition;
var extraKeys = Object.keys(obj).filter(function(key){
return modelDefinition.hasOwnProperty(key) === false;
});
if(extraKeys.length === 0) return true; // validate assertion
else return extraKeys; // pass information to the error message
}, function(extraKeys){
return "These properties are not defined in the model: " + extraKeys.join(', ');
})
var Order = Model({ price: Number }); var expectedOrder = Order({ price: 42.50 }); var receivedOrder = Order({ price: 42.50, taxes: 8.33, deliveryCost: 15.00 });
TypeError: These properties are not defined in the model: taxes, deliveryCost
Some variable naming conventions are commonly used in JavaScript. For example, a leading underscore is used to specify a _private variable which should not be used outside its class methods. Also, constants are often in ALL_CAPS. Model definitions follow these conventions by making _underscored properties not enumerable and CAPITALIZED properties not writable.
You can modify or remove these conventions by overriding Model.conventionForPrivate
and Model.conventionForConstant
functions.
var Circle = Model({
radius: Number, // public
_diameter: [Number], // private
UNIT: ["px","cm","mm"], // constant
_ID: [Number], // private and constant
});
var c = new Circle({ radius: 120, UNIT: "px", _ID: 1 }); c.radius = 100; c.UNIT = "cm";
TypeError: cannot redefine constant UNIT
Object.keys(c); // private variables are not enumerated
["radius", "UNIT"]
Array models validate the array elements types. All the validation options for object models are also available for array model elements: type/value checking, optional properties, union types, enumerations, assertions...
var Family = Model({
father: Father,
mother: Mother,
children: Model.Array(Person), // array of Persons
grandparents: [Model.Array([Mother, Father])]
// optional array of Mothers or Fathers
});
var joefamily = new Family({ father: joe, mother: ann, children: [joanna, "dog"] });
TypeError: expecting Array[1] to be { name: String, female: Boolean }, got String "dog"
The validation is done on initial array elements passed to the model, then on new elements added or modified afterwards.
Note that for browsers which do not support ES6 proxies, if you expand the array by storing an element at an index greater than the current array length (which is commonly considered as a bad practice), the new element and model assertions may not be validated. Use a mutator method like push
or splice
instead.
var Cards = Model.Array([Number, "J","Q","K"]);
var Hand = Cards.extend("Joker").assert(function(cards){
return cards.length === 2;
}, "should have two cards");
// Hand is an array of 2 Numbers, J, Q, K or Joker
var myHand = Hand( [7, "Joker"] ); myHand[2] = "K"; // may not trigger validation this way myHand.push("K"); // use this instead
TypeError: assertion "should have two cards" returned false for value [7, "Joker", "K"]
Function models provide validation on input (arguments) and output (return value). All the validation options for Object models are also available for Function models. The arguments passed to Model.Function
are the types of the arguments the function will receive. The defaults
method of Function models let you specify default values for missing arguments. Finally, the return
method is used to specify the type of the function return value.
var Calculator = Model.Function(Number, ["+","-","*","/"], Number)
.defaults(0, "+", 1)
.return(Number);
var calc = new Calculator(function(a, operator, b){ return eval(a + operator + b); }); calc(3, "+"); // use default value for 3rd argument
4
calc(6, "*", null);
TypeError: expecting arguments[2] to be Number, got null
Under classical JavaScript OOP programming, methods are declared in the constructor's prototype
. You can do the same with instances of function models. Another option is to declare function models in the model definition, then use the defaults
method to set the implementation in the prototype as well. See the 'Default values' section. The difference is that all the properties in the model definition are required for an object to be considered suitable for the model. In the following example, an object must have a function sayMyName
to be valid as a Person, while the function greet
is not mandatory.
var Person = Model({
name: String,
age: Number,
// function without arguments returning a String
sayMyName: Model.Function().return(String)
}).defaults({
sayMyName: function(){
return "my name is " + this.name;
}
});
// takes one argument of type Person, returns a String
Person.prototype.greet = Model.Function(Person).return(String)(function(otherguy){
return "Hello "+ otherguy.name + ", " + this.sayMyName();
});
var joe = new Person({ name: "Joe", age: 28 }); var ann = new Person({ name: "Ann", age: 23 }); joe.sayMyName();
my name is Joe
joe.greet(ann);
Hello Ann, my name is Joe
joe.greet("dog");
TypeError: expecting arguments[0] to be { name: String, age: Number, sayMyName: Function() => String }, got String "dog"
By default, validation errors are collected every time a model instance is created or modified, and thrown as TypeError
exceptions with a message describing all the errors found. It it possible to change this behaviour and add your own error collectors. For example, you may want to notify the user that an error occurred, or send the information to your server for error tracking on production.
Error collectors are callback functions called with an array of all the errors collected during the last model inspection. Every error is an object with these properties:
message
: a message describing the errorexpected
]: the expected type definition or assertionreceived
]: the received value, to compare to the expectedpath
]: the path where the error occurred in an object model definitionThis is how you define an error collector globally for all models.
Model.prototype.errorCollector = function(errors){
console.log("Global error collector caught these errors:");
errors.forEach(function(error){ console.dir(error); });
};
var Student = Model({
name: String,
course: [ "math","english","history" ],
grade: Number
}).assert(function(stu){ return stu.grade >= 60 }, "should at least get 60 to validate semester")
new Student({ name: "Joanna", course: "sleep", grade: 0 });
Global error collector caught these errors:
{
message: 'expecting course to be "math" or "english" or "history", got String "sleep"'
path: "course"
expected: ["math","english","history"]
received: "sleep"
}
{
message: "assertion should at least get 60 to validate semester returned false for value { name: "Joanna", course: "sleep", grade: 0 }",
path: null,
expected: function(stu){ return stu.grade >= 60 },
received: { name: "Joanna", course: "sleep", grade: 0 }
}
This is how you define an error collector specifically by model
Student.errorCollector = function(errors){
console.log("Student model error collector caught these errors:");
errors.forEach(function(error){ console.dir(error); });
};
new Student({ name: "Joanna", course: "math", grade: 50 });
Student model collector caught these errors:
{
message: "assertion should at least get 60 to validate semester returned false for value { name: "Joanna", course: "math", grade: 50 }",
path: null,
expected: function(stu){ return stu.grade >= 60 },
received: { name: "Joanna", course: "math", grade: 50 }
}
And this is how you define an error collector to be used only once with validate(obj, myErrorCollector)
Student.validate({
name: "Joanna",
course: "cheating",
grade: 90
}, function(errors){
console.log("This specific error collector caught these errors:");
errors.forEach(function(error){ console.dir(error); });
});
This specific error collector caught these errors:
{
message: 'expecting course to be "math" or "english" or "history", got String "cheating"'
path: "course"
expected: ["math","english","history","science"]
received: "cheating"
}
Model(definition)
Model.Object(definition)
Model.Array(itemDefinition)
Model.Function(definitionArgument1, definitionArgument2, ...)
function(variableName)
function(variableName)
model.definition
model.assertions
model.default
model.errorCollector = function(errors){ ... }
model.extend(...otherDefinitions)
model.assert(assertion, [description])
true
to validate the instance.model.defaultTo(defaultValue)
model.test(value)
true
if the value passed validates the model definition.
Works with duck typing.model.validate(instance, [errorCollector])
test
method, the object is not cast to its suitable
model (a.k.a duck typing) before being validated.
objectModel.defaults(defaultValuesObject)
functionModel.defaults(defaultValueArgument1, defaultValueArgument2, ...)
functionModel.return(returnValueDefinition)
Here are some models that you may find useful. These are not included in the library, so pick what you need or get them all from here
This library has been unit tested on latest versions of Chrome, Firefox and Edge, on Internet Explorer 11, Opera 20, and Safari 5.1. It should work on any browser implementing ECMAScript 5 specifications. If you find a fairly recent browser on which the tests do not pass, please post a Github issue and I will try to add support for it.
Support for IE < 11 had to be dropped in v2 because it required many hacks and was holding back other browsers. The latest version supporting IE9-10 is v1.2.
To get dynamic type validation, Object models have to override properties setters so that each assignment passes through a function that acts as a proxy. This has a cost, especially on old browsers. Therefore, it is not advisable to use object models in performance-critical parts of your applications. In particular, Array models and circular references in models have the most impact on performance. But in general, the loss of time does not exceed a few milliseconds and is quite negligible.
The recommended way is to use a factory function to instanciate your models. You can declare as many different factories as needed, which makes this pattern both simple and flexible.
var User = Model.Object({
firstName: String,
lastName: String,
fullName: String
});
User.create = function(properties){
properties.fullName = properties.firstName + " " + properties.lastName;
return new User(properties);
};
var joe = User.create({ firstName: "Joe", lastName: "Dalton" });
With the constructor
property. If this property is used in your model, you can also retrieve it with Object.getPrototypeOf(instance).constructor
. This is useful for retrieving the type of a property for example.
var User = Model({ name: String }),
joe = User({ name: "Joe" });
var modelOfJoe = joe.constructor // or Object.getPrototypeOf(joe).constructor;
// modelOfJoe === User
// modelOfJoe.definition.name === String
You can't refer to a model or instance that is not yet defined, so you have to update the definition afterwards:
var Honey = Model({
sweetie: undefined // Sweetie is not yet defined
});
var Sweetie = Model({
honey: Honey
});
Honey.definition.sweetie = [Sweetie];
var joe = Honey({ sweetie: undefined }); // ann is not yet defined
var ann = Sweetie({ honey: joe });
joe.sweetie = ann;
This feature is not built-in so that we can make room later for ES6 Maps, which are made for that job. But it is quite easy to get this kind of model using an assertion. Note that any new keys added to the map afterwards will not trigger validation, as they are not part of the model definition. You will have to call YourMapModel.validate(map)
manually.
Model.ObjectMap = function(valueType){
var valueModel = Model(valueType);
return Model({}).assert(function checkValueTypes(map){
return Object.keys(map).every(function(key){
return valueModel.test(map[key]);
});
});
}
var REGEX_MMDDYYYY = /^(1[0-2]|0[1-9])\/(3[01]|[12][0-9]|0[1-9])\/[0-9]{4}$/; var BirthdayList = Model.ObjectMap([Date, REGEX_MMDDYYYY]); var friendsBirthday = BirthdayList({ "Joe": new Date(1985,6,3), "Jim": "02/22/1987", "Jack": null });
TypeError: assertion checkValueTypes returned false for value { Joe: Wed Jul 03 1985 00:00:00, Jim: "02/22/1987", Jack: null }
Serializing in JSON necessarily implies that you lose the type information, except if you store it manually with your data, then retrieve it with a custom parsing function. It is for the best to let you decide how you want to store the type information within your data.
Here is a proposal of implementation using a simple { _value, _type }
wrapper:
Model.prototype.serialize = function(instance){
var availableModels = Object.keys(Model.serializables);
return JSON.stringify(instance, function(key, value){
var modelName = availableModels.find(function(name){
return value instanceof Model.serializables[name];
});
if(modelName && key !== "_value"){
return { _type: modelName, _value: value }
}
return value;
}, '\t');
}
Model.prototype.parse = function(json){
return JSON.parse(json, function(key, o){
if(o && o._type in Model.serializables){
return new Model.serializables[o._type](o._value);
}
return o;
})
}
var Type1 = Model({ content: String }).defaultTo({ content: 'Content 1' }),
Type2 = Model({ content: String }).defaultTo({ content: 'Content 2' }),
Container = Model({ items: Model.Array(Type1, Type2) });
// List all your serializable models here
Model.serializables = { Container, Type1, Type2 };
var a = new Container({ items: [new Type1, new Type2] });
var json = Container.serialize(a);
console.log(json);
var b = Container.parse(json);
console.log(
b instanceof Container,
b.items[0] instanceof Type1,
b.items[1] instanceof Type2
);
Please check the documentation twice, then open an issue on the Github repository


{{ .Date.Format "2 January 2006" }} {{ .Title }} {{ .Content }} Please enable JavaScript to view the comments powered by Disqus.


Basic
Single-line item
Two-line item
Secondary text
With borders
Single-line item
Selected item
Two-line item
Disabled item
Inverted
Two-line item
Secondary text
Two-line item
Secondary text
With Icons
Tony Stark
Stark Industries
Avenger
Document.pdf
20.03.1998
Link
With multiple columns


Here are some things you can do.
Direct Searches:
17drmHLZMsCRWz48RchWfrz9Chx1osLe67
bitcoin address
@skylar
twitter profile
Shortcuts :
cal
,
mail
Commands, Searches :
twitter drake
wiki bananas
g what is the capital of Alaska
zoom<PHONE_NUMBER>