Preparation time
less than 30 mins
Cooking time
30 mins to 1 hour
Serves
Serves 4
Dietary
Insert a sharp knife into one end of the bananas to create a slit in the skin and insert the sprig of fresh rosemary. Heat a griddle pan until very hot.
Place the bananas with the skin still on onto the griddle pan and griddle for 3-4 minutes each side, or until the skin is dark brown and starting to split.
To make the toffee sauce, simply place the double cream, butter, sugar, treacle and golden syrup into a saucepan over a medium heat and bring to the boil. Stir well to ensure all the ingredients are combined and dissolved.
To make the ice cream, tip the frozen banana chunks into a food processor. Add the vanilla essence, sugar and 75ml/2½fl oz of the buttermilk. Turn on the processor and let it run for 20-30 seconds.
While the food processor is still running, gradually pour in the remaining buttermilk in a steady stream. Let the machine run until the mixture is smooth and creamy.
Serve each banana in a bowl as you would a jacket potato: cut open down the centre, with the skin on. Pour over a spoonful of the toffee sauce and place a scoop of ice cream on top.


{% extends "mocha/base.html" %} {% load hq_shared_tags %} {% block dependencies %} {% include "formplayer/dependencies.html" %} {% endblock %} {% block mocha_tests %} {% endblock %} {% block fixtures %} {% include "formplayer/case_list.html" %}
{% include 'form_entry/templates.html' %} {% include 'formplayer/debugger.html' %} {% include 'formplayer/grid_view.html' %} {% include 'formplayer/settings_view.html' %} {% include 'formplayer/case_detail.html' %} {% include 'formplayer/case_list.html' %} {% include 'formplayer/menu_list.html' %} {% include 'formplayer/users.html' %} {% include 'formplayer/session_list.html' %} {% include 'formplayer/query_view.html' %} {% include 'formplayer/confirmation_modal.html' %} {% include 'formplayer/progress.html' %} {% endblock %}


WITNESS LIST Appropriations Committee (Subcommittee on State Park System Review) April 22, 1998-9:30A State Park System Review On: Brown, Robert D. (Texas A&M) Murdock, Steve (Texas A&M) Sansom, Andrew (TPWD) Witt, Peter (Texas A&M)


About
I'm a full stack developer, amateur woodworker, and rock climber. I've always loved to build things, whether it was out of Lego bricks, pieces of wood, or digital 1s and 0s.
Projects
Contact
Have a question or want to work together?
Your message was sent successfully, thanks!


Kingdom Hearts III
Kingdom Hearts III[a] is an action role-playing game developed and published by Square Enix for the PlayStation
4 and Xbox One. It is the twelfth installment in the Kingdom Hearts series, a sequel to Kingdom Hearts II, and the
final chapter in the Dark Seeker saga. Set after the events of Kingdom Hearts 3D: Dream Drop Distance, returning
protagonist Sora is joined by Donald Duck, Goofy, King Mickey and Riku in their search for the seven Guardians of
Light and the "Key to Return Hearts" as they attempt to thwart the restored Xehanort's plan to bring about a second
Keyblade War. Their journey has them cross paths with characters and visit worlds based on different Disney and
Pixar properties.


I worked at Radio Cab for many years, performing different duties. However, for the past two years I have been a driver. Being an independent contractor has helped me develop essential life skills, such as managing my own finances, and developing intrinsic motivation. In addition to those necessary skills, it has also helped my judgment improve, from assessing risk, to driving defensively. While my time at Radio Cab has been invaluable and I enjoyed it a great deal, it's simply time to move on. Enter programming!
Before Radio Cab, I worked at various places, Starbucks and Old Navy to name a few.


Please enter a valid email address
Sorry, field password is required!
Sorry, minimum password length is 8!
Password does not match


This ! is not on a condition and skips errexit. Use && exit 1
instead, or make sure $? is checked.
set -e
! false
set -e
false && exit 1
ShellCheck has found a command inverted with !
that may have no effect. In particular, it does not appear as a condition in an if
statement or while
loop, or as the final command in a script or function.
The most common reason for this is thinking that it'll trigger set -e
aka errexit
if a command succeeds, as in the example. This is not the case: !
will inhibit errexit both on success and failure of the inverted command.
Using && exit
will instead exit when failure when the command succeeds.
ShellCheck will not detect cases where $?
is implicitly or explicitly used to check the value afterwards:
set -e;
check_success() { [ $? -eq 0 ] || exit 1; }
! false; check_success
! true; check_success
In this case, you can [[ignore]] the warning.


@if($hasResult)
@endif
@if($hasResult)
paginate($products, 20);
$products = $page->fetchResults();
?>
@foreach($products as $product)
{{$product->label}}
@if($product->description)
{{$product->description}}
@endif
- ${{ $product->offer->price }}
- @if($product['nr-of-merchants'] != 0){{ $product->offer->merchant->label }}@endif
See Product
×
See it
@endforeach
@else
Sorry....no results for {{$query}}
@endif


Dialup/VPN Passwords (2000/XP/Vista/2003): Dialup/VPN passwords are stored as LSA secrets under HKEY_LOCAL_MACHINE\Security\Policy\Secrets. This key contains multiple sub-keys, and the sub-keys which store the dialup passwords contains one of the following strings: RasDefaultCredentials and RasDialParams.
This key is not accessible from RegEdit and other tools by default, but you can use one of the following methods to access this key:
- Use at command to run RegEdit.exe as SYSTEM user: (doesn't work under Vista)
- For Example:
- at 16:14 /interactive regedit.exe
- Change the permission of entire Security key. If you do that, it's recommeneded to return the permissions back to the original after you finish.


Staying at the forefront of technology provides a significant edge to the security industry. Be it homeland security, commercial security, freight and transportation checking or military checkpoint, whatever the application, being able to have reliable, accurate data fast in order to make decisions quickly is essential. Generating a highly accurate X-ray image in as short a space of time as possible supports security professionals in the difficult process of taking appropriate actions quickly. XCounter detectors are redefining the speeds at which X-ray detectors can generate high resolution images, with frame rates of up to 20,000fps. A fast snapshot with incredible detail can be valuable to any security imaging application.
The full product range of XCounter detectors have dual energy capability grounded in cutting edge pulse-height photon energy equivalence. During dual energy acquisition, the energy of the detected photon is compared to two independent thresholds that are read out separately. The two energy sets then give ground breaking material separation information providing you with one of the most powerful material differentiation X-ray detectors available.
And for low dose personnel security scanning, the sensitivity of our detectors provide high quality images for the lowest possible radiation exposure. With our established track record of manufacturing detectors to ISO13485 for the medical industry, XCounter has a profound depth of understanding in delivering low dose X-ray imaging.
With Detector Quantum Efficiency (DQE) of 85% @ RQA5 spectra and a Modulation Transfer Function (MTF) of >80% @ 2lp/mm, our detectors provide images of the highest spatial resolution. And with our direct conversion CdTe CMOS technology in our solutions, you will not suffer from ghosting, lag issues or blurring at high energies that is often found in ordinary TFT based flat panel detectors.
Our unparalleled Dynamic range gives the opportunity so see all of an object in one exposure and presents more data for analysis. This ability to observe both objects of a broad range of densities in the same exposure provides powerful analysis in identifying contraband and explosives.
In time delay summation (TDS) modes and superfast frame rates, our detectors deliver faster scan times enabling quick throughput imaging. Imaging objects passing the detector at 2m/s is possible. This speed along with high end resolution, contrast and sensitivity of the core direct conversion technology, is further enhanced with proprietary charge sharing correction (CSC) software. Such powerful performance brings new levels of image accuracy and material discernment, helping the security industry “find” objects in the most obscure of hiding places.
XCounter has a solid foundation in both integrating and photon counting state of the art x-ray detector technology.
The basic component in our detectors are a conversion material, which converts the x-rays into electrical signals, and a CMOS (ASIC) which transforms the electric signals into a datastream of either the integrated electric charge or the number of photons which has entered each pixel. This data is then used to create a digital image which is either two- or threedimensional, depending on the scan geometry.
Our solid state detector uses CdTe which is a direct conversion material. When an x-ray photon enters the material it is converted directly to an electric signal which is captured, measured and finally processed into an image. This provides significantly better MTF (Modulation Transfer Function) and DQE (Detection Quantum Efficiency) compared to scintillation detectors due to the high sensitivity and very good stopping power for high energy photons. By combining the CdTe conversion layer with our custom ASICs (CMOS) we can supply detectors that support integrating as well as photon counting modes, fast readout and low power consumption.


TSHN
Home
About
Blog
Top Stories of Hacker News in last 24 hours
Loading...
#
Title
User
Comments
Points
Time Posted


Linear Algebra kernels belong either to BLAS (stands for Basic Linear Algebra Subprograms) - basic operations or LAPACK (Linear Algebra PACKage) - larger operations.
There are the following dense or sparse matrix operations grouped by the BLAS levels:
\[ \begin{equation} \label{level1} \boldsymbol{y} \leftarrow \alpha \boldsymbol{x} + \boldsymbol{y} \! \end{equation} \]
These operations include:
* DOT (inner product)
* SUM (sum)
* AXPBY (Scaled vector accumulation)
* WAXPBY (Scaled vector addition)
\[ \begin{equation} \label{level2} \boldsymbol{y} \leftarrow \alpha A \boldsymbol{x} + \beta \boldsymbol{y}, \quad \boldsymbol{y} \leftarrow \alpha A^T \boldsymbol{x} + \beta \boldsymbol{y} \! \end{equation} \] These operations include:
* GEMV (General matrix vector product)
* GBMV (Banded matrix vector product)
* SYMV (Symmetric matrix vector product)
* SPMV (Symmetric matrix vector product, packed format)
* HEMV (Hermitian matrix vector product)
* HPMV (Hermitian matrix vector product, packed format)
* TRSV (Triangular solve)
dtrsv, strsv, ztrsv and ctrsv solve one of the systems of equations \[ \begin{equation} \label{level2_trsv} A \boldsymbol{x} = \boldsymbol{b}, \quad A^T \boldsymbol{x} = \boldsymbol{b} \! \end{equation} \] ### BLAS Level 3 - matrix-matrix operation \[ \begin{equation} \label{level3_gemm} C \leftarrow \alpha A B + \beta C \ \end{equation} \]
for
- GEMM (General matrix matrix product)
- SYMM, HEMM (Symmetric or Hermitian matrix matrix product)
- TRMM (triangular matrix multiply)
- GBMM (general banded matrix multiply)
and
- SYRK, SYR2K, HERK, HER2K (symmetric or Hermitian rank-k and rank-2k updates)
* Level 1: idamax, dcopy, dscal, dswap
* iamax (idamax) - find index of maximum element in a vector
* copy (dcopy) - copy vector
* scal (dscal) - scale a vector by a constant
* swap (dswap) - swap two vectors
* Level 2:
* DGER - ``A\leftarrow{A}+\alpha{x}y^T``
* Level 3:
* DTRSM - solve one of the matrix equations ``op(A)*X=\alpha*B, X*op(A) = \alpha*B``
LAPACK operations include:
* GTSV - solve the equation ``Ax=b``, where ``A`` is a tridiagonal matrix, ``x`` and ``b`` - vectors
* GETRF - compute an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges
Sparse matrix-vector multiplication (SpMV) is one of the most important operation in sparse matrix computations. Iterative methods for solving large linear systems (\(Ax=b\)) and eigenvalue problems (\(Ax = \lambda x\)) require huge number of these operations.
Compared to dense linear algebra kernels, sparse kernels suffer from higher instruction and storage overheads per ﬂop, as well as indirect and irregular memory access patterns. Achieving higher performance on these platforms requires choosing a compact data structure and code transformations that best exploit properties of both the sparse matrix – which may be known only at run-time – and the underlying machine architecture. This need for optimization and tuning at run-time is a major distinction from the dense case.
The general form for the SpMV operation is \(y \leftarrow Ax+y\) where A is large and sparse and x and y are dense column vectors. There are many sparse formats for storing sparse matrices. The most popular is Compressed Sparse Row (CSR) format. The CSR format stores an sparse matrix having k non-zero elements using three one-dimensional arrays: the arrays val and col ind, each of size k, to store the non-zeros values and column indices, respectively; and an array row ptr of size m + 1 to store pointers to the ﬁrst element of each row in the val and col ind arrays. Basic reference SpMV kernel implementation for Compressed Sparse Row (CSR) matrix where: * the column indices within a given row are sorted in increasing order (i.e., the last element of each row is the diagonal non-zero value), * \(x\) is an array with unit-stride
// y <- y + A*x, where A is in CSR format
for (size_t i = 0; i < m; i++) {
float acc = y[i];
for (size_t k = ptr[i]; k < ptr[i+1]; k++) {
acc = acc + val[k] * x[ind[k]];
}
y[i] = acc;
}
Fortran 90 introduced vector notation, vector intrinsics such as dot product and triplet notation for vector slices, thus an equivalent code is shorter than C one:
DO I=1,M
K1 = IPTR(I)
K2 = IPTR(I+1)-1
Y(I) = DOTPRODUCT(VAL(K1:K2),X(IND(K1:K2)))
ENDDO
Consider the internal loop in the above C code excerpt - dot product. For single precision SpMV pumping of 12 bytes is required for processing one non-zero matrix entry (value from A, value from vector x, column index) and 2 flops (multiplication and addition - FFMA/DFMA is a natural choice). The outer loop can be very large - proportional to the number of matrix rows, internal loop workload is proportional to the number of non-zeros of this row. Thus imbalance in the number of non-zeros might lead to workload imbalance.
Another interesting kernel: SpTRSV
Basic reference triangular solver kernel implementation for \(T\cdot x = b\) for \(T\) where: \(T\) is a lower triangular a full (all non-zero) diagonal exists, the column indices within a given row are sorted in increasing order (i.e., the last element of each row is the diagonal non-zero value), \(x\) is an array with unit-stride
for (size_t i = 0; i < m; i++) {
float xi = x[i];
for (size_t k = ptr[i]; k < ptr[i+1]-1; k++) {
xi -= val[k] * x[ind[k]];
}
xi /= val[ptr[i+1]-1];
x[i] = xi;
}
We wish to solve a system of n linear equations of the form \(Ax = d\), where \(A\) is a tridiagonal matrix: \[ \begin{equation*} \begin{aligned} \begin{pmatrix} {b_1} & {c_1} & { } & { } & { 0 } \\ {a_2} & {b_2} & {c_2} & { } & { } \\ { } & {a_3} & {b_3} & \ddots & { } \\ { } & { } & \ddots & \ddots & {c_{n-1}}\\ { 0 } & { } & { } & {a_n} & {b_n}\\ \end{pmatrix} = \begin{pmatrix} {d_1 } \\ {d_2 } \\ {d_3 } \\ \vdots \\ {d_n } \\ \end{pmatrix} . \end{aligned} \end{equation*} \] Classical Thomas algorithm - a simplified form of Gaussian elimination - has asymptotic complexity \(O(N)\) instead of \(O(N^3)\) for Gaussian elimination. This algorithm is a base for sweep variant of solvers.
Sweep algorithm doesn’t parallelize tridiagonal system solution, parallelism appear only during of large number of systems simultaneously. Cyclic reduction and parallel cyclic reduction from another hand parallelize tridiagonal system solution. Cyclic reduction has better asymptotic compxity \(O(N)\) compared to \(O(\log(N))\) for pcr, but it worse in terms of address divergence. An appropriate algorithm choice depends on the task.


| KAFKA-3088 |
<IP_ADDRESS> broker crash on receipt of produce request with empty client ID |
Major |
producer |
Dave Peterson |
Grant Henke |
| KAFKA-3594 |
Kafka new producer retries doesn't work in <IP_ADDRESS> |
Critical |
producer |
Nicolas PHUNG |
Manikumar Reddy |
| KAFKA-3632 |
ConsumerLag metrics persist after partition migration |
Minor |
core |
Brian Lueck |
Jason Gustafson |
| KAFKA-3773 |
SocketServer inflightResponses collection leaks memory on client disconnect |
Major |
core |
Jason Gustafson |
Jason Gustafson |
| KAFKA-3952 |
VerifyConsumerRebalance cannot succeed when checking partition owner |
Minor |
core |
Simon Wan Wenli |
Simon Wan Wenli |


Getting Started
Download From Nuget.org¶
There are two Nuget packagesto download:
Install Via Nuget Package Manager¶
- Right-click on the project where you want to install the package(s)
- Select Manage Nuget Packages
- Type
luminous.code
in the search box - Click on the package(s) you want to install
- Click the Install button
Install Via Package Manager Console¶
- Click on the project where you want to install the package(s)
- Click View | Other Windows | Package Manager Console
- Make sure the correct project is selected as Default Project
- Type
install-package luminous.code.core
orinstall-package luminous.code.visualstudio
- Press
ENTER


It is difficult to analyse pitch contours at word level, because word-level patterns are commonly distorted or overridden by higher- level intonational patterns; see §17.4, where we discuss how intonation is used for discourse purposes in a real text, and see also §3.40 for elongated interjections.
Although it is somewhat artificial to "factor out" such intonational patterns (extended high monotones, etc.), we may try to indicate in general terms what "unmarked" pitch contours for words are like. Without pretending to understand the nuances of pitch contours perfectly, I offer the following general points:
We may illustrate with some exx. (recall that all pitch transcriptions, using 'for high pitch with light stress, and occasionally' for intermediate stress/pitch, are somewhat idealised "context-free" transcriptions which may be overridden by intonational patterns).
| /nga=ná-ni/ 'I saw it' | penultimate |
| /ngà=ngu-ví:/ 'I eat it' | long V: attracts stress |
| /ngá=na-ny/ 'I saw it' | penultimate (on prefix) |
| /ná:=ná-ni/ 'We saw them' | penultimate, also long V : |
| /ána-lgu/ 'honey' | penultimate, alternating |
| /á-lagú-wuy/ 'to honey' | case suffix causes shift |
| /a-lágu-yínyung/ 'of honey' | bisyllabic suffix has little effect on stem |
| /wù:=yà;-rì:/ 'they go' | contour level (but unstable) with several long V:'s |
| /gúrujújurg/ 'whistling eagle' | two 2-syllable feet |
| /wúrulámbilámbi/ 'grass sp.' | three 2-syllable feet |
| /gáramínyanmínyan/ 'bee sp.' | three 2-syllable feet |
| /wádanawádana/ 'hawk sp.' | two 3-syllable feet |
| /ambúruyuwúruyuj/ 'grass sp.' | two 3-syllable feet plus initial syllable |
When a monosyllabic suffix is added to one of the last few noun stems shown above, only the pitch/stress of the final foot is shifted to the word-penultimate syllable: /wá: -gáramínyanminyán-guy/ 'to the bees'.
When there is no obvious reduplication or other internal structure in a stem, the usual preference seems to be in favour of 2-syllable feet (rather than 3-syllable). In the last ex., above, the pitch contour is due to identification of reduplicative patterning; note that /b/ after nasal may be underlying /w2/ after Hardening P-18. The "reduplication" in such situations is often unrelated to the regular, productive reduplication rules (P-2, P-3). The latter never give reduplicative segments more than two syllables, and never have more than one vowel quality in the reduplicative segment (contrast trisyllabic "reduplication" in the final two exx. above, and distinct vowel qualities in the bisyllabic reduplicative segments in the two exx. preceding them).
Word-final consonant clusters do not greatly affect pitch/stress patterns, though they may give a final syllable slightly more pitch and stress than it would otherwise acquire: /wúmurng/ 'stringybark shelter', /wúnalg/ 'painting torso'. In nonfinal syllables, a syllable closed with a consonant or consonant cluster (not counting the consonant opening the following syllable) may have some extra Pitch/stress, but this is not very consistent: /wírnggil/ 'pond scum', Allative-Dative /à-wirnggíl-wuy/ or /à-wìrnggíl-wuy/. Some consonant clusters, notably homorganic nasal-stop clusters like /mb/, appear to syllabify with the following (not preceding) vowel so that the nasal component cannot really be said to close the preceding syllable for purposes of this (occasional) effect on pitch/stress contours.


--- title: Instantiates a placeholder tensor and returns it. type: docs repo: https://github.com/rstudio/keras menu: main: name: Instantiates a placeholder tensor and returns it. - keras parent: keras-reference aliases: - /reference/keras/k_placeholder.html - /keras/reference/k_placeholder.html - /guide/keras/reference/k_placeholder.html - /tools/tools/keras/reference/k_placeholder.html - /installation/keras/reference/k_placeholder.html - /tutorials/keras/reference/k_placeholder.html - /guide/tools/keras/reference/k_placeholder.html - /deploy/keras/reference/k_placeholder.html - /tools/keras/reference/k_placeholder.html - /tutorials/tools/keras/reference/k_placeholder.html ---
Instantiates a placeholder tensor and returns it.
k_placeholder(
shape = NULL,
ndim = NULL,
dtype = NULL,
sparse = FALSE,
name = NULL
)
| shape | Shape of the placeholder (integer list, may include |
| ndim | Number of axes of the tensor. At least one of |
| dtype | Placeholder type. |
| sparse | Logical, whether the placeholder should have a sparse type. |
| name | Optional name string for the placeholder. |
Tensor instance (with Keras metadata included).
This function is part of a set of Keras backend functions that enable lower level access to the core operations of the backend tensor engine (e.g. TensorFlow, CNTK, Theano, etc.).
You can see a list of all available backend functions here: https://keras.rstudio.com/articles/backend.html#backend-functions.


A step by step game creation tutorial
Introduction:
Prerequisites :
- The Tiled Map Editor, installed and running (0.9.0 or later)
-
This template file, containing what we will
use for the tutorial :
- a level tileset and a metatileset for collision (/data/area01_tileset/)
- two background for parallax layers (/data/area01_parallax/)
- some basic spritesheet (/data/sprite/)
- some audio sfx and music (/data/audio/)
- a title screen background (/data/GUI/)
- a main.js skeleton
- a default index.html
- The melonJS library, to be copied under the /lib directory (or anywhere else you want)
- The melonJS documentation for more details
Testing/debugging :
When using Chrome, and due to the "cross-origin request" security mechanism implemented,
you need to use the "--disable-web-security" parameter or better "--allow-file-access-from-files"
when launching the browser in order to test any local content, else the browser will complain
when trying to load a level map.
Additional Credits :
-
SpicyPixel.NET for the GfxLib-Fuzed assets
- noSoapRadio for the in game music
Feel free to modify whatever you want. We also assume here, that you are already familiar with Tiled; if you need more help with the tool, you can check the Tiled homepage and wiki for further help.
Part 1: Creating a level using Tiled
melonJS supports only uncompressed tilemaps, so before continuing, please check that your settings are correct (Tiled/Preferences). I recommend the Base64 encoding, since it produces a smaller file, but it's really up to you.
First let's open Tiled and create a new map : for this tutorial we will we use a 640x480 canvas, and since we have 32x32 tiles, we must specify at least 20 and 15 for the map size. In my example I'll define a 40x15 level, so we can play with scrolling background later.
Then let's add both our tileset (using Map/New Tileset), and the "meta" tileset that we will use for collision. Both have no spacing or margin, so be sure to let the corresponding values to zero in tiled (note: melonJS support tilesets with margin and space)
For the beauty of it, we will create two layers - one background layer, and one foreground layer. Feel free to use your imagination and do whatever you want. I named them logically "background" and "foreground", but you can put whatever you want.
Here's what my level looked like when I finished it :
Finally, let's define a background color for our level, by using the color picker tool (Map/Map Properties), and just specify any color you prefer.
To finish, let's save our new map as "area01" under the "data" folder. We are done the first step!
Part 2: Loading our level
First let's have a look at our main.js skeleton :
// game resources var g_resources = []; var jsApp = { /* --- Initialize the jsApp --- */ onload: function() { // init the video if (!me.video.init('jsapp', 640, 480, false, 1.0)) { alert("Sorry but your browser does not support html 5 canvas."); return; } // initialize the "audio" me.audio.init("mp3,ogg"); // set all resources to be loaded me.loader.onload = this.loaded.bind(this); // set all resources to be loaded me.loader.preload(g_resources); // load everything & display a loading screen me.state.change(me.state.LOADING); }, /* --- callback when everything is loaded --- */ loaded: function() { // set the "Play/Ingame" Screen Object me.state.set(me.state.PLAY, new PlayScreen()); // start the game me.state.change(me.state.PLAY); } }; // jsApp /* the in game stuff*/ var PlayScreen = me.ScreenObject.extend({ onResetEvent: function() { // stuff to reset on state change }, /* --- action to perform when game is finished (state change) --- */ onDestroyEvent: function() { } }); //bootstrap :) window.onReady(function() { jsApp.onload(); });
This is very simple. Once the page is loaded, the onload() function is called, the display and audio is initialized, and all game resources begin loading. We also define a callback to be called when everything is ready to be used. Within the callback, we define a new state that will be used for the in game stuff, together with a PlayScreen object that we will use to manage the game event (reset, etc...).
So in order to load our level, the next thing is to add the resources to be loaded by adding the following information into here (for example) the g_resources object :
- the tileset itself, an image
- our map "area01", a TMX object
//game resources var g_resources = [{ name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, { name: "area01", type: "tmx", src: "data/area01.tmx" }];
Be sure as well to correctly name the tileset resource name accordingly to the filename, else the level loader will not be able to find the tileset and will fail.
Finally, in the onResetEvent() function (which is called on a state change), we ask the level director to display our previously preloaded level :
/* the in game stuff*/ var PlayScreen = me.ScreenObject.extend({ onResetEvent: function() { // stuff to reset on state change // load a level me.levelDirector.loadLevel("area01"); }, /* --- action to perform when game is finished (state change) --- */ onDestroyEvent: function() { } });
That's all! If you did everything correctly, and open you index.html (Remember that if you don’t use a web server, you will need to allow your browser to access local files, please refer to the “Testing/debugging” at the beginning of the tutorial if required) :
(click on the image to see it running in your browser), you should see
something like this
Yes, nothing fancy yet, but that's only the beginning!
Also in case you didn't noticed, since we defined a 640x480 display in our application, we only see a part of the map (the half of it to be exact), which is normal. melonJS automatically create a corresponding viewport, and we will be able to navigate through the map in the next step, when we will add a "main player"
Part 3: Add a main player
Here we will create a new object by extending the default me.ObjectEntity, to create our player. We will use the provided simple spritesheet (gripe_run_right.png) to animate our character. It's of course possible to define different animation for the same entity, but let's keep things simple first.
First, let's add our spritesheet in the list of the resources to be loaded, just after our map :
//game resources var g_resources = [{ name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, { name: "area01", type: "tmx", src: "data/area01.tmx" }, { name: "gripe_run_right", type: "image", src: "data/sprite/gripe_run_right.png" }];
Then it's time to create our entity:
(Feel free to put this object either in our main.js or in a new file, in my example I use entities.js)
/*------------------- a player entity -------------------------------- */ var PlayerEntity = me.ObjectEntity.extend({ /* ----- constructor ------ */ init: function(x, y, settings) { // call the constructor this.parent(x, y, settings); // set the default horizontal & vertical speed (accel vector) this.setVelocity(3, 15); // set the display to follow our position on both axis me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH); }, /* ----- update the player pos ------ */ update: function() { if (me.input.isKeyPressed('left')) { // flip the sprite on horizontal axis this.flipX(true); // update the entity velocity this.vel.x -= this.accel.x * me.timer.tick; } else if (me.input.isKeyPressed('right')) { // unflip the sprite this.flipX(false); // update the entity velocity this.vel.x += this.accel.x * me.timer.tick; } else { this.vel.x = 0; } if (me.input.isKeyPressed('jump')) { // make sure we are not already jumping or falling if (!this.jumping && !this.falling) { // set current vel to the maximum defined value // gravity will then do the rest this.vel.y = -this.maxVel.y * me.timer.tick; // set the jumping flag this.jumping = true; } } // check & update player movement this.updateMovement(); // update animation if necessary if (this.vel.x!=0 || this.vel.y!=0) { // update object animation this.parent(); return true; } // else inform the engine we did not perform // any update (e.g. position, animation) return false; } });
I think the above code is quite easy to understand. Basically, we extend the ObjectEntity, configure the default player speed, tweak the camera, test if some keys are pressed and manage our player movement (by setting player speed, and then calling the updateMovement function). Also, you may notice that I'm testing the final velocity (this.vel.x and this.vel.y) of my object, which allows me to know if my object actually moved, and control if I want the sprite animation to run or not.
Then, we have to modify our "main" to actually declare our new Object in the EntityPool (that is used by the engine to instantiate object), and finally to map the keys we will use for the player movement. So our loaded() function will become :
/* --- callback when everything is loaded --- */ loaded: function () { // set the "Play/Ingame" Screen Object me.state.set(me.state.PLAY, new PlayScreen()); // add our player entity in the entity pool me.entityPool.add("mainPlayer", PlayerEntity); // enable the keyboard me.input.bindKey(me.input.KEY.LEFT, "left"); me.input.bindKey(me.input.KEY.RIGHT, "right"); me.input.bindKey(me.input.KEY.X, "jump", true); // start the game me.state.change(me.state.PLAY); }
And now we can add our entity into the level! Go back to Tiled, add an new Object
Layer, and finally a new Entity.
Name it (case does not matter) mainPlayer (or using the same name you used
when adding our Object into the entityPool), and add two properties to the Object
:
- image with the gripe_run_right value (name of our resource
- spritewidth with the value 64 which is the size of a single sprite in
the spritesheet
- spriteheight we don't define this value here since we use a single line spritesheet,
and since in this case the engine will take the actual image height as a value for it.
These two parameters will be passed as parameters (settings object here above
used by the constructor) when the object will be created. Now you can either specify
these fields here in Tiled, or directly in your code (when dealing with multiple
objects, it can be easier to just specify the name in Tiled, and manage the rest in
the constructor directly).
Note: You also free to add as many properties as you want, they will all be available
in the settings object passed to your constructor.
Once the object is created just positionate your entity in the level, and as in the below example make sure you are also resizing the object rectangle in Tiled to match with your actual sprite size.
We are almost done! The last step is to define the collision layer, for this we will use the other tileset we previously added into Tiled, and specify for each tile a property corresponding to the tile type.
First, right click on the "Solid" tile (1st one), and add a "type" property with "solid" as a value.
Then, right click on the "Platform" tile (2nd one), and add a "type" property with "platform" as a value.
That's it! Though we won't be using them for this tutorial, it is nice to know that the others possible values are "lslope" for the left slope, "rslope" for the right slope, "ladder" for ladder tiles and "breakable" (you'll never guess) for breakable tiles. Also be careful when defining these two fields, as the engine is exactly looking for these labels, so if they are incorrect, it won't work.
Now add a new Tilelayer. This layer MUST contains the keyword "collision" for the engine to recognize it as a collision layer.
Once the layer added, select it, and just "draw" you level collision map. At the end it should look like this:
Save everything, and if you now re-open you index.html, you should see something like
this :
(click on the image to see it running in your browser)
You will also notice that display is automatically following our player.
One last thing - when creating an object, a collision rectangle is automatically created to manage collision between objects. For debugging purposes, you can use the following debug settings in your main to enable it :
me.debug.renderHitBox = true;
If you reload the game, you will see this:
As you can see we have a lot of white space on the left and right of our character, so let's adjust the collision rectangle to our sprite:
/* ----- constructor ------ */ init: function(x, y, settings) { // call the constructor this.parent(x, y, settings); // set the walking & jumping speed this.setVelocity(3, 15); // adjust the bounding box this.updateColRect(8, 48, -1, 0); // set the display to follow our position on both axis me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH); },
Here we add a horizontal 8 pixel offset, and set it's width to 48 pixels. We don't change the height, so we specify -1.
Part 4: Add a scrolling background
This one is very easy. We don't even have to add a single line of code, since everything is done through Tiled.
First, let's remove in Tiled the backgroun d color that we added previously at the end of Part 1. (to do so, you will need to text edit the TMX file and remove the `backgroundcolor` property). Since the background will be filled with our scrolling layers, we don't need the display to be cleared with a specific color (furthermore it will save some precious frames).
Then we will use the two following backgrounds :
/data/area01_parallax/area01_bkg0.png for the first background layer
/data/area01_parallax/area01_bkg1.png for the second background layer
Let's add them in the resource list:
// game resources var g_resources = [ // our level tileset { name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, // our level { name: "area01", type: "tmx", src: "data/area01.tmx" }, // the main player spritesheet { name: "gripe_run_right", type: "image", src: "data/sprite/gripe_run_right.png" }, // the parallax background { name: "area01_bkg0", type: "image", src: "data/area01_parallax/area01_bkg0.png" }, { name: "area01_bkg1", type: "image", src: "data/area01_parallax/area01_bkg1.png" }];
Open Tiled, and add two new Image Layers, name them to whatever you like and make sure to adjust correctly the layer order (the display order being from bottom to top)
Now right-click the layers to define their properties and set the following property :
- Click the browse button and select the area01_bkg0 image for the first layer
(Parallax_layer1 on the picture), and area01_bkg1 value for the second
one (Parallax_layer2 also on the picture)
Note that default behavior for Image Layer is to be automatically repeated on both x and y axis, which is exactly what we want here to create the parallax effect.
"Et voila!". If you now open you index.html, you should see:
Play around with your player, and enjoy the view :)
Part 5: Adding some basic objects and enemies
In this part we will add a collectible coin (that we will use later to add to our score), using the spinning_coin_gold.png spritesheet :
And a basic enemy, using the wheelie_right.png spritesheet :
As always, add them to the resource list:
// game resources var g_resources = [ // our level tileset { name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, // our level { name: "area01", type: "tmx", src: "data/area01.tmx" }, // the main player spritesheet { name: "gripe_run_right", type: "image", src: "data/sprite/gripe_run_right.png" }, // the parallax background { name: "area01_bkg0", type: "image", src: "data/area01_parallax/area01_bkg0.png" }, { name: "area01_bkg1", type: "image", src: "data/area01_parallax/area01_bkg1.png" }, // the spinning coin spritesheet { name: "spinning_coin_gold", type: "image", src: "data/sprite/spinning_coin_gold.png" }, // our enemty entity { name: "wheelie_right", type: "image", src: "data/sprite/wheelie_right.png" }];
The coin itself is pretty easy; we just extend the me.CollectableEntity. Actually, we could directly use it in Tiled (without needing to create CoinEntity here), but since we will add some score and some audio sfx later when the coin is collected, let's do it directly this way.
/*---------------- a Coin entity ------------------------ */ var CoinEntity = me.CollectableEntity.extend({ // extending the init function is not mandatory // unless you need to add some extra initialization init: function(x, y, settings) { // call the parent constructor this.parent(x, y, settings); }, // this function is called by the engine, when // an object is touched by something (here collected) onCollision: function() { // do something when collected // make sure it cannot be collected "again" this.collidable = false; // remove it me.game.remove(this); } });
Also, just to be sure it's clear for you that both ways of doing this is possible,
we will define the Coin object properties directly in Tiled, so we don't need to add
anything else in the constructor for now :
For our enemy, it's a bit longer :
/* -------------------------- an enemy Entity ------------------------ */ var EnemyEntity = me.ObjectEntity.extend({ init: function(x, y, settings) { // define this here instead of tiled settings.image = "wheelie_right"; settings.spritewidth = 64; // call the parent constructor this.parent(x, y, settings); this.startX = x; this.endX = x + settings.width - settings.spritewidth; // size of sprite // make him start from the right this.pos.x = x + settings.width - settings.spritewidth; this.walkLeft = true; // walking & jumping speed this.setVelocity(4, 6); // make it collidable this.collidable = true; // make it a enemy object this.type = me.game.ENEMY_OBJECT; }, // call by the engine when colliding with another object // obj parameter corresponds to the other object (typically the player) touching this one onCollision: function(res, obj) { // res.y >0 means touched by something on the bottom // which mean at top position for this one if (this.alive && (res.y > 0) && obj.falling) { this.flicker(45); } }, // manage the enemy movement update: function() { // do nothing if not visible if (!this.visible) return false; if (this.alive) { if (this.walkLeft && this.pos.x <= this.startX) { this.walkLeft = false; } else if (!this.walkLeft && this.pos.x >= this.endX) { this.walkLeft = true; } // make it walk this.flipX(this.walkLeft); this.vel.x += (this.walkLeft) ? -this.accel.x * me.timer.tick : this.accel.x * me.timer.tick; } else { this.vel.x = 0; } // check and update movement this.updateMovement(); // update animation if necessary if (this.vel.x!=0 || this.vel.y!=0) { // update object animation this.parent(); return true; } return false; } });
As you can see here, I specified the settings.image and
settings.spritewidth properties in the constructor directly, meaning that in
Tiled, I won't have to add these properties to my Object (Once again, it's up to you
to decide how to use it).
Also, I am using the width property given by Tiled to specify a path on which
this enemy will run. Finally, in the onCollision method, I make the enemy flicker if
something is jumping on top of it.
Then again, we add these new objects in the entityPool
// add our object entities in the entity pool me.entityPool.add("mainPlayer", PlayerEntity); me.entityPool.add("CoinEntity", CoinEntity); me.entityPool.add("EnemyEntity", EnemyEntity);
And we are ready to complete our level in Tiled. Create a new object layer, and use the Insert Object tool to add coins and enemies where you want. Right-click on each object and make sure to set their name to either CoinEntity or EnemyEntity.
Before testing, we also need to modify our player to check for collision with other entities. In order to do this, we add a call to the me.game.collide(this) function in our mainPlayer code, see below :
/* ----- update the player pos ------ */ update: function() { if (me.input.isKeyPressed('left')) { // flip the sprite on horizontal axis this.flipX(true); // update the entity velocity this.vel.x -= this.accel.x * me.timer.tick; } else if (me.input.isKeyPressed('right')) { // unflip the sprite this.flipX(false); // update the entity velocity this.vel.x += this.accel.x * me.timer.tick; } else { this.vel.x = 0; } if (me.input.isKeyPressed('jump')) { if (!this.jumping && !this.falling) { // set current vel to the maximum defined value // gravity will then do the rest this.vel.y = -this.maxVel.y * me.timer.tick; // set the jumping flag this.jumping = true; } } // check & update player movement this.updateMovement(); // check for collision var res = me.game.collide(this); if (res) { // if we collide with an enemy if (res.obj.type == me.game.ENEMY_OBJECT) { // check if we jumped on it if ((res.y > 0) && ! this.jumping) { // bounce (force jump) this.falling = false; this.vel.y = -this.maxVel.y * me.timer.tick; // set the jumping flag this.jumping = true; } else { // let's flicker in case we touched an enemy this.flicker(45); } } } // update animation if necessary if (this.vel.x!=0 || this.vel.y!=0) { // update object animation this.parent(); return true; } // else inform the engine we did not perform // any update (e.g. position, animation) return false; } });
And this is what you should get (note that I completed the level a little bit, adding
platforms, etc...) :
Try to collect your coins, avoid the enemy or jump on it!
Part 6: Adding some basic HUD information
It's time now to display some score when we collect those coins, right?
We will use a bitmap font (data/sprite/32x32_font.png) to display our score, as always we need to add it in our list of resources to be loaded :
// game resources var g_resources = [ // our level tileset { name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, // our level { name: "area01", type: "tmx", src: "data/area01.tmx" }, // the main player spritesheet { name: "gripe_run_right", type: "image", src: "data/sprite/gripe_run_right.png" }, // the parallax background { name: "area01_bkg0", type: "image", src: "data/area01_parallax/area01_bkg0.png" }, { name: "area01_bkg1", type: "image", src: "data/area01_parallax/area01_bkg1.png" }, // the spinning coin spritesheet { name: "spinning_coin_gold", type: "image", src: "data/sprite/spinning_coin_gold.png" }, // our enemty entity { name: "wheelie_right", type: "image", src: "data/sprite/wheelie_right.png" }, // game font { name: "32x32_font", type: "image", src: "data/sprite/32x32_font.png" }];
Let's then define a new Object, that will extend the me.HUD_Item, in which we will draw the object value using our font.
/*-------------- a score HUD Item --------------------- */ var ScoreObject = me.HUD_Item.extend({ init: function(x, y) { // call the parent constructor this.parent(x, y); // create a font this.font = new me.BitmapFont("32x32_font", 32); }, /* ----- draw our score ------ */ draw: function(context, x, y) { this.font.draw(context, this.value, this.pos.x + x, this.pos.y + y); } });
And display it when we start a new game :
/* the in game stuff*/ var PlayScreen = me.ScreenObject.extend({ onResetEvent: function() { // load a level me.levelDirector.loadLevel("area01"); // add a default HUD to the game mngr me.game.addHUD(0, 430, 640, 60); // add a new HUD item me.game.HUD.addItem("score", new ScoreObject(620, 10)); // make sure everyhting is in the right order me.game.sort(); }, /* --- action to perform when game is finished (state change) --- */ onDestroyEvent: function() { // remove the HUD me.game.disableHUD(); } });
The me.game.addHUD() function is used to enable a HUD Object (specifying the HUD size), and we can then add our previously created score HUD Item by calling the me.game.HUD.addItem() function (and specifying its position within the HUD). We also assign the "score" keyword to that item, so that we can later access and modify it's value.
Additionally, we also add a call to me.game.disableHUD() in the onDestroyEvent() function, so that the HUD is removed when exiting the "play" state.
Now let's modify our Coin Object, and add some score when a coin is collected :
onCollision : function () { // do something when collected // give some score me.game.HUD.updateItemValue("score", 250); // make sure it cannot be collected "again" this.collidable = false; // remove it me.game.remove(this); }
As you can see, in the onCollision function, we just call the me.game.HUD.updateItemValue function, giving the "score" keyword (we previously defined), and the value to be added to the score. Then we ensure the object cannot be collected again, and remove the coin
We can now check the result, and we should now have our score displayed in the
bottom-right corner of the screen :
Part 7: Adding some audio
In this section we will add some audio to our game:
- a sound when collecting a coin
- a sound when jumping
- a sound when stomping on enemy
- a background (or in game music)
Then we will first add them to our resource list:
//game resources var g_resources = [ // our level tileset { name: "area01_level_tiles", type: "image", src: "data/area01_tileset/area01_level_tiles.png" }, // our level { name: "area01", type: "tmx", src: "data/area01.tmx" }, // the main player spritesheet { name: "gripe_run_right", type: "image", src: "data/sprite/gripe_run_right.png" }, // the parallax background { name: "area01_bkg0", type: "image", src: "data/area01_parallax/area01_bkg0.png" }, { name: "area01_bkg1", type: "image", src: "data/area01_parallax/area01_bkg1.png" }, // the spinning coin spritesheet { name: "spinning_coin_gold", type: "image", src: "data/sprite/spinning_coin_gold.png" }, // our enemty entity { name: "wheelie_right", type: "image", src: "data/sprite/wheelie_right.png" }, // game font { name: "32x32_font", type: "image", src: "data/sprite/32x32_font.png" }, // audio resources { name: "cling", type: "audio", src: "data/audio/", channel: 2 }, { name: "stomp", type: "audio", src: "data/audio/", channel: 1 }, { name: "jump", type: "audio", src: "data/audio/", channel: 1 }, { name: "DST-InertExponent", type: "audio", src: "data/audio/", channel: 1 }];
In case you did not notice yet, we didn't specify any extension when adding the audio element to the resource list, but instead, the path where the audio can be found. Why? Simply because we cannot know which format is supported by the browser. Instead, we let melonJS find the right format, and then load the right audio file accordingly.
If we take a look back on how we first initialized the audio, you can see that I passed the "mp3,ogg" parameter to the initialization function, asking to try to use first the mp3 format, and then ogg as a fallback if mp3 is not supported. This also means, in this case, I must provide two versions of my audio files, one as mp3, and one as ogg. The engine will then use the right based on your browser capabilities
// initialize the "audio" me.audio.init("mp3,ogg");
Then finally, still in the resource list, an audio element takes an extra parameter, the number of channel. This is useful if you need a sound to be played simultaneously. Let's take the example of the coin, if two coins are very close, there is a high "risk" ou player will hit them almost at the same time, and we must be able to notify the user with two distinct "bling" sound.
Still following? Let's modify our game :
- Collecting a coin
In the CoinEntity code, where we previously managed our earned points, we just need to add a new call to me.audio.play() and use the "cling" audio resource. that's all !
onCollision : function () { // do something when collected // play a "coin collected" sound me.audio.play("cling"); // give some score me.game.HUD.updateItemValue("score", 250); // make sure it cannot be collected "again" this.collidable = false; // remove it me.game.remove(this); }
- Jumping
In the update() function of the mainPlayer, we also add a call to me.audio.play() and use the "jump" audio resource. You can also note that I added a test on the return value of doJump(). doJump can return false in case you are not allowed to jump (already jumping, etc..) and in that case there is no need to play the sound sfx.
if (me.input.isKeyPressed('jump')) { if (!this.jumping && !this.falling) { // set current vel to the maximum defined value // gravity will then do the rest this.vel.y = -this.maxVel.y * me.timer.tick; // set the jumping flag this.jumping = true; // play some audio me.audio.play("jump"); } }
- Stomping
And still the same for this one, but using the "stomp" resource, still in the update function of the mainPlayer :
// check for collision var res = me.game.collide(this); if (res) { if (res.obj.type == me.game.ENEMY_OBJECT) { if ((res.y > 0) && ! this.jumping) { // bounce (force jump) this.falling = false; this.vel.y = -this.maxVel.y * me.timer.tick; // set the jumping flag this.jumping = true; // play some audio me.audio.play("stomp"); } else { // let's flicker in case we touched an enemy this.flicker(45); } } }
- In game music
In our main, in the onResetEvent() function, we just add a call to the me.audio.playTrack() function, specifying the audio track to be used:
onResetEvent: function() { // play the audio track me.audio.playTrack("DST-InertExponent"); .... },
And we also need to modify the onDestroyEvent() function to stop the current track when exiting the game :
onDestroyEvent: function() { // remove the HUD me.game.disableHUD(); // stop the current audio track me.audio.stopTrack(); }
That's all! click here to see the final result.
Part 8: Adding a second level
You should know how to create a level now. However, here I will show you how to go to another level.
To do this, melonJS has an Object call me.LevelEntity, that we will add in Tiled and specify what to do when our main player hit it :
Assuming that our new level is called "area02", we just need to add a "to"
property with "area02" for the value. So that when our player will hit the
Object, the engine will automatically load the "area02" level.
Optionally we can also ask the engine to add a fadeOut/fadeIn effect when changing
level by adding the "fade" color and "duration" (in ms) properties (as in the
image)
click here to see the final result.
Part 9: Adding a title screen
To finish, let's add a title screen to our game, using the title_screen.png files in the "/data/GUI" folder (and of course to be added in the ressource list, as we done it previously for other images) : and on top of it we will add some message, and wait for the user input to start the game !
First let's declare a new Object, extending me.ScreenObject :
/*---------------------- A title screen ----------------------*/ var TitleScreen = me.ScreenObject.extend({ // constructor init: function() { this.parent(true); }, // reset function onResetEvent: function() { }, // update function update: function() { }, // draw function draw: function(context) { }, // destroy function onDestroyEvent: function() { } });
Note that in this example, when I call the parent constructor, I'm passing the "true" to the function, allowing me to extend the update and draw function of my Object (else they are not called by the engine).
So now we want to:
- display the above screen
- add some text to the center of the screen ("Press enter to play")
- wait for user input (pressing enter)
Additionally, I also want to add a small scrolling text about this tutorial.
/*---------------------- A title screen ----------------------*/ var TitleScreen = me.ScreenObject.extend({ // constructor init: function() { this.parent(true); // title screen image this.title = null; this.font = null; this.scrollerfont = null; this.scrollertween = null; this.scroller = "A SMALL STEP BY STEP TUTORIAL FOR GAME CREATION WITH MELONJS "; this.scrollerpos = 600; }, // reset function onResetEvent: function() { if (this.title == null) { // init stuff if not yet done this.title = me.loader.getImage("title_screen"); // font to display the menu items this.font = new me.BitmapFont("32x32_font", 32); this.font.set("left"); // set the scroller this.scrollerfont = new me.BitmapFont("32x32_font", 32); this.scrollerfont.set("left"); } // reset to default value this.scrollerpos = 640; // a tween to animate the arrow this.scrollertween = new me.Tween(this).to({ scrollerpos: -2200 }, 10000).onComplete(this.scrollover.bind(this)).start(); // enable the keyboard me.input.bindKey(me.input.KEY.ENTER, "enter", true); // play something me.audio.play("cling"); }, // some callback for the tween objects scrollover: function() { // reset to default value this.scrollerpos = 640; this.scrollertween.to({ scrollerpos: -2200 }, 10000).onComplete(this.scrollover.bind(this)).start(); }, // update function update: function() { // enter pressed ? if (me.input.isKeyPressed('enter')) { me.state.change(me.state.PLAY); } return true; }, // draw function draw: function(context) { context.drawImage(this.title, 0, 0); this.font.draw(context, "PRESS ENTER TO PLAY", 20, 240); this.scrollerfont.draw(context, this.scroller, this.scrollerpos, 440); }, // destroy function onDestroyEvent: function() { me.input.unbindKey(me.input.KEY.ENTER); //just in case this.scrollertween.stop(); } });
What do we have above?
1) In the constructor, we declare a few objects to handle the background tile, a font
for displaying our message, and our scroller.
Note : Concerning the font, if you check carefully the corresponding asset
(32x32_font.png), you will notice that it only contains uppercase letters, so be sure
as well to only use uppercase letter in your text.
2) In the reset function, we load the resources we need (image, font, etc..) and
reset our scrolling text position, add a tween object for it (with a callback to
reset the scrolling text), and bind the ENTER key. Additionally, I'm also playing the
"cling" sound, when the title menu is loaded, because it's nice :)
3) In the update function, we check for user input (to press enter) and switch to the
PLAY state if pressed.
4) In the draw function, we draw our background (using the drawImage function), draw
both the static and scrolling text.
5) On destroy, we unbind the ENTER key, and stop the tween!
Easy, no?
And of course the very last thing is to indicate to the engine we created a new
object and associate it to the corresponding state (here, MENU). Also, using
the transition function of me.state, I'm telling the engine to add a fading effect between state
changes.
Finally, instead of switching to the PLAY state at the end of the loaded
function, I'm switching now to the MENU state:
/* --- callback when everything is loaded --- */ loaded: function() { // set the "Play/Ingame" Screen Object me.state.set(me.state.MENU, new TitleScreen()); // set the "Play/Ingame" Screen Object me.state.set(me.state.PLAY, new PlayScreen()); // set a global fading transition for the screen me.state.transition("fade", "#FFFFFF", 250); // add our player entity in the entity pool me.entityPool.add("mainPlayer", PlayerEntity); me.entityPool.add("CoinEntity", CoinEntity); me.entityPool.add("EnemyEntity", EnemyEntity); // enable the keyboard me.input.bindKey(me.input.KEY.LEFT, "left"); me.input.bindKey(me.input.KEY.RIGHT, "right"); me.input.bindKey(me.input.KEY.X, "jump", true); // display the menu title me.state.change(me.state.MENU); }
.... and ... congratulations! You reached the end of this tutorial, time to test it, and you should have something like this:
Part 10: Conclusion
Well, I hope that you enjoyed this time spent together with this little introduction of melonJS. I hope you like it and are willing to give it a try! Please keep in mind that melonJS is still in development, so it won't be perfect and that it's free! Also, don't hesitate to contact me if you have any feedback, suggestions, or found some bugs in the engine (and for sure you'll find some). I will be very happy to help you!
Never forget that this is all for fun, so have fun!


The Flask documentation and example applications are using HTML5. You may notice that in many situations, when end tags are optional they are not used, so that the HTML is cleaner and faster to load. Because there is much confusion about HTML and XHTML among developers, this document tries to answer some of the major questions.
For a while, it appeared that HTML was about to be replaced by XHTML. However, barely any websites on the Internet are actual XHTML (which is HTML processed using XML rules). There are a couple of major reasons why this is the case. One of them is Internet Explorer’s lack of proper XHTML support. The XHTML spec states that XHTML must be served with the MIME type application/xhtml+xml, but Internet Explorer refuses to read files with that MIME type. While it is relatively easy to configure Web servers to serve XHTML properly, few people do. This is likely because properly using XHTML can be quite painful.
One of the most important causes of pain is XML’s draconian (strict and ruthless) error handling. When an XML parsing error is encountered, the browser is supposed to show the user an ugly error message, instead of attempting to recover from the error and display what it can. Most of the (X)HTML generation on the web is based on non-XML template engines (such as Jinja, the one used in Flask) which do not protect you from accidentally creating invalid XHTML. There are XML based template engines, such as Kid and the popular Genshi, but they often come with a larger runtime overhead and, are not as straightforward to use because they have to obey XML rules.
The majority of users, however, assumed they were properly using XHTML. They wrote an XHTML doctype at the top of the document and self-closed all the necessary tags (
 becomes
 or

 in XHTML). However, even if the document properly validates as XHTML, what really determines XHTML/HTML processing in browsers is the MIME type, which as said before is often not set properly. So the valid XHTML was being treated as invalid HTML.
XHTML also changed the way JavaScript is used. To properly work with XHTML, programmers have to use the namespaced DOM interface with the XHTML namespace to query for HTML elements.
Development of the HTML5 specification was started in 2004 under the name “Web Applications 1.0” by the Web Hypertext Application Technology Working Group, or WHATWG (which was formed by the major browser vendors Apple, Mozilla, and Opera) with the goal of writing a new and improved HTML specification, based on existing browser behavior instead of unrealistic and backwards-incompatible specifications.
For example, in HTML4 <title/Hello/ theoretically parses exactly the same as <title>Hello</title>. However, since people were using XHTML-like tags along the lines of <link />, browser vendors implemented the XHTML syntax over the syntax defined by the specification.
In 2007, the specification was adopted as the basis of a new HTML specification under the umbrella of the W3C, known as HTML5. Currently, it appears that XHTML is losing traction, as the XHTML 2 working group has been disbanded and HTML5 is being implemented by all major browser vendors.
The following table gives you a quick overview of features available in HTML 4.01, XHTML 1.1 and HTML5. (XHTML 1.0 is not included, as it was superseded by XHTML 1.1 and the barely-used XHTML5.)
| HTML4.01 | XHTML1.1 | HTML5 | |
|---|---|---|---|
| <tag/value/ == <tag>value</tag> | [1] | ||
|
 supported | [2] | ||
|


Carolina Amane
This book focuses on viral videos of life hacks, office hacks and kitchen hacks. It highlights the number of views and followers these videos have and the effects these videos have on the viewers. All the videos from this book are found on Youtube.com and have been made into gifs and short videos. The printed book can be purchased and previewed on Lulu and the e-book can be downloaded for free via the Internet Archive.


Asking a simple question: if letters can be measured by the amount of vertices and edges they have, what does a typical name look like, numerically? Is there something special about certain names?


Creates violations for files that do not meet style conventions. Only highly obvious, probable, and non-controversial checks are performed here. It is not the goal of the tool to provide an extensive style report, but only to prevent stupid mistakes.
# File lib/cane/style_check.rb, line 14 def self.key; :style; end
# File lib/cane/style_check.rb, line 15 def self.name; "style checking"; end
# File lib/cane/style_check.rb, line 16 def self.options { style_glob: ['Glob to run style checks over', default: '{app,lib,spec}/**/*.rb', variable: 'GLOB', clobber: :no_style], style_measure: ['Max line length', default: 80, cast: :to_i, clobber: :no_style], style_exclude: ['Exclude file or glob from style checking', variable: 'GLOB', type: Array, default: [], clobber: :no_style], no_style: ['Disable style checking', cast: ->(x) { !x }] } end
# File lib/cane/style_check.rb, line 35 def violations return [] if opts[:no_style] worker.map(file_list) do |file_path| map_lines(file_path) do |line, line_number| violations_for_line(line.chomp).map {|message| { file: file_path, line: line_number + 1, label: message, description: "Lines violated style requirements" }} end end.flatten end
# File lib/cane/style_check.rb, line 80 def excluded?(file) exclusions.include?(file) end
# File lib/cane/style_check.rb, line 74 def exclusions @exclusions ||= opts.fetch(:style_exclude, []).flatten.map do |i| Dir[i] end.flatten.to_set end
# File lib/cane/style_check.rb, line 62 def file_list Dir[opts.fetch(:style_glob)].reject {|f| excluded?(f) } end
# File lib/cane/style_check.rb, line 70 def map_lines(file_path, &block) Cane::File.iterator(file_path).map.with_index(&block) end
# File lib/cane/style_check.rb, line 66 def measure opts.fetch(:style_measure) end
# File lib/cane/style_check.rb, line 52 def violations_for_line(line) result = [] if line.length > measure result << "Line is >%i characters (%i)" % [measure, line.length] end result << "Line contains trailing whitespace" if line =~ /\s$/ result << "Line contains hard tabs" if line =~ /\t/ result end
# File lib/cane/style_check.rb, line 84 def worker Cane.task_runner(opts) end


2020 Grammy Awards: List of nominees in top categories
by The Associated Press, StaffA list of nominees in the top categories at the 62nd annual Grammy Awards, announced Wednesday by The Recording Academy.
Album of the year:
- "I,I," Bon Iver
- "Norman (Expletive) Rockwell!," Lana Del Rey
- "When We All Fall Asleep, Where Do We Go?," Billie Eilish
- "Thank U, Next," Ariana Grande
- "I Used to Know Her," H.E.R.
- "7," Lil Nas X
- "Cuz I Love You (Deluxe)," Lizzo
- "Father of the Bride," Vampire Weekend.
Record of the year:
- "Hey, Ma," Bon Iver
- "Bad Guy," Billie Eilish
- "7 Rings," Ariana Grande
- "Hard Place," H.E.R.
- "Talk," Khalid
- "Old Town Road," Lil Nas X featuring Billy Ray Cyrus
- "Truth Hurts," Lizzo
- "Sunflower," Post Malone and Swae Lee
Song of the year (songwriter's award):
- "Always Remember Us This Way," Lady Gaga, Natalie Hemby, Hillary Lindsey and Lori McKenna
- "Bad Guy," Billie Eilish and Finneas O'Connell
- "Bring My Flowers Now," Tanya Tucker, Brandi Carlile, Phil Hanseroth and Tim Hanseroth
- "Hard Place," H.E.R., Rodney Jerkins, Ruby Amanfu, Sam Ashworth and D. Arcelious Harris
- "Lover," Taylor Swift
- "Norman (Expletive) Rockwell," Lana Del Rey and Jack Antonoff
- "Someone You Loved," Lewis Capaldi, Tom Barnes, Pere Kelleher, Benjamin Kohn and Sam Roman
- "Truth Hurts," Lizzo, Ricky Reed, Tele and Jesse Saint John
Best new artist:
- Black Pumas
- Billie Eilish
- Lil Nas X
- Lizzo
- Maggie Rogers
- Rosalia
- Tank and the Bangas
- Yola
Best pop solo performance:
- "Spirit," Beyonce
- "Bad Guy," Billie Eilish
- "7 Rings," Ariana Grande
- "Truth Hurts," Lizzo
- "You Need to Calm Down," Taylor Swift
Best pop duo/group performance:
- "Boyfriend," Ariana Grande and Social House
- "Sucker," Jonas Brothers
- "Old Town Road," Lil Nas X featuring Billy Ray Cyrus
- "Sunflower," Post Malone and Swae Lee
- "Senorita," Shawn Mendes and Camila Cabello
Best pop vocal album:
- "The Lion King: The Gift," Beyonce
- "When We All Fall Asleep, Where Do We Go?," Billie Eilish
- "Thank U, Next," Ariana Grande
- "No. 6 Collaborations Project," Ed Sheeran
- "Lover," Taylor Swift
Best traditional pop vocal album:
- "Si," Andrea Bocelli
- "Love (Deluxe Edition)," Michael Buble
- "Look Now," Elvis Costello & The Imposters
- "A Legendary Christmas," John Legend
- "Walls," Barbra Streisand
Best dance/electronic album:
- "LP5," Apparat
- "No Geography," The Chemical Brothers
- "Hi This Is Flume (Mixtape)," Flume
- "Solace," Rufus Du Sol
- "Weather," Tycho
Best rock album:
- "Amo," Bring Me the Horizon
- "Social Cues," Cage the Elephant
- "In the End," The Cranberries
- "Trauma," I Prevail
- "Feral Roots," Rival Sons
Best alternative music album:
- "U.F.O.F.," Big Thief
- "Assume Form," James Blake
- "I,I," Bon Iver
- "Father of the Bride," Vampire Weekend
- "Anima," Thom Yorke
Best urban contemporary album:
- "Apollo XXI," Steve Lacy
- "Cuz I Love You (Deluxe Edition)," Lizzo
- "Overload," Georgia Anne Muldrow
- "Saturn," NAO
- "Being Human In Public," Jessie Reyez
Best R&B album:
- "1123," BJ the Chicago Kid
- "Painted," Lucky Daye
- "Ella Mai," Ella Mai
- "Paul," PJ Morton
- "Ventura," Anderson.Paak
Best rap album:
- "Revenge of the Dreamers III," Various artists
- "Championships," Meek Mill
- "I Am I Was," 21 Savage
- "Igor," Tyler, The Creator
- "The Lost Boy," YBN Cordae
Best country album:
- "Desperate Man," Eric Church
- "Stronger Than the Truth," Reba McEntire
- "Interstate Gospel," Pistol Annies
- "Centre Point Road," Thomas Rhett
- "While I'm Livin'," Tanya Tucker
Best jazz vocal album:
- "Thirsty Ghost," Sara Gazarek
- "Love & Liberation," Jazzmeia Horn
- "Alone Together," Catherine Russell
- "12 Little Spells," Esperanza Spalding
- "Screenplay," The Tierney Sutton Band
Best jazz instrumental album:
- "In the Key of the Universe," Joey DeFrancesco
- "The Secret Between the Shadow and the Soul," Branford Marsalis Quartet
- "Christian McBride's New Jawn," Christian McBride
- "Finding Gabriel," Brad Mehldau
- "Come What May," Joshua Redman Quartet
Best gospel album:
- "Long Live Love," Kirk Franklin
- "Goshen," Donald Lawrence and the Tri-City Singers
- "Tunnel Vision," Gene Moore
- "Settle Here," William Murphy
- "Something's Happening! A Christmas Album," CeCe Winans
Best Latin pop album:
- "Vida," Luis Fonsi
- "11:11," Maluma
- "Montaner," Ricardo Montaner
- ".Eldisco," Alejandro Sanz
- "Fantasia," Sebastian Yatra
Best Latin rock, urban or alternative album:
- "X 100PRE," Bad Bunny
- "Oasis," J Balvin and Bad Bunny
- "Indestructible," Flor De Toloache
- "Almadura," iLe
- "El Mal Querer," Rosalia
Best comedy album:
- "Quality Time," Jim Gaffigan
- "Relatable," Ellen DeGeneres
- "Right Now," Aziz Ansari
- "Son of Patricia," Trevor Noah
- "Sticks & Stones," Dave Chappelle
Best compilation soundtrack for visual media:
- "The Lion King: The Songs"
- "Quentin Tarantino's Once Upon a Time in Hollywood"
- "Rocketman"
- "Spider-Man: Into the Spider-Verse"
- "A Star Is Born"
Producer of the year, non-classical:
- Jack Antonoff
- Dan Auerbach
- John Hill
- Finneas
- Ricky Reed
Best music video:
- "We've Got to Try," The Chemical Brothers
- "This Land," Gary Clark Jr.
- "Cellophane," FKA twigs
- "Old Town Road (Official Movie)," Lil Nas X and Billy Ray Cyrus
- "Glad He's Gone," Tove Lo
Best music film:
- "Homecoming," Beyonce
- "Remember My Name," David Crosby
- "Birth of the Cool," Miles Davis
- "Shangri-La," Various artists
- "Anima," Thom Yorke


A plugin to convert console output into navigable links for absolute paths, file://
, fqn://
and diff://
URIs, with optional #line:column
references to specify the line and column
location in the editor.
Absolute paths in the form: /...../some-file.ext:xxx
on OS X/Unix systems and
x:\....\some-file.ext:xxx
or x:/..../some-file.ext:xxx
on Windows systems, where xxx
is
line/column information, will be converted into links.
fqn://
protocol followed by a language specific fully qualified class name and optional line
and column information. This link only requires a fully qualified class name which is
independent of the physical location of the project.
diff://
protocol followed by two file paths as /somePath/...../file1.ext:xxx ? /someOtherPath/file2.ext:xxx &
to be opened in the IDE difference view with each file’s caret
to be located at the optional coordinates given by xxx
. To prevent other console filters
from hijacking the individual paths as links to single files, the file paths can be optionally
wrapped in []
after the first /
, as:
diff:///[somePath/...../file1.ext:xxx]?/[someOtherPath/file2.ext:xxx]&
. Spaces around ?
and the terminating &
are optional.
The plugin is liberal in recognizing the line/column suffix with yyy
being line number and
xxx
column and will accept #Lyyy
, :yyy:xxx
, (yyy:xxx)
, [yyy-xxx]
and their
permutations.
diff://
links allow creating output with integrated difference links similar to test console
output in IntelliJ for test failure. It allows creating these links in test frameworks not
recognized by the IDE or where the IDE does not have the facility to easily show difference view
for files.
fqn://
links are for generating links in test output with only the class name to specify the
file location. This includes parameterized tests with assertXXX(message, expected, actual)
assertions. Adding an fqn://
reference for the file/line/column of the source of the test
parameter data to create a navigable link to the line of the failed parameter data, instead of
the test source. See README


apamax.eplapplications.platform¶
CumulocityPlatform¶
-
class
apamax.eplapplications.platform.
CumulocityPlatform
(parent)[source]¶ Bases:
object
Class to create a connection to the Cumulocity platform configured in pysysproject.xml and spool the logs from the platform locally.
- Requires the following properties to be set in pysysproject.xml:
CUMULOCITY_SERVER_URL
CUMULOCITY_TENANT
CUMULOCITY_USERNAME
CUMULOCITY_PASSWORD
For use with the EPLApps class for uploading EPL applications:
self.platform = CumulocityPlatform(self) eplapps = EPLApps(self.platform.getC8YConnection()) eplapps.deploy(self.input+’/test.mon’, activate=True) self.waitForGrep(self.platform.getApamaLogFile(), expr=’Added monitor eplfiles.test’)
- Parameters
parent – The PySys test object using this platform object.


| add_totals_col | Append a totals column to a data.frame. |
| add_totals_row | Append a totals row to a data.frame. |
| adorn_ns | Add underlying Ns to a tabyl displaying percentages. |
| adorn_pct_formatting | Format a data.frame of decimals as percentages. |
| adorn_percentages | Convert a data.frame of counts to percentages. |
| adorn_rounding | Round the numeric columns in a data.frame. |
| adorn_title | Add column name to the top of a two-way tabyl. |
| adorn_totals | Append a totals row and/or column to a data.frame. |
| as_tabyl | Add 'tabyl' attributes to a data.frame. |
| chisq.test | Apply stats::chisq.test to a two-way tabyl |
| chisq.test.default | Apply stats::chisq.test to a two-way tabyl |
| chisq.test.tabyl | Apply stats::chisq.test to a two-way tabyl |
| clean_names | Cleans names of an object (usually a data.frame). |
| clean_names.data.frame | Cleans names of an object (usually a data.frame). |
| clean_names.default | Cleans names of an object (usually a data.frame). |
| clean_names.sf | Cleans names of an object (usually a data.frame). |
| clean_names.tbl_graph | Cleans names of an object (usually a data.frame). |
| compare_df_cols | Generate a comparison of data.frames (or similar objects) that indicates if they will successfully bind together by rows. |
| compare_df_cols_same | Do the the data.frames have the same columns & types? |
| convert_to_date | Convert many date and datetime formats as may be received from Microsoft Excel |
| convert_to_datetime | Convert many date and datetime formats as may be received from Microsoft Excel |
| convert_to_NA | Convert string values to true 'NA' values. |
| describe_class | Describe the class(es) of an object |
| describe_class.default | Describe the class(es) of an object |
| describe_class.factor | Describe the class(es) of an object |
| excel_numeric_to_date | Convert dates encoded as serial numbers to Date class. |
| fisher.test | Apply stats::fisher.test to a two-way tabyl |
| fisher.test.default | Apply stats::fisher.test to a two-way tabyl |
| fisher.test.tabyl | Apply stats::fisher.test to a two-way tabyl |
| get_dupes | Get rows of a 'data.frame' with identical values for the specified variables. |
| janitor_deprecated | Deprecated Functions in Package janitor |
| make_clean_names | Cleans a vector of text, typically containing the names of an object. |
| remove_constant | Remove constant columns from a data.frame or matrix. |
| remove_empty | Remove empty rows and/or columns from a data.frame or matrix. |
| remove_empty_cols | Removes empty columns from a data.frame. |
| remove_empty_rows | Removes empty rows from a data.frame. |
| round_half_up | Round a numeric vector; halves will be rounded up, ala Microsoft Excel. |
| round_to_fraction | Round to the nearest fraction of a specified denominator. |
| row_to_names | Elevate a row to be the column names of a data.frame. |
| signif_half_up | Round a numeric vector to the specified number of significant digits; halves will be rounded up. |
| tabyl | Generate a frequency table (1-, 2-, or 3-way). |
| tabyl.data.frame | Generate a frequency table (1-, 2-, or 3-way). |
| tabyl.default | Generate a frequency table (1-, 2-, or 3-way). |
| top_levels | Generate a frequency table of a factor grouped into top-n, bottom-n, and all other levels. |
| untabyl | Remove 'tabyl' attributes from a data.frame. |
| use_first_valid_of | Returns first non-NA value from a set of vectors. |


scraps: SuperConducting Resonator Analysis and Plotting Software¶
Scraps is a package designed to help you analyze lots of data from superconducting resonators. The basic idea is that you hook up your VNA (or mixer) and measure S21 at several different temperatures and driving powers.  Enter scraps. Scraps will organize it all and run fits on it, and make pretty pictures you can show your advisor or funding committee or spouse (when asked what you do all day upon returning home) or even put into a journal article.
Currently scraps is designed to handle resonator S21 data at varying temperatures and input powers. There are plans to extend scraps to handle varying magnetic field also, as well as noise in addition to S21. If you would like to be a part of that, get involved by posting a message at the github repo.
Scraps is licensed under the MIT license, so feel free to copy it, play with it, modify it, etc. under those terms (which are pretty loose!).
Development of scraps happens over at github so that is a great place to post bug reports, requests, kudos, etc.
Contents:¶
- Installation
- Example 1: Introduction
- Example 2: Lots of Data
- Figure generation for a manuscript (using NbN CPW resonator data)
- Now we can make a plot of the traces.
- Use the MCMC sampler to calculate covariances for one of the fits
- S21 fit results vs temperature and power
- Fitting secondary fit parameters to a model
- API


{{student.name}}
RollNumber : {{student.admissionId.registrations[0].rollNumber}}
{{teacher.name}}
Class Teacher
{{teacher.mobile}}


Azure Subscription Inventory
Total Active Subscriptions: ${subscription_count}
Subscription Name
Subscription ID
Tenant Name
Cost
Status
% for row in subscriptions:
${row['display_name']}
${row['subscription_id']}
${row['tenant_name']}
${row['cost']}
${row['subscription_state']}
%endfor
Page Generated on ${timestamp}


/** Express router providing WorkContract-related routes
* @module controllers/workcontracts
* @requires express
*/
/**
* Express router to mount WorkContract-related functions on.
* @type {object}
* @const
* @namespace workcontractsRouter
*/
const workcontractsRouter = require("express").Router()
const { body } = require("express-validator")
const Agency = require("../models/Agency")
const Business = require("../models/Business")
const WorkContract = require("../models/WorkContract")
const User = require("../models/User")
const authenticateToken = require("../utils/auhenticateToken")
const { needsToBeAgency, bodyBusinessExists } = require("../utils/middleware")
const { workerExists, deleteTracesOfFailedWorkContract } = require("../utils/common")
const logger = require("../utils/logger")
const domainUrl = "http://localhost:8000/"
const workContractsApiPath = "workcontracts/"
/**
* Returns response.body: { The found WorkContract object }
* Should require that the logged in user is authored to see this contract
* @name GET /workcontracts
* @function
* @memberof module:controllers/workcontracts~workcontractsRouter
* @inner
*/
workcontractsRouter.get("/:contractId", authenticateToken, (request, response, next) => {
// TODO: Validate the id for malicious inputs
try {
WorkContract.findById({ _id: request.params.contractId }, (error, result) => {
if (!result || error) {
response.status(400).send(error || { success: false, error: "Could not find WorkContract with id " + request.params.contractId })
} else {
return response.status(200).send(result)
}
})
} catch (exception) {
next(exception)
}
})
/**
* Requires User logged in as Agency. request.body MANDATORY: { businessId: "businessId", workerId: "workerId", validityPeriod: "valid end date" }. request.body OPTIONAL: { processStatus: "integer" } has a default of "1"
* Agency creates a new WorkContract between a Business and a Worker.
* The WorkContract id is then saved to lists in: Worker, Agency, Business
* Returns response.body: { created: domainUrl + workContractsApiPath + contract._id }
* @example { created: http://localhost:8080/api/workcontracts/2lkdfrakws9a9vcsv}
* @name POST /workcontracts
* @function
* @memberof module:controllers/workcontracts~workcontractsRouter
* @inner
*/
workcontractsRouter.post("/", authenticateToken, needsToBeAgency, bodyBusinessExists, async (request, response, next) => {
try {
// TODO: Validate body objects for malicious code, and the validate the validityPeriod date object and processStatus for correctness
const businessId = request.body.businessId
console.log("businessId" + businessId)
const workerId = request.body.workerId
const validityPeriod = new Date(request.body.validityPeriod)
const processStatus = request.body.processStatus
const agencyId = request.agencyId
// Check contract between business and agency
if (!request.agency.businessContracts || request.agency.businessContracts.length <= 0) {
response.status(400).send({ message: "The logged in Agency has no BusinessContracts." })
}
// request.agency.businessContracts
const arr = request.agency.businessContracts
// Go through the contracts from this agency and check if the required :businessId can be found from any of them
let commonContractIndex = -1
if (request.agency.businessContracts || request.agency.businessContracts.length > 0) {
commonContractIndex = request.agency.businessContracts.findIndex((contract) => {
return contract.toString() === businessId.toString()
})
}
// If a common contract is found,
let commonContractId = null
console.log("commoncontractindex: " + commonContractIndex)
if (commonContractIndex === -1) {
response.status(400).send({ message: "The logged in Agency has no BusinessContracts with Business with ID " + businessId })
} else {
commonContractId = arr[commonContractIndex]
}
if (!workerExists(body.workerId)) {
response.status(404).json({ success: false, message: "Couldn't find Worker with ID " + body.workerId })
}
let createFields = {
business: businessId,
user: workerId,
validityPeriod: validityPeriod,
processStatus: processStatus
}
if (body.processStatus) {
createFields.processStatus = body.processStatus
}
const contractToCreate = new WorkContract(createFields)
// Add the contract id to the business, agency and worker
await Business.findOneAndUpdate({ _id: businessId }, { $addToSet: { workcontracts: contractToCreate._id } }, (error, result) => {
if (!result || error) {
// Adding the WorkContract to Business failed, no contract saved
response
.status(500)
.send(error || { message: "Could not add WorkContract to Business with ID" + businessId + ". No WorkContract created." })
}
})
let errorInDelete = null
await Agency.findOneAndUpdate({ _id: agencyId }, { $addToSet: { workcontracts: contractToCreate._id } }, (error, result) => {
if (!result || error) {
console.log("Adding the WorkContract to Agency failed, no contract saved. Running deleteTracesOfFailedWorkContract()")
// Adding the WorkContract to Agency failed, no contract saved
errorInDelete = deleteTracesOfFailedWorkContract(workerId, businessId, agencyId, contractToCreate._id, next)
// Deleting the id of the new WorkContract from agency, business, worker was successful
if (!errorInDelete) {
logger.error("Could not add WorkContract to Agency with ID" + agencyId + ". No WorkContract created.")
response
.status(500)
.send(error || { message: "Could not add WorkContract to Agency with ID" + agencyId + ". No WorkContract created." })
} else if (errorInDelete) {
// Deleting the id references for the nonexisting WorkContract was not successful, log the result.
logger.error("Could not add WorkContract to Agency with ID" + agencyId + ". No WorkContract created, but references to the nonexisting workContract ID " + contractToCreate._id+" could not be removed. \n"
+ "Check Agency with ID " + agencyId + " and Business with ID " + businessId + ".")
response
.status(500)
.send(error || { message: "Could not add WorkContract to Agency with ID" + agencyId + ". No WorkContract created." })
}
}
})
errorInDelete = null
await User.findOneAndUpdate({ _id: workerId }, { $addToSet: { workcontracts: contractToCreate._id } }, (error, result) => {
if (!result || error) {
// Adding the WorkContract to Worker failed, no contract saved
errorInDelete = deleteTracesOfFailedWorkContract(workerId, businessId, agencyId, contractToCreate._id, next)
if (!errorInDelete) { // Deleting the id of the new WorkContract from agency, business, worker was successful
logger.error("Could not add WorkContract to Worker with ID" + workerId + ". No WorkContract created.")
response
.status(500)
.send(error || { message: "Could not add WorkContract to Worker with ID" + workerId + ". No WorkContract created." })
} else if (errorInDelete) {
// Deleting the id references for the nonexisting WorkContract was not successful, log the result.
logger.error("Could not add WorkContract to Worker with ID" + workerId + ". No WorkContract created, but references to the nonexisting workContract ID " + contractToCreate._id+" could not be removed. \n"
+ "Check with ID " + agencyId + " and Business with ID " + businessId + " and Worker with ID " + workerId + ".")
response
.status(500)
.send(error || { message: "Could not add WorkContract to Worker with ID" + agencyId + ". No WorkContract created, but references to the nonexisting workContract ID " + contractToCreate._id+" could not be removed. \n"
+ "Check with ID " + agencyId + " and Business with ID " + businessId + " and Worker with ID " + workerId + "." })
}
}
})
// Updating Agency, Business, Worker successful
const contract = await contractToCreate.save()
console.log(contract.toString)
if (!contract) {
errorInDelete = deleteTracesOfFailedWorkContract(workerId, businessId, agencyId, contractToCreate._id, next)
// Deleting the id of the new WorkContract from agency, business, worker was successful
if (!errorInDelete) {
logger.error("Could not save WorkContract with ID" + contractToCreate._id + ". No WorkContract created.")
response
.status(500)
.send( { message: "Could not save WorkContract with ID" + contractToCreate._id + ". No WorkContract created." })
} else if (errorInDelete) {
// Deleting the id references for the nonexisting WorkContract was not successful, log the result.
logger.error("Could not save WorkContract with ID" + contractToCreate._id + ". No WorkContract created, but references to the nonexisting workContract could not be removed. \n"
+ "Check with ID " + agencyId + " and Business with ID " + businessId + " and Worker with ID " + workerId + ".")
response
.status(500)
.send( { message: "Could not save WorkContract with ID" + contractToCreate._id + ". No WorkContract created, but references to the nonexisting workContract could not be removed. \n"
+ "Check with ID " + agencyId + " and Business with ID " + businessId + " and Worker with ID " + workerId + "." })
}
} else {
return response
.status(201)
.json({ created: domainUrl + workContractsApiPath + contract._id })
}
} catch (exception) {
next(exception)
}
})
/**
* Returns response.body: { The updated workcontract object }
* Requires TODO: Should check that the logged in user is authored for this
* Update a WorkContract
* Body can contain one or more of the following:
* { businessId: "businessId", workerId: "workerId", validityPeriod: "valid end date", processStatus: "integer"}
* @name PUT /workcontracts/:contractId
* @function
* @memberof module:controllers/workcontracts~workcontractsRouter
* @inner
*/
workcontractsRouter.put("/:contractId", authenticateToken, (request, response, next) => {
// TODO: Validate the id, check that the logged in user is authored for this
// TODO: What form the end date need to be?
try {
const updateFields = {
...request.body
}
WorkContract.findByIdAndUpdate(request.params.contractId, updateFields, { new: false, omitUndefined: true, runValidators: true }, (error, result) => {
if (!result || error) {
response.status(400).send(error || { success: false, error: "Could not update WorkContract with id " + request.params.contractId })
} else {
return response.status(200).send(result)
}
})
} catch (exception) {
next(exception)
}
})
module.exports = workcontractsRouter


About
Civic technologists do not need to reinvent the wheel. Civic software solutions to pressing developmental challenges already exist elsewhere in the world, and often simply need be customised or adapted to local requirements.
Locally developed software solutions are also appropriate for reuse elsewhere on the continent, and the wider world. The challenge is discovery: end-user organisations and technologists are seldom aware of existing solutions elsewhere and/or struggle to find credible recommendations that are sensitive to local operational requirements.
AfricanCOMMONS is a platform to showcase re-useable tools built across Africa and the people & organizations building them.
Attributions
- Icon by Freepik from www.flaticon.com
- Icons by Eucalyp from www.flaticon.com


Sample nosql Pouchdb App
View the Whole nosql integrated Application
Show Clock
Contact
Show the Contact details
Extra Feautres
Extra Photo Plugin


Trusted by over 1 million developers and these companies
- Documentation
- Full code
- Domains: 1 / product
- Team size: 1 person
- Tech support: 6 months
- Free updates: 6 months
- Documentation
- Full code
- Domains: 1 / product
- Team size: 1-5 people
- Tech support: 12 months
- Free updates: 12 months
- Documentation
- Full code
- Domains: unlimited
- Team size: 5-10 people
- Tech support: 12 months
- Free updates: 12 months
- Documentation
- Full code
- Domains: unlimited
- Team size: 10-15 people
- Tech support: 18 months
- Free updates: 18 months


You can either fill the SMILES (and their names) of the compounds or upload a (.xls, .csv, .txt) table file.
If both are input, it will first try to handle the uploaded files
The size of the file should be no more than 100K.
Size of the pictures
{{col}}:
{{dialogCmp[col]}}


bufread/[2,4]
bufread/2 – - runs the Prolog parser on a string of text
bufread/4 – - similiar to bufread/2, giving additional information
FORMS
bufread(Buffer,[Structure|Vars])
bufread(Buffer,[Structure|Vars],FullStop,LeftOver)
DESCRIPTION
bufread/2 takes a Prolog string, Buffer, and attempts to transform it into a Prolog term. It does this by:
Reading the first term out of Buffer (trailing characters from Buffer are ignored) and unifying it with Structure.
Returning in Vars a list of the quoted variable names occurring in the term
read.
If an error has occured, the head will be an error message (a Prolog string),
and the tail will be the column number where the error is suspected to have
occurred. bufread/4 is the same as bufread/2, except that more information is provided. FullStop is a flag indicating whether a full stop has been typed. Its value is 1 if
there was a full stop, and 0 if there was not. LeftOver is the text that is not transformed yet. Although, bufread/4 only transforms one term at a time, it returns the text it has not
transformed yet in the LeftOver argument. This text can then be transformed by issuing another bufread call, with LeftOver given as the Buffer.
EXAMPLES
The following example converts the buffer:
"f(abc, Bob) some stuff"
to the term f(abc,_53).
?- bufread("f(abc, Bob) some stuff", [T | Vars]).
T = f(abc,_53)
Vars = [’Bob’]
yes.
Observe that the characters "some stuff" are discarded by bufread/2. This next examples demonstrates how error messages are returned:
?- bufread("hello(",[Message|Column]),
printf("\nMessage: %s\nColumn: %d\n",[Message,Column]).
Message: Non-empty term expected.
Column: 6
Message = [78,111,110,45,101,109,112,116,121,32,116,101,
114,109,32,101,120,112,101,99,116,101,100,46]
Column = 6
yes.
bufread/2 can be used to convert strings to integers in the following manner:
?- bufread("123",[Int|_]).
Int = 123
yes.
In the following example, the term inside(Where) was not terminated with a full stop, so FullStop is bound to 0. There is no leftover text to run, so LeftOver is bound to the empty list.
?- bufread("inside(Where)",[Term|Vars],FullStop,LeftOver).
Term = inside(_38)
Vars = [’Where’]
FullStop = 0
LeftOver = []
yes.
If you are writing a shell in Prolog using bufread/4, you could write a continuation prompt to tell the user of your shell that
they must terminate the term with a full stop. In the next example, the term food(tai) was terminated by a full stop, so FullStop is bound to 1. This time, there is some leftover text that can be processed, so LeftOver is bound to the remaining Prolog string:
" food(indian). food(chinese). "
?- bufread("food(tai). food(indian). food(chinese). ",
[Term|Vars],FullStop,Rest),
printf("Rest = %s\n",[LeftOver]).
LeftOver = food(indian). food(chinese).
Term = food(tai)
Vars = []
FullStop = 1
LeftOver = [32,102,111,111,100,40,105,110,100,105,97,110,41,46,32,
102,111,111,100,40,99,104,105,110,101,115,101,41,46,32]
yes.
If you are writing a shell such as mentioned above, you can use use the LeftOver argument to allow multiple goals per line. You do this by continually calling bufread/4 and checking whether you still have further input to process in LeftOver.


>
>
Home
About the Journal
Scope
Physiome
Philosophy
Definitions
For Authors
Instructions
Types of submissions
Preparing your submission
Submission
Curation
Publishing
Copyright
Published Articles
Editorial Board
The Physiome Project
Frequently Asked Questions
EMAIL US
{% block body %} {% endblock %}
{% if GOOGLE_ANALYTICS %} {% endif %}