|
This document describes how to render the basic geometry of a Quake 3 map using OpenGL. It describes how to texture and lightmap this geometry, but does not describe how to render shaders, effects, characters, or movers (elevators and doors).
This is intended as a sequel to Kekoa Proudfoot's Unofficial Quake 3 Map Specs document, which describes how to parse BSP files. It therefore uses the same notation.
This is an unofficial document. Quake 3 is a registered trademark of id Software, which does not sponsor, authorize, or endorse this document.
This document describes the Quake 3 BSP file format as the author
understands it. While every effort has been made to ensure that the
contents of this document are accurate, the author does not guarantee that
any portion of this document is actually correct. In addition, the author
cannot be held responsible the consequences of the any use or misuse of the
information contained in this document.
|
The rendering process has five steps:
The first two steps do not involve any OpenGL calls. Step 3 renders a cube centered at the viewer with a pre-warped texture to create the illusion of a detailed 3D environment. The practice of creating and rendering sky boxes is discussed elsewhere and is not detailed further in this document. Steps 4 and 5 render the actual visible surfaces of the map. The opaque list contains triangles that will be rendered without alpha blending. It is sorted from front to back to take advantage of early-out depth tests on newer graphics hardware. The transparent list contains alpha blended surfaces which must be rendered from back to front to generate a correct image. A straightforward quicksort on the camera-space depth of first vertex of each surface is sufficient for these purposes. For the kinds of maps involved, splitting overlapping polygons for truly correct render order or using a radix sort for faster sorting will only increase the complexity of a renderer with improving the resulting image quality or frame rate.
1. Determine the set of visible faces.
2. Partition the visible faces into transparent and opaque lists.
3. Clear the frame buffer and render the sky box
4. Render the opaque list in front-to-back order.
5. Render the transparent list in back-to-front order.
The Visible Surface Determination section explains how to use the BSP tree and precomputed visibility data to find visible faces.
The remaining steps are straightforward and not discussed in detail,
except for the actual face rendering. The vertex indexing scheme of
Quake 3 files can be confusing because there are two levels of
indirection. The Rendering Faces
section explains how to generate triangle sets from
the indices stored in a face.
|
A Quake 3 map contains multiple models. The first of these is always a static mesh that is the map itself and the remainders are "movers" like doors and elevators. This document is restricted to model[0]; it does not address the movers.
Assume the in-memory data structures mimic those in the file structure, and that the overarching class is named Q3Map. There are a few cases where I used a Vector3 in this document instead of float[3] to make the code easier to read. Not all data from the file is used for rendering. For example, the brushs are used for collision detection but ignored during rendering. The subset of data used during rendering is (links are to Proudfoot's structure definitions):
| Lump Index | Lump Name | Description |
|---|---|---|
| 1 | Textures | Surface descriptions (assume these have been converted to OpenGL textures). |
| 2 | Planes | Planes used by map geometry. |
| 3 | Nodes | BSP tree nodes. |
| 4 | Leaves | BSP tree leaves. |
| 5 | Leaffaces | Lists of face indices, one list per leaf. |
| 7 | Models | Descriptions of rigid world geometry in map (we only use model[0]). |
| 10 | Vertexes | Vertices used to describe faces. |
| 11 | Meshverts | Lists of offsets, one list per mesh. |
| 13 | Faces | Surface geometry. |
| 14 | Lightmaps | Packed lightmap data (assume these have been converted to an OpenGL texture) |
| 16 | Visdata | Cluster-cluster visibility data. |
There are additional data used during rendering that do not appear in the file. These are:
Camera camera
A camera description that contains viewer position and frustum
parameters. The Camera class must have accessors for these parameters
and a method, isVisible(float min[3], float max[3]). This method
returns true if the world space bounding box with the specified
corners has non-zero intersection with the camera's view frustum.
Set<int> alreadyVisible
Set of indices of faces that are already visible. This is used to
prevent the same face from being rendered multiple times. A general
set implementation is not necessary. Because the face indices are
consecutive integers, a bit-set can provide an efficient
implementation.
Array<int> visibleFace
Set of indices of faces that are visible; that is, the members of the
alreadyVisible set. For efficiency this is maintained as a separate
array instead of iterating through the set.
Array<Patch> patch
Patches are Faces that
describe sets of biquadratic Bezier surfaces. Each Patch contains an
array of Bezier instances, which are described later
in this document.
These Beziers are tessellated into triangles during loading so they
can be rendered as triangle strips. Your implementation must create
this tessellation and add an index into the patch array for patch
faces.
|
Quake 3 uses a coordinate system where the x-axis points East, the y-axis points South, and the z-axis points vertically downward. If you prefer a coordinate system where the y-axis points vertically upward and the z-axis points South, you can use the following function to convert from Quake 3 coordinates to your coordinate system.
void swizzle(Vector3& v) { float temp = v.y; v.y = v.z; v.z = -temp; } |
When swizzling data, you must convert the vertex positions, vertex normals, plane normals, and all bounding box min and max vectors. The Quake coordinate system is also scaled so that one meter is about 0.03 units. You may wish to change this scale factor. If you scale vertex positions remember to also scale plane distances, and min and max vectors appropriately.
Depending on the conventions of your rendering system, you may also want to invert Quake's lightmap texture coordinates to (1 - s, 1 - t) or (s, 1 - t). It is usually easy to tell when light map texture coordinates need to be inverted by looking at a rendering.
|
The input to the visible face determination step is the camera (and the map). The output is the visibleFace array, which contains the indices of all faces that are potentially visible to that camera. During the step, the alreadyVisible set is used to prevent a face index from being added to the visibleFace array more than once.
Two notes before we look at this process in more detail. First, the output is an array of potentially visible faces. A z-buffer test and frustum clipping (both typically provided by hardware) are still needed to generate the exactly visible set. Second, as Max McGuire says in his Quake 2 BSP File Format,
Many people incorrectly associate the BSP tree with the visibility algorithm used by Quake and similar engines. As described above, the visible surface determination is done using a precomputed PVS. The BSP tree is primarily used to divide the map into regions and to quickly determine which region the camera is in. As a result, it isn't that fundamental to any of the rendering algorithms used in Quake and any data structure giving a spatial subdivision (like an octree or a k-D tree) could be used instead. BSP trees are very simple however, and they are useful for some of the other non-rendering tasks in the Quake engine.
To determine the set of visible faces:
1. Find visCluster, the index of the cluster containing the camera position.
2. Select all leaves visible from that cluster.
3. Iterate through all faces in those clusters.
Find the camera cluster (visCluster)
Recall that a Quake 3 map is divided into convex spaces called
leaves. Adjacent leaves are joined into clusters. The
map file contains precomputed visibility information at the cluster
level, which is stored in the visData bit
array.
The index of the cluster containing the camera is
The root node is index 0 in the nodeArray. Each node has a splitting
plane associated with it. This plane divides space into two child
subnodes. If the camera lies in front of the splitting plane, recurse
into the front node. Otherwise recurse into the back node. We repeat
this process until a BSP leaf is reached.
In the Node data structure, a leaf is denoted by a negative child node
index. To convert the negative index into a legal leaf index, negate
and subtract one.
The following function takes a camera position as input. It walks the
BSP tree until a leaf is found and then returns the index of that
leaf. Remember that this is return value is a leaf index, not a
cluster index. The cluster index is stored in the leaf.
leaf[index].cluster
, where index is the index of
the leaf containing the camera. To find the index of the leaf
containing the camera, walk the BSP tree.
int Q3Map::findLeaf(const Vector3& camPos) const { int index = 0; while (index >= 0) { const Node& node = nodeArray[index]; const Plane& plane = planeArray[node.plane]; // Distance from point to a plane const double distance = plane.normal.dot(camPos) - plane.distance; if (distance >= 0) { index = node.front; } else { index = node.back; } } return -index - 1; } |
bool Q3Map::isClusterVisible(int visCluster, int testCluster) const { if ((visData.bitsets == NULL) || (visCluster < 0)) { return true; } int i = (visCluster * visData.bytesPerCluster) + (testCluster >> 3); uint8 visSet = visData.bitsets[i]; return (visSet & (1 << (testCluster & 7))) != 0; } |
In the function, the expression (testCluster >> 3) computes (testCluster / 8), i.e. the byte within visData that contains information about the given cluster. The expression (1 << (testCluster & 7)) creates a bit mask that selects bit (testCluster mod 8) within that byte.
The visData information only considers the position of the viewer and
not the orientation. Orientation is handled by the frustum culling
step. The leaf contains two corners of its bounding box, min and max.
If camera.isVisible(leaf[L].min, leaf[L].max)
returns
false, the leaf should be dropped from consideration because it is
outside the view frustum. Note that some of the faces in the leaf are
also in adjacent leaves and may therefore still be visible-- the other
leaves will take care of that when we iterate through them.
Iterate through faces
A leaf contains all faces that have non-zero intersection with the
leaf volume. The faces in leaf with index L have indices
Because a face may protrude out of the leaf, the same face may be in
multiple leaves. Use the alreadyVisible
set to avoid touching the same face twice. A simple code snippet for
this is:
leaf[L].firstFace
through (leaf[L].firstFace +
leaf[L].facesCount - 1)
.
for (int i = 0; i < leaf[L].facesCount; ++i) { const int f = i + leaf[L].firstFace; if (! alreadyVisible.contains(f)) { alreadyVisible.insert(f); visibleFaces.append(f); } } |
|
There are four kinds of Faces in a Quake 3 map: polygons, patches, meshes, and billboards. Polygons and meshes are collections of triangles. A patch is a bezier-spline patch that must be tessellated into triangles for rendering. Billboards are polygons whose orientation changes to always face the viewer.
Polygons and meshes are rendered in the same manner. The position, texture coordinate, and lightmap coordinate are stored in the vertex array. Using OpenGL vertex arrays, these can be referenced with a single index by setting the active vertex pointer and tex coord pointers into the same array, offset by the memory location within a Vertex for each type of coordinate.
Patches are tessellated into triangles, either during loading or per-frame, and rendered as triangle strips. The tessellation process creates vertices that did not exist in the original mesh, so each patch contains its own vertex array instead of using the global one stored in the map file.
Although handling the shaders and effects that can be stored in Quake
3 maps is more complicated, simple alpha blending can be supported to
render translucent surfaces correctly. When a texture contains an
alpha channel, enable blending and select the
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
blending mode. Alpha blended faces should not be backfaced culled;
they appear to have only one polygon for both sides (there is probably
a two-sided polygon flag somewhere that is the correct place to obtain
such information).
Render a mesh
Each face mesh, curFace of type Face describes a mesh
containing (curFace.meshVertexesCount / 3) triangles. The indices
into the vertex array for the vertices of these triangles are
themselves indirected. The meshVertex
array stores the indices of the vertices, in the correct order to
create triangle lists. For a given face, these are
This indexing scheme, although confusing, is arranged conveniently for
using glDrawElements to render the triangle lists. The following code
renders a mesh using this function.
meshVertex[curFace.firstMeshVertex]
through
meshVertex[curFace.firstMeshVertex + curFace.mushVertexesCount -
1]
. The meshVertex values are also offet by
curFace.firstVertex
.
const Face& curFace = face[visibleFace[f]]; static const stride = sizeof(Vertex); // BSP Vertex, not float[3] const int offset = face.firstVertex; glVertexPointer(3, GL_FLOAT, stride, &(vertex[offset].position)); glClientActiveTextureARB(GL_TEXTURE0_ARB); glTexCoordPointer(2, GL_FLOAT, stride, &(vertex[offset].textureCoord)); glClientActiveTextureARB(GL_TEXTURE1_ARB); glTexCoordPointer(2, GL_FLOAT, stride, &(vertex[offset].lightmapCoord)); glDrawElements(GL_TRIANGLES, curFace.meshVertexesCount, GL_UNSIGNED_INT, &meshVertex[curFace.firstMeshVertex]); |
In the above code, the firstMeshVertex offset is applied directly to
the vertex pointer since there is no other provision for offsetting
the indices with glDrawElements.
Render a patch
Patches are surfaces defined by an array of Bezier curves. These
curves are represented by the following data structure.
class Bezier { private: int level; Array<Vertex> vertex; Array<uint32> indexes; Array<int32> trianglesPerRow; Array<uint32*> rowIndexes; public: Vertex controls[9]; void tessellate(int level); void render(); }; |
The controls array contains the 9 control points for this curve. The
Beziers form a grid within a patch, so adjacent Beziers will share
three of these. The Bezier curves must be tessellated prior to
rendering. The level of the tessellation is the number of
edges into which each side of a 2D curve is subdivided. The total
number of triangles in the tessellation is (2 * pow(level,
2))
. The remainder of the private data is the tessellation,
stored in a form we can pass directly to glMultiDrawElements. The
pointers in the rowIndexes array point into the indexes array; they
are not referring to separately allocated memory.
The tessellate method computes the private data for rendering from the control points (which must themselves be set up during loading of the containing patch). Any number between five and 10 is a reasonable subdivision level for most maps. The intent of subdivision is to provide smoother curves on faster machines by increasing the level at runtime. Another use for subdivision is to allocate more polygons to larger curves-- implementors are free to provide their own metric for choosing a good subdivision level.
The following is an implementation of the tessellate method with structure based on the tessellator in the Paul Baker's Octagon project.
void Bezier::tessellate(int L) { level = L; // The number of vertices along a side is 1 + num edges const int L1 = L + 1; vertex.resize(L1 * L1); // Compute the vertices int i; for (i = 0; i <= L; ++i) { double a = (double)i / L; double b = 1 - a; vertex[i] = controls[0] * (b * b) + controls[3] * (2 * b * a) + controls[6] * (a * a); } for (i = 1; i <= L; ++i) { double a = (double)i / L; double b = 1.0 - a; BSPVertex temp[3]; int j; for (j = 0; j < 3; ++j) { int k = 3 * j; temp[j] = controls[k + 0] * (b * b) + controls[k + 1] * (2 * b * a) + controls[k + 2] * (a * a); } for(j = 0; j <= L; ++j) { double a = (double)j / L; double b = 1.0 - a; vertex[i * L1 + j]= temp[0] * (b * b) + temp[1] * (2 * b * a) + temp[2] * (a * a); } } // Compute the indices int row; indexes.resize(L * (L + 1) * 2); for (row = 0; row < L; ++row) { for(int col = 0; col <= L; ++col) { indexes[(row * (L + 1) + col) * 2 + 1] = row * L1 + col; indexes[(row * (L + 1) + col) * 2] = (row + 1) * L1 + col; } } trianglesPerRow.resize(L); rowIndexes.resize(L); for (row = 0; row < L; ++row) { trianglesPerRow[row] = 2 * L1; rowIndexes[row] = &indexes[row * 2 * L1]; } } |
Once constructed, this data can be rendered directly with vertex arrays:
void Bezier::render() { glVertexPointer(3, GL_FLOAT,sizeof(BSPVertex), &vertex[0].position); glClientActiveTextureARB(GL_TEXTURE0_ARB); glTexCoordPointer(2, GL_FLOAT,sizeof(BSPVertex), &vertex[0].textureCoord); glClientActiveTextureARB(GL_TEXTURE1_ARB); glTexCoordPointer(2, GL_FLOAT, sizeof(BSPVertex), &vertex[0].lightmapCoord); glMultiDrawElementsEXT(GL_TRIANGLE_STRIP, trianglesPerRow.getCArray(), GL_UNSIGNED_INT, (const void **)(rowIndexes.getCArray()), patch.level); } |
| Copyright © 2003 Morgan McGuire. All rights reserved. |<EMAIL_ADDRESS>|
Acknowledgements
Kris Taeleman answered a question while I was working on this document, and I used the following resources:
Max McGuire's Quake 2 BSP File Format,
Kekoa Proudfoot's
Unofficial Quake 3 Map Specs,
Ben "Digiben" Humphrey's Unofficial Quake 3 BSP Format,
Nathan Ostgard's Quake 3 BSP Collision Detection,
Leonardo Boselli's Apocalyx source code,
Paul Baker's Octagon source code,
The Aside Software Titan source code,
The Q3Radient Manual
Keywords: quake 3 quake3 q3 arena quake3arena q3arena map bsp file render opengl spec specs format vertex order


Blood is the part of life that is given to those who need it by those who have the resource to satisfy the need. The love of fellow human and a desire to share something of oneself is what singles out a blood donor from the others. Emergencies occur every minute. For each patient requiring blood, it is an emergency and the patients could have set back if blood is not available.
Your blood donation may be even more special than you realize A single donation from you can help one or more patients.  These components perform special functions in your body and in the body of patients who receive your blood.
Various blood components are Red Blood Cells, White Blood Cells, Platelets, Plasma and selected Plasma Proteins. Each of these components can be separated from your donated volume of blood and transfused into a specific patient requiring that particular component. Thus, many can benefit from one unit of blood. Every year India requires 40 million units of 250cc blood out of which only a meager 500,000 of blood units are available.


Snow Removal Waiting List: This waiting list will alert volunteer organizations in your area that you need assistance and allow them to contact you directly. Due to overwhelming need, we cannot guarantee you will receive help, and we expect the average wait time to be several weeks. Thanks for your patience.


I recently got the STM Small Alley bag to use with my notebook. The bag I used previously was sort of falling apart, was a bit too rough inside for the MacBook (not a very rugged computer, though lovely in other ways) and also squeaked.
The Small Alley is great, but there are some small things about it I would want differently. I was a bit surprised to realize that physical items can actually be extended similar to software.
Many people, me included, take issue with the zippered compartment inside the flap. The inside of the flap is one big pocket. Combined with the facts that gravity pulls downwards and that the flap opens upwards, this means that things you put inside the flap slide all the way to its top when it’s opened. Worse, they tend to want to stay there because the flap curves around the top of the bag.
Easily solved.
I got about 20 centimeters of black, self-adhesive (on the back…) hook-and-loop fasteners (i.e. Velcro) and stuck these horizontally across the vertical middle of the pocket. I put the loops toward the bag body and the hooks toward the outside – my rationale was that as I’m more likely to leave the bag body-side down, gravity and momentum will pull stuff against the softer side rather than the rougher one. I doubt that it matters much.
The obvious idea is that you can close off the pocket across the middle, so that stuff you put at the bottom can’t travel further up than to the middle. Works a charm for me.
The fact that it’s just hook-and-loop fasteners means that you can just tear it to fit something larger in the pocket.
Something I haven’t tried, but that seems to make sense, is to instead or additionally put fasteners (or something more permanent) across the top of the pocket, only blocking off the very top, where things can get stuck.
There are some more things about the bag I want to adjust – most importantly adding pockets for cards (such as credit cards). Will blog when done.


Currently: Sunny
High: °F
Windchill: °F
Humidity:%
Windspeed: m/hr
Author: Max Cayanan
Studies have shown that kittens are not bad for you. They are friendly and relieves stress. For many cultures they are renowned for the good luck they bring their owners. You should adopt one right away when you see it. Studies have shown that kittens are not bad for you. They are friendly and relieves stress. For many cultures they are renowned for the good luck they bring their owners. You should adopt one right away when you see it. Studies have shown that kittens are not bad for you. They are friendly and relieves stress. For many cultures they are renowned for the good luck they bring their owners. You should adopt one right away when you see it.
| °F | °F | °F | °F | °F |
Image Icon Path Test:
Address: Preston, Idaho
Phone Number: 99999999
Email: rasanelforecasting@gg.com


Calculation of pressure loss in a straight pipe for laminar flow regime of single-phase fluid flow only. See more information.
Calculation of pressure loss in a straight pipe for turbulent flow regime of single-phase fluid flow only considering surface roughness. See more information.
Calculation of pressure loss in a straight pipe for laminar or turbulent flow regime of single-phase fluid flow only considering surface roughness. See more information.
Calculation of pressure loss for two phase flow in a horizontal or vertical straight pipe for an overall flow regime considering frictional, momentum and geodetic pressure loss. See more information.
| Name | Description |
|---|---|
| dp_laminar_DP | Pressure loss of straight pipe | calculate pressure loss| laminar flow regime (Hagen-Poiseuille) |
| dp_laminar_MFLOW | Pressure loss of straight pipe | calculate mass flow rate | laminar flow regime (Hagen-Poiseuille) |
| dp_laminar_IN_con | Input record for function dp_laminar_DP and dp_laminar_MFLOW |
| dp_laminar_IN_var | Input record for function dp_laminar_DP and dp_laminar_MFLOW |
| dp_overall_DP | Pressure loss of straight pipe | calculate pressure loss | overall flow regime | surface roughness |
| dp_overall_MFLOW | Pressure loss of straight pipe | calculate mass flow rate | overall flow regime | surface roughness |
| dp_overall_IN_con | Input record for function dp_overall_DP and dp_overall_MFLOW |
| dp_overall_IN_var | Input record for function dp_overall_DP and dp_overall_MFLOW |
| dp_turbulent_DP | Pressure loss of straight pipe | calculate pressure loss | turbulent flow regime | surface roughness |
| dp_turbulent_MFLOW | Pressure loss of straight pipe | calculate mass flow rate | turbulent flow regime | surface roughness |
| dp_turbulent_IN_con | Input record for function dp_turbulent_DP and dp_turbulent_MFLOW |
| dp_turbulent_IN_var | Input record for function dp_turbulent_DP and dp_turbulent_MFLOW |
| dp_twoPhaseOverall_DP | Pressure loss of straight pipe for two phase flow | calculate (frictional, momentum, geodetic) pressure loss |
| dp_twoPhaseOverall_IN_con | Input record for function dp_twoPhaseOverall_DP |
| dp_twoPhaseOverall_IN_var | Input record for function dp_twoPhaseOverall_DP |


--- layout: post title: Free HTML Mobile App Generator! date: type: post published: false status: pending categories: - Fun IT Projects - Utilities And Other Useful Things tags: - free - html - information technology - mobile - mobile apps - technology meta: _wpas_done_all: '1' jabber_published: '1347719937' tagazine-media: a:7:{s:7:"primary";s:79:"http://alexdglover.files.wordpress.com/2012/09/ristorantegenericoscreenshot.jpg";s:6:"images";a:1:{s:79:"http://alexdglover.files.wordpress.com/2012/09/ristorantegenericoscreenshot.jpg";a:6:{s:8:"file_url";s:79:"http://alexdglover.files.wordpress.com/2012/09/ristorantegenericoscreenshot.jpg";s:5:"width";i:480;s:6:"height";i:800;s:4:"type";s:5:"image";s:4:"area";i:384000;s:9:"file_path";b:0;}}s:6:"videos";a:0:{}s:11:"image_count";i:1;s:6:"author";s:8:"34836694";s:7:"blog_id";s:8:"34954019";s:9:"mod_stamp";s:19:"2012-09-15 14:41:12";} email_notification: '1347719938' _wpas_done_twitter: '1' _wpas_skip_linkedin: '1' reddit: a:2:{s:5:"count";i:0;s:4:"time";i:1353508155;} _edit_last: '1' _s2mail: 'yes' _wpas_skip_1477652: '1' _wpas_skip_1477650: '1' author: login: AlexDGlover email<EMAIL_ADDRESS>display_name: AlexDGlover first_name: Alex last_name: Glover ---
Ristorante Generico is back, with variable width!
Awhile back, I tried making a generic HTML web app using Sencha, for a hypothetical restaurant 'Ristorante Generico.' It wasn't great! Used a lot of fixed width, and when I tested it on phones other than my HTC EVO 4g it looked awful. Well I've revisited the topic, dropped Sencha, and created a PHP form so people can build their own HTML mobile app for their group or small business. Tested on the HTC Evo, iPhone 4s, and 1st Generation iPad, and it looks good!
For those interested, the 'app' is all HTML and CSS. All CSS is inline and image paths are absolute (''http://www.site.domain/image/image.ext" instead of "../img/image.ext"). Because there are no resource files or relative paths, users can steal the source and deploy it in their own site/hosting! Alternatively, users can simply generate an app with the PHP form and then link their site to the page they created, hosted on my domain.
The 'app' will display business/group name, a motto or sub-header, body text as defined by the user (which accepts HTML markup), and has 3 buttons for calling the group, pulling up directions on their phone, or pulling up the company/group's main site.
Create your own or check out the Ristorante Generico demo site on your Android or iPhone!
As always, if you want to use or modify the code for any reason, it is provided at no cost and with no guarantees.


The saturator~ external performs a nonlinear compression on the input signal based on threshold (rms), attack/release (ms), push/pull, autogain, and polynomial order (N = [2, 736]) settings. It works by deriving a polynomial tangent to y=x at some threshold between 0 and 1 where there's a maximum (peak) at x=1. It uses one of two time dependent algorithms for the attack and release.
The compressor's transfer function is a two part function where f(x)=x when x < threshold and f(x) = some polynomial function when x >= threshold. Some polynomial function can be of any order but must have a maximum at x=1.
saturator~'s polynomial functions are relatively simple. There are two cases. When N is even f(x) = -1r(x-1)^N+1-c, when it's odd f(x) = r(x-1)^N+1+c. We solve for the coefficient r and c by deriving the function's tangent with y=x at some thresh h. We can do this since f(h) = h and f'(h)=1. The latter is true because the derivative of a function solved at some point gives the m of some line y=mx tangent with the function at that point. Since y=x then m=1.
Solving for r and c with even N-polynomials gives us r=-1/ [N (x-1)^(N-1)] and c = -r(h-1)^N+1-h, while for odd it's r = 1/ [N (x-1)^(N-1)] and c= h - [r(h-1)^N+1].
| two part quadratic transfer function with threshold at 0.5 rms | two part quadratic transfer function with threshold at 0.75 rms |
| two part cubic transfer function with threshold at 0.5 rms | two part cubic transfer function with threshold at 0.75 rms |
The threshold is set with the thresh number method. The order is set with the order number method. An invalid threshold (not [0.0,1.0]) or order (below 2 or above 736) will do nothing. The limit of 736 is chosen arbitrarily. Above this value the transfer function doesn't change much.
When passing through the transfer function the signal is tested against the threshold. If it is above the threshold it is then tested for push/pull. Passing that it is then evaluated with the polynomial part of the function. If none of these conditions are met, it is left alone.
The input signal will be clipped at -1,1. If this were not the case then it would go over the peak of the polynomial function.
The code could be further optimized or adapted to work with double precision floating points (64bits).
The time dependent portion of the compression works in one of two ways. The first (default) is performed by scaling the peak (-1,1) of the original signal to the threshold and then pumping that into the compression. The second varies the working threshold from 1 to the set threshold.
First the signal is tested against the threshold. Then a factor used to scale the signal is determined. This is done in a recursive way. The factor will arbitrarily start at 1. When the signal is above the threshold a value in amplitude per time multiplied by the time since the last recursion will be added to the factor (never allowing it above 1). When the signal is below the threshold this value will be subtracted (never allowing it below the threshold).
When the factor is set to 1 then the compression will be in full force and when it's set to the threshold, there will be no compression.
In saturator~ the amplitude per time is determined in rms/ms by dividing the threshold by the duration: thresh / attack in ms and thresh / release in ms. When the duration is 0 then the factor is directly set to 1 for attack, or thresh for release. The durations are set by the methods attack number and release number.
The factor is then scaled by a one of three possible transformations. The default is a linear transformation which leaves the factor alone. The second raises the factor by some value, thresh + (1-thresh)[(factor-thresh)/(1-thresh) ] ^ param. This gives a faster rate. The third is thresh + (1-thresh) * [0.5 + 0.5 * cos((factor-thresh)pi/(1-thresh) - pi)] which gives a smooth curve, starting slower than linear but ending faster than linear. To change transformation use the method attack type (number), where type is either linear, pow or cos and number is only relevant for pow. The same works for release, release type (number).
Now one of two methods are used. The first scales the original signal by the transformed factor. This scaled signal will then run through the transfer function. Afterwards the signal is rescaled back to where it's supposed to be, by the inverse of the transformed factor.
The second methods subtracts the transformed factor from 1, adds it to the set threshold and that becomes the new working threshold. r and c are recalculated from this new threshold. autogain and the amplitude per time value are left as is; based on the set threshold. This method does more work per block than the first.
To change the TD implementation use the method cheap number, where 0 sets the expensive algorithm and any other number sets the cheap one.
More factor transformations should be devised. Perhaps a rate of change based threshold should be considered (based on transients).
The push/pull settings dictate which sign of the signal will pass through the transfer function. Push corresponds to the negative portion while pull corresponds to the positive portion. These settings are used to create asymmetrical transfer functions. For example, if pull is not set then the positive portion will not be compressed.
there are three methods to set push/pull: push, pull and pushpull
By default the object will perform an autogain. This can be disabled by the method autogain number where number is 0 to disable and any other to enable.
The autogain works by taking the result of the time dependent transfer function and dividing it by 1 - c in case of even N-polynomials and 1 + c in case of odd.


Since HTTP driven applications are stateless, sessions provide a way to store information about the user across requests. Laravel ships with a variety of session back-ends available for use through a clean, unified API. Support for popular back-ends such as Memcached, Redis, and databases is included out of the box.
The session configuration is stored in config/session.php
. Be sure to review the well documented options available to you in this file. By default, Laravel is configured to use the file
session driver, which will work well for the majority of applications.
Before using Redis sessions with Laravel, you will need to install the predis/predis
package (~1.0) via Composer.
Note: If you need all stored session data to be encrypted, set the
encrypt
configuration option totrue
.Note: When using the
cookie
session driver, you should never remove theEncryptCookie
middleware from your HTTP kernel. If you remove this middleware, your application will be vulnerable to remote code injection.
The Laravel framework uses the flash
session key internally, so you should not add an item to the session by that name.
The session may be accessed in several ways, via the HTTP request's session
method, the Session
facade, or the session
helper function. When the session
helper is called without arguments, it will return the entire session object. For example:
session()->regenerate();
Session::put('key', 'value');
session(['key' => 'value']);
Session::push('user.teams', 'developers');
$value = Session::get('key');
$value = session('key');
$value = Session::get('key', 'default');
$value = Session::get('key', function() { return 'default'; });
$value = Session::pull('key', 'default');
$data = Session::all();
if (Session::has('users'))
{
//
}
Session::forget('key');
Session::flush();
Session::regenerate();
Sometimes you may wish to store items in the session only for the next request. You may do so using the Session::flash
method:
Session::flash('key', 'value');
Session::reflash();
Session::keep(['username', 'email']);
When using the database
session driver, you will need to setup a table to contain the session items. Below is an example Schema
declaration for the table:
Schema::create('sessions', function($table)
{
$table->string('id')->unique();
$table->text('payload');
$table->integer('last_activity');
});
Of course, you may use the session:table
Artisan command to generate this migration for you!
php artisan session:table
composer dump-autoload
php artisan migrate
The session "driver" defines where session data will be stored for each request. Laravel ships with several great drivers out of the box:
file
- sessions will be stored in storage/framework/sessions
.cookie
- sessions will be stored in secure, encrypted cookies.database
- sessions will be stored in a database used by your application.memcached
/ redis
- sessions will be stored in one of these fast, cached based stores.array
- sessions will be stored in a simple PHP array and will not be persisted across requests.Note: The array driver is typically used for running unit tests, so no session data will be persisted.


When you work with us, you are part of a team of committed collaborators.
All aspects of our software development process are integrated, interactive
and agile.
We start each project by understanding your business goals, the user's needs and the product
requirements.
Then we help translate them into effective and elegant solutions.
Before we sign a contract or write a line of code our team will spend the necessary tome needed to understand your product vision
The outcome of this scoping session is proposal or high-level statement of work.
Based on your requirements, we can provide a complete offering or just the pieces you need.
DESIGN
Our design practice offers a full range of services including brand strategy, interaction and visual design and user experience testing.
your project, our designers create and implement visual design and workflows, solicit user feedback and work with you to make sure what gets built is what is needed.
DEVELOPMENT
All engineers are fluent in the latest enterprise, mobile and web development technologies.
They collaborate with your team to write, and improve code on a daily basis, using proven practices such as test-driven development and pair programming
PROJECT MANAGEMENT
Planning and development is iterative. Because we are constantly coding and testing, the products we build are always ready to go live.
iterative process allows for changes as business requirements evolve.
Hi Your message has been received.
Thank you for contacting Us.


About Internet
Interent is the way we use computers to communicate with others.Firstly, we go to a web page which computer there could send a http request to a server,
and then server sends appropriate HTML documents back to user's computer and its browser
does interpretation and presents it on the screen.
Language we use here
HTML - HyperText Markup Language.Tags, Elments, Attribute
They are basic vocabularies of HTML.
Tags present inline or block text, some of them are paired which include opening and closing, such as bold, emphasis, paragraph; while others only have opening without closing part.
Elements are everything within the a set of opening and closing tags. They are either inline or block. Block elements are invisible box around the contents inside of them.
Attribute is about a property of a HTML element; for example, we use href of an anchor tag to link a url.


Accessible Name
The accessible name is the programmatically determined name of a user interface element that is included in the accessibility tree.
The accessible name is calculated using the accessible name and description computation.
For native markup languages, such as HTML and SVG, additional information on how to calculate the accessible name can be found in HTML Accessibility API Mappings 1.0, Accessible Name and Description Computation (working draft) and SVG Accessibility API Mappings, Name and Description (working draft).
For more details, see ACT’s examples of accessible name.
Note: As per the accessible name and description computation, each element always has an accessible name. When no accessible name is provided, the element will nonetheless be assigned an empty (""
) one.
Note: As per the accessible name and description computation, accessible names are flat string trimmed of leading and trailing whitespace. Notably, it is not possible for a non-empty accessible name to be composed only of whitespace since these must be trimmed.
Accessibility Support For Accessible Name
- Because the accessible name and description computation is not clear about which whitespace are considered, browsers behave differently when trimming and flattening the accessible name. For example, some browsers completely trim non-breaking spaces while some keep them in the accessible name.
- There exists a popular browser which does not perform the same trimming and flattening depending whether the accessible name comes from content, an
aria-label
attribute, or analt
attribute. - There exists a popular browser which assign no accessible name (
null
) when none is provided, instead of assigned an empty accessible name (""
). - The accessible name and description computation suggest that if an
aria-labelledby
attribute refers to an existing but empty element, the computation should stop and return an empty name without defaulting to the next steps. Several user agents and assistive technologies chose to use the next step in the computation in this case.
Accessibility Support For Definition Of Semantic Role For Semantic Role
- There exist popular web browsers and assistive technologies which do not correctly implement Presentational Roles Conflict Resolution. These technologies will not include in the accessibility tree elements that should be, according to Specifications. Thus, some elements that should have their semantic role fixed by case Conflict above are instead falling into case Explicit and are hidden for users of assistive technologies.
- A similar conflict exists for focusable elements with a
aria-hidden="true"
attribute. The WAI ARIA specification does not explain how to solve it. Some browsers give precedence to the element being focusable (and expose it in the accessibility tree) while some give precedence to thearia-hidden
attribute (and hide the element).
Accessibility Support For Explicit Semantic Role
Some browsers and assistive technologies treat the tokens of the role
attribute as case-sensitive. Unless lowercase letters are used for the value of the role
attribute, not all user agents will be able to interpret the tokens correctly. ARIA in HTML (working draft) also specifies that authors must use lowercase letters for the role
and aria-*
attributes.
Accessibility Support For Implicit Semantic Role
Images with an empty alt
attribute should have an implicit role of presentation
, according to the HTML Accessibility API Mapping (work in progress). However, there are several popular browsers that do not treat images with empty alt
attribute as having a role of presentation
. Instead, they add the img
element to the accessibility tree with a role of either img
or graphic
.
Ancestor
An object A is called an ancestor of an object B if and only if B is a descendant of A.
Current Request
An img
element has a current request and a pending request. The current request is initially set to a new image request. The pending request is initially set to null.
Explicit Semantic Role
The explicit semantic role of an element is determined by its role attribute (if any).
The role attribute takes a list of tokens. The explicit semantic role is the first valid role in this list. The valid roles are all non-abstract roles from WAI-ARIA Specifications. If the element has no role attribute, or if it has one with no valid role, then this element has no explicit semantic role.
Other roles may be added as they become available. Not all roles will be supported in all assistive technologies. Testers are encouraged to adjust which roles are allowed according to the accessibility support base line. For the purposes of executing test cases in all rules, it should be assumed that all roles are supported by assistive technologies so that none of the roles fail due to lack of accessibility support.
Flat Tree
While Selectors operates on the DOM tree as the host language presents it, with separate trees that are unreachable via the standard parent/child relationship, the rest of CSS needs a single unified tree structure to work with. This is called the flattened element tree (or flat tree)
Focusable
Elements that can become the target of keyboard input as described in the HTML specification of focusable and HTML specification of can be focused.
Image Request State
An image request has a state, current URL, and image data. An image request's state is one of the following:
- Unavailable
- The user agent hasn't obtained any image data, or has obtained some or all of the image data but hasn't yet decoded enough of the image to get the image dimensions.
- Partially available
- The user agent has obtained some of the image data and at least the image dimensions are available.
- Completely available
- The user agent has obtained all of the image data and at least the image dimensions are available.
- Broken
- The user agent has obtained all of the image data that it can, but it cannot even decode the image enough to get the image dimensions (e.g. the image is corrupted, or the format is not supported, or no data could be obtained).
Implicit Semantic Role
The implicit semantic role of an element is a pre-defined value given by the host language which depends on the element and its ancestors.
Implicit roles for HTML and SVG, are documented in the HTML accessibility API mappings (working draft) and the SVG accessibility API mappings (working draft).
Included In The Accessibility Tree
Elements included in the accessibility tree of platform specific accessibility APIs. Elements in the accessibility tree are exposed to assistive technologies, allowing users to interact with the elements in a way that meet the requirements of the individual user.
The general rules for when elements are included in the accessibility tree are defined in the core accessibility API mappings. For native markup languages, such as HTML and SVG, additional rules for when elements are included in the accessibility tree can be found in the HTML accessibility API mappings (working draft) and the SVG accessibility API mappings (working draft).
For more details, see ACT’s examples of included in the accessibility tree.
Note: Users of assistive technologies might still be able to interact with elements that are not included in the accessibility tree. An example of this is a focusable element with an aria-hidden
attribute with a value of true
. Such an element could still be interacted using sequential keyboard navigation regardless of the assistive technologies used, even though the element would not be included in the accessibility tree.
Marked As Decorative
An element is marked as decorative if one of the following conditions is true:
- it has an explicit role of
none
orpresentation
; or - it is an
img
element with analt
attribute whose value is the empty string (alt=""
), and with no explicit role.
Elements are marked as decorative as a way to convey the intention of the author that they are pure decoration. It is different from the element actually being pure decoration as authors may make mistakes. It is different from the element being effectively ignored by assistive technologies as rules such as presentational roles conflict resolution may overwrite this intention.
Elements can also be ignored by assistive technologies if their hidden state is true. This is different from marking the element as decorative and does not convey the same intention. Notably, the hidden state of an element may change as users interact with the page (showing and hiding elements) while being marked as decorative should stay the same through all states of the page.
Outcome
An outcome is a conclusion that comes from evaluating an ACT Rule on a test subject or one of its constituent test target. An outcome can be one of the three following types:
- Inapplicable:
- No part of the test subject matches the applicability.
- Passed:
- A test target meets all expectations.
- Failed:
- A test target does not meet all expectations
Note: A rule has one passed
or failed
outcome for every test target. When there are no test targets the rule has one inapplicable
outcome. This means that each test subject will have one or more outcomes.
Note: Implementations using the EARL 1.0 Schema can express the outcome with the outcome property. In addition to passed
, failed
and inapplicable
, EARL 1.0 also defined an incomplete
outcome. While this cannot be the outcome of an ACT Rule when applied in its entirety, it often happens that rules are only partially evaluated. For example, when applicability was automated, but the expectations have to be evaluated manually. Such “interim” results can be expressed with the incomplete
outcome.
Pure Decoration
serving only an aesthetic purpose, providing no information, and having no functionality.
Note: Text is only purely decorative if the words can be rearranged or substituted without changing their purpose.
Semantic Role
The semantic role of an element is determined by the first of these cases that applies:
- Conflict:
- If the element is marked as decorative, but the element is included in the accessibility tree; or would be included in the accessibility tree when its hidden state is false, then its semantic role is its implicit role.
- Explicit:
- If the element has an explicit role, then its semantic role is its explicit role.
- Implicit:
- The semantic role of the element is its implicit role.
Visible
Content perceivable through sight.
Content is considered visible if making it fully transparent would result in a difference in the pixels rendered for any part of the document that is currently within the viewport or can be brought into the viewport via scrolling.
For more details, see ACT examples of visible.
WAI-ARIA Specifications
The WAI-ARIA Specifications group both the WAI ARIA W3C Recommendation and ARIA modules, namely:
- Accessible Rich Internet Applications (WAI-ARIA) 1.1
- WAI-ARIA Graphics Module 1.0
- Digital Publishing WAI-ARIA Module 1.0
Note: depending on the type of content being evaluated, part of the specifications might be irrelevant and should be ignored.


ESRequestError
public enum ESRequestError : Error
Undocumented
-
Undocumented
Declaration
Swift
case noConnection
-
Undocumented
Declaration
Swift
case lostConnection
-
Undocumented
Declaration
Swift
case unauthorized
-
Undocumented
Declaration
Swift
case internalServerError
-
Undocumented
Declaration
Swift
case badRequest
-
Undocumented
Declaration
Swift
case cancelled
-
Undocumented
Declaration
Swift
case timedOut
-
Undocumented
Declaration
Swift
case notFound
-
Undocumented
Declaration
Swift
case forbidden
-
Undocumented
Declaration
Swift
case unspecified(statusCode: Int)
-
Undocumented
Declaration
Swift
case dataDecodingError
-
Undocumented
Declaration
Swift
case noData
-
Undocumented
Declaration
Swift
case wrongURL
-
Undocumented
Declaration
Swift
case wrongBodyParams


Plato on Github
Report Home
src\ng\rootScope.js
Maintainability
62.49
Lines of code
1349
Difficulty
105.84
Estimated Errors
5.02
Function weight
By Complexity
By SLOC
'use strict'; /** * DESIGN NOTES * * The design decisions behind the scope are heavily favored for speed and memory consumption. * * The typical use of scope is to watch the expressions, which most of the time return the same * value as last time so we optimize the operation. * * Closures construction is expensive in terms of speed as well as memory: * - No closures, instead use prototypical inheritance for API * - Internal state needs to be stored on scope directly, which means that private state is * exposed as $$____ properties * * Loop operations are optimized by using while(count--) { ... } * - this means that in order to keep the same order of execution as addition we have to add * items to the array at the beginning (unshift) instead of at the end (push) * * Child scopes are created and removed often * - Using an array would be slow since inserts in middle are expensive so we use linked list * * There are few watches then a lot of observers. This is why you don't want the observer to be * implemented in the same way as watch. Watch requires return of initialization function which * are expensive to construct. */ /** * @ngdoc provider * @name $rootScopeProvider * @description * * Provider for the $rootScope service. */ /** * @ngdoc method * @name $rootScopeProvider#digestTtl * @description * * Sets the number of `$digest` iterations the scope should attempt to execute before giving up and * assuming that the model is unstable. * * The current default is 10 iterations. * * In complex applications it's possible that the dependencies between `$watch`s will result in * several digest iterations. However if an application needs more than the default 10 digest * iterations for its model to stabilize then you should investigate what is causing the model to * continuously change during the digest. * * Increasing the TTL could have performance implications, so you should not change it without * proper justification. * * @param {number} limit The number of digest iterations. */ /** * @ngdoc service * @name $rootScope * @description * * Every application has a single root {@link ng.$rootScope.Scope scope}. * All other scopes are descendant scopes of the root scope. Scopes provide separation * between the model and the view, via a mechanism for watching the model for changes. * They also provide an event emission/broadcast and subscription facility. See the * {@link guide/scope developer guide on scopes}. */ function $RootScopeProvider() { var TTL = 10; var $rootScopeMinErr = minErr('$rootScope'); var lastDirtyWatch = null; var applyAsyncId = null; this.digestTtl = function(value) { if (arguments.length) { TTL = value; } return TTL; }; function createChildScopeClass(parent) { function ChildScope() { this.$$watchers = this.$$nextSibling = this.$$childHead = this.$$childTail = null; this.$$listeners = {}; this.$$listenerCount = {}; this.$$watchersCount = 0; this.$id = nextUid(); this.$$ChildScope = null; } ChildScope.prototype = parent; return ChildScope; } this.$get = ['$injector', '$exceptionHandler', '$parse', '$browser', function($injector, $exceptionHandler, $parse, $browser) { function destroyChildScope($event) { $event.currentScope.$$destroyed = true; } /** * @ngdoc type * @name $rootScope.Scope * * @description * A root scope can be retrieved using the {@link ng.$rootScope $rootScope} key from the * {@link auto.$injector $injector}. Child scopes are created using the * {@link ng.$rootScope.Scope#$new $new()} method. (Most scopes are created automatically when * compiled HTML template is executed.) * * Here is a simple scope snippet to show how you can interact with the scope. * ```html * <file src="./test/ng/rootScopeSpec.js" tag="docs1" /> * ``` * * # Inheritance * A scope can inherit from a parent scope, as in this example: * ```js var parent = $rootScope; var child = parent.$new(); parent.salutation = "Hello"; expect(child.salutation).toEqual('Hello'); child.salutation = "Welcome"; expect(child.salutation).toEqual('Welcome'); expect(parent.salutation).toEqual('Hello'); * ``` * * When interacting with `Scope` in tests, additional helper methods are available on the * instances of `Scope` type. See {@link ngMock.$rootScope.Scope ngMock Scope} for additional * details. * * * @param {Object.<string, function()>=} providers Map of service factory which need to be * provided for the current scope. Defaults to {@link ng}. * @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should * append/override services provided by `providers`. This is handy * when unit-testing and having the need to override a default * service. * @returns {Object} Newly created scope. * */ function Scope() { this.$id = nextUid(); this.$$phase = this.$parent = this.$$watchers = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = null; this.$root = this; this.$$destroyed = false; this.$$listeners = {}; this.$$listenerCount = {}; this.$$watchersCount = 0; this.$$isolateBindings = null; } /** * @ngdoc property * @name $rootScope.Scope#$id * * @description * Unique scope ID (monotonically increasing) useful for debugging. */ /** * @ngdoc property * @name $rootScope.Scope#$parent * * @description * Reference to the parent scope. */ /** * @ngdoc property * @name $rootScope.Scope#$root * * @description * Reference to the root scope. */ Scope.prototype = { constructor: Scope, /** * @ngdoc method * @name $rootScope.Scope#$new * @kind function * * @description * Creates a new child {@link ng.$rootScope.Scope scope}. * * The parent scope will propagate the {@link ng.$rootScope.Scope#$digest $digest()} event. * The scope can be removed from the scope hierarchy using {@link ng.$rootScope.Scope#$destroy $destroy()}. * * {@link ng.$rootScope.Scope#$destroy $destroy()} must be called on a scope when it is * desired for the scope and its child scopes to be permanently detached from the parent and * thus stop participating in model change detection and listener notification by invoking. * * @param {boolean} isolate If true, then the scope does not prototypically inherit from the * parent scope. The scope is isolated, as it can not see parent scope properties. * When creating widgets, it is useful for the widget to not accidentally read parent * state. * * @param {Scope} [parent=this] The {@link ng.$rootScope.Scope `Scope`} that will be the `$parent` * of the newly created scope. Defaults to `this` scope if not provided. * This is used when creating a transclude scope to correctly place it * in the scope hierarchy while maintaining the correct prototypical * inheritance. * * @returns {Object} The newly created child scope. * */ $new: function(isolate, parent) { var child; parent = parent || this; if (isolate) { child = new Scope(); child.$root = this.$root; } else { // Only create a child scope class if somebody asks for one, // but cache it to allow the VM to optimize lookups. if (!this.$$ChildScope) { this.$$ChildScope = createChildScopeClass(this); } child = new this.$$ChildScope(); } child.$parent = parent; child.$$prevSibling = parent.$$childTail; if (parent.$$childHead) { parent.$$childTail.$$nextSibling = child; parent.$$childTail = child; } else { parent.$$childHead = parent.$$childTail = child; } // When the new scope is not isolated or we inherit from `this`, and // the parent scope is destroyed, the property `$$destroyed` is inherited // prototypically. In all other cases, this property needs to be set // when the parent scope is destroyed. // The listener needs to be added after the parent is set if (isolate || parent != this) child.$on('$destroy', destroyChildScope); return child; }, /** * @ngdoc method * @name $rootScope.Scope#$watch * @kind function * * @description * Registers a `listener` callback to be executed whenever the `watchExpression` changes. * * - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#$digest * $digest()} and should return the value that will be watched. (Since * {@link ng.$rootScope.Scope#$digest $digest()} reruns when it detects changes the * `watchExpression` can execute multiple times per * {@link ng.$rootScope.Scope#$digest $digest()} and should be idempotent.) * - The `listener` is called only when the value from the current `watchExpression` and the * previous call to `watchExpression` are not equal (with the exception of the initial run, * see below). Inequality is determined according to reference inequality, * [strict comparison](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators) * via the `!==` Javascript operator, unless `objectEquality == true` * (see next point) * - When `objectEquality == true`, inequality of the `watchExpression` is determined * according to the {@link angular.equals} function. To save the value of the object for * later comparison, the {@link angular.copy} function is used. This therefore means that * watching complex objects will have adverse memory and performance implications. * - The watch `listener` may change the model, which may trigger other `listener`s to fire. * This is achieved by rerunning the watchers until no changes are detected. The rerun * iteration limit is 10 to prevent an infinite loop deadlock. * * * If you want to be notified whenever {@link ng.$rootScope.Scope#$digest $digest} is called, * you can register a `watchExpression` function with no `listener`. (Since `watchExpression` * can execute multiple times per {@link ng.$rootScope.Scope#$digest $digest} cycle when a * change is detected, be prepared for multiple calls to your listener.) * * After a watcher is registered with the scope, the `listener` fn is called asynchronously * (via {@link ng.$rootScope.Scope#$evalAsync $evalAsync}) to initialize the * watcher. In rare cases, this is undesirable because the listener is called when the result * of `watchExpression` didn't change. To detect this scenario within the `listener` fn, you * can compare the `newVal` and `oldVal`. If these two values are identical (`===`) then the * listener was called due to initialization. * * * * # Example * ```js // let's assume that scope was dependency injected as the $rootScope var scope = $rootScope; scope.name = 'misko'; scope.counter = 0; expect(scope.counter).toEqual(0); scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; }); expect(scope.counter).toEqual(0); scope.$digest(); // the listener is always called during the first $digest loop after it was registered expect(scope.counter).toEqual(1); scope.$digest(); // but now it will not be called unless the value changes expect(scope.counter).toEqual(1); scope.name = 'adam'; scope.$digest(); expect(scope.counter).toEqual(2); // Using a function as a watchExpression var food; scope.foodCounter = 0; expect(scope.foodCounter).toEqual(0); scope.$watch( // This function returns the value being watched. It is called for each turn of the $digest loop function() { return food; }, // This is the change listener, called when the value returned from the above function changes function(newValue, oldValue) { if ( newValue !== oldValue ) { // Only increment the counter if the value changed scope.foodCounter = scope.foodCounter + 1; } } ); // No digest has been run so the counter will be zero expect(scope.foodCounter).toEqual(0); // Run the digest but since food has not changed count will still be zero scope.$digest(); expect(scope.foodCounter).toEqual(0); // Update food and run digest. Now the counter will increment food = 'cheeseburger'; scope.$digest(); expect(scope.foodCounter).toEqual(1); * ``` * * * * @param {(function()|string)} watchExpression Expression that is evaluated on each * {@link ng.$rootScope.Scope#$digest $digest} cycle. A change in the return value triggers * a call to the `listener`. * * - `string`: Evaluated as {@link guide/expression expression} * - `function(scope)`: called with current `scope` as a parameter. * @param {function(newVal, oldVal, scope)} listener Callback called whenever the value * of `watchExpression` changes. * * - `newVal` contains the current value of the `watchExpression` * - `oldVal` contains the previous value of the `watchExpression` * - `scope` refers to the current scope * @param {boolean=} objectEquality Compare for object equality using {@link angular.equals} instead of * comparing for reference equality. * @returns {function()} Returns a deregistration function for this listener. */ $watch: function(watchExp, listener, objectEquality, prettyPrintExpression) { var get = $parse(watchExp); if (get.$$watchDelegate) { return get.$$watchDelegate(this, listener, objectEquality, get, watchExp); } var scope = this, array = scope.$$watchers, watcher = { fn: listener, last: initWatchVal, get: get, exp: prettyPrintExpression || watchExp, eq: !!objectEquality }; lastDirtyWatch = null; if (!isFunction(listener)) { watcher.fn = noop; } if (!array) { array = scope.$$watchers = []; } // we use unshift since we use a while loop in $digest for speed. // the while loop reads in reverse order. array.unshift(watcher); incrementWatchersCount(this, 1); return function deregisterWatch() { if (arrayRemove(array, watcher) >= 0) { incrementWatchersCount(scope, -1); } lastDirtyWatch = null; }; }, /** * @ngdoc method * @name $rootScope.Scope#$watchGroup * @kind function * * @description * A variant of {@link ng.$rootScope.Scope#$watch $watch()} where it watches an array of `watchExpressions`. * If any one expression in the collection changes the `listener` is executed. * * - The items in the `watchExpressions` array are observed via standard $watch operation and are examined on every * call to $digest() to see if any items changes. * - The `listener` is called whenever any expression in the `watchExpressions` array changes. * * @param {Array.<string|Function(scope)>} watchExpressions Array of expressions that will be individually * watched using {@link ng.$rootScope.Scope#$watch $watch()} * * @param {function(newValues, oldValues, scope)} listener Callback called whenever the return value of any * expression in `watchExpressions` changes * The `newValues` array contains the current values of the `watchExpressions`, with the indexes matching * those of `watchExpression` * and the `oldValues` array contains the previous values of the `watchExpressions`, with the indexes matching * those of `watchExpression` * The `scope` refers to the current scope. * @returns {function()} Returns a de-registration function for all listeners. */ $watchGroup: function(watchExpressions, listener) { var oldValues = new Array(watchExpressions.length); var newValues = new Array(watchExpressions.length); var deregisterFns = []; var self = this; var changeReactionScheduled = false; var firstRun = true; if (!watchExpressions.length) { // No expressions means we call the listener ASAP var shouldCall = true; self.$evalAsync(function() { if (shouldCall) listener(newValues, newValues, self); }); return function deregisterWatchGroup() { shouldCall = false; }; } if (watchExpressions.length === 1) { // Special case size of one return this.$watch(watchExpressions[0], function watchGroupAction(value, oldValue, scope) { newValues[0] = value; oldValues[0] = oldValue; listener(newValues, (value === oldValue) ? newValues : oldValues, scope); }); } forEach(watchExpressions, function(expr, i) { var unwatchFn = self.$watch(expr, function watchGroupSubAction(value, oldValue) { newValues[i] = value; oldValues[i] = oldValue; if (!changeReactionScheduled) { changeReactionScheduled = true; self.$evalAsync(watchGroupAction); } }); deregisterFns.push(unwatchFn); }); function watchGroupAction() { changeReactionScheduled = false; if (firstRun) { firstRun = false; listener(newValues, newValues, self); } else { listener(newValues, oldValues, self); } } return function deregisterWatchGroup() { while (deregisterFns.length) { deregisterFns.shift()(); } }; }, /** * @ngdoc method * @name $rootScope.Scope#$watchCollection * @kind function * * @description * Shallow watches the properties of an object and fires whenever any of the properties change * (for arrays, this implies watching the array items; for object maps, this implies watching * the properties). If a change is detected, the `listener` callback is fired. * * - The `obj` collection is observed via standard $watch operation and is examined on every * call to $digest() to see if any items have been added, removed, or moved. * - The `listener` is called whenever anything within the `obj` has changed. Examples include * adding, removing, and moving items belonging to an object or array. * * * # Example * ```js $scope.names = ['igor', 'matias', 'misko', 'james']; $scope.dataCount = 4; $scope.$watchCollection('names', function(newNames, oldNames) { $scope.dataCount = newNames.length; }); expect($scope.dataCount).toEqual(4); $scope.$digest(); //still at 4 ... no changes expect($scope.dataCount).toEqual(4); $scope.names.pop(); $scope.$digest(); //now there's been a change expect($scope.dataCount).toEqual(3); * ``` * * * @param {string|function(scope)} obj Evaluated as {@link guide/expression expression}. The * expression value should evaluate to an object or an array which is observed on each * {@link ng.$rootScope.Scope#$digest $digest} cycle. Any shallow change within the * collection will trigger a call to the `listener`. * * @param {function(newCollection, oldCollection, scope)} listener a callback function called * when a change is detected. * - The `newCollection` object is the newly modified data obtained from the `obj` expression * - The `oldCollection` object is a copy of the former collection data. * Due to performance considerations, the`oldCollection` value is computed only if the * `listener` function declares two or more arguments. * - The `scope` argument refers to the current scope. * * @returns {function()} Returns a de-registration function for this listener. When the * de-registration function is executed, the internal watch operation is terminated. */ $watchCollection: function(obj, listener) { $watchCollectionInterceptor.$stateful = true; var self = this; // the current value, updated on each dirty-check run var newValue; // a shallow copy of the newValue from the last dirty-check run, // updated to match newValue during dirty-check run var oldValue; // a shallow copy of the newValue from when the last change happened var veryOldValue; // only track veryOldValue if the listener is asking for it var trackVeryOldValue = (listener.length > 1); var changeDetected = 0; var changeDetector = $parse(obj, $watchCollectionInterceptor); var internalArray = []; var internalObject = {}; var initRun = true; var oldLength = 0; function $watchCollectionInterceptor(_value) { newValue = _value; var newLength, key, bothNaN, newItem, oldItem; // If the new value is undefined, then return undefined as the watch may be a one-time watch if (isUndefined(newValue)) return; if (!isObject(newValue)) { // if primitive if (oldValue !== newValue) { oldValue = newValue; changeDetected++; } } else if (isArrayLike(newValue)) { if (oldValue !== internalArray) { // we are transitioning from something which was not an array into array. oldValue = internalArray; oldLength = oldValue.length = 0; changeDetected++; } newLength = newValue.length; if (oldLength !== newLength) { // if lengths do not match we need to trigger change notification changeDetected++; oldValue.length = oldLength = newLength; } // copy the items to oldValue and look for changes. for (var i = 0; i < newLength; i++) { oldItem = oldValue[i]; newItem = newValue[i]; bothNaN = (oldItem !== oldItem) && (newItem !== newItem); if (!bothNaN && (oldItem !== newItem)) { changeDetected++; oldValue[i] = newItem; } } } else { if (oldValue !== internalObject) { // we are transitioning from something which was not an object into object. oldValue = internalObject = {}; oldLength = 0; changeDetected++; } // copy the items to oldValue and look for changes. newLength = 0; for (key in newValue) { if (newValue.hasOwnProperty(key)) { newLength++; newItem = newValue[key]; oldItem = oldValue[key]; if (key in oldValue) { bothNaN = (oldItem !== oldItem) && (newItem !== newItem); if (!bothNaN && (oldItem !== newItem)) { changeDetected++; oldValue[key] = newItem; } } else { oldLength++; oldValue[key] = newItem; changeDetected++; } } } if (oldLength > newLength) { // we used to have more keys, need to find them and destroy them. changeDetected++; for (key in oldValue) { if (!newValue.hasOwnProperty(key)) { oldLength--; delete oldValue[key]; } } } } return changeDetected; } function $watchCollectionAction() { if (initRun) { initRun = false; listener(newValue, newValue, self); } else { listener(newValue, veryOldValue, self); } // make a copy for the next time a collection is changed if (trackVeryOldValue) { if (!isObject(newValue)) { //primitive veryOldValue = newValue; } else if (isArrayLike(newValue)) { veryOldValue = new Array(newValue.length); for (var i = 0; i < newValue.length; i++) { veryOldValue[i] = newValue[i]; } } else { // if object veryOldValue = {}; for (var key in newValue) { if (hasOwnProperty.call(newValue, key)) { veryOldValue[key] = newValue[key]; } } } } } return this.$watch(changeDetector, $watchCollectionAction); }, /** * @ngdoc method * @name $rootScope.Scope#$digest * @kind function * * @description * Processes all of the {@link ng.$rootScope.Scope#$watch watchers} of the current scope and * its children. Because a {@link ng.$rootScope.Scope#$watch watcher}'s listener can change * the model, the `$digest()` keeps calling the {@link ng.$rootScope.Scope#$watch watchers} * until no more listeners are firing. This means that it is possible to get into an infinite * loop. This function will throw `'Maximum iteration limit exceeded.'` if the number of * iterations exceeds 10. * * Usually, you don't call `$digest()` directly in * {@link ng.directive:ngController controllers} or in * {@link ng.$compileProvider#directive directives}. * Instead, you should call {@link ng.$rootScope.Scope#$apply $apply()} (typically from within * a {@link ng.$compileProvider#directive directive}), which will force a `$digest()`. * * If you want to be notified whenever `$digest()` is called, * you can register a `watchExpression` function with * {@link ng.$rootScope.Scope#$watch $watch()} with no `listener`. * * In unit tests, you may need to call `$digest()` to simulate the scope life cycle. * * # Example * ```js var scope = ...; scope.name = 'misko'; scope.counter = 0; expect(scope.counter).toEqual(0); scope.$watch('name', function(newValue, oldValue) { scope.counter = scope.counter + 1; }); expect(scope.counter).toEqual(0); scope.$digest(); // the listener is always called during the first $digest loop after it was registered expect(scope.counter).toEqual(1); scope.$digest(); // but now it will not be called unless the value changes expect(scope.counter).toEqual(1); scope.name = 'adam'; scope.$digest(); expect(scope.counter).toEqual(2); * ``` * */ $digest: function() { var watch, value, last, watchers, length, dirty, ttl = TTL, next, current, target = this, watchLog = [], logIdx, logMsg, asyncTask; beginPhase('$digest'); // Check for changes to browser url that happened in sync before the call to $digest $browser.$$checkUrlChange(); if (this === $rootScope && applyAsyncId !== null) { // If this is the root scope, and $applyAsync has scheduled a deferred $apply(), then // cancel the scheduled $apply and flush the queue of expressions to be evaluated. $browser.defer.cancel(applyAsyncId); flushApplyAsync(); } lastDirtyWatch = null; do { // "while dirty" loop dirty = false; current = target; while (asyncQueue.length) { try { asyncTask = asyncQueue.shift(); asyncTask.scope.$eval(asyncTask.expression, asyncTask.locals); } catch (e) { $exceptionHandler(e); } lastDirtyWatch = null; } traverseScopesLoop: do { // "traverse the scopes" loop if ((watchers = current.$$watchers)) { // process our watches length = watchers.length; while (length--) { try { watch = watchers[length]; // Most common watches are on primitives, in which case we can short // circuit it with === operator, only when === fails do we use .equals if (watch) { if ((value = watch.get(current)) !== (last = watch.last) && !(watch.eq ? equals(value, last) : (typeof value === 'number' && typeof last === 'number' && isNaN(value) && isNaN(last)))) { dirty = true; lastDirtyWatch = watch; watch.last = watch.eq ? copy(value, null) : value; watch.fn(value, ((last === initWatchVal) ? value : last), current); if (ttl < 5) { logIdx = 4 - ttl; if (!watchLog[logIdx]) watchLog[logIdx] = []; watchLog[logIdx].push({ msg: isFunction(watch.exp) ? 'fn: ' + (watch.exp.name || watch.exp.toString()) : watch.exp, newVal: value, oldVal: last }); } } else if (watch === lastDirtyWatch) { // If the most recently dirty watcher is now clean, short circuit since the remaining watchers // have already been tested. dirty = false; break traverseScopesLoop; } } } catch (e) { $exceptionHandler(e); } } } // Insanity Warning: scope depth-first traversal // yes, this code is a bit crazy, but it works and we have tests to prove it! // this piece should be kept in sync with the traversal in $broadcast if (!(next = ((current.$$watchersCount && current.$$childHead) || (current !== target && current.$$nextSibling)))) { while (current !== target && !(next = current.$$nextSibling)) { current = current.$parent; } } } while ((current = next)); // `break traverseScopesLoop;` takes us to here if ((dirty || asyncQueue.length) && !(ttl--)) { clearPhase(); throw $rootScopeMinErr('infdig', '{0} $digest() iterations reached. Aborting!\n' + 'Watchers fired in the last 5 iterations: {1}', TTL, watchLog); } } while (dirty || asyncQueue.length); clearPhase(); while (postDigestQueue.length) { try { postDigestQueue.shift()(); } catch (e) { $exceptionHandler(e); } } }, /** * @ngdoc event * @name $rootScope.Scope#$destroy * @eventType broadcast on scope being destroyed * * @description * Broadcasted when a scope and its children are being destroyed. * * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to * clean up DOM bindings before an element is removed from the DOM. */ /** * @ngdoc method * @name $rootScope.Scope#$destroy * @kind function * * @description * Removes the current scope (and all of its children) from the parent scope. Removal implies * that calls to {@link ng.$rootScope.Scope#$digest $digest()} will no longer * propagate to the current scope and its children. Removal also implies that the current * scope is eligible for garbage collection. * * The `$destroy()` is usually used by directives such as * {@link ng.directive:ngRepeat ngRepeat} for managing the * unrolling of the loop. * * Just before a scope is destroyed, a `$destroy` event is broadcasted on this scope. * Application code can register a `$destroy` event handler that will give it a chance to * perform any necessary cleanup. * * Note that, in AngularJS, there is also a `$destroy` jQuery event, which can be used to * clean up DOM bindings before an element is removed from the DOM. */ $destroy: function() { // We can't destroy a scope that has been already destroyed. if (this.$$destroyed) return; var parent = this.$parent; this.$broadcast('$destroy'); this.$$destroyed = true; if (this === $rootScope) { //Remove handlers attached to window when $rootScope is removed $browser.$$applicationDestroyed(); } incrementWatchersCount(this, -this.$$watchersCount); for (var eventName in this.$$listenerCount) { decrementListenerCount(this, this.$$listenerCount[eventName], eventName); } // sever all the references to parent scopes (after this cleanup, the current scope should // not be retained by any of our references and should be eligible for garbage collection) if (parent && parent.$$childHead == this) parent.$$childHead = this.$$nextSibling; if (parent && parent.$$childTail == this) parent.$$childTail = this.$$prevSibling; if (this.$$prevSibling) this.$$prevSibling.$$nextSibling = this.$$nextSibling; if (this.$$nextSibling) this.$$nextSibling.$$prevSibling = this.$$prevSibling; // Disable listeners, watchers and apply/digest methods this.$destroy = this.$digest = this.$apply = this.$evalAsync = this.$applyAsync = noop; this.$on = this.$watch = this.$watchGroup = function() { return noop; }; this.$$listeners = {}; // All of the code below is bogus code that works around V8's memory leak via optimized code // and inline caches. // // see: // - https://code.google.com/p/v8/issues/detail?id=2073#c26 // - https://github.com/angular/angular.js/issues/6794#issuecomment-38648909 // - https://github.com/angular/angular.js/issues/1313#issuecomment-10378451 this.$parent = this.$$nextSibling = this.$$prevSibling = this.$$childHead = this.$$childTail = this.$root = this.$$watchers = null; }, /** * @ngdoc method * @name $rootScope.Scope#$eval * @kind function * * @description * Executes the `expression` on the current scope and returns the result. Any exceptions in * the expression are propagated (uncaught). This is useful when evaluating Angular * expressions. * * # Example * ```js var scope = ng.$rootScope.Scope(); scope.a = 1; scope.b = 2; expect(scope.$eval('a+b')).toEqual(3); expect(scope.$eval(function(scope){ return scope.a + scope.b; })).toEqual(3); * ``` * * @param {(string|function())=} expression An angular expression to be executed. * * - `string`: execute using the rules as defined in {@link guide/expression expression}. * - `function(scope)`: execute the function with the current `scope` parameter. * * @param {(object)=} locals Local variables object, useful for overriding values in scope. * @returns {*} The result of evaluating the expression. */ $eval: function(expr, locals) { return $parse(expr)(this, locals); }, /** * @ngdoc method * @name $rootScope.Scope#$evalAsync * @kind function * * @description * Executes the expression on the current scope at a later point in time. * * The `$evalAsync` makes no guarantees as to when the `expression` will be executed, only * that: * * - it will execute after the function that scheduled the evaluation (preferably before DOM * rendering). * - at least one {@link ng.$rootScope.Scope#$digest $digest cycle} will be performed after * `expression` execution. * * Any exceptions from the execution of the expression are forwarded to the * {@link ng.$exceptionHandler $exceptionHandler} service. * * __Note:__ if this function is called outside of a `$digest` cycle, a new `$digest` cycle * will be scheduled. However, it is encouraged to always call code that changes the model * from within an `$apply` call. That includes code evaluated via `$evalAsync`. * * @param {(string|function())=} expression An angular expression to be executed. * * - `string`: execute using the rules as defined in {@link guide/expression expression}. * - `function(scope)`: execute the function with the current `scope` parameter. * * @param {(object)=} locals Local variables object, useful for overriding values in scope. */ $evalAsync: function(expr, locals) { // if we are outside of an $digest loop and this is the first time we are scheduling async // task also schedule async auto-flush if (!$rootScope.$$phase && !asyncQueue.length) { $browser.defer(function() { if (asyncQueue.length) { $rootScope.$digest(); } }); } asyncQueue.push({scope: this, expression: expr, locals: locals}); }, $$postDigest: function(fn) { postDigestQueue.push(fn); }, /** * @ngdoc method * @name $rootScope.Scope#$apply * @kind function * * @description * `$apply()` is used to execute an expression in angular from outside of the angular * framework. (For example from browser DOM events, setTimeout, XHR or third party libraries). * Because we are calling into the angular framework we need to perform proper scope life * cycle of {@link ng.$exceptionHandler exception handling}, * {@link ng.$rootScope.Scope#$digest executing watches}. * * ## Life cycle * * # Pseudo-Code of `$apply()` * ```js function $apply(expr) { try { return $eval(expr); } catch (e) { $exceptionHandler(e); } finally { $root.$digest(); } } * ``` * * * Scope's `$apply()` method transitions through the following stages: * * 1. The {@link guide/expression expression} is executed using the * {@link ng.$rootScope.Scope#$eval $eval()} method. * 2. Any exceptions from the execution of the expression are forwarded to the * {@link ng.$exceptionHandler $exceptionHandler} service. * 3. The {@link ng.$rootScope.Scope#$watch watch} listeners are fired immediately after the * expression was executed using the {@link ng.$rootScope.Scope#$digest $digest()} method. * * * @param {(string|function())=} exp An angular expression to be executed. * * - `string`: execute using the rules as defined in {@link guide/expression expression}. * - `function(scope)`: execute the function with current `scope` parameter. * * @returns {*} The result of evaluating the expression. */ $apply: function(expr) { try { beginPhase('$apply'); return this.$eval(expr); } catch (e) { $exceptionHandler(e); } finally { clearPhase(); try { $rootScope.$digest(); } catch (e) { $exceptionHandler(e); throw e; } } }, /** * @ngdoc method * @name $rootScope.Scope#$applyAsync * @kind function * * @description * Schedule the invocation of $apply to occur at a later time. The actual time difference * varies across browsers, but is typically around ~10 milliseconds. * * This can be used to queue up multiple expressions which need to be evaluated in the same * digest. * * @param {(string|function())=} exp An angular expression to be executed. * * - `string`: execute using the rules as defined in {@link guide/expression expression}. * - `function(scope)`: execute the function with current `scope` parameter. */ $applyAsync: function(expr) { var scope = this; expr && applyAsyncQueue.push($applyAsyncExpression); scheduleApplyAsync(); function $applyAsyncExpression() { scope.$eval(expr); } }, /** * @ngdoc method * @name $rootScope.Scope#$on * @kind function * * @description * Listens on events of a given type. See {@link ng.$rootScope.Scope#$emit $emit} for * discussion of event life cycle. * * The event listener function format is: `function(event, args...)`. The `event` object * passed into the listener has the following attributes: * * - `targetScope` - `{Scope}`: the scope on which the event was `$emit`-ed or * `$broadcast`-ed. * - `currentScope` - `{Scope}`: the scope that is currently handling the event. Once the * event propagates through the scope hierarchy, this property is set to null. * - `name` - `{string}`: name of the event. * - `stopPropagation` - `{function=}`: calling `stopPropagation` function will cancel * further event propagation (available only for events that were `$emit`-ed). * - `preventDefault` - `{function}`: calling `preventDefault` sets `defaultPrevented` flag * to true. * - `defaultPrevented` - `{boolean}`: true if `preventDefault` was called. * * @param {string} name Event name to listen on. * @param {function(event, ...args)} listener Function to call when the event is emitted. * @returns {function()} Returns a deregistration function for this listener. */ $on: function(name, listener) { var namedListeners = this.$$listeners[name]; if (!namedListeners) { this.$$listeners[name] = namedListeners = []; } namedListeners.push(listener); var current = this; do { if (!current.$$listenerCount[name]) { current.$$listenerCount[name] = 0; } current.$$listenerCount[name]++; } while ((current = current.$parent)); var self = this; return function() { var indexOfListener = namedListeners.indexOf(listener); if (indexOfListener !== -1) { namedListeners[indexOfListener] = null; decrementListenerCount(self, 1, name); } }; }, /** * @ngdoc method * @name $rootScope.Scope#$emit * @kind function * * @description * Dispatches an event `name` upwards through the scope hierarchy notifying the * registered {@link ng.$rootScope.Scope#$on} listeners. * * The event life cycle starts at the scope on which `$emit` was called. All * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get * notified. Afterwards, the event traverses upwards toward the root scope and calls all * registered listeners along the way. The event will stop propagating if one of the listeners * cancels it. * * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed * onto the {@link ng.$exceptionHandler $exceptionHandler} service. * * @param {string} name Event name to emit. * @param {...*} args Optional one or more arguments which will be passed onto the event listeners. * @return {Object} Event object (see {@link ng.$rootScope.Scope#$on}). */ $emit: function(name, args) { var empty = [], namedListeners, scope = this, stopPropagation = false, event = { name: name, targetScope: scope, stopPropagation: function() {stopPropagation = true;}, preventDefault: function() { event.defaultPrevented = true; }, defaultPrevented: false }, listenerArgs = concat([event], arguments, 1), i, length; do { namedListeners = scope.$$listeners[name] || empty; event.currentScope = scope; for (i = 0, length = namedListeners.length; i < length; i++) { // if listeners were deregistered, defragment the array if (!namedListeners[i]) { namedListeners.splice(i, 1); i--; length--; continue; } try { //allow all listeners attached to the current scope to run namedListeners[i].apply(null, listenerArgs); } catch (e) { $exceptionHandler(e); } } //if any listener on the current scope stops propagation, prevent bubbling if (stopPropagation) { event.currentScope = null; return event; } //traverse upwards scope = scope.$parent; } while (scope); event.currentScope = null; return event; }, /** * @ngdoc method * @name $rootScope.Scope#$broadcast * @kind function * * @description * Dispatches an event `name` downwards to all child scopes (and their children) notifying the * registered {@link ng.$rootScope.Scope#$on} listeners. * * The event life cycle starts at the scope on which `$broadcast` was called. All * {@link ng.$rootScope.Scope#$on listeners} listening for `name` event on this scope get * notified. Afterwards, the event propagates to all direct and indirect scopes of the current * scope and calls all registered listeners along the way. The event cannot be canceled. * * Any exception emitted from the {@link ng.$rootScope.Scope#$on listeners} will be passed * onto the {@link ng.$exceptionHandler $exceptionHandler} service. * * @param {string} name Event name to broadcast. * @param {...*} args Optional one or more arguments which will be passed onto the event listeners. * @return {Object} Event object, see {@link ng.$rootScope.Scope#$on} */ $broadcast: function(name, args) { var target = this, current = target, next = target, event = { name: name, targetScope: target, preventDefault: function() { event.defaultPrevented = true; }, defaultPrevented: false }; if (!target.$$listenerCount[name]) return event; var listenerArgs = concat([event], arguments, 1), listeners, i, length; //down while you can, then up and next sibling or up and next sibling until back at root while ((current = next)) { event.currentScope = current; listeners = current.$$listeners[name] || []; for (i = 0, length = listeners.length; i < length; i++) { // if listeners were deregistered, defragment the array if (!listeners[i]) { listeners.splice(i, 1); i--; length--; continue; } try { listeners[i].apply(null, listenerArgs); } catch (e) { $exceptionHandler(e); } } // Insanity Warning: scope depth-first traversal // yes, this code is a bit crazy, but it works and we have tests to prove it! // this piece should be kept in sync with the traversal in $digest // (though it differs due to having the extra check for $$listenerCount) if (!(next = ((current.$$listenerCount[name] && current.$$childHead) || (current !== target && current.$$nextSibling)))) { while (current !== target && !(next = current.$$nextSibling)) { current = current.$parent; } } } event.currentScope = null; return event; } }; var $rootScope = new Scope(); //The internal queues. Expose them on the $rootScope for debugging/testing purposes. var asyncQueue = $rootScope.$$asyncQueue = []; var postDigestQueue = $rootScope.$$postDigestQueue = []; var applyAsyncQueue = $rootScope.$$applyAsyncQueue = []; return $rootScope; function beginPhase(phase) { if ($rootScope.$$phase) { throw $rootScopeMinErr('inprog', '{0} already in progress', $rootScope.$$phase); } $rootScope.$$phase = phase; } function clearPhase() { $rootScope.$$phase = null; } function incrementWatchersCount(current, count) { do { current.$$watchersCount += count; } while ((current = current.$parent)); } function decrementListenerCount(current, count, name) { do { current.$$listenerCount[name] -= count; if (current.$$listenerCount[name] === 0) { delete current.$$listenerCount[name]; } } while ((current = current.$parent)); } /** * function used as an initial value for watchers. * because it's unique we can easily tell it apart from other values */ function initWatchVal() {} function flushApplyAsync() { while (applyAsyncQueue.length) { try { applyAsyncQueue.shift()(); } catch (e) { $exceptionHandler(e); } } applyAsyncId = null; } function scheduleApplyAsync() { if (applyAsyncId === null) { applyAsyncId = $browser.defer(function() { $rootScope.$apply(flushApplyAsync); }); } } }]; }


Hamilton describes the Brazilian Grand Prix as racing with the "gloves off"
by Tom Mason2019 World Champion Lewis Hamilton has said his experiences at the Brazilian Grand Prix this year will prove to be an important learning curve when it comes to racing with the "gloves off".
The Brit battled with Max Verstappen for large parts of the Brazilian Grand Prix before losing his place on the podium after an incident with Alex Albon.
“When you look at the last race, my gloves were off,” Hamilton said speaking during an appearance at the Gran Turismo World Finals in Monaco.
“If that was a championship race, I would have just finished second. A pretty chilled in second and bag the points.
“So of course you have the balance of knowing when to push for it. And that was the first race really this year that I could really push like that - go over the edge and see how it is."
The Brit has enjoyed another successful season winning the title and is now just one championship victory behind F1 legend Michael Schumacher.


WNV human mosquito cases Nile West virus data infection MIR weeks positive pools used []. spatial number illness study using temperature higher total week land {border-style Chicago annual area cumulative developed px;} #ffffff;} Cook United demographic DuPage Illinois associated population precipitation vector Mosquito Proportion average surveillance weekly analysis included probability urban years (Table Culex factors health hexagon local model rate risk temporal <. areas calculated case cases. drivers hexagons mosquitoes reported weather year (.–.) Health Number correlation counties earlier high increased open region transmission variability variables Average dynamic incidence mid-summer observed tested weather, Fig Public based cover, important percentage proportion public relationship scale testing Med States [,]. cases, conditions fine-scale housing identified identify infection, intensity models px; results spatiotemporal {font-family Disease Sciences built case. characteristics compared counties, cover disease font-size infections low obtained regression species variation ArcGIS Biology Data Department IDPH Illinois, Illinois. Int New birds census daily data. double; effects numbers patterns people predicted region. statistical variable ./journal.pone..tTable Control Dis. Entomol. Geogr. HamerGL, Health. However, Human RuizMO, States. Virus WNV, [], area, available best better bird border-color border-width climate conducted dead determine different explain fine forests having houses indicated information landscape long-term occurrence outbreak pathogens pipiens pool populations reduce role scales seasonal solid; studies study, time use water {font-style {font-weight (Fig (weeks ./-X-- African Centers Climate Division Flaviviruses: Hispanic KilpatrickAM, Organisms Percentage Prevention Temperature abatement absence abundance access actual additional analysis, association avian block bold breeding clustering clusters collection correlated courier; criteria develop em; environment. epidemic epidemics geographic illness, include income increase indicating interpolation lagged landcover level locations maps mirlag modeling mosquitoes, original positively potential precilag predict pt;} rates region, relatively review sciences showed strongly surface templag test threshold trap week. white years, zoonotic


| 036:032 Khan | : |
And surely, all, everyone of them will be brought before Us. |
| 036:032 Maulana | : |
And all -- surely all -- will be brought before Us. |
| 036:032 Pickthal | : |
But all, without exception, will be brought before Us. |
| 036:032 Rashad | : |
Every one of them will be summoned before us. |
| 036:032 Sarwar | : |
They will all be brought into Our presence together. |
| 036:032 Shakir | : |
And all of them shall surely be brought before Us. |
| 036:032 Sherali | : |
And all of them, gathered together, will certainly be brought before US. |
| 036:032 Yusufali | : |
But each one of them all - will be brought before Us (for judgment). |
Concepts/Themes Covered: الإيمان > اليوم الآخر > الحشر Faith> The Hereafter> The Day of Resurrection
This tool uses eight English parallel translations for the Holy Quran imported from Mr. Clay Smith. You can also visit Qurany Concepts for browsing the Quran themes or topics. If you want to search the Holy Quran for keywords, please visit Qurany Keywords.