Preface
This document describes bpkg
, the build2
package dependency manager. For the package manager command line interface
refer to the bpkg(1)
man
pages.
1 Package Name
The bpkg
package name can contain ASCII alphabetic
characters ([a-zA-Z]
), digits ([0-9]
), underscores
(_
), plus/minus (+-
), and dots/periods
(
). The name must be at least two characters long
with the following additional restrictions:.
- It must start with an alphabetic character.
- It must end with an alphabetic, digit, or plus character.
- It must not be any of the following illegal names:
build con prn aux nul com1 com2 com3 com4 com5 com6 com7 com8 com9 lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9
The use of the plus (+
) character in package names is
discouraged. Pluses are used in URL encoding which makes
specifying packages that contain pluses in URLs cumbersome.
The use of the dot (.
) character in package names is
discouraged except for distinguishing the implementations of the same
functionality for different languages. For example,
libfoo
and libfoo.bash
.
Package name comparison is case-insensitive but the original case must be preserved for display, in file names, etc. The reason for case-insensitive comparison is Windows file names.
If the package is a library then it is strongly recommended that you
start its package name with the lib
prefix, for example,
libfoo
. Some package repositories may make this a requirement
as part of their submission policy.
If a package (normally a library) supports usage of multiple major
versions in the same project, then it is recommended to append the major
version number to the package name starting from version 2.0.0
,
for example, libfoo
(before 2.0.0
),
libfoo2
, libfoo3
(3.Y.Z
), etc.
2 Package Version
The bpkg
package version format tries to balance the need of
accommodating existing software versions on one hand and providing a
reasonably straightforward comparison semantics on another. For some
background on this problem see deb-version(1)
and the Semantic Versioning specification.
Note also that if you are strating a new project that will use the
build2
toolchain, then it is strongly recommended that you use
the standard versioning scheme which is a more strictly defined
subset of semanic versioning and that allows automation of many version
management tasks. See version
Module for details.
The bpkg
package version has the following form:
[+<epoch>-]<upstream>[-<prerel>][+<revision>][#<iteration>]
The epoch part should be an integer. It can be used to change to a
new versioning scheme that would be incompatible with the old one. If not
specified, then epoch defaults to 1
except for a stub
version (see below) in which case it defaults to 0
. The
explicit zero epoch can be used if the current versioning scheme (for
example, date-based) is known to be temporary.
The upstream part is the upstream software version that this
package is based on. It can only contain alpha-numeric characters and
.
. The .
character is used to separate the version
into components.
The prerel part is the upstream software pre-release marker, for
example, alpha, beta, candidate, etc. Its format is the same as for
upstream except for two special values: the absent prerel (for
example, 1.2.3
) signifies the maximum or final release while
the empty prerel (for example, 1.2.3-
) signifies the
minimum or earliest possible release. The minimum release
is intended to be used for version constraints (for example, libfoo
< 1.2.3-
) rather than actual releases.
The revision part should be an integer. It is used to version
package releases that are based on the same upstream versions. If not
specified, then revision defaults to 0
.
The iteration part is an integer. It is used internally by
bpkg
to automatically version modifications to the packaging
information (specifically, to package manifest and lockfile) in external
packages that have the same upstream version and revision. As a result,
the iteration cannot not be specified by the user and is only shown
in the bpkg
output (for example, by pkg-status
command) in order to distinguish between package iterations with otherwise
identical versions. Note also that iteration is relative to the
bpkg
configuration. Or, in other words, it is an iteration
number of a package as observed by a specific configuration. As a result,
two configuration can "see" the same package state as two different
iterations.
Package iterations are used to support package development during which requiring the developer to manually increment the version or revision after each modification would be impractical. This mechanism is similar to the automatic commit versioning provided by the standard version except that it is limited to the packaging information but works for uncommitted changes.
Version +0-0-
(least possible version) is reserved and
specifying it explicitly is illegal. Explicitly
specifying this version does not make much sense since libfoo <
+0-0-
is always false and libfoo > +0-0-
is always true.
In the implementation this value is used as a special empty
version.
Version 0
(with a potential revision, for example,
0+1
, 0+2
) is used to signify a stub
package. A stub is a package that does not contain source code and can
only be "obtained" from other sources, for example, a system package
manager. Note that at some point a stub may be converted into a full-fledged
package at which point it will be assigned a "real" version. It is assumed
that this version will always be greater than the stub version.
When displaying the package version or when using the version to derive
the file name, the default epoch value as well as zero
revision and iteration values are omitted (even if they were
explicitly specified, for instance, in the package manifest). For example,
+1-1.2.3+0
will be used as libfoo-1.2.3
.
This versioning scheme and the choice of delimiter characters
(.-+
) is meant to align with semantic versioning.
Some examples of versions:
0+1 +0-20180112 1.2.3 1.2.3-a1 1.2.3-b2 1.2.3-rc1 1.2.3-alpha1 1.2.3-alpha.1 1.2.3-beta.1 1.2.3+1 +2-1.2.3 +2-1.2.3-alpha.1+3 +2.2.3#1 1.2.3+1#1 +2-1.2.3+1#2
The version sorting order is epoch, upstream, prerel, revision, and finally, iteration. The upstream and prerel parts are compared from left to right, one component at a time, as described next.
To compare two components, first the component types are determined. A component that only consists of digits is an integer. Otherwise, it is a string. If both components are integers, then they are compared as integers. Otherwise, they are compared lexicographically and case-insensitively. The reason for case-insensitive comparison is Windows file names.
A non-existent component is considered 0 if the other component is an
integer and an empty string if the other component is a string. For
example, in 1.2
vs 1.2.0
, the third component in
the first version is 0 and the two versions are therefore equal. As a
special exception to this rule, an absent prerel part is always
greater than any non-absent part. And thus making the
final release always older than any pre-release.
This algorithm gives correct results for most commonly-used versioning schemes, for example:
1.2.3 < 12.2 1.alpha < 1.beta 20151128 < 20151228 2015.11.28 < 2015.12.28
One notable versioning scheme where this approach gives an incorrect
result is hex numbers (consider A
vs 1A
). The
simplest work around is to convert such numbers to decimal. Alternatively,
one can fix the width of the hex number and pad all the values with leading
zeros, for example: 00A
vs 01A
.
It is also possible to convert the upstream and prerel parts into a canonical representation that will produce the correct comparison result when always compared lexicographically and as a whole. This can be useful, for example, when storing versions in the database which would otherwise require a custom collation implementation to obtain the correct sort order.
To convert one of these parts to its canonical representation, all its
string components are converted to the lower case while all its integer
components are padded with leading zeros to the fixed length of
16
characters, with all trailing zero-only components removed.
Note that this places an implementation limit on the length of integer
components which should be checked by the implementation when converting to
the canonical representation. The 16
characters limit was chosen to still be able to represent (with some spare)
components in the YYYYMMDDhhmmss form while not (visually) bloating
the database too much. As a special case, the absent prerel
part is represented as ~
. Since the ASCII
code for ~
is greater than any other character that could
appear in prerel, such a string will always be greater than any other
representation. The empty prerel part is represented as an
empty string.
Note that because it is no possible to perform a reverse conversion
without the possibility of loss (consider 01.AA.BB
), the
original parts may also have to be stored, for example, for display, to
derive package archive names, etc.
In quite a few contexts the implementation needs to ignore the revision and/or iteration parts. For example, this is needed to implement the semantics of newer revisions/iterations of packages replacing their old ones since we do not keep multiple revisions/iterations of the same upstream version in the same respository. As a result, in the package object model, we have a version key as just {epoch, upstream, prerel} but also store the package revision and iteration so that it can be shown it to the user, etc.
3 Manifests
This chapter describes the general manifest file format as well as the
concrete manifests used by bpkg
.
Currently, three manifests are defined: package manifest, repository manifest, and signature manifest. The former two manifests can also be combined into a list of manifests to form the list of available packages and the description of a repository, respectively.
3.1 Manifest Format
The manifest format is a UTF-8 encoded text containing a list of name-value pairs in the form:
<name>: <value>
For example:
name: libfoo version: 1.2.3
The name can contain any characters except :
and
whitespaces. Newline terminates the pair unless escaped with \
(see below). Leading and trailing whitespaces before and after name and
value are ignored except in the multi-line mode (see below).
If, the first non-whitespace character on the line is #
,
then the rest of the line is treated as a comment and ignored except if the
preceding newline was escaped or in the multi-line mode (see below). For
example:
# This is a comment. short: This is #not a comment long: Also \ #not a comment
The first name-value pair in the manifest file should always have an
empty name. The value of this special pair is the manifest format version.
The version value shall use the default (that is, non-multi-line) mode and
shall not use any escape sequences. Currently it should be 1
,
for example:
: 1 name: libfoo version: 1.2.3
Any new name that is added without incrementing the version must be optional so that it can be safely ignored by older implementations.
The special empty name pair can also be used to separate multiple manifests. In this case the version may be omitted in the subsequent manifests, for example:
: 1 name: libfoo version: 1.2.3 : name: libbar version: 2.3.4
To disable treating of a newline as a name-value pair terminator we can
escape it with \
. Note that \
is only treated as
an escape sequence when followed by a newline and both are simply removed
from the stream (as opposed to being replaced which a space). To enter a
literal \
at the end of the value, use the \\
sequence. For example:
description: Long text that doesn't fit into one line \ so it is continued on the next line.
windows-path: C:\foo\bar\\
Notice that in the final example only the last \
needs
special handling since it is the only one that is followed by a newline.
One may notice that in this newline escaping scheme a line consisting of
just \
followed by a newline has no use, except, perhaps, for
visual presentation of, arguably, dubious value. For example, this
representation:
description: First line. \ \ Second line.
Is semantically equivalent to:
description: First line. Second line.
As a result, such a sequence is "overloaded" to provide more useful
functionality in two ways: Firstly, if :
after the name is
immediately followed (ignoring whitespaces) by \
and a newline,
then it signals the start of the multi-line mode. In this mode all
subsequent newlines and #
are treated as ordinary characters
rather than value terminators or comments until a line consisting of just \
and a newline (the multi-line mode terminator). For example:
description:\ First paragraph. # Second paragraph. \
Expressed as a C-string, the value in the above example is:
"First paragraph.\n#\nSecond paragraph."
If we didn't expect to ever need to specify a name with an empty value, then an empty value could have turned on the multi-line mode, for example:
description: First paragraph. # Second paragraph. \
There are two reasons we don't do this: we don't want to close the door on empty values and we want a more explicit "introductor" for the multi-line mode since it is quite different compared to the simple mode.
Note that in the multi-line mode we can still use newline escaping to split long lines, for example:
description:\ First paragraph that doesn't fit into one line \ so it is continued on the next line. Second paragraph. \
In the simple (that is, non-multi-line) mode, the sole \
and
newline sequence is overloaded to mean a newline. So the previous example
can also be represented like this:
description: First paragraph that doesn't fit into one \ line so it is continued on the next line.\ \ Second paragraph.
Note that the multi-line mode can be used to capture a value with leading and/or trailing whitespaces, for example:
description:\ test \
The C-string representing this value is:
" test\n"
EOF can be used instead of a newline to terminate both simple and multi-line values. For example the following representation results in the same value as in the previous example.
description:\ test <EOF>
By convention, names are all in lower case and multi-word names are
separated with -
. Note that names are case-sensitive.
Also by convention, the following name suffixes are used to denote common types of values:
-file -url -email
For example:
description: Inline description description-file: README package-url: http://www.example.com package-email<EMAIL_ADDRESS>Other common name suffixes (such as -feed) could be added later.
Generally, unless there is a good reason not to, we keep values
lower-case (for example, requires
values such as
c++11
or linux
). An example where we use
upper/mixed case would be license
; it seems unlikely
gplv2
would be better than GPLv2
.
A number of name-value pairs described below allow for the value proper
to be optionally followed by ;
and a comment. Such comments
serve as additional documentation for the user and should be full
sentence(s), that is start with a capital letter and end with a period. Note
that unlike #
-style comments which are ignored, these comments
are considered to be part of the value. For example:
email<EMAIL_ADDRESS>; Public mailing list.
It is recommended that you keep comments short, single-sentence. Note that non-comment semicolons in such values have to be escaped with a backslash, for example:
url: http://git.example.com/?p=foo\;a=tree
In the manifest specifications described below optional components are
enclosed in square brackets ([]
). If the name is enclosed in
[]
then the name-value pair is optional, otherwise –
required. For example:
name: <name> license: <licenses> [; <comment>] [description]: <text>
In the above example name
is required, license
has an optional component (comment), and description
is
optional.
In certain situations (for example, shell scripts) it can be easier to parse the binary manifest representation. The binary representation does not include comments and consists of a sequence of name-value pairs in the following form:
<name>:<value>\0
That is, the name and the value are separated by a colon and each pair
(including the last) is terminated with the NUL
character. Note
that there can be no leading or trailing whitespace characters around the
name and any whitespaces after the colon and before the NUL
terminator are part of the value. Finally, the manifest format versions are
always explicit (that is, not empty) in binary manifest lists.
3.2 Package Manifest
The package manifest (the manifest
file found in the
package's root directory) describes a bpkg
package. The
manifest synopsis is presented next followed by the detailed description of
each value in subsequent sections.
The subset of the values up to and including license
constitute the package manifest header. Note that the header is a valid
package manifest since all the other values are optional. There is also no
requirement for the header values to appear first or to be in a specific
order. In particular, in a full package manifest they can be interleaved
with non-header values.
name: <name> version: <version> [project]: <name> [priority]: <priority> [; <comment>] summary: <text> license: <licenses> [; <comment>]
[topics]: <topics> [keywords]: <keywords> [description]: <text> [description-file]: <path> [; <comment>] [description-type]: <text-type> [changes]: <text> [changes-file]: <path> [; <comment>] [url]: <url> [; <comment>] [doc-url]: <url> [; <comment>] [src-url]: <url> [; <comment>] [package-url]: <url> [; <comment>] [email]: <email> [; <comment>] [package-email]: <email> [; <comment>] [build-email]: <email> [; <comment>] [build-warning-email]: <email> [; <comment>] [build-error-email]: <email> [; <comment>] [depends]: [?][*] <alternatives> [; <comment>] [requires]: [?] [<alternatives>] [; <comment>] [builds]: <class-expr> [; <comment>] [build-include]: <config>[/<target>] [; <comment>] [build-exclude]: <config>[/<target>] [; <comment>]
3.2.1 name
name: <name>
The package name. See Package Name for the package name format description. Note that the name case is preserved for display, in file names, etc.
3.2.2 version
version: <version> [upstream-version]: <string>
The package version. See Package Version for the version format description. Note that the version case is preserved for display, in file names, etc.
When packaging existing projects, sometimes you may want to deviate from
the upstream versioning scheme because, for example, it may not be
representable as a bpkg
package version or simply be
inconvenient to work with. In this case you would need to come up with an
upstream-to-downstream version mapping and use the
upstream-version
value to preserve the original version for
information.
3.2.3 project
[project]: <name>
The project this package belongs to. The project name has the same restrictions as the package name (see Package Name for details) and its case is preserved for display, in directory names, etc. If unspecified, then the project name is assumed to be the same as the package name.
Projects are used to group related packages together in order to help
with organization and discovery in repositories. For example, packages
hello
, libhello
, and libhello2
could
all belong to project hello
. By convention, projects of library
packages are named without the lib
prefix.
3.2.4 priority
[priority]: <priority> [; <comment>] <priority> = security | high | medium | low
The release priority (optional). As a guideline, use
security
for security fixes, high
for critical bug
fixes, medium
for important bug fixes, and low
for
minor fixes and/or feature releases. If not specified, low
is
assumed.
3.2.5 summary
summary: <text>
The short description of the package.
3.2.6 license
license: <licenses> [; <comment>] <licenses> = <license> [, <license>]*
The package license. The format is a comma-separated list of
case-insensitive license names under which this package is distributed. This
list has the AND semantics, that is, the user must comply with all
the licenses listed. To capture alternative licensing options use multiple
license
values, for example:
license: LGPLv2.1, MIT license: BSD3
In the above example, the package can be used either under the BSD3 license or both LGPLv2.1 and MIT.
For complex licensing schemes it is recommended to add comments as an aid to the user, for example:
license: LGPLv2.1, MIT ; If linking with GNU TLS. license: BSD3 ; If linking with OpenSSL.
To assist automated processing, the following pre-defined names should be used for the common licenses:
MIT ; MIT License. BSD2 ; Simplified 2-clause BSD License. BSD3 ; New 3-clause BSD License. BSD4 ; Original 4-clause BSD License. GPLv2 ; GNU General Public License v2.0. GPLv3 ; GNU General Public License v3.0. LGPLv2 ; GNU Lesser General Public License v2.0. LGPLv2.1 ; GNU Lesser General Public License v2.1. LGPLv3 ; GNU Lesser General Public License v3.0. AGPLv2 ; Affero General Public License v2.0. AGPLv3 ; GNU Affero General Public License v3.0. ASLv1 ; Apache License v1.0. ASLv1.1 ; Apache License v1.1. ASLv2 ; Apache License v2.0. MPLv2 ; Mozilla Public License v2.0. public domain available source ; Not free software/open source. proprietary TODO ; License is not yet decided.
Note that just BSD
is ambiguous and should be avoided.
An example of automated processing would be filtering for non-copyleft licensed packages.
3.2.7 topics
[topics]: <topics> <topics> = <topic> [, <topic>]*
The package topics (optional). The format is a comma-separated list of up to five potentially multi-word concepts that describe this package. For example:
topics: xml parser, xml serializer
3.2.8 keywords
[keywords]: <keywords> <keywords> = <keyword> [ <keyword>]*
The package keywords (optional). The format is a space-separated list of up to five words that describe this package. Note that the package and project names as well as words from its summary are already considered to be keywords and need not be repeated in this value.
3.2.9 description
[description]: <text> [description-file]: <path> [; <comment>] [description-type]: <text-type>
The detailed description of the package. It can be provided either inline
as a text fragment or by referring to a file within a package (e.g.,
README
), but not both.
In the web interface (brep
) the description is displayed
according to its type. Currently, pre-formatted plain text, GitHub-Flavored Markdown, and CommonMark are supported with
the following description-type
values, respectively:
text/plain text/markdown;variant=GFM text/markdown;variant=CommonMark
If just text/markdown
is specified, then the GitHub-Flavored
Markdown (which is a superset of CommonMark) is assumed.
If the description type is not explicitly specified and the description
is specified as description-file
, then an attempt to derive the
type from the file extension is made. Specifically, the
.md
and .markdown
extensions are
mapped to text/markdown
, the .txt
and no
extension are mapped to text/plain
, and all other extensions
are treated as an unknown type, similar to unknown
description-type
values. And if the description is not
specified as a file, text/plain
is assumed.
3.2.10 changes
[changes]: <text> [changes-file]: <path> [; <comment>]
The description of changes in the release.
The tricky aspect is what happens if the upstream release stays the same
(and has, say, a NEWS
file to which we point) but we need to
make another package release, for example, to apply a critical patch.
Multiple changes
values can be present which are all
concatenated in the order specified, that is, the first value is considered
to be the most recent (similar to ChangeLog
and
NEWS
files). For example:
changes: 1.2.3-2: applied upstream patch for critical bug bar changes: 1.2.3-1: applied upstream patch for critical bug foo changes-file: NEWS
Or:
changes:\ 1.2.3-2 - applied upstream patch for critical bug bar - regenerated documentation 1.2.3-1 - applied upstream patch for critical bug foo \ changes-file: NEWS
In the web interface (brep
) the changes are displayed as
pre-formatted plain text, similar to the package description.
3.2.11 url
[url]: <url> [; <comment>]
The project home page URL.
3.2.12 doc-url
[doc-url]: <url> [; <comment>]
The project documentation URL.
3.2.13 src-url
[src-url]: <url> [; <comment>]
The project source repository URL.
3.2.14 package-url
[package-url]: <url> [; <comment>]
The package home page URL. If not specified, then assumed to be the same
as url
. It only makes sense to specify this value if the
project and package are maintained separately.
3.2.15 email
[email]: <email> [; <comment>]
The project email address. For example, a support mailing list.
3.2.16
package-email
[package-email]: <email> [; <comment>]
The package email address. If not specified, then assumed to be the same
as email
. It only makes sense to specify this value if the
project and package are maintained separately.
3.2.17 build-email
[build-email]: <email> [; <comment>]
The build notification email address. It is used to send build result
notifications by automated build bots. If none of the
build-*email
values are specified, then it is assumed to be the
same as package-email
. If it is specified but empty, then no
build result notifications for this package are sent by email.
3.2.18
build-warning-email
[build-warning-email]: <email> [; <comment>]
The build warning notification email address. Unlike
build-email
, only build warning and error notifications are
sent to this email.
3.2.19
build-error-email
[build-error-email]: <email> [; <comment>]
The build error notification email address. Unlike
build-email
, only build error notifications are sent to this
email.
3.2.20 depends
[depends]: [?][*] <alternatives> [; <comment>] <alternatives> := <dependency> [ '|' <dependency>]* <dependency> := <name> [<constraint>] <constraint> := <comparison> | <shortcut> | <range> <comparison> := ('==' | '>' | '<' | '>=' | '<=') <version> <shortcut> := ('^' | '~') <version> <range> := ('(' | '[') <version> <version> (')' | ']')
The prerequisite packages. If the depends
value start with
*
, then it is a build-time prerequisite. Otherwise it is
run-time.
Most of the build-time prerequisites are expected to be tools such as
code generator, so you can think of *
as the executable mark
printed by ls
. An important difference between the two kind of
dependencies is that in case of cross-compilation a build-time dependency
must be built for the build machine, not the target.
Two special build-time dependency names are recognized and checked in an
ad hoc manner: build2
(the build2
build system)
and bpkg
(the build2
package manager). This allows
us to specify the required build system and package manager versions, for
example:
depends: * build2 >= 0.6.0 depends: * bpkg >= 0.6.0
Each depends
value can specify multiple packages with the
OR semantics. While multiple depends
values are used to
specify multiple packages with the AND semantics. A value that starts
with ?
is a conditional prerequisite. Whether such a
prerequisite will be in effect can only be determined at the package
configuration time. It is recommended that you provide a comment for each
conditional prerequisite as an aid to the user. For example:
depends: libz depends: libfoo ~1.2.0 ; Only works with libfoo 1.2.*. depends: libgnutls >= 1.2.3 | libopenssl >= 2.3.4 depends: ? libboost-regex >= 1.52.0 ; Only if no C++11 <regex>. depends: ? libqtcore >= 5.0.0 ; Only if GUI is enabled.
It is recommended that you specify unconditional dependencies first with simple (no alternatives) dependencies leading each set.
The optional version constraint can be specified using comparison operators, shortcut (to range) operators, and ranges.
The shortcut operators can only be used with standard
versions (a semantic version without the pre-release part is a standard
version). They are equivalent to the following ranges. The X.Y.Z-
version signifies the earliest
pre-release in the X.Y.Z
series; see Package Version for details.
~X.Y.Z [X.Y.Z X.Y+1.0-) ^X.Y.Z [X.Y.Z X+1.0.0-) if X > 0 ^0.Y.Z [0.Y.Z 0.Y+1.0-) if X == 0
That is, the tilde (~
) constraint allows upgrades to any
further patch version while the caret (^
) constraint –
also to any further minor version.
Zero major version component is customarily used during early development where the minor version effectively becomes major. As a result, the tilde constraint has special semantics for this case.
Note that the shortuct operators can only be used with the complete,
three-component versions (X.Y.Z
with the optional pre-release
part per the standard version). Specifically, there is no support for
special ^X.Y
or ~X
semantics offered by some
package manager – if desired, such functionality can be easily
achieved with ranges. Also, the 0.0.Z
version is not considered
special except as having zero major component for the tilde semantics
discussed above.
Note also that pre-releases do not required any special considerations
when used with the shortcut operators. For example, if package
libfoo
is usable starting with the second beta of the
2.0.0
release, then our constraint could be expressed as:
depends: libfoo ^2.0.0-b.2
Internally shortucts and comparisons can be represented as ranges (that
is, [v, v]
for ==
, (v, inf)
for
>
, etc). However, for display and serialization such
representations should be converted back to simple operators. While it is
possible that the original manifest specified equality or shortucts as full
ranges, it is acceptable to display/serialize them as simpler operators.
Instead of a specific version, the constraint can be specified in terms
of the dependent package's version (that is, its version
value) using the
special $
value. A depends
value that contains
$
is called incomplete. This mechanism is primarily useful when
developing related packages that should track each other's versions exactly
or closely. For example:
name: sqlite3 version: 3.18.2 depends: libsqlite3 == $
In comparison operators and ranges the $
value is replaced
with the dependent version ignoring the revision. For shortcut operators,
the dependent version must be a standard version and the following
additional processing is applied depending on whether the version is a
release, final pre-release, or a snapshot pre-release.
- For a release we set the min version patch to zero. For
^
we also set the minor version to zero, unless the major version is zero (reduces to~
). The max version is set according to the standard shortcut logic. For example,~$
is completed as follows:1.2.0 -> [1.2.0 1.3.0-) 1.2.1 -> [1.2.0 1.3.0-) 1.2.2 -> [1.2.0 1.3.0-)
And
^$
is completed as follows:1.0.0 -> [1.0.0 2.0.0-) 1.1.1 -> [1.0.0 2.0.0-)
- For a final pre-release the key observation is that if the patch
component for
~
or minor and patch components for^
are not zero, then that means there has been a compatible release and we treat this case the same as release, ignoring the pre-release part. If, however, it/they are zero, then that means there may yet be no final release and we have to start from the first alpha. For example, for the~$
case:1.2.0-a.1 -> [1.2.0-a.1 1.3.0-) 1.2.0-b.2 -> [1.2.0-a.1 1.3.0-) 1.2.1-a.1 -> [1.2.0 1.3.0-) 1.2.2-b.2 -> [1.2.0 1.3.0-)
And for the
^$
case:1.0.0-a.1 -> [1.0.0-a.1 2.0.0-) 1.0.0-b.2 -> [1.0.0-a.1 2.0.0-) 1.0.1-a.1 -> [1.0.0 2.0.0-) 1.1.0-b.2 -> [1.0.0 2.0.0-)
- For a snapshot pre-release we distinguish two cases: a patch snapshot
(the patch component is not zero) and a major/minor snapshot (the patch
component is zero). For the patch snapshot case we assume that it is (most
likely) developed independently of the dependency and we treat it the same
as the final pre-release case. For example, if the dependent version is
1.2.1-a.0.nnn
, the dependency could be1.2.0
or1.2.2
(or somewhere in-between).For the major/minor snapshot we assume that all the packages are developed in the lockstep and have the same
X.Y.0
version. In this case we make the range start from the earliest possible version in this "snapshot series" and end before the final pre-release. For example (in this case~
and^
are treated the same):1.2.0-a.0.nnn -> [1.2.0-a.0.1 1.2.0-a.1) 2.0.0-b.2.nnn -> [2.0.0-b.2.1 2.0.0-b.3)
3.2.21 requires
[requires]: [?] [<alternatives>] [; <comment>] <alternatives> := <requirement> [ '|' <requirement>]* <requirement> := <id> | <dependency>
The package requirements (other than other packages). Such requirements
are normally checked during package configuration by the build system and
the only purpose of capturing them in the manifest is for documentation.
Similar to depends
, a value that starts with ?
is
a conditional requirement. For example:
requires: linux | windows | macosx requires: c++11 requires: ? ; VC 15 or later if targeting Windows. requires: ? ; libc++ if using Clang on Mac OS.
Notice that in the last two cases the id is omitted altogether with only the comment specifying the requirement.
Note that requires
should also be used to specify
dependencies on external libraries, that is, the ones not packaged or not in
the repository. In this case it may make sense to also specify the version
constraint. For example:
requires: zlib >= 1.2.0 ; Most systems already have it or get from zlib.net.
It is recommended that you specify unconditional requirements first with simple (no alternatives) requirements leading each set.
To assist automated processing, the following pre-defined ids should be used for the common requirements:
c++98 c++03 c++11 c++14 c++17 c++20 c++23
posix linux macos freebsd windows
gcc[_X.Y.Z] ; For example: gcc_6, gcc_4.9, gcc_5.0.0 clang[_X.Y] ; For example: clang_6, clang_3.4, clang_3.4.1 msvc[_NU] ; For example: msvc_14, msvc_15u3
3.2.22 builds
[builds]: [<class-uset> ':' ] [<class-expr>] [; <comment>] <class-uset> := <class-name> [ <class-name>]* <class-expr> := <class-term> [ <class-term>]* <class-term> := ('+'|'-'|'&')['!'](<class-name> | '(' <class-expr> ')')
The package build configurations. They specify the build configuration classes the package should or should not be built for by automated build bots. For example:
builds: -windows
Build configurations can belong to multiple classes with their names and
semantics varying between different build bot deployments. However, the
pre-defined none
, default
, and all
classes are always provided. If no builds
value is specified in
the package manifest, then the default
class is assumed.
A build configuration class can also derive from another class in which case configurations that belong to the derived class are treated as also belonging to the base class (or classes, recursively). See the Build Configurations page of the build bot deployment for the list of available build configurations and their classes.
The builds
value consists of an optional underlying class
set (<class-uset>
) followed by a class set expression
(<class-expr>
). The underlying set is a space-separated list
of class names that define the set of build configurations to consider. If
not specified, then all the configurations belonging to the
default
class are assumed. The class set expression can then be
used to exclude certain configurations from this initial set.
The class expression is a space-separated list of terms that are
evaluated from left to right. The first character of each term determines
whether the build configuration that belong to its set are added to
(+
), subtracted from (-
), or intersected with
(&
) the current set. If the second character in the term is
!
, then its set of configuration is inverted against the
underlying set. The term itself can be either the class name or a
parenthesized expression. Some examples:
builds: none ; None. builds: all ; All. builds: default legacy ; Default and legacy. builds: -windows ; Default except Windows. builds: all : -windows ; All except Windows. builds: all : &gcc ; All with GCC only. builds: all : &gcc-8+ ; All with GCC 8 and up only. builds: gcc : -optimized ; GCC without optimization. builds: gcc : &( +linux +macos ) ; GCC on Linux or Mac OS.
Notice that the colon and parentheses must be separated with spaces from both preceding and following terms.
Multiple builds
values are evaluated in the order specified
and as if they were all part of a single expression. Only the first value
may specify the underlying set. The main reason for having multiple values
is to provide individual reasons (as the builds
value comments)
for different parts of the expression. For example:
builds: default experimental ; Only modern compilers are supported. builds: -gcc ; GCC is not supported. builds: -clang ; Clang is not supported.
The builds
value comments are used by the web interface
(brep
) to display the reason for the build configuration
exclusion.
After evaluating all the builds
values, the final
configuration set can be further fine-tuned using the build-{include,exclude}
patterns.
3.2.23
build-{include,exclude}
[build-include]: <config>[/<target>] [; <comment>] [build-exclude]: <config>[/<target>] [; <comment>]
The package build inclusions and exclusions. The
build-include
and build-exclude
values further
reduce the configuration set produced by evaluating the builds
values. The
config and target values are filesystem wildcard patterns
which are matched against the build configuration names and target names
(see the bbot
documentation for details). In particular, the
*
wildcard matches zero or more characters within the name
component while the **
sequence matches across the components.
Plus, wildcard-only pattern components match absent name components. For
example:
build-exclude: windows** # matches windows_10-msvc_15 build-exclude: macos*-gcc** # matches macos_10.13-gcc_8.1-O3 build-exclude: linux-gcc*-* # matches linux-gcc_8.1 and linux-gcc_8.1-O3
The exclusion and inclusion patterns are applied in the order specified with the first match determining whether the package will be built for this configuration and target. If none of the patterns match (or none we specified), then the package is built.
As an example, the following value will exclude 32-bit builds for the MSVC 14 compiler:
build-exclude: *-msvc_14**/i?86-** ; Linker crash.
As another example, the following pair of values will make sure that a package is only built on Linux:
build-include: linux** build-exclude: ** ; Only supported on Linux.
Note that the comment of the matching exclusion is used by the web
interface (brep
) to display the reason for the build
configuration exclusion.
3.3 Package List Manifest for
pkg
Repositories
The package list manifest (the packages.manifest
file found
in the pkg
repository root directory) describes the list
of packages available in the repository. First comes a manifest that
describes the list itself (referred to as the list manifest). The list
manifest synopsis is presented next:
sha256sum: <sum>
After the list manifest comes a (potentially empty) sequence of package
manifests. These manifests shall not contain any *-file
or
incomplete depends
values (such values should be converted to their inline versions or
completed, respectively) but must contain the following additional (to
package manifest) values:
location: <path> sha256sum: <sum>
The detailed description of each value follows in the subsequent sections.
3.3.1 sha256sum
(list manifest)
sha256sum: <sum>
The SHA256 checksum of the repositories.manifest
file
(described below) that corresponds to this repository. The sum value
should be 64 characters long (that is, just the SHA256 value, no file name
or any other markers), be calculated in the binary mode, and use lower-case
letters.
This checksum is used to make sure that the
repositories.manifest
file that was fetched is the same as the
one that was used to create the packages.manifest
file. This
also means that if repositories.manifest
is modified in any
way, then packages.manifest
must be regenerated as well.
3.3.2
location
(package manifest)
location: <path>
The path to the package archive file relative to the repository root. It should be in the POSIX representation.
if the repository keeps multiple versions of the package and places them
all into the repository root directory, it can get untidy. With
location
we allow for sub-directories.
3.3.3
sha256sum
(package manifest)
sha256sum: <sum>
The SHA256 checksum of the package archive file. The sum value should be 64 characters long (that is, just the SHA256 value, no file name or any other markers), be calculated in the binary mode, and use lower-case letters.
3.4 Package List Manifest for
dir
Repositories
The package list manifest (the packages.manifest
file found
in the dir
repository root directory) describes the list
of packages available in the repository. It is a (potentially empty)
sequence of manifests with the following synopsis:
location: <path> [fragment]: <string>
The detailed description of each value follows in the subsequent
sections. The fragment
value can only be present in a merged
packages.manifest
file for a multi-fragment repository.
As an example, if our repository contained the src/
subdirectory that in turn contained the libfoo
and
foo
packages, then the corresponding
packages.manifest
file could look like this:
: 1 location: src/libfoo/ : location: src/foo/
3.4.1 location
location: <path>
The path to the package directory relative to the repository root. It should be in the POSIX representation.
3.4.2 fragment
[fragment]: <string>
The repository fragment id this package belongs to.
3.5 Repository Manifest
The repository manifest (only used as part of the repository manifest
list described below) describes a pkg
,
dir
, or git
repository. The manifest
synopsis is presented next followed by the detailed description of each
value in subsequent sections.
[location]: <uri> [type]: pkg|dir|git [role]: base|prerequisite|complement [trust]: <fingerprint> [url]: <url> [email]: <email> [; <comment>] [summary]: <text> [description]: <text> [certificate]: <pem> [fragment]: <string>
See also the Repository Chaining documentation for further information @@ TODO.
3.5.1 location
[location]: <uri>
The repository location. The location can only and must be omitted for the base repository. Since we got hold of its manifest, then we presumably already know the location of the base repository. If the location is a relative path, then it is treated as relative to the base repository location.
For the git
repository type the relative location
does not inherit the URL fragment from the base repository. Note also that
the remote git
repository locations normally have the
.git
extension that is stripped when a repository is
cloned locally. To make the relative locations usable in both contexts, the
.git
extension should be ignored if the local
prerequisite repository with the extension does not exist while the one
without the extension does.
While POSIX systems normally only support POSIX paths (that is, forward
slashes only), Windows is generally able to handle both slash types. As a
result, it is recommended that POSIX paths are always used in the
location
values, except, perhaps, if the repository is
explicitly Windows-only by, for example, having a location that is an
absolute Windows path with the drive letter. The
bpkg
package manager will always try to represent the
location as a POSIX path and only fallback to the native representation if
that is not possible (for example, there is a drive letter in the
path).
3.5.2 type
[type]: pkg|dir|git
The repository type. The type must be omitted for the base repository. If
the type is omitted for a prerequisite/complement repository, then it is
guessed from its location
value as described in bpkg-rep-add(1)
.
3.5.3 role
[role]: base|prerequisite|complement
The repository role. The role
value can be omitted for the
base repository only.
3.5.4 trust
[trust]: <fingerprint>
The repository fingerprint to trust. The trust
value can
only be specified for prerequisite and complement repositories and only for
repository types that support authentication (currently only
pkg
). The fingerprint value should be an SHA256
repository fingerprint represented as 32 colon-separated hex digit pairs.
The repository in question is only trusted for use as a
prerequisite or complement of this repository. If it is also used by other
repositories or is added to the configuration by the user, then such uses
cases are authenticated independently.
3.5.5 url
[url]: <url>
The repository's web interface (brep
) URL. It can only be
specified for the base repository (the web interface URLs for
prerequisite/complement repositories can be extracted from their respective
manifests).
For example, given the following url
value:
url: https://example.org/hello/
The package details page for libfoo
located in this
repository will be https://example.org/hello/libfoo
.
The web interface URL can also be specified as relative to the repository
location (the location
value). In this case url should
start with two path components each being either .
or
..
. If the first component is ..
, then the
www
, pkg
or bpkg
domain component, if
any, is removed from the location
URL host, just like when
deriving the repository name.
Similarly, if the second component is ..
, then the
pkg
or bpkg
path component, if any, is removed
from the location
URL path, again, just like when deriving the
repository name.
Finally, the version component is removed from the location
URL path, the rest (after the two .
/..
components)
of the url
value is appended to it, and the resulting path is
normalized with all remaining ..
and .
applied
normally.
For examples, assuming repository location is:
https://pkg.example.org/test/pkg/1/hello/stable
The following listing shows some of the possible combinations (the
<>
marker is used to highlight the changes):
./. -> https://pkg.example.org/test/pkg/hello/stable ../. -> https://< >example.org/test/pkg/hello/stable ./.. -> https://pkg.example.org/test/< >hello/stable ../.. -> https://< >example.org/test/< >hello/stable ././.. -> https://pkg.example.org/test/pkg/hello< > ../../../.. -> https://< >example.org/test< >
The rationale for the relative web interface URLs is to allow deployment
of the same repository to slightly different configuration, for example,
during development, testing, and public use. For instance, for development
we may use the https://example.org/pkg/
setup while in
production it becomes https://pkg.example.org/
. By specifying
the web interface location as, say, ../.
, we can run the web
interface at these respective locations using a single repository
manifest.
3.5.6 email
[email]: <email> [; <comment>]
The repository email address. It must and can only be specified for the
base repository. The email address is displayed by the web interface
(brep
) in the repository about page and could be used to
contact the maintainers about issues with the repository.
3.5.7 summary
[summary]: <text>
The short description of the repository. It must and can only be specified for the base repository.
3.5.8 description
[description]: <text>
The detailed description of the repository. It can only be specified for the base repository.
In the web interface (brep
) the description is formatted
into one or more paragraphs using blank lines as paragraph separators.
Specifically, it is not represented as <pre>
so any kind of
additional plain text formatting (for example, lists) will be lost and
should not be used in the description.
3.5.9 certificate
[certificate]: <pem>
The X.509 certificate for the repository. It should be in the PEM format
and can only be specified for the base repository. Currently only used for
the pkg
repository type.
The certificate should contain the CN
and O
components in the subject as well as the email:
component in
the subject alternative names. The CN
component should start
with name:
and continue with the repository name
prefix/wildcard (without trailing slash) that will be used to verify the
repository name(s) that are authenticated with this certificate. See bpkg-repository-signing(1)
for details.
If this value is present then the packages.manifest
file
must be signed with the corresponding private key and the signature saved in
the signature.manifest
file. See Signature Manifest for details.
3.5.10 fragment
[fragment]: <string>
The repository fragment id this repository belongs to.
3.6 Repository List Manifest
@@ TODO See the Repository Chaining document for more information on the terminology and semantics.
The repository list manifest (the repositories.manifest
file
found in the repository root directory) describes the repository. It is a
sequence of repository manifests consisting of the base repository manifest
(that is, the manifest for the repository that is being described) as well
as manifests for its prerequisite and complement repositories. The
individual repository manifests can appear in any order and the base
repository manifest can be omitted.
The fragment
values can only be present in a merged
repositories.manifest
file for a multi-fragment repository.
As an example, a repository manifest list for the
math/testing
repository could look like this:
# math/testing # : 1 email<EMAIL_ADDRESS>summary: Math package repository : role: complement location: ../stable : role: prerequiste location: https://pkg.example.org/1/misc/testing
Here the first manifest describes the base repository itself, the second manifest – a complement repository, and the third manifest – a prerequisite repository. Note that the complement repository's location is specified as a relative path. For example, if the base repository location were:
https://pkg.example.org/1/math/testing
Then the completement's location would be:
https://pkg.example.org/1/math/stable
3.7 Signature Manifest for
pkg
Repositories
The signature manifest (the signature.manifest
file found in
the pkg
repository root directory) contains the
signature of the repository's packages.manifest
file. In order
to detect the situation where the downloaded signature.manifest
and packages.manifest
files belong to different updates, the
manifest contains both the checksum and the signature (which is the
encrypted checksum). We cannot rely on just the signature
since a mismatch could mean either a split update or tampering. The
manifest synopsis is presented next followed by the detailed description of
each value in subsequent sections.
sha256sum: <sum> signature: <sig>
3.7.1 sha256sum
sha256sum: <sum>
The SHA256 checksum of the packages.manifest
file. The
sum value should be 64 characters long (that is, just the SHA256
value, no file name or any other markers), be calculated in the binary mode,
and use lower-case letters.
3.7.2 signature
signature: <sig>
The signature of the packages.manifest
file. It should be
calculated by encrypting the above sha256sum
value with the
repository certificate's private key and then base64
-encoding
the result.


Latest Movies.
Latest Movies By Genre
December
Star Wars: L'ascension de Skywalker (2019)
General | 141 min | Action, Adventure, Fantasy, Sci-FiTwo young British privates during the First World War are given an impossible mission: deliver a message deep in enemy territory that will stop 1,600 men, and one of the soldier's brothers, from walking straight into a deadly trap.
Director: J. J. Abrams.
Stars: Adam Driver, Daisy Ridley, Billie Lourd, Carrie Fisher
Add to cart: 19,99€1917 (2019)
R | 118 min | Drama, WarThe surviving Resistance faces the First Order once more in the final chapter of the Skywalker saga.
Director: Sam Mendes
Stars: Andrew Scott, Benedict Cumberbatch, Mark Strong, Richard Madden
Add to cart: 19,99€The Grudge (2020)
R | 94 min | Horror, MysteryA house is cursed by a vengeful ghost that dooms those who enter it with a violent death.
Director: Nicolas Pesce
Stars: Betty Gilpin, Andrea Riseborough, William Sadler, Lin Shaye
Add to cart: 19,99€Bad Boys for Life (2020)
General | 113 min | Action, Comedy, CrimeMarcus Burnett is now a police inspector and Mike Lowery is in a midlife crisis. They unite again when an Albanian mercenary, whose brother they killed, promises them an important bonus.
Directors: Adil El Arbi, Bilall Fallah
Stars: Vanessa Hudgens, Will Smith, Alexander Ludwig, Joe Pantoliano
Add to cart: 19,99€Jumanji: Next Level (2019)
General | 123 min | Action, Adventure, Comedy, FantasyIn Jumanji: The Next Level, the gang is back but the game has changed. As they return to rescue one of their own, the players will have to brave parts unknown from arid deserts to snowy mountains, to escape the world's most dangerous game..
Director: Jake Kasdan
Stars: Dwayne Johnson, Jack Black, Kevin Hart, Karen Gillan
Add to cart: 19,99€


It's a custom event command that opens up a window and prompts the player to put in a new name for the specified unit.
Refer to $commandreference.html for instructions on using the even command.
Aside from me, you can thank CardCaph (Discord: CardCaph#0588) for some of the lovely key button graphics!
Assuming you are using the default keyboard settings for SRPG Studio: Z selects a key. X back spaces unless the string is empty, in which it cancels the name entry if that's enabled. A and S both toggle upper and lower case. C adds a space unless the keyboard doesn't have a space key. Lastly, the space key confirms the name entry.
There is a file called "name-entry-settings.js" located inside the "Name-Entry-Event-Command" folder. You can set the font color, which is in hexidecimal. You can also set which set of key graphics are used. KEYS_GRAPHICS_INDEX tells the plugin what row of graphics to use in the keys material folder. You can add more options by simply editing the image.
Preferably by me e-mail at markyjoe1990@gmail.com


This is JavaScript!
Change text
This is JavaScript!
Change text
RESTRUCTURING THE DOM Interactively
Append to Elements
JavaScript is ....
Append Text
Create Text
Create Button
This is some text
Style Text
First name:


rb-fsevent
Very simple & usable Mac OSX FSEvents API
- RubyCocoa not required!
- Signals are working (really)
- Tested on MRI 1.8.7 & 1.9.2
- Tested on JRuby 1.6.3
Install
gem install rb-fsevent
Usage
Singular path
require 'rb-fsevent' fsevent = FSEvent.new fsevent.watch Dir.pwd do |directories| puts "Detected change inside: #{directories.inspect}" end fsevent.run
Multiple paths
require 'rb-fsevent' paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd] fsevent = FSEvent.new fsevent.watch paths do |directories| puts "Detected change inside: #{directories.inspect}" end fsevent.run
Multiple paths and additional options as a Hash
require 'rb-fsevent' paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd] options = {:latency => 1.5, :no_defer => true } fsevent = FSEvent.new fsevent.watch paths, options do |directories| puts "Detected change inside: #{directories.inspect}" end fsevent.run
Multiple paths and additional options as an Array
require 'rb-fsevent' paths = ['/tmp/path/one', '/tmp/path/two', Dir.pwd] options = ['--latency', 1.5, '--no-defer'] fsevent = FSEvent.new fsevent.watch paths, options do |directories| puts "Detected change inside: #{directories.inspect}" end fsevent.run
Options
When defining options using a hash or hash-like object, it gets checked for validity and converted to the appropriate fsevent_watch commandline arguments array when the FSEvent class is instantiated. This is obviously the safest and preferred method of passing in options.
You may, however, choose to pass in an array of commandline arguments as your options value and it will be passed on, unmodified, to the fsevent_watch binary when called.
So far, the following options are supported...
- :latency => 0.5 # in seconds
- :no_defer => true
- :watch_root => true
- :since_when =><PHONE_NUMBER>3709551615 # an FSEventStreamEventId
Latency
The :latency parameter determines how long the service should wait after the first event before passing that information along to the client. If your latency is set to 4 seconds, and 300 changes occur in the first three, then the callback will be fired only once. If latency is set to 0.1 in the exact same scenario, you will see that callback fire somewhere closer to between 25 and 30 times.
Setting a higher latency value allows for more effective temporal coalescing, resulting in fewer callbacks and greater overall efficiency... at the cost of apparent responsiveness. Setting this to a reasonably high value (and NOT setting :no_defer) is particularly well suited for background, daemon, or batch processing applications.
Implementation note: It appears that FSEvents will only coalesce events from a maximum of 32 distinct subpaths, making the above completely accurate only when events are to fewer than 32 subpaths. Creating 300 files in one directory, for example, or 30 files in 10 subdirectories, but not 300 files within 300 subdirectories. In the latter case, you may receive 31 callbacks in one go after the latency period. As this appears to be an implementation detail, the number could potentially differ across OS revisions. It is entirely possible that this number is somehow configurable, but I have not yet discovered an accepted method of doing so.
NoDefer
The :no_defer option changes the behavior of the latency parameter completely. Rather than waiting for $latency period of time before sending along events in an attempt to coalesce a potential deluge ahead of time, that first event is sent along to the client immediately and is followed by a $latency period of silence before sending along any additional events that occurred within that period.
This behavior is particularly useful for interactive applications where that feeling of apparent responsiveness is most important, but you still don’t want to get overwhelmed by a series of events that occur in rapid succession.
WatchRoot
The :watch_root option allows for catching the scenario where you start watching “~/src/demo_project“ and either it is later renamed to “~/src/awesome_sauce_3000“ or the path changes in such a manner that the original directory is now at “~/clients/foo/iteration4/demo_project“.
Unfortunately, while this behavior is somewhat supported in the fsevent_watch binary built as part of this project, support for passing across detailed metadata is not (yet). As a result, you would not receive the appropriate RootChanged event and be able to react appropriately. Also, since the C code doesn’t open watched directories and retain that file descriptor as part of path-specific callback metadata, we are unable to issue an F_GETPATH fcntl() to determine the directory’s new path.
Please do not use this option until proper support is added in an upcoming (planned) release.
SinceWhen
The FSEventStreamEventId passed in to :since_when is used as a base for reacting to historic events. Unfortunately, not only is the metadata for transitioning from historic to live events not currently passed along, but it is incorrectly passed as a change event on the root path, and only per-host event streams are currently supported. When using per-host event streams, the event IDs are not guaranteed to be unique or contiguous when shared volumes (firewire/USB/net/etc) are used on multiple macs.
Please do not use this option until proper support is added in an upcoming (planned) release, unless it’s acceptable for you to receive that one fake event that’s handled incorrectly when events transition from historical to live. Even in that scenario, there’s no metadata available for determining the FSEventStreamEventId of the last received event.
WARNING: passing in 0 as the parameter to :since_when will return events for every directory modified since “the beginning of time”.
Debugging output
If the gem is installed with the environment variable FWDEBUG set to the string “true”, then fsevent_watch will be built with its various DEBUG sections defined, and the output to STDERR is truly verbose (and hopefully helpful in debugging your application and not just fsevent_watch itself). If enough people find this to be directly useful when developing code that makes use of rb-fsevent, then it wouldn’t be hard to clean this up and make it a feature enabled by a commandline argument instead.  You can still see the code in the ffi branch.
Development
- Source hosted at GitHub
- Report issues/Questions/Feature requests on GitHub Issues
Pull requests are quite welcome! Please ensure that your commits are in a topic branch for each individual changeset than can be reasonably isolated. It is also important to ensure that your changes are well tested... whether that means new tests, modified tests, or fixing a scenario where the existing tests currently fail. If you have rvm and the required rubies currently installed, we have a helper task for running the testsuite in all of them:
rake spec:portability
The list of tested RVM targets is currently:
%w[1.8.6 1.8.7 1.9.2 jruby-head]


ECMAScript 6
ES6 includes the following new features:
- arrows
- classes
- enhanced object literals
- template strings
- destructuring
- default + rest + spread
- let + const
- iterators + for..of
- generators
- unicode
- modules
- module loaders
- map + set + weakmap + weakset
- proxies
- symbols
- subclassable built-ins
- promises
- math + number + string + array + object APIs
- binary and octal literals
- reflect api
- tail calls
ECMAScript 6 Features
Arrows
Arrows are a function shorthand using the =>
syntax. They are syntactically similar to the related feature in C#, Java 8 and CoffeeScript. They support both statement block bodies as well as expression bodies which return the value of the expression. Unlike functions, arrows share the same lexical this
as their surrounding code.
 Having a single convenient declarative form makes class patterns easier to use, and encourages interoperability. Classes support prototype-based inheritance, super calls, instance and static methods and constructors.
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
get boneCount() {
return this.bones.length;
}
set matrixType(matrixType) {
this.idMatrix = SkinnedMesh[matrixType]();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
More info: MDN Classes
Enhanced Object Literals
Object literals are extended to support setting the prototype at construction, shorthand for foo: foo
assignments, defining methods, making super calls, and computing property names with expressions. Together, these also bring object literals and class declarations closer together, and let object-based design benefit from some of the same conveniences.
var obj = {
// __proto__
__proto__: theProtoObj,
// Shorthand for ‘handler: handler’
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
More info: MDN Grammar and types: Object literals
Template Strings
Template strings provide syntactic sugar for constructing strings. This is similar to string interpolation features in Perl, Python and more. Optionally, a tag can be added to allow the string construction to be customized, avoiding injection attacks or constructing higher level data structures from string contents.
// Basic literal string creation
`In JavaScript '\n' is a line-feed.`
// Multiline strings
`In JavaScript this is
not legal.`
// String interpolation
var name = "Bob", time = "today";
`Hello ${name}, how are you ${time}?`
// Construct an HTTP request prefix is used to interpret the replacements and construction
POST`http://foo.org/bar?a=${a}&b=${b}
Content-Type: application/json
X-Credentials: ${credentials}
{ "foo": ${foo},
"bar": ${bar}}`(myOnReadyStateChangeHandler);
More info: MDN Template Strings
Destructuring
Destructuring allows binding using pattern matching, with support for matching arrays and objects. Destructuring is fail-soft, similar to standard object lookup foo["bar"]
, producing undefined
values when not found.
// list matching
var [a, , b] = [1,2,3];
// object matching
var { op: a, lhs: { op: b }, rhs: c }
= getASTNode()
// object matching shorthand
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()
// Can be used in parameter position
function g({name: x}) {
console.log(x);
}
g({name: 5})
// Fail-soft destructuring
var [a] = [];
a === undefined;
// Fail-soft destructuring with defaults
var [a = 1] = [];
a === 1;
More info: MDN Destructuring assignment
Default + Rest + Spread
Callee-evaluated default parameter values. Turn an array into consecutive arguments in a function call. Bind trailing parameters to an array. Rest replaces the need for arguments
and addresses common cases more directly.
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) == 15
function f(x, ...y) {
// y is an Array
return x * y.length;
}
f(3, "hello", true) == 6
function f(x, y, z) {
return x + y + z;
}
// Pass each elem of array as argument
f(...[1,2,3]) == 6
More MDN info: Default parameters, Rest parameters, Spread Operator
Let + Const
Block-scoped binding constructs. let
is the new var
. const
is single-assignment. Static restrictions prevent use before assignment.
function f() {
{
let x;
{
// okay, block scoped name
const x = "sneaky";
// error, const
x = "foo";
}
// error, already declared in block
let x = "inner";
}
}
More MDN info: let statement, const statement
Iterators + For..Of
Iterator objects enable custom iteration like CLR IEnumerable or Java Iterable. Generalize for..in
to custom iterator-based iteration with for..of
. Don’t require realizing an array, enabling lazy design patterns like LINQ.
let fibonacci = {
[Symbol.iterator]() {
let pre = 0, cur = 1;
return {
next() {
[pre, cur] = [cur, pre + cur];
return { done: false, value: cur }
}
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}
Iteration is based on these duck-typed interfaces (using TypeScript type syntax for exposition only):
interface IteratorResult {
done: boolean;
value: any;
}
interface Iterator {
next(): IteratorResult;
}
interface Iterable {
[Symbol.iterator](): Iterator
}
More info: MDN for...of
Generators
Generators simplify iterator-authoring using function*
and yield
. A function declared as function* returns a Generator instance. Generators are subtypes of iterators which include additional next
and throw
. These enable values to flow back into the generator, so yield
is an expression form which returns a value (or throws).
Note: Can also be used to enable ‘await’-like async programming, see also ES7 await
proposal.
var fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
var temp = pre;
pre = cur;
cur += temp;
yield cur;
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 1000
if (n > 1000)
break;
console.log(n);
}
The generator interface is (using TypeScript type syntax for exposition only):
interface Generator extends Iterator {
next(value?: any): IteratorResult;
throw(exception: any);
}
More info: MDN Iteration protocols
Unicode
Non-breaking additions to support full Unicode, including new Unicode literal form in strings and new RegExp u
mode to handle code points, as well as new APIs to process strings at the 21bit code points level. These additions support building global apps in JavaScript.
// same as ES5.1
"𠮷".length == 2
// new RegExp behaviour, opt-in ‘u’
"𠮷".match(/./u)[0].length == 2
// new form
"\u{20BB7}"=="𠮷"=="\uD842\uDFB7"
// new String ops
"𠮷".codePointAt(0) == 0x20BB7
// for-of iterates code points
for(var c of "𠮷") {
console.log(c);
}
More info: MDN RegExp.prototype.unicode
Modules
Language-level support for modules for component definition. Codifies patterns from popular JavaScript module loaders (AMD, CommonJS). Runtime behaviour defined by a host-defined default loader. Implicitly async model – no code executes until requested modules are available and processed.
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
// otherApp.js
import {sum, pi} from "lib/math";
alert("2π = " + sum(pi, pi));
Some additional features include export default
and export *
:
// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
return Math.log(x);
}
// app.js
import ln, {pi, e} from "lib/mathplusplus";
alert("2π = " + ln(e)*pi*2);
More MDN info: import statement, export statement
Module Loaders
Module loaders support:
- Dynamic loading
- State isolation
- Global namespace isolation
- Compilation hooks
- Nested virtualization
The default module loader can be configured, and new loaders can be constructed to evaluate and load code in isolated or constrained contexts.
// Dynamic loading – ‘System’ is default loader
System.import('lib/math').then(function(m) {
alert("2π = " + m.sum(m.pi, m.pi));
});
// Create execution sandboxes – new Loaders
var loader = new Loader({
global: fixup(window) // replace ‘console.log’
});
loader.eval("console.log('hello world!');");
// Directly manipulate module cache
System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized
Map + Set + WeakMap + WeakSet
Efficient data structures for common algorithms. WeakMaps provides leak-free object-key’d side tables.
// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;
// Weak Maps
var wm = new WeakMap();
wm.set(s, { extra: 42 });
wm.size === undefined
// Weak Sets
var ws = new WeakSet();
ws.add({ data: 42 });
// Because the added object has no other references, it will not be held in the set
More MDN info: Map, Set, WeakMap, WeakSet
Proxies
Proxies enable creation of objects with the full range of behaviors available to host objects. Can be used for interception, object virtualization, logging/profiling, etc.
// Proxying a normal object
var target = {};
var handler = {
get: function (receiver, name) {
return `Hello, ${name}!`;
}
};
var p = new Proxy(target, handler);
p.world === 'Hello, world!';
// Proxying a function object
var target = function () { return 'I am the target'; };
var handler = {
apply: function (receiver, ...args) {
return 'I am the proxy';
}
};
var p = new Proxy(target, handler);
p() === 'I am the proxy';
There are traps available for all of the runtime-level meta-operations:
var handler =
{
get:...,
set:...,
has:...,
deleteProperty:...,
apply:...,
construct:...,
getOwnPropertyDescriptor:...,
defineProperty:...,
getPrototypeOf:...,
setPrototypeOf:...,
enumerate:...,
ownKeys:...,
preventExtensions:...,
isExtensible:...
}
More info: MDN Proxy
Symbols
Symbols enable access control for object state. Symbols allow properties to be keyed by either string
(as in ES5) or symbol
. Symbols are a new primitive type. Optional description
parameter used in debugging - but is not part of identity. Symbols are unique (like gensym), but not private since they are exposed via reflection features like Object.getOwnPropertySymbols
.
var MyClass = (function() {
// module scoped symbol
var key = Symbol("key");
function MyClass(privateData) {
this[key] = privateData;
}
MyClass.prototype = {
doStuff: function() {
... this[key] ...
}
};
return MyClass;
})();
var c = new MyClass("hello")
c["key"] === undefined
More info: MDN Symbol
Subclassable Built-ins
In ES6, built-ins like Array
, Date
and DOM Element
s can be subclassed.
Object construction for a function named Ctor
now uses two-phases (both virtually dispatched):
- Call
Ctor[@@create]
to allocate the object, installing any special behavior - Invoke constructor on new instance to initialize
The known @@create
symbol is available via Symbol.create
. Built-ins now expose their @@create
explicitly.
// Pseudo-code of Array
class Array {
constructor(...args) { /* ... */ }
static [Symbol.create]() {
// Install special [[DefineOwnProperty]]
// to magically update 'length'
}
}
// User code of Array subclass
class MyArray extends Array {
constructor(...args) { super(...args); }
}
// Two-phase 'new':
// 1) Call @@create to allocate object
// 2) Invoke constructor on new instance
var arr = new MyArray();
arr[1] = 12;
arr.length == 2
Math + Number + String + Array + Object APIs
Many new library additions, including core Math libraries, Array conversion helpers, String helpers, and Object.assign for copying.
Number.EPSILON
Number.isInteger(Infinity) // false
Number.isNaN("NaN") // false
Math.acosh(3) // 1.762747174039086
Math.hypot(3, 4) // 5
Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
"abcde".includes("cd") // true
"abc".repeat(3) // "abcabcabc"
Array.from(document.querySelectorAll('*')) // Returns a real Array
Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
[0, 0, 0].fill(7, 1) // [0,7,7]
[1, 2, 3].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
["a", "b", "c"].keys() // iterator 0, 1, 2
["a", "b", "c"].values() // iterator "a", "b", "c"
Object.assign(Point, { origin: new Point(0,0) })
More MDN info: Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign
Binary and Octal Literals
Two new numeric literal forms are added for binary (b
) and octal (o
).
0b111110111 === 503 // true
0o767 === 503 // true
Promises
Promises are a library for asynchronous programming. Promises are a first class representation of a value that may be made available in the future. Promises are used in many existing JavaScript libraries.
function timeout(duration = 0) {
return new Promise((resolve, reject) => {
setTimeout(resolve, duration);
})
}
var p = timeout(1000).then(() => {
return timeout(2000);
}).then(() => {
throw new Error("hmm");
}).catch(err => {
return Promise.all([timeout(100), timeout(200)]);
})
More info: MDN Promise
Reflect API
Full reflection API exposing the runtime-level meta-operations on objects. This is effectively the inverse of the Proxy API, and allows making calls corresponding to the same meta-operations as the proxy traps. Especially useful for implementing proxies.
// No sample yet
More info: MDN Reflect
Tail Calls
Calls in tail-position are guaranteed to not grow the stack unboundedly. Makes recursive algorithms safe in the face of unbounded inputs.
function factorial(n, acc = 1) {
'use strict';
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
// Stack overflow in most implementations today,
// but safe on arbitrary inputs in ES6
factorial(100000)


FrontKit
Front-end Development Kit
Global (what is FrontKit and the story behind)
What is Frontkit?
FrontKit is a custom tailored, less bloated web front-end development kit created to assist you to develop the front-end aspects of your web development projects.
FrontKit's current key features are:
- Using the latest HML5 and CSS3 properties
- Serving both barebone (the minimum needs for your front-end development) and fully customizable example version with 16-column grid.
- Responsive design. Components are scaled according to a range of resolutions and devices.
- Built on LESS, with fully customizable variables, nesting, operations and mixins to your needs for efficient coding.
Requirements and Acknowledgements
FrontKit's HTML and CSS properties requires HTML5 doctype, but despite all that FrontKit also inspired from and even makes use of some of the following libraries and resources:


Ruby Enumerable#group_by not very popular but very interesting method
Sep 19th, 2014
As part of my DevBootcamp course I am coming across several methods that I used very often but discovered new aspects, and I also came across other methods that I never really used but are very interesting to manipulate and process data.
A great example of the latter category is Enumerable#group_by. This is a very cool method that can come handy when you have a long array and you need to organize them in a bit more sophisticated way than something like
some_array.sort
or some_array.sort_by {|item| item.some_method }
could do.Let's take a quick look at what Enumerable#group_by can do for us.
[43] pry(main)> a
=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[44] pry(main)> a.group_by { |item| item * 2}
=> {2=>[1], 4=>[2], 6=>[3], 8=>[4], 10=>[5], 12=>[6], 14=>[7], 16=>[8], 18=>[9], 20=>[10]}
[45] pry(main)> a.group_by { |item| item % 2 }
=> {1=>[1, 3, 5, 7, 9], 0=>[2, 4, 6, 8, 10]}
[46] pry(main)> a.group_by { |item| item % 2 == 0 }
=> {false=>[1, 3, 5, 7, 9], true=>[2, 4, 6, 8, 10]}
[47] pry(main)> a.group_by { |item| item.to_s.match(/\d/)[0] }
=> {"1"=>[1, 10], "2"=>[2], "3"=>[3], "4"=>[4], "5"=>[5], "6"=>[6], "7"=>[7], "8"=>[8], "9"=>[9]}
Wow, that's quite a bit of magic. If you ready the ruby-docs you will find:
Groups the collection by result of the block. Returns a hash where the keys are the evaluated result from the block and the values are arrays of elements in the collection that correspond to the key.Let's take another look.
[48] pry(main)> a.group_by { |item| "I am number " + item.to_s }
=> {"I am number 1"=>[1],
"I am number 2"=>[2],
"I am number 3"=>[3],
"I am number 4"=>[4],
"I am number 5"=>[5],
"I am number 6"=>[6],
"I am number 7"=>[7],
"I am number 8"=>[8],
"I am number 9"=>[9],
"I am number 10"=>[10]}
We can see how this method can come handy to process and extract data from a Range or Array object.


Atayal still has few magics need to know, otherwise it's not a CMS but just Laravel anyway.
Atayal needs you to create your Module under 'Atayal/Modules' folder.
Atayal needs you to create a Main folder as Laravel package under your Module.
If you also want to create an admin panel for your Module, create an Admin folder as Laravel package under the same Module.
Atayal will load your packages automatically. And that's what all Atayal do for you.
Because all Modules classes (including those made by you) are loaded by Composer under PSR-0, you need to obey it, too.
For example, the Page Module are under namespace Atayal\Modules\Page.


Hi <%= seller.name %>,
Congratulations! <%= buyer.name %> (<%= buyer.email %>) bought one of your listings! 🎉
You can post more listings by visiting https://rishabhrawat.tech/item/sell.
Happy flipping! 🎉🎉🎉
- Flipit Support.


Twilio - CTI Central
Computer telephony integration central, featuring Voice/Video Call and Live Chat.
Call Agent Page
Client Side
Call Center Administration


HTTP client
| url | (character) A url. One of |
|---|---|
| opts | (list) curl options, a named list. See
|
| proxies | an object of class |
| auth | result of a call to the |
| headers | (list) a named list of headers |
| handle | A handle, see |
| progress | a function with logic for printing a progress bar for an HTTP request, ultimately passed down to curl. only supports httr::progress() for now |
| hooks | (list) a named list (accepts: request, response) of functions (callbacks) to run on request and response objects. See hooks for more details. |
an HttpResponse object
Methods
get(path, query, disk, stream, ...)
Make a GET request
post(path, query, body, disk, stream, ...)
Make a POST request
put(path, query, body, disk, stream, ...)
Make a PUT request
patch(path, query, body, disk, stream, ...)
Make a PATCH request
delete(path, query, body, disk, stream, ...)
Make a DELETE request
head(path, query, ...)
Make a HEAD request
verb(verb, ...)
Use an arbitrary HTTP verb supported on this class Supported verbs: get, post, put, patch, delete, head. Also supports retry
retry(verb, ..., pause_base = 1, pause_cap = 60, pause_min = 1, times = 3, terminate_on, retry_only_on, onwait)
Retries the request given by verb
until successful (HTTP response
status < 400), or a condition for giving up is met. Automatically
recognizes Retry-After
and X-RateLimit-Reset
headers in the
response for rate-limited remote APIs.
handle_pop()
reset your curl handle
url_fetch(path, query)
get the URL that would be sent (i.e., before executing the request). the only things that change the URL are path and query parameters; body and any curl options don't change the URL - returns: URL as a character vector
Possible parameters (not all are allowed in each HTTP verb):
path
- URL path, appended to the base URL
query
- query terms, as a named list
body
- body as an R list
encode
- one of form, multipart, json, or raw
disk
- a path to write to. if NULL (default), memory used.
See curl::curl_fetch_disk()
for help.
stream
- an R function to determine how to stream data. if
NULL (default), memory used. See curl::curl_fetch_stream()
for help
verb
- an HTTP verb supported on this class: get, post, put,
patch, delete, head. Also supports retry.
...
- For retry
, the options to be passed on to the method
implementing the requested verb, including curl options. Otherwise,
curl options, only those in the acceptable set from curl::curl_options()
except the following: httpget, httppost, post, postfields, postfieldsize,
and customrequest
pause_base,pause_cap,pause_min
- basis, maximum, and minimum for
calculating wait time for retry. Wait time is calculated according to the
exponential backoff with full jitter algorithm. Specifically, wait time is
chosen randomly between pause_min
and the lesser of pause_base * 2
and
pause_cap
, with pause_base
doubling on each subsequent retry attempt.
Use pause_cap = Inf
to not terminate retrying due to cap of wait time
reached.
times
- the maximum number of times to retry. Set to Inf
to
not stop retrying due to exhausting the number of attempts.
terminate_on,retry_only_on
- a vector of HTTP status codes. For
terminate_on
, the status codes for which to terminate retrying, and for
retry_only_on
, the status codes for which to retry the request.
onwait
- a callback function if the request will be retried and
a wait time is being applied. The function will be passed two parameters,
the response object from the failed request, and the wait time in seconds.
Note that the time spent in the function effectively adds to the wait time,
so it should be kept simple.
A little quirk about crul
is that because user agent string can
be passed as either a header or a curl option (both lead to a User-Agent
header being passed in the HTTP request), we return the user agent
string in the request_headers
list of the response even if you
pass in a useragent
string as a curl option. Note that whether you pass
in as a header like User-Agent
or as a curl option like useragent
,
it is returned as request_headers$User-Agent
so at least accessing
it in the request headers is consistent.
curl handles are re-used on the level of the connection object, that is,
each HttpClient
object is separate from one another so as to better
separate connections.
If you don't pass in a curl handle to the handle
parameter,
it gets created when a HTTP verb is called. Thus, if you try to get handle
after creating a HttpClient
object only passing url
parameter, handle
will be NULL
. If you pass a curl handle to the handle parameter, then you can get the handle from the
HttpClientobject. The response from a http verb request does have the handle in the
handle` slot.
# NOT RUN { # set your own handle (h <- handle("https://httpbin.org")) (x <- HttpClient$new(handle = h)) x$handle x$url (out <- x$get("get")) x$handle x$url class(out) out$handle out$request_headers out$response_headers out$response_headers_all # if you just pass a url, we create a handle for you # this is how most people will use HttpClient (x <- HttpClient$new(url = "https://httpbin.org")) x$url x$handle # is empty, it gets created when a HTTP verb is called (r1 <- x$get('get')) x$url x$handle r1$url r1$handle r1$content r1$response_headers r1$parse() (res_get2 <- x$get('get', query = list(hello = "world"))) res_get2$parse() library("jsonlite") jsonlite::fromJSON(res_get2$parse()) # post request (res_post <- x$post('post', body = list(hello = "world"))) ## empty body request x$post('post') # put request (res_put <- x$put('put')) # delete request (res_delete <- x$delete('delete')) # patch request (res_patch <- x$patch('patch')) # head request (res_head <- x$head()) # arbitrary verb (x <- HttpClient$new(url = "https://httpbin.org")) x$verb('get') x$verb('GET') x$verb('GET', query = list(foo = "bar")) x$verb('retry', 'GET', path = "status/400") # retry, by default at most 3 times (res_get <- x$retry("GET", path = "status/400")) # retry, but not for 404 NOT FOUND (res_get <- x$retry("GET", path = "status/404", terminate_on = c(404))) # retry, but only for exceeding rate limit (note that e.g. Github uses 403) (res_get <- x$retry("GET", path = "status/429", retry_only_on = c(403, 429))) # query params are URL encoded for you, so DO NOT do it yourself ## if you url encode yourself, it gets double encoded, and that's bad (x <- HttpClient$new(url = "https://httpbin.org")) res <- x$get("get", query = list(a = 'hello world')) # get full url before the request is made (x <- HttpClient$new(url = "https://httpbin.org")) x$url_fetch() x$url_fetch('get') x$url_fetch('post') x$url_fetch('get', query = list(foo = "bar")) # access intermediate headers in response_headers_all x <- HttpClient$new("https://doi.org/10.1007/978-3-642-40455-9_52-1") bb <- x$get() bb$response_headers_all # }


Preparation time
less than 30 mins
Cooking time
1 to 2 hours
Serves
Serves 4
Many Middle Eastern recipes for stuffed aubergines begin with deep-frying the aubergines. However, they don't need to be precooked at all as long as there is enough moisture in the dish to soften them properly.
For the aubergines, halve the aubergines lengthways and scoop out a little of the centre (you can use it in another dish, such as a soup or a stew). Season the aubergines with salt, then turn upside down on a wire rack to drain.
For the filling, heat the olive oil in a large, heavy-bottomed pan and fry the onion until tender. Add the garlic and fry for a minute or so longer.
Add the meat and fry until it has changed colour, breaking up the lumps. Sprinkle over the spices, season with salt and freshly ground black pepper and fry for another minute.
Add the tomatoes and just enough water to cover and stir well. Simmer gently for 30 minutes until the meat is tender. Taste and adjust the seasoning.
Add the bulgur wheat, pine nuts and currants and stir well.
Preheat the oven to 170C/325F/Gas 3.
Lightly oil an ovenproof dish and place the aubergine halves into the dish. Fill them with the spiced meat mixture.
Place the tomato purée, lemon juice, sugar, olive oil and water into a bowl. Season with salt and freshly ground black pepper and mix well.
Pour the tomato purée mixture over the aubergines. Cover with foil, transfer to the oven and bake for 45 minutes.
Remove the foil, baste the aubergines in their juices and cook for a further 15-20 minutes. Serve hot or warm.


Game and Fish Registration
Title:
Applying for hunts and downloading content
Name of user and their role:
John Montgomery is a new user and needs to enroll for hunts and download the most up to date rules and regulations.
Usage preconditions:
Must have a personal account and have payment information on file to apply
Usage postconditons:
Registering allows him to apply for hunts and download other content to his devices.
Interaction flow: Create an account for NM Game and Fish
- Mr. Montgomery enters the http://www.wildlife.state.nm.us website into his Iphone browser.
- The NM Game and Fish website pops up on his browser
- John Selects the Customer Login option on the top of the page.
- John Selects 'Create a New Account'
- NM Game and fish directs John to Read and agree to the terms and conditions, before he continues.
- After accepting, the page directs John to fill in all his personal information, name, DOB, create a password and enter an email address.
- He clicks continue, and the next page has John fill in his additional contact informatio. (ex:ph:, address and email confirmation.
- John clicks next page and the page has John review his information, beore he hit's complete.
- John is directed back to the customer login page, where he will now use his username and password to login.
- John logs in and now can select "Draw Hunt Applications" on the left tool bar.
- John review's his hunts and is directed to the 'Checkout Cart'
- The page directs John to the payment screen, where he must enter his credit card information
- John clicks purchase and the Game and Fish website send's John an e-mail confirmation for his payment
- John is now a user for Game and Fish and can view all his purchases and not have to wait on the phone for hours.
Frequency of Use:
- 4-5 times a week
Persona Page
User Story
Interaction Flow
Conceptual Model


This blog is about our research project where we studied abuse and offense detection in the code switched pair of Hindi and English(i.e., Hinglish) under the expert guidance of Dr. Rajiv Ratn Shah, Dr. Roger Zimmermann, and Dr. Ponnurangam Kumaraguru.
As we write this blog, we remember our journey as research interns at MIDAS Lab. We started this project as our college project in August ’18 when this idea was like a small seed which was sown by our friend Yaman Kumar who is experienced in this field. He introduced us with the highly intellectual professors at MIDAS Lab, who not only gave us a direction but also galvanized us each day into transforming this small idea into a full-fledged research project. As we started working, we became cognizant of the fact that it this a vital issue in today’s world and must be addressed. From what we discovered in our journey; we would like to give everyone a glimpse of it - A small idea that turned into a publication in one of the most prestigious conference of Artificial Intelligence - AAAI’19 at Honolulu, Hawaii, USA, as part of the student abstract and poster track.
Why Hinglish(code switched pair of Hindi and English) ?
In the Indian Subcontinent the number of Internet users has been continuously rising with the penetration of internet among the masses.It is being estimated that the number of internet users in India will cross 700 million by 2021.With about 53% of the users using Hinglish as the medium of communication on social media in India, the need of the the hour is to have some system to detect hate speech,offensive and abusive posts on social media.
Has it been done before?
Although there are many previous works which deal with Hindi and English hate speech (the top two languages in India), but very few on the code-switched version (Hinglish) of the two (Mathur et al. 2018). This is partially due to the following reasons:
- Hinglish consists of no-fixed grammar and vocabulary. It derives a part of its semantics from Devnagari and another part from the Roman script.
- Hinglish speech and written text consists of a concoction of words spoken in Hindi as well as English, but written in the Roman script. This makes the spellings variable and dependent on the writer of the text.
Hence code-switched languages present tough challenges in terms of parsing and getting the meaning out of the text.
Our contribution!
Our work primarily consists of these steps: Preprocessing of the dataset, training of word embeddings,training of the classifier model and then using that on HEOT dataset. Preprocessing involves transliteration using Indic-transliteration python library and translation using Xlit-crowd conversion dictionary which was manually added with common Hinglish words and some profane words. This was followed by training of Glove(Pennington, Socher, and Manning 2014) and Twitter word2vec(Godin et al. 2015) embeddings on both the Davidson and HEOT dataset.Finally a ternary classification model was used using LSTM to classify these tweets into three categories(offensive, abusive and benign).
As shown in the above figure the model was initially trained on the dataset provided by Davidson and then re-trained on the HEOT dataset so as to benefit from the transfer of learned features in the last stage.
Results
We have produced “state of the art” results for english.Our model trained on Glove embeddings gives the best results on HEOT dataset. For comparison purposes we also calculate the results of our model on the Davidson dataset.
Applications
- Detect False Propaganda by Political Groups in Elections.
- Youtube/Netflix Subtitles – “Auto-beep” offensive language.
- Online Social Media - Report Defamatory Pages and comments.
- Feedback analytics for better user experience.
- Real time “clean-chat” facility.
- Censor board – Auto-eliminate abusive content
Future Work
In future we look to extend the work in the following ways:
Use dependency based word embeddings and compare them to the normal word embeddings.
Work on a model to classify images and videos(also having hindi text) into three categories offensive, abusive and benign.
Detect and report facebook users and pages based on their recent posts.
We feel immensely proud to be the part of this extremely enjoyable journey where we not only learnt just theoretically but also implemented those concepts to real life applications to witness the great impact that technology and artificial intelligence brings to life. We feel honoured and grateful on being able to contribute our skills and simultaneously learn each day from our guides and professors at MIDAS Lab who inspired us throughout the project. This has been a totally satisfying and rewarding experience and would wish to work with the team in future as well to use technology for a better tomorrow. Also, we would like to thank Puneet Mathur for sharing the HEOT dataset and inspiring us through his work in the following paper “Mathur, P.; Shah, R.; Sawhney, R.; and Mahata, D. 2018. Detecting offensive tweets in hindi-english code-switched language. In Proceedings of the Sixth International Workshop on Natural Language Processing for Social Media, 18–26.”
Above all, we thank Almighty God for giving us this opportunity, being with us and guiding us in all situations and making our way through each and every problem.
Here is a link to a short video for better understanding of the project - https://drive.google.com/open?id=1rpEcsv03B1yifjLftllK3Hep-Ecyzew2


{namespace bootstrap=TYPO3\Twitter\Bootstrap\ViewHelpers} {namespace demo=Flowpack\SingleSignOn\DemoInstance\ViewHelpers}
You are viewing a secured resource. It should only be visible to authenticated accounts with an Administrator roles.
Logged in as: {account.accountIdentifier}, Roles:


DummyPlayer
public final class DummyPlayer : RemoteMediaPlayer
Mock FireTV / player Use only for testing purposes
-
Initializes the player
Declaration
Swift
public init()
-
Returns the name of player
Declaration
Swift
public func name() -> String!
Return Value
DummyPlayer
-
Returns the unique identifier of the player
Declaration
Swift
public func uniqueIdentifier() -> String!
Return Value
DummyPlayerID
-
Returns the current volume of the player The volume api is currently not supported by the built-in receiver app
Declaration
Swift
public func getVolume() -> BFTask<AnyObject>!
Return Value
a nil task result
-
Sets the volume of the player The volume api is currently not supported by the built-in receiver app
Declaration
Swift
public func setVolume(_ volume: Double) -> BFTask<AnyObject>!
Return Value
a nil task result
-
Asks the player if he is muted The mute api is currently not supported by the built-in receiver app
Declaration
Swift
public func isMute() -> BFTask<AnyObject>!
Return Value
a nil task result
-
Mutes or unmutes the player The mute api is currently not supported by the built-in receiver app
Declaration
Swift
public func setMute(_ mute: Bool) -> BFTask<AnyObject>!
Return Value
a nil task result
-
Returns the current position of the player
Declaration
Swift
public func getPosition() -> BFTask<AnyObject>!
Return Value
a
NSNumber
with the value5948
as task result -
Returns the duration of the currently playing media
Declaration
Swift
public func getDuration() -> BFTask<AnyObject>!
Return Value
a
NSNumber
with the value178934
as task result -
Fetch the current player status
Declaration
Swift
public func getStatus() -> BFTask<AnyObject>!
Return Value
a
MediaPlayerStatus
with the stateReadyToPlay
and the conditionGood
as task result -
Asks the player if the given mime type is supported
Declaration
Swift
public func isMimeTypeSupported(_ mimeType: String!) -> BFTask<AnyObject>!
Parameters
mimeType
mime type to check
Return Value
the string
true
as task result -
Pauses the playback on the player
Declaration
Swift
public func pause() -> BFTask<AnyObject>!
Return Value
a nil task result
-
Starts the playback on the player
Declaration
Swift
public func play() -> BFTask<AnyObject>!
Return Value
a nil task result
-
Stops the playback on the player
Declaration
Swift
public func stop() -> BFTask<AnyObject>!
Return Value
a nil task result
-
Seeks the player position to the given milliseconds using the given mode
Declaration
Swift
public func seek(toPosition positionMilliseconds: Int64, andMode seekMode: SeekType) -> BFTask<AnyObject>!
Parameters
positionMilliseconds
position to seek to in milliseconds
seekMode
mode to use for the seeking
Return Value
a nil task result
-
Sets the media source of the player
Declaration
Swift
public func setMediaSourceToURL(_ mediaLoc: String!, metaData: String!, autoPlay: Bool, andPlayInBackground playInBg: Bool) -> BFTask<AnyObject>!
Parameters
mediaLoc
the url of the media which should be played
metaData
the metadata of the media
autoPlay
indicates if media should be autoplayed, currently not supported by the built-in media receiver
playInBg
indicates if media should be played in background, currently not supported by the built-in media receiver
Return Value
a nil task result
-
Adds a status listener to the player Currently only one listener is supported by the built-in media receiver
Declaration
Swift
public func add(_ listener: MediaPlayerStatusListener!) -> BFTask<AnyObject>!
Parameters
listener
an object conforming to
MediaPlayerStatusListener
which will get status updates from the playerReturn Value
a nil task result
-
Removes the given listener from the playe
Declaration
Swift
public func remove(_ listener: MediaPlayerStatusListener!) -> BFTask<AnyObject>!
Parameters
listener
listener to remove
Return Value
a nil task result
-
Sets the position update interval
Declaration
Swift
public func setPositionUpdateInterval(_ intervalMs: Int64) -> BFTask<AnyObject>!
Parameters
intervalMs
update interval in milliseconds
Return Value
a nil task result
-
Sends the given command to the player Currently not supported by the built-in media receiver
Declaration
Swift
public func sendCommand(_ cmd: String!) -> BFTask<AnyObject>!
Parameters
cmd
the command string
Return Value
a nil task result
-
Sets the style of the player
Declaration
Swift
public func setPlayerStyle(_ styleJson: String!) -> BFTask<AnyObject>!
Parameters
styleJson
the json encoded player style
Return Value
a nil task result
-
Fetches the info of the currently playing media
Declaration
Swift
public func getMediaInfo() -> BFTask<AnyObject>!
Return Value
a media player info with
http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4
as source,{\
title\: \
Testvideo\, \
description\: \
Only use for test purposes\, \
type\: \
video\}
as metadata and “” as extra