/* global define, module, require, console */
/*!
Script: easyrtc_recorder.js
This code demonstrate recording of local and remote streams.
About: License
Copyright (c) 2016, Priologic Software Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
"use strict";
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
//RequireJS (AMD) build system
define(['easyrtc'], factory);
} else if (typeof module === 'object' && module.exports) {
//CommonJS build system
module.exports = factory(require('easyrtc'));
} else {
//Vanilla JS, ensure dependencies are loaded correctly
if (typeof window.easyrtc !== 'object' || !window.easyrtc) {
throw new Error("easyrtc_recorder requires easyrtc");
}
root.easyrtc = factory(window.easyrtc);
}
}(this, function (easyrtc, undefined) {
/**
* Provides methods for building MediaStream recorders.
* @class Easyrtc_Recorder
*/
/**
* Determines if recording is supported by the browser.
* @function
* @memberOf Easyrtc_Recorder
* @returns true if recording is supported.
*/
easyrtc.supportsRecording = function() {
return (typeof MediaRecorder !== "undefined" && navigator.getUserMedia );
};
/**
* Check if a particular codec can be used for recording.
* @function
* @memberOf Easyrtc_Recorder
* @param {String} codecName, either "vp8" or "vp9 or "h264"
* @returns true if the type can be used, or if the browser doesn't
* support a method to find out.
*/
easyrtc.isRecordingTypeSupported = function(videoCodecName) {
var mimeType = "video/webm;codecs=" + videoCodecName;
if( MediaRecorder.isTypeSupported ) {
// chrome definitely, maybe firefox
return MediaRecorder.isTypeSupported(mimeType);
}
else if( MediaRecorder.isMimeTypeSupported ) {
// maybe firefox
return MediaRecorder.isMimeTypeSupported(mimeType);
}
else {
if( typeof easyrtc.hasNoRecordTypeCheck === "undefined") {
easyrtc.hasNoRecordTypeCheck = true;
window.alert("This browser doesn't know what media types it supports. Assuming all types.");
}
return true;
}
};
var mimeType;
/**
* Set the desired codec for the video encoding.
* @function
* @memberOf Easyrtc_Recorder
* @param {String} codecName, either "vp8" or "vp9 or "h264"
* @returns true if the type can be used.
*/
easyrtc.setRecordingVideoCodec = function(videoCodecName) {
if( !easyrtc.supportsRecording ) {
return false;
}
if(easyrtc.isRecordingTypeSupported(videoCodecName)) {
mimeType = "video/webm;codecs=" + videoCodecName;
return true;
}
else {
return false;
}
};
if( easyrtc.supportsRecording()) {
easyrtc.setRecordingVideoCodec("vp8");
}
/**
* Create a recording object and attach a media stream to it.
* @function
* @memberOf Easyrtc_Recorder
* @param {HTMLMediaStream} mediaStream
* @returns a recorder object or null if recording not supported.
*/
function startRecording( mediaStream) {
if( !easyrtc.supportsRecording ) {
console.log("recording not supported by your browser");
return null;
}
var mediaRecorder = new MediaRecorder(mediaStream, {mimeType: mimeType});
if( !mediaRecorder ) {
console.log("no media recorder");
return;
}
mediaRecorder.start();
mediaRecorder.onerror = function(e) {
console.log("Media recording error:", e);
}
mediaRecorder.onwarning = function(e) {
console.log("Media recording error:", e);
}
mediaRecorder.onstart = function(e) {
console.log("Media recording started");
}
mediaRecorder.onstop = function(e) {
console.log("Media recording stopped");
}
return mediaRecorder;
};
/** This method creates a media recorder and populates it's ondataavailable
* method so that your own callback gets called with the data.
* Use the media recorder's start(), stop(), pause() and resume() methods
* on the returned object.
* @function
* @memberOf Easyrtc_Recorder
* @param {HTMLMediaStream} mediaStream a local or remote media stream.
* @param {Function} dataCallback a function to receive the webm data from.
*/
easyrtc.recordToCallback = function (mediaStream, dataCallback) {
var mediaRecorder = startRecording(mediaStream);
if( !mediaRecorder) {
return null;
}
mediaRecorder.ondataavailable = function(e) {
dataCallback(e.data);
}
return mediaRecorder;
};
/** This method creates a media recorder that builds a blob
* Use the media recorder's start(), stop(), pause() and resume() methods
* on the returned object.
* @function
* @memberOf Easyrtc_Recorder
* @param {HTMLMediaStream} mediaStream a local or remote media stream.
* @param {Function} blobCallback a callback function that gets called with a
* blob once you invoke the stop method.
**/
easyrtc.recordToBlob = function(mediaStream, blobCallback) {
var chunks = [];
function dataConsumer(chunk) {
chunks.push(chunk);
}
var mediaRecorder = easyrtc.recordToCallback(mediaStream,
dataConsumer);
if( !mediaRecorder) {
return null;
}
mediaRecorder.onstop = function() {
blobCallback( new Blob(chunks, {type:"video/webm"}));
chunks = [];
}
return mediaRecorder;
};
/** This method creates a media recorder that builds a file.
* Use the media recorder's start(), stop(), pause() and resume() methods
* on the returned object.
* @function
* @memberOf Easyrtc_Recorder
* @param {HTMLMediaStream} a local or remote media stream.
* @param {Object} downloadLink an anchor tag to attach the file to.
* @param {String} basename the name of the file. A .webm will be appended
* to the file if its not already present. The file doesn't get written
* until you call the mediaRecorder's stop method.
**/
easyrtc.recordToFile = function(mediaStream, downloadLink, basename) {
function blobCallback( blob ) {
var videoURL = window.URL.createObjectURL(blob);
downloadLink.href = videoURL;
downloadLink.appendChild(document.createTextNode(basename));
var name = basename + ((basename.indexOf(".webm")>0)?"": ".webm") ;
downloadLink.setAttribute( "download", name);
downloadLink.setAttribute( "name", name);
}
downloadLink.innerHTML = "";
var mediaRecorder = easyrtc.recordToBlob(mediaStream, blobCallback);
return mediaRecorder;
};
return easyrtc;
}));


Section 3.1
Integration Tutorial (ISO)
This tutorial will walk you through integrating Windows Updates (including Internet Explorer) into a standard Windows 7 ISO. If you have trouble with Slips7ream or are a beginner at the Slipstreaming process, you may want to consult this guide.
I suggest you start by setting up a folder for Slipstreaming if you are going to be doing this regularly, so I'll be using the following directory tree for this tutorial:
- C:\Users\Admin\Documents\Win7_ISO\32-Bit\
-
You can use any location you want, C:\Users\Admin\Documents\ is just the path used in the example
- IE11\
-
This folder contains Internet Explorer 11 and its prerequisites
- Windows6.1-KB2533623-x86.msu
- Windows6.1-KB2639308-x86.msu
- Windows6.1-KB2670838-x86.msu
- Windows6.1-KB2729094-v2-x86.msu
- Windows6.1-KB2731771-x86.msu
- Windows6.1-KB2786081-x86.msu
- Windows6.1-KB2834140-x86.msu
- Windows6.1-KB2882822-x86.msu
- Windows6.1-KB2888049-x86.msu
- IE11-Windows6.1-x86-en-us.exe
- This is the offline installer for Internet Explorer 11 (English). If you want to include Spelling and Hyphenation packages for other languages, you can use their EXEs as well
- Updates\
-
This folder contains the updates that will be integrated. For this example, only two updates will be used
- Windows6.1-KB2775511-x86.msu
- The Windows 7 hotfix rollup Update
- WindowsUpdateAgent-7.6-x86.exe
- An update to Windows Update, contained in an EXE file
- RTM.iso
- an original 32-Bit Windows 7 RTM image
- SP1.exe
- the 32-Bit Windows 7 Service Pack 1 offline installer
- Win7.iso
- a copy of RTM.iso which will contain the final version
Slips7ream, ready to begin integrating Service Pack 1, Internet Explorer 11, and Windows Updates into Windows 7 Professional
-
The first step is to select your source INSTALL.WIM, which is stored inside the "RTM.iso" file above.
Click the "Browse..." button next to the INSTALL.WIM field to select "C:\Users\Admin\Documents\Win7_ISO\32-Bit\RTM.iso". You can also drag-and-drop the file into the field with your mouse.
Slips7ream will automatically extract the INSTALL.WIM file and read its properties, giving you a list of Image Packages.
-
You can optionally include or remove Image Packages as needed. All the Updates will be integrated into all of the finalized Image Packages automatically.
You can also read more package data from the Image Packages if you want to change Features, remove Updates, or just see what's already installed. Having a list of Integrated Updates will also ensure that there aren't version conflicts between Updates.
-
Next, click the "Service Pack" checkbox to enable the Service Pack field(s). Click "Browse..." next to the Service Pack field and choose "SP1.exe", or drag-and-drop the file into the right field.
Note that if you have mixed 32-Bit and 64-Bit architectures in your Image Packages list, there will be two fields, one for the x86 Service Pack, one for x64.
-
After providing the Service Pack, it's time to add some Updates.
Click on "Add to Updates..." and open the "IE11" folder, then select all of the prerequisite MSU files in this folder and click "Open".
When all of the selected files have been added to the Updates list, click "Add to Updates..." again to add "IE11-Windows6.1-x86-en-us.exe".
As before, you can also drag the files (or the "IE11" folder) into the Updates list to add them. You can also re-order the files in the list by dragging one or more selected Updates up or down, or by right-clicking your selection and choosing a menu item.
- Practice adding Updates by including the files in the "Updates" folder as well.
-
Once all the updates have been included and organized, check the "Save to ISO" field. If it's not enabled, enable it by checking the "Save to ISO" checkbox next to the field.
Click "Browse..." and select the "Win7.iso" file or drag the file into the field, and then choose the Label and Features you want to use.
-
Now it's time to begin the Slipstream operation: click "Begin" at the bottom of the window to start the process, then sit back and wait as Slips7ream does its work.
When the process is complete, you can click the "Open Folder" button to open the folder containing the finalized ISO file, "Win7.iso". You can burn the ISO to a disc or extract the contents to a USB flash drive, or store the file for later updating.


- Provider Dashboard
- My Dashboard
- Apps
- Provider Profile
- Views
- Patient Records
- Patient List
Eligibilty Screening
BZRAs Currently Prescribed
BZRA Regimen Details
Note
Some BZRAs are not easily tapered due to dosage formulation limitation. This includes capsules (chlordiazepoxide, clorazepate, flurazepam, temazepam) and specially formulated tablets (zolpidem orally disintegrating tablets). You may wish to switch to an equivalent dose of an alternative BZRA available in multiple tablet strengths that can further split into smaller doses. Taper schedule are available for shorter (oxazepam), intermediate (lorazepam), and longer (clonazepam) half-life BZRAs.
Proposed Taper Schedule
| # | Week | Drug | Rounded Dose | Unrounded Dose | Dose Combination |
|---|---|---|---|---|---|
| 1 | Week 1 | Alprazolam | 5 | 6.8 | 5 X 1 |
| 2 | Week 2 | Alprazolam | 5 | 6.8 | 5 X 1 |
| 3 | Week 3 | Alprazolam/td> | 5 | 6.8 | 5 X 1 |
Taper Schedule Adjustment
Taper Start Date
Copyright © Designed & Developed by Health enSuit Research Team 2020


| Week Start | {# TODO(AMK): color red/green/yellow if we've booked too few or too many #} {% for room_type in ROOM_TYPES %}Min {{room_type}} | Max {{room_type}} | Booked {{room_type}} | {% endfor %}Hotels |
|---|---|---|---|---|
| {{ start_date.strftime("%b %d") }} | {% for room_type in ROOM_TYPES %}{{ week.capacity[room_type].min }} | {{ week.capacity[room_type].max }} | {{ week.booked[room_type] | count }} | {% endfor %}
Please update these (especially hotels) as necessary.


Checks path references for dependencies configured as
path packages
in
pubspec.yaml
. Paths must be valid and target folders must contain
pubspec.yaml
file.


Using Activity Implementor InvokeMultipleProcessActivity
This implementor allows you to start multiple instances of
a given subprocess. It uses a table (of type MbengTableArray)
or a java.util.List (whose elements are of type DynaRow)
as the means of controlling how many instances to create
and how the parameters are bound for each instance.
Please refer to this link
for invoking a single instance of the sub process. The linked
document also explains parameter modes and bindings, if you're not
already familiar with these concepts.
The column names of the table or list are used to match parameters
of the subprocesses. The activity creates one instance of the subprocess
for each row. The parameters to be bound for the instance
of the subprocess are specified in the corresponding row
of the table or list. It should contain columns corresponding
to all input or input/output parameters of the subprocess.
Besides the table or list, you also need to specify
which column contains the key and which column
is used for return code. The key column values
must be unique, as these are used to distinguish
between subprocesses. The return code column is currently
used only by the implementor to record whether the subprocesses
have terminated, so even though you need to define such
a column, your code should not try to assign values to the
fields of the column.
MbengTableArray Example
The control table can be created as in the following example
(argument column is the key, retcode column is for
return code, and result column is for output):
String[] header = {"argument", "retcode", "result"};
MbengTableArray table = new MbengTableArray(header);
String[] row1 = {"1", "", ""};
String[] row2 = {"2", "", ""};
String[] row3 = {"3", "", ""};
table.addRow(row1);
table.addRow(row2);
table.addRow(row3);
DynaRows Examples
DynaRows are especially helpful when you're decomposing an XML
document on the main process into parseable fragments for the subprocess(es).
DynaRows build on the Groovy Expando concept, and they can be initialized
either using either XMLBeans or GPath syntax:
// XMLBeans example
travelers = vacRequest.getVacationPlan().getTravelers().getTravelerList();
dynaRows = [];
for (i in 0..travelers.size()-1)
{
row = new DynaRow();
row.keyval = i.toString();
row.retcode = '';
row.traveler = travelers.get(i);
row.cuid = travelers.get(i).getCuid();
dynaRows.add(row);
}
// GPath example
vacPlan = new XmlParser().parseText(xml);
travelers = vacPlan.Travelers.Traveler;
dynaRows = [];
for (i in 0..travelers.size()-1)
{
row = new DynaRow();
row.keyval = i.toString();
row.retcode = '';
row.traveler = travelers[i];
row.cuid = travelers[i].@cuid;
dynaRows.add(row);
}
Key Points
- The variable corresponding to the key in the subprocess must have
Input/Output mode, not just Input, even though the subprocess should
never change its value. The reason is that the parent
process needs to read its value when a subprocess terminates, in order
to determine which subprocess has terminated.
- The return code column should not have a corresponding variable defined
in the subprocess, and should not need an initialization value. It is used
by the framework internally to manage the status of subprocesses.
- When using DynaRows, Eclipse Designer is able to view the DynaRow content
in human-readable format only when the Groovy plug-in is also installed.
After the processes are completed,
the return code column should contain the value "FINISH",
and all columns corresponding to output or input/output
parameters of the subprocess should be populated.
For MbengTables, you can use the following code to retrieve output values:
String key = "2";
Object row = table.getRow(key);
String result = table.getValue(row, 2);
// 2 is the index of column "result"
For DynaRows, the code looks like this:
myCuid = dynaRows[i].cuid;
myXmlBean = dynaRows[i].traveler;
// or
myGroovyNode = dynaRows[i].traveler;
Wait For Unsolicited Events
It is often desired that when a process is waiting
for all sub processes, it needs to handle
unsolicited external events such as receiving a supplemental
order or cancellation of the request.
The activity allows to optionally register for listening
to unsolicited events before all subprocesses terminate.
It uses the same mechanism as EventWaitActivity
to register
the event waits (following this link
for details of event wait registration and additional details).
When the activity instance receives an event before the timer expires,
it can be left in one of the 2 statuses:
- Hold. The activity instance will be put on a hold status (showing cyan color
in the designer's process instance view). While the activity instance in hold status,
subprocess termination will be recorded but the activity will remain in hold
status, without being completed. When the
activity is put back on waiting status (see this link
for discussion on how this can happen), if all subprocesses are already terminated, or
another event it is waiting for has been received,
the activity instance will process that.
- Waiting. The activity instance continues waiting (i.e. still actively responds
to sub process termination as well as other unsolicited events).
We note that the activity can only listen to recurring events. This limitation
is needed to avoid infinite looping when the activity instances resume
waiting from hold status, non-recurring events that have already arrived
would always trigger a transition.
To provide custom code handling unsolicited events, you will need to override
processOtherMessage(String message)
.
The method is passed in with one argument, which is the entire message. The default
method does nothing. The completion code after processing the message is configured
in the designer, but you can override it in the code by invoking setReturnCode()
.


1 Exemplary Research question
What is the sample size needed to estimate the proportion of the event “high quality study” with an error margin of ±5%, and a confidence level of 99%? Let’s assume the probability of the event is 50%, and we draw the studies independently?
2 Task definition
Let’s simulate the width of a \(1-\alpha\) compatibility interval with a given margin of error \(E\) for varying samples sizes \(n_i\), where \(i = 1,...,N\), and \(N\) is the maximum sample size we can afford. We’ll assume indendently distributed and independent trials (iid).
Let’s further assume we are looking at a binary event \(X\) with a success \(x\) probability of \(Pr(X=x)=p\).
Let \(Y_k = \sum_1^i X_j\); think of \(Y_k\) as one sample of a given sample size, \(n_i\). Note that \(Y_k \overset{iid}{\sim} \mathcal{B}(n,p)\) (Binomially distributed).
Let’s draw \(K\) samples for each \(Y_k\), and dub the resulting statistic \(Z_i\). We’ll compute \(Z_i\) for each sample size \(n_i\), with \(i = 1,...,N\).
Finally, we’ll compute the arithmetic average of each \(Y_k\) and of \(Z_i\), for scale independency.
3 Technical setup
We’ll run this simulation in R, making use of the following packages:
library(tidyverse)
library(scales)
library(glue)
library(moments)
4 Define constants
N <- 1e04 # max. sample size
E <- .05 # error margin
p <- 1/2 # probability of event (success)
alpha = .01 # compatibility level
K <- 1e03 # repetitions per sample size
q <- abs(qnorm(p = alpha/2))
q # quantile in the normal distribution for alpha
## [1] 2.575829
Note that \(p=1/2\) is the maximum conservative assumption yielding the largest sample size.
5 Prepare data frame for the simulation
df <- tibble(
i = 1:N,
estimate = NA,
se = NA,
lwr = NA,
upr = NA,
width = NA,
small_enough = NA
)
6 Simulation
Let’s draw \(N\) samples with increasing sample size from 1 to \(N=10^{4}\), each time with \(K=1000\) repetitions, assuming independent draws and a Binomial distribution with \(p=0.5\).
for (i in 1:N) {
# draw K "coin flip" samples of size i,
# with succcess propability p:
tmp <- rbinom(n = K, size = i, prob = p)
# compute succcess rate for each sample:
prop_success <- tmp/i
# compute success rate over all K samples:
df$estimate[i] <- mean(prop_success)
# compute standard error:
df$se[i] <- sd(prop_success)
# compute interval borders and width:
df$lwr[i] <- df$estimate[i] - q * df$se[i]
df$upr[i] <- df$estimate[i] + q * df$se[i]
df$width[i] <- df$upr[i] - df$lwr[i]
# check if intervals is as small as desired:
if (df$width[i] < 2*E)
{df$small_enough[i] <- TRUE} else {
df$small_enough[i] <- FALSE}
}
7 Check some distributions
Note that the binomial distributions converges against the normal distribution. For instance, let’s pick \(n_i=100\) and \(K=10^4\).
smple <- tibble(
estimate = rbinom(n = 1e04,
size = 100,
prob = p))
smple %>%
ggplot(aes(x = estimate)) +
geom_density()
Let’s briefly check for normality, using a quantile-quantile plot:
ggplot(smple, aes(sample = estimate)) +
stat_qq() +
stat_qq_line(col = "red")
This check reassured us that this distribution is normal.
Add some stats for checking normality:
skewness(smple$estimate)
## [1] -0.01740677
kurtosis(smple$estimate)
## [1] 2.952453
Which nicely fits a normal distribution.
Also note that a linear transformation of a normal curve is still normal:
tibble(
estimate = rbinom(n = 1e04,
size = 100,
prob = p),
prop = estimate / 100) %>%
ggplot(aes(x = prop)) +
geom_density()
8 Minimum sample size
What’s the minimum sample size \(n_{min}\) needed such that \(w \le 2E\), where \(w\) denotes the width of the compatibility interval?
n_min <-
df$width %>%
detect_index(~ .x <= 2*E)
n_min
## [1] 357
What’s the maximum sample size \(n_{max}\) needed such that \(w > 2E\)?
n_max <-
df$width %>%
detect_index(~ .x > 2*E, .dir = "backward")
n_max
## [1] 419
9 Plot results
df %>%
filter(i > 30) %>%
ggplot(aes(x = i, y = width)) +
geom_line() +
scale_x_continuous(trans = log10_trans()) +
geom_hline(yintercept = 2*E, linetype ="dashed", color = "grey60") +
annotate("label", x = 100, y = .1, label = "2E") +
geom_vline(xintercept = n_max, linetype = "dashed",
color = "blue") +
geom_vline(xintercept = n_min, linetype = "dashed",
color = "red") +
annotate("label", x = n_max, y = .3,
label = glue("nmax={n_max}"),
color = "blue") +
annotate("label", x = n_max, y = .2,
label = glue("nmin={n_min}"),
color = "red") +
labs(x = "sample size (log)",
y = "margin of error",
subtitle = "for estimating the width of compatibility intervals",
title = "Simulating minimum sample sizes",
caption = glue("Alpha: {alpha}, desired E = {E}, p = 1/2. See text for details.\n Each x-value depicts the average of {K} samples")) +
theme_minimal()
10 Summary
The simulation implies that we need a sample size \(n\) of approx. around 357 to 419 to get a compatibility interval of width \(2E\) for an alpha level of \(1-\alpha=0.99\).
11 Discussion
This post proposes a rough approach of attaining practical sample sizes when an analytical approach is not wanted or feasible. Several limitations should be put forward: One might want with finite populations; one might want to compare the simulation results with typical formulas; one might prefer different stopping rules.
12 Suggested reading
Check out the following sources for related issues and more in-depth treatment: Landau and Stahl (2013), Schönbrodt and Perugini (2013), Maxwell, Kelley, and Rausch (2008), Arnold et al. (2011), Kruschke (2015).


About this website
This website is made for aspiring learners who want to gain more knowledge but do not have the good resources. And that's what this website aims to provide. All the topics here have links to the websites and pages to learn them. These links are voted by users so you can see which ones are more popular.


title = "Dashboard"
url = "/dashboard"
layout = "default"
is_hidden = 0
[AdminDashboard]
==
function onEnd() {
$this->page->activePage = 'admin-dashboard';
}
==
{{ AdminDashboard.getEmployee().count() }}
{{ AdminDashboard.getAsset().count() }}
{{ AdminDashboard.getReport().count() }}
{% partial 'dashboard/chart-timeline-asset' %}
{% partial 'dashboard/chart-timeline-report' %}
{% put scripts %}
{% partial 'dashboard/chart-timeline-asset-script' timelines=AdminDashboard.getAssetTimeline(currentYear) %}
{% partial 'dashboard/chart-timeline-report-script' timelines=AdminDashboard.getReportTimeline(currentYear) %}
{% endput %}


src/components/upgrader/hpkUpgrader.ts
Controller class for instrumenting the upgrade process on Huddly IQ camera.
EventEmitter
IDeviceUpgrader
Methods |
|
constructor(manager: IDeviceManager, sdkDeviceDiscoveryEmitter: EventEmitter)
|
|||||||||
|
Defined in src/components/upgrader/hpkUpgrader.ts:47
|
|||||||||
|
Parameters :
|
| Async doUpgrade | ||||||||||||||||||||
doUpgrade(uploadStatusStep: UpgradeStatusStep, runStatusStep: UpgradeStatusStep, completionStatusStep: UpgradeStatusStep, rebootStatusStep: UpgradeStatusStep)
|
||||||||||||||||||||
|
Defined in src/components/upgrader/hpkUpgrader.ts:428
|
||||||||||||||||||||
|
Uploads firmware image to the camera and makes sure the camera loads it.
Parameters :
Returns :
Promise<boolean>
{Promise |
| init | ||||||||
init(opts: UpgradeOpts)
|
||||||||
|
Defined in src/components/upgrader/hpkUpgrader.ts:61
|
||||||||
|
Initializes the upgrader with the necessary options.
Parameters :
Returns :
void
|
| Async runHPKScript | ||||||||
runHPKScript(runStatusStep: UpgradeStatusStep)
|
||||||||
|
Defined in src/components/upgrader/hpkUpgrader.ts:391
|
||||||||
|
Invokes an internal camera api that instruments the camera to load and run the uploaded firmware image on target.
Parameters :
Returns :
Promise<void>
{Promise |
| Async start |
start()
|
|
Defined in src/components/upgrader/hpkUpgrader.ts:196
|
|
Starts the upgrade process on the Huddly IQ camera and also reports upgrade status to the consumer using events.
Returns :
Promise<void>
{Promise |
| Async upgradeIsValid |
upgradeIsValid()
|
|
Defined in src/components/upgrader/hpkUpgrader.ts:461
|
|
Validates the firmware image uploaded to the camera before commanding the camera to always start booting with the new update firmware.
Returns :
Promise<boolean>
{Promise |
In order to perform a software upgarde on the camera, this interface should be used. Please note that there is a convenience function in the IDeviceManager
for performing the upgrade, but if you want to implement your own handler then this documentation needs to be reviewed.
Each upgrader class (BoxfishUpgrader, HuddlyGoUpgrader, AceUPgrader) requires some options that should be provided when initializing it:
const upgrader = cameraManager.getUpgrader();
const upgradeOptions = {
file: fs.readSync('/path/to/firmware/image'),
bootTimeout: 60 // Default is 60 seconds
verboseStatusLog: true // Default is true
}; // See the `IUpgraderOpts` for explanation of each option
// Initialize upgrader
upgrader.init(upgraderOptions);
After you have initialized the upgrader, then you can proceed with starting the upgrade process.
// Start the upgrade process
upgrader.start();
During the upgrade process, the upgrader class will emit the following events:
| Event | Description |
|---|---|
UPGRADE_START |
Fired when upgrade is initiated. |
UPGRADE_COMPLETE |
Fired when upgrade is completed successfully. |
UPGRADE_FAILED |
Fired when something fails during upgrade. The handler contains the error trace of the upgrade failure. |
TIMEOUT |
Fired when the camera does not come back up after reboot (reboot is necessary to complete the upgrade sequence. |
UPGRADE_PROGRESS |
Fired when constantly during the upgrade process providing with information on how far the upgrade process is from completion. |
The events above can be used as shown below:
const onUpgradeStartHandler = () => {
// Do something.... Inform your system that upgrade has started
upgrader.removeListener('UPGRADE_PROGRESS', onUpgradeProgressHandler);
}
const onUpgradeFailedHandler = (e) => {
// Upgrade has failed. Print error log to debug the reason
console.error(e);
upgrader.removeListener('UPGRADE_PROGRESS', onUpgradeProgressHandler);
}
const onUpgradeCompleteHandler = () => {
// Hurrayyy! Sucessfully upgraded your Huddly camera
upgrader.removeListener('UPGRADE_PROGRESS', onUpgradeProgressHandler);
}
const onUpgradeTimeoutHandler = () => {
// Ups! Looks like the camera did not come back up after rebooting during upgrade.
// This also means that the new software that was loaded into the camera will be discarded.
// Try to initiate upgrade again.
upgrader.removeListener('UPGRADE_PROGRESS', onUpgradeProgressHandler);
}
const onUpgradeProgressHandler = (progress) => {
// The progress object contains the following information:
/*
* status: A string representation of how far the upgrade progress has come (ex. Uploading firmware on the device)
* progress: A numerical value representing the percentage of upgrade completion (ex 30)
*/
console.log(`Upgrade Progress: ${progress.progress} %`)
}
upgrader.once('UPGRADE_START', onUpgradeStartHandler);
upgrader.once('UPGRADE_FAILED', onUpgradeFailedHandler);
upgrader.once('UPGRADE_COMPLETE', onUpgradeCompleteHandler);
upgrader.once('TIMEOUT', onUpgradeTimeoutHandler);
upgrader.on('UPGRADE_PROGRESS', onUpgradeProgressHandler);
// Finally start the upgrade after having setup all the listeners
upgrader.start();
import { EventEmitter } from 'events';
import IDeviceUpgrader from '@huddly/sdk-interfaces/lib/interfaces/IDeviceUpgrader';
import IDeviceManager from '@huddly/sdk-interfaces/lib/interfaces/IDeviceManager';
import UpgradeOpts from '@huddly/sdk-interfaces/lib/interfaces/IUpgradeOpts';
import Logger from '@huddly/sdk-interfaces/lib/statics/Logger';
import HuddlyHEX from '@huddly/sdk-interfaces/lib/enums/HuddlyHex';
import CameraEvents from './../../utilitis/events';
import Api from '../api';
import Boxfish from './../device/boxfish';
import BoxfishHpk from './boxfishhpk';
import UpgradeStatus, { UpgradeStatusStep } from './upgradeStatus';
import ErrorCodes from './../../error/errorCodes';
import HPKUpgradeError from './../../error/hpkUpgradeError';
import Smartbase from '../device/smartbase';
import SmartbaseCamera from '../device/smartbaseCamera';
const MAX_UPLOAD_ATTEMPTS = 5;
/**
* Controller class for instrumenting the upgrade process on Huddly IQ camera.
*
* @export
* @class HPKUpgrader
* @extends {EventEmitter}
* @implements {IDeviceUpgrader}
*/
export default class HPKUpgrader extends EventEmitter implements IDeviceUpgrader {
/** @ignore */
verboseStatusLog: boolean;
/** @ignore */
_cameraManager: IDeviceManager;
/** @ignore */
_sdkDeviceDiscoveryEmitter: EventEmitter;
/** @ignore */
_fileBuffer: Buffer;
/** @ignore */
_upgradeStatus: UpgradeStatus;
/** @ignore */
_production_upgrade: boolean;
/** @ignore */
_bootTimeout: number = 60000;
/** @ignore */
_bufferWriteTimeout: number = 60000;
/** @ignore */
private _statusMessageTimeout: number = 60000;
constructor(manager: IDeviceManager, sdkDeviceDiscoveryEmitter: EventEmitter) {
super();
this._cameraManager = manager;
this._sdkDeviceDiscoveryEmitter = sdkDeviceDiscoveryEmitter;
this._production_upgrade = false;
}
/**
* Initializes the upgrader with the necessary options.
*
* @param {UpgradeOpts} opts The upgrade options required for performing a firmware upgrade on Huddly IQ.
* @memberof HPKUpgrader
*/
init(opts: UpgradeOpts) {
if (opts.verboseStatusLog !== undefined) {
this.verboseStatusLog = opts.verboseStatusLog;
}
if (opts.statusMessageTimeout) {
this._statusMessageTimeout = opts.statusMessageTimeout;
}
if (opts.production_upgrade) {
this._production_upgrade = opts.production_upgrade;
}
if (opts.bootTimeout) {
this._bootTimeout = opts.bootTimeout;
}
if (opts.bufferWriteTimeout) {
this._bufferWriteTimeout = opts.bufferWriteTimeout;
}
this._fileBuffer = opts.file;
this.registerHotPlugEvents();
}
/**
* @ignore
*
* On camera attach handler.
*
* @param {IDeviceManager} devManager Controller class for the attached device.
* @memberof HPKUpgrader
*/
onAttach = (devManager: IDeviceManager) => {
if (
devManager &&
(devManager instanceof Boxfish ||
devManager instanceof Smartbase ||
devManager instanceof SmartbaseCamera) &&
this._cameraManager['serialNumber'].includes(devManager['serialNumber'])
) {
this._cameraManager = devManager;
this.emit('UPGRADE_REBOOT_COMPLETE');
}
};
/**
* @ignore
*
* On camera detach handler.
*
* @param {*} deviceSerial Serial number of the detached device.
* @memberof HPKUpgrader
*/
onDetach = (deviceSerial) => {
if (this._cameraManager && deviceSerial === this._cameraManager['serialNumber']) {
try {
this._cameraManager.transport.close();
} catch (e) {
// Error on close is ok
}
}
this.emit('UPGRADE_REBOOT');
};
/**
* @ignore
* Subsribes for ATTACH and DETACH camera events since the upgrade involves booting the camera in between upgrade steps.
*
* @memberof HPKUpgrader
*/
registerHotPlugEvents() {
this._sdkDeviceDiscoveryEmitter.on(CameraEvents.ATTACH, this.onAttach);
this._sdkDeviceDiscoveryEmitter.on(CameraEvents.DETACH, this.onDetach);
}
/**
* @ignore
* Unsubsribes for ATTACH and DETACH camera events since the upgrade involves booting the camera in between upgrade steps.
*
* @memberof HPKUpgrader
*/
deRegisterHotPlugEvents() {
this._sdkDeviceDiscoveryEmitter.removeListener(CameraEvents.ATTACH, this.onAttach);
this._sdkDeviceDiscoveryEmitter.removeListener(CameraEvents.DETACH, this.onDetach);
}
/**
* @ignore
* Uploads the firmware image on target.
*
* @param {Buffer} hpkBuffer The buffer stream of the firmware image (.hpk)
* @param {UpgradeStatusStep} uploadStatusStep Status step representing the progress of the upload process.
* @memberof HPKUpgrader
*/
async upload(hpkBuffer: Buffer, uploadStatusStep: UpgradeStatusStep) {
let tryAgain = true;
let attempt = 0;
uploadStatusStep.progress = 1;
while (tryAgain && attempt < MAX_UPLOAD_ATTEMPTS) {
try {
const m = await this._cameraManager.api.sendAndReceiveMessagePack(
{ name: 'upgrade.hpk', file_data: hpkBuffer },
{
send: 'hcp/write',
receive: 'hcp/write_reply',
},
this._bufferWriteTimeout
);
const { status } = m;
if (status !== 0) {
throw new HPKUpgradeError(
`Upload hpk failed with status ${status}`,
ErrorCodes.UPGRADE_UPLOAD
);
}
uploadStatusStep.progress = 100;
this.emitProgressStatus();
tryAgain = false;
} catch (e) {
Logger.error(`Failed uploading hpk file ${e} attemt ${attempt}`, e, HPKUpgrader.name);
attempt += 1;
}
}
if (tryAgain && attempt >= MAX_UPLOAD_ATTEMPTS) {
throw new HPKUpgradeError('Upgrading HPK: Could not upload hpk', ErrorCodes.UPGRADE_UPLOAD);
}
}
/**
* Starts the upgrade process on the Huddly IQ camera and also reports upgrade status to the consumer
* using events.
*
* @return {*} {Promise<void>} Void function that relies on events for communicating the upgrade result/progress.
* @memberof HPKUpgrader
*/
async start(): Promise<void> {
const firstUploadStatusStep = new UpgradeStatusStep('Uploading software', 5);
const executingHpkStep = new UpgradeStatusStep('Executing upgrade package', 1);
const runningHpkStep = new UpgradeStatusStep('Running upgrade procedures', 80);
const rebootStep = new UpgradeStatusStep('Rebooting camera', 3);
const secondUploadStatusStep = new UpgradeStatusStep('Uploading software to verify', 3);
const executingHpkVerificationStep = new UpgradeStatusStep(
'Executing verification of new software',
1
);
const runningHpkVerificationStep = new UpgradeStatusStep('Verifying new software', 3);
this._upgradeStatus = new UpgradeStatus([
firstUploadStatusStep,
executingHpkStep,
runningHpkStep,
rebootStep,
secondUploadStatusStep,
executingHpkVerificationStep,
runningHpkVerificationStep,
]);
this.emitProgressStatus('Starting upgrade');
Logger.debug('Starting Upgrade', HPKUpgrader.name);
this.emit(CameraEvents.UPGRADE_START);
let upgradeTimoutId: NodeJS.Timer;
this.once('UPGRADE_REBOOT_COMPLETE', async () => {
Logger.debug('Camera successfully booted after upgrade', HPKUpgrader.name);
rebootStep.progress = 100;
global.clearTimeout(upgradeTimoutId);
try {
Logger.debug('Verifying new software', HPKUpgrader.name);
this.emitProgressStatus('Verifying new software');
// Wait two seconds to allow drivers to attach properly to the USB endpoint
await new Promise((resolve) => setTimeout(resolve, 2000));
await this.doUpgrade(
secondUploadStatusStep,
executingHpkVerificationStep,
runningHpkVerificationStep,
rebootStep
);
Logger.debug('Upgrade Completed', HPKUpgrader.name);
this.emitProgressStatus('Upgrade complete');
await this.deRegisterHotPlugEvents();
this.emit(CameraEvents.UPGRADE_COMPLETE);
} catch (e) {
await this.deRegisterHotPlugEvents();
this.emit(CameraEvents.UPGRADE_FAILED, e);
throw e;
}
});
try {
Logger.debug('Loading new sw to the camera', HPKUpgrader.name);
this.emitProgressStatus('Loading new software to camera');
const rebooted = await this.doUpgrade(
firstUploadStatusStep,
executingHpkStep,
runningHpkStep,
rebootStep
);
upgradeTimoutId = global.setTimeout(
() =>
this.emit(
CameraEvents.UPGRADE_FAILED,
new HPKUpgradeError('Did not come back after reboot', ErrorCodes.UPGRADE_REBOOT_FAILED)
),
this._bootTimeout
);
if (!rebooted) {
clearTimeout(upgradeTimoutId);
this.emit(CameraEvents.UPGRADE_COMPLETE);
}
} catch (e) {
Logger.error('Upgrade failed', e, HPKUpgrader.name);
this.emit(CameraEvents.UPGRADE_FAILED, e);
throw e;
}
}
/**
* @ignore
* Helper function for firing upgrade progress status events.
*
* @param {string} [statusString] The status of the upgrade to be reported.
* @memberof HPKUpgrader
*/
emitProgressStatus(statusString?: string) {
if (statusString) this._upgradeStatus.statusString = statusString;
this.emit(CameraEvents.UPGRADE_PROGRESS, this._upgradeStatus.getStatus());
}
/**
* @ignore
*
* Queries the camera for the firmware upload status, performs a software boot when the firmware upload is completed
* and then resolves when the camera comes back up correctly after the upload.
*
* @param {UpgradeStatusStep} completionStatusStep The upgrade status step reporting the progress of the hpk upload completion.
* @param {UpgradeStatusStep} rebootStatusStep The upgrade status step reporting the progress of the soft reboot on target.
* @return {*} {Promise<boolean>} Resolves when the process is completed.
* @memberof HPKUpgrader
*/
async awaitHPKCompletion(
completionStatusStep: UpgradeStatusStep,
rebootStatusStep: UpgradeStatusStep
): Promise<boolean> {
const reboot = await this._cameraManager.api.withSubscribe<boolean>(
['upgrader/status'],
() =>
new Promise((resolve, reject) => {
const startTimeout = () => {
return setTimeout(() => {
Logger.debug(
`Upgrade failure: no status message within ${this._statusMessageTimeout}`,
HPKUpgrader.name
);
reject(
new HPKUpgradeError(
`Upgrading HPK: no status message within ${this._statusMessageTimeout}`,
ErrorCodes.UPGRADE_STATUS_TIMEOUT
)
);
}, this._statusMessageTimeout);
};
let totalProgressPoints = 1;
let elapsedPoints = 0;
let messageTimeoutIt = startTimeout();
let lastTime = Date.now();
let lastOperation: undefined | string = undefined;
this._cameraManager.transport.on('upgrader/status', async (message) => {
clearTimeout(messageTimeoutIt);
const statusMessage = Api.decode(message.payload, 'messagepack');
totalProgressPoints = statusMessage.total_points || totalProgressPoints;
if (statusMessage.operation === 'done' && statusMessage.reboot) {
resolve(true);
return;
} else if (statusMessage.operation === 'done') {
resolve(false);
return;
}
if (statusMessage.error_count > 0) {
return reject(
new HPKUpgradeError(
`Failed during upgrade ${statusMessage}`,
ErrorCodes.UPGRADE_FAILED
)
);
}
const now = Date.now();
const deltaT = now - lastTime;
lastTime = now;
elapsedPoints = statusMessage.elapsed_points || elapsedPoints;
const progressPercentage = (elapsedPoints / totalProgressPoints) * 100;
if (statusMessage.operation !== lastOperation || deltaT >= 1000) {
Logger.info(
`Upgrading HPK: Status: ${Math.round(progressPercentage)}% step ${
statusMessage.operation
}\r`,
HPKUpgrader.name
);
}
lastOperation = statusMessage.operation;
completionStatusStep.operation = statusMessage.operation;
completionStatusStep.progress =
Math.ceil(progressPercentage) > 100 ? 100 : Math.ceil(progressPercentage);
this.emitProgressStatus();
messageTimeoutIt = startTimeout();
});
})
);
if (reboot) {
Logger.debug('Rebooting camera after upgrade', HPKUpgrader.name);
rebootStatusStep.progress = 1;
rebootStatusStep.operation = 'Issuing reboot command';
await this._cameraManager.reboot();
try {
await this._cameraManager.transport.close();
} catch (e) {
Logger.error('Failed while closing the device on reboot', e, HPKUpgrader.name);
}
}
return reboot;
}
/**
* Invokes an internal camera api that instruments the camera to load and run the uploaded firmware image on target.
*
* @param {UpgradeStatusStep} runStatusStep The upgrade status step reporting the progress of the firmware loading on target.
* @return {*} {Promise<void>} Resolves when the process is completed.
* @memberof HPKUpgrader
*/
async runHPKScript(runStatusStep: UpgradeStatusStep): Promise<void> {
Logger.debug('RUN hpk');
runStatusStep.progress = 1;
try {
const runMessage = await this._cameraManager.api.sendAndReceiveMessagePack(
{ filename: 'upgrade.hpk' },
{
send: 'hpk/run',
receive: 'hpk/run_reply',
},
15000
);
if (runMessage.string === 'Success') {
Logger.debug('RUN hpk complete', HPKUpgrader.name);
runStatusStep.progress = 100;
this.emitProgressStatus();
return;
} else {
Logger.error(`HPK run failed ${JSON.stringify(runMessage)}`, '', HPKUpgrader.name);
throw new HPKUpgradeError(`run failed ${runMessage}`, ErrorCodes.UPGRADE_RUN_FAILED);
}
} catch (e) {
Logger.error('Unable to run the hpk script', e, HPKUpgrader.name);
throw new HPKUpgradeError(`Could not run hpk ${e}`, ErrorCodes.UPGRADE_RUN_FAILED);
}
}
/**
* Uploads firmware image to the camera and makes sure the camera loads it.
*
* @param {UpgradeStatusStep} uploadStatusStep The upload step reporting the upload of the firmware image on target.
* @param {UpgradeStatusStep} runStatusStep The step reporting the load of the firmware image into one of the boot slots on target.
* @param {UpgradeStatusStep} completionStatusStep The step reporting when all the other steps are finished and upgrade is completed.
* @param {UpgradeStatusStep} rebootStatusStep The step reporing the status of camera being rebooted and then coming back up.
* @return {*} {Promise<boolean>} Resolves when the process is completed.
* @memberof HPKUpgrader
*/
async doUpgrade(
uploadStatusStep: UpgradeStatusStep,
runStatusStep: UpgradeStatusStep,
completionStatusStep: UpgradeStatusStep,
rebootStatusStep: UpgradeStatusStep
): Promise<boolean> {
Logger.info('Upgrading HPK', HPKUpgrader.name);
const hpkBuffer = this._fileBuffer;
try {
if (!BoxfishHpk.isHpk(this._fileBuffer)) {
throw new HPKUpgradeError(
'HPK upgrader file is not a valid hpk file',
ErrorCodes.UPGRADE_INVALID_FILE
);
}
await this.upload(hpkBuffer, uploadStatusStep);
const completedPromise = this.awaitHPKCompletion(completionStatusStep, rebootStatusStep);
await this.runHPKScript(runStatusStep);
return await completedPromise;
} catch (e) {
Logger.error('Failed performing hpk upgrade on boxfish device', e, HPKUpgrader.name);
this.deRegisterHotPlugEvents();
throw e;
}
}
/**
* Validates the firmware image uploaded to the camera before commanding the camera to always start
* booting with the new update firmware.
*
* @return {*} {Promise<boolean>} Resolves when the validation process is completed
* @memberof HPKUpgrader
*/
async upgradeIsValid(): Promise<boolean> {
// Quick fix for not calling getState on dartfish, which throws an error.
// This needs to be properly fixed in the future.
const prodId = this._cameraManager['productId'];
if ([HuddlyHEX.DARTFISH_PID, HuddlyHEX.SMARTBASE_PID].includes(prodId)) {
return true;
}
try {
const response = await this._cameraManager.getState();
Logger.info(`Upgrade status ${response.string}`, HPKUpgrader.name);
if (response.status === 10) {
// EMMC is not ready lets wait and try again
await new Promise((resolve) => setTimeout(resolve, 1000));
return await this.upgradeIsValid();
}
if (!this._production_upgrade) {
return response.status === 0;
} else {
// When flashing the boxfish-prod.hpk we can ignore the cnn emmc error
return response.status === 0 || response.status === 3;
}
} catch (e) {
return false;
}
}
}


Please choose an export format. Currently iCalendar exports are not supported. By clicking Sign in with Google,
you will be redirected to the sign in page for your Google Account, allowing us to enter the information from your
PDF into your Google Calendar.


new()
: the constructorIsStopHead()
: test if a term is in the stop head dictionaryIsStopTail()
: test if a term is in the stop tail dictionaryIsCSW()
: test if a term is in the Chinese Stop word dictionaryIsESW()
: test if a term is in the English stop word dictionaryIsEmark()
: test if a term is an English punctuation markIsCmark()
: test if a term is a Chinese punctuation markAddStopHead()
: add a term to the stop head dictionaryAddStopTail()
: add a term to the stop tail dictionaryAddCSW()
: add a term to the Chinese stop word dictionaryAddESW()
: add a term to the English stop word dictionaryAddEmark()
: add a term to the English punctuation mark dictionaryAddCmark()
: add a term to the Chinese punctuation mark dictionaryDelStopHead()
: delete a term from the stop head dictionaryDelStopTail()
: delete a term from the stop tail dictionaryDelCSW()
: delete a term from the Chinese stop word dictionaryDelESW()
: delete a term from the English stop word dictionaryDelEmark()
: delete a mark from the English punctuation dictionaryDelCmark()
: delete a mark from the Chinese punctuation dictionaryGetStopHead()
: get a reference to the stop head hash (dictionary)GetStopTail()
: get a reference to the stop tail hash (dictionary)GetCSW()
: get a reference to the Chinese stop word hash (dictionary)GetESW()
: get a reference to the English stop word hash (dictionary)GetEmark()
: get a reference to the English punctuation mark hashGetCmark()
: get a reference to the Chinese punctuation mark hash
Stopword -- A class for handling stop words.
use Stopword; $Stop = Stopword->new( ); $Stop->AddESW('font'); # add 'font' as an English Stop word $Stop->AddCSW('牽 涉'); # add '牽 涉' as a Chinese Stop word $Stop->AddEmark("\t"); # add "\t" as an English punctuation mark $Stop->AddCmark('﹗'); # add '﹗' as a Chinese punctuation mark $Stop->AddStopHead('逐'); # add '逐' as a Chinese stop head character $Stop->AddStopTail('遂'); # add '遂' as a Chinese stop tail character $Stop->DelESW('font'); # delete 'font' as an English Stop word $Stop->DelCSW('牽 涉'); # delete '牽 涉' as a Chinese Stop word $Stop->DelEmark("\t"); # delete "\t" as an English punctuation mark $Stop->DelCmark('﹗'); # delete '﹗' as a Chinese punctuation mark $Stop->DelStopHead('逐'); # delete '逐' as a Chinese stop head character $Stop->DelStopTail('遂'); # delete '遂' as a Chinese stop tail character if ($Stop->IsESW('the')) { print "'the' is an English Stop Word\n"; } if ($Stop->IsCSW('但 是')) { print "'但 是' is a Chinese Stop Word\n"; } if ($Stop->IsEmark(',')) { print "',' is an English punctuation mark\n"; } if ($Stop->IsCmark('，')) { print "'，' is a Chinese punctuation mark\n"; } if ($Stop->IsStopHead(substr('第 五 號', 0, 2))) { print "'第' is a Chinese Stop Head Character\n"; } if ($Stop->IsStopTail(substr('第 五 日', 6, 2))) { print "'日' is a Chinese Stop Tail Character\n"; } print "English Stop Words: ", (join ', ', $Stop->GetESW()), "\n", "Chinese Stop Words: ", (join ', ', $Stop->GetCSW()), "\n", "English puntuation marks: ", (join ', ', $Stop->GetEmark()), "\n", "Chinese puntuation marks: ", (join ', ', $Stop->GetCmark()), "\n", "Chinese stop head characters: ", (join ', ', $Stop->GetStopHead()), "\n", "Chinese stop tail characters: ", (join ', ', $Stop->GetStopTail()), "\n";
Stop words are often used as in a search engine to filter out non-semantic-bearing terms. Author: Yuen-Hsien Tseng. Date: 1998/04/28, last update: 2003/06/02, 2003/11/07
new()
: the constructor$Stop = Stopword->new( {'Attribute_Name'=>'Attribute_Value', ... } );
IsStopHead()
: test if a term is in the stop head dictionary$True_Or_False = $stop->IsStopHead( $term );
IsStopTail()
: test if a term is in the stop tail dictionary$True_Or_False = $stop->IsStopTail( $term );
IsCSW()
: test if a term is in the Chinese Stop word dictionary$True_Or_False = $stop->IsCSW( $term );
IsESW()
: test if a term is in the English stop word dictionary$True_Or_False = $stop->IsWSW( $term );
IsEmark()
: test if a term is an English punctuation mark$True_Or_False = $stop->IsEmark( $term );
IsCmark()
: test if a term is a Chinese punctuation mark$True_Or_False = $stop->IsCmark( $term );
AddStopHead()
: add a term to the stop head dictionary$stop->AddStopHead( $term );
AddStopTail()
: add a term to the stop tail dictionary$stop->AddStopTail( $term );
AddCSW()
: add a term to the Chinese stop word dictionary$stop->AddCSW( $term );
AddESW()
: add a term to the English stop word dictionary$stop->AddESW( $term );
AddEmark()
: add a term to the English punctuation mark dictionary$stop->AddEmark( $term );
AddCmark()
: add a term to the Chinese punctuation mark dictionary$stop->AddCmark( $term );
DelStopHead()
: delete a term from the stop head dictionary$stop->DelStopHead( $term );
DelStopTail()
: delete a term from the stop tail dictionary$stop->DelStopTail( $term );
DelCSW()
: delete a term from the Chinese stop word dictionary$stop->DelCSW( $term );
DelESW()
: delete a term from the English stop word dictionary$stop->DelESW( $term );
DelEmark()
: delete a mark from the English punctuation dictionary$stop->DelEmark( $term );
DelCmark()
: delete a mark from the Chinese punctuation dictionary$stop->DelCmark( $term );
GetStopHead()
: get a reference to the stop head hash (dictionary)$rStopHead = $stop->GetStopHead( );
GetStopTail()
: get a reference to the stop tail hash (dictionary)$rStopTail = $stop->GetStopTail( );
GetCSW()
: get a reference to the Chinese stop word hash (dictionary)$rCSW = $stop->GetCSW( );
GetESW()
: get a reference to the English stop word hash (dictionary)$rESW = $stop->GetESW( );
GetEmark()
: get a reference to the English punctuation mark hash$rEmark = $stop->GetEmark( );
GetCmark()
: get a reference to the Chinese punctuation mark hash$rCmark = $stop->GetCmark( );


{{ partial "head.html" . }}
{{ partial "nav.html" . }} {{ partial "hero.html" . }} {{ partial "approach.html" . }} {{ partial "case-studies.html" . }} {{ partial "us.html" . }} {{ partial "contact.html" . }} {{ partial "footer.html" . }} {{ partial "scripts.html" . }}


The DjangoCon.us brand uses the official Django brand as a base. A case could be made for a designer to change the colors and positioning of the date and location from year-to-year. However, the goal with this logo is to highlight the casual, friendly, professional atmosphere of the conference and can be used for subsequent years with minimal alterations.


Search
Log in
Registration
Create Personal Account
Create Company Account
Suppliers
Intelligence
News
Expert articles
Contacts
Add company
Search
Suppliers
Intelligence
News
Expert articles
Contacts
Log in
Registration
Add company
Log In to Your Account
Email
Password
Remember me
Forget password?
Log in
Haven’t account yet?
Create an Account


{% extends 'base_fluid.html' %} {% block title %}{{ instance }}{% endblock %} {% block content %} {% load bootstrap %} {% load size_utils %} {% if not instance.initialised %}
In order to get you started, here is a little HowTo.
First pick an install medium from the drop down list (CD/DVD), then hit 'Start'. Give it a few ticks then hit 'Launch VNC' (you will need Java for this!).
When prompted for network details, configure manually using all the details specified below.
Any questions, drop us an email! Click here to get rid of this!
| Name | {{ instance.alias }} |
|---|---|
| Status | {{ instance.get_status_html|safe }} | Refresh Delete |
| Power | Start Resume Suspend Restart Shutdown Force Shutdown |
| CD/DVD | |
| VNC |
| Hardware | |||
|---|---|---|---|
| VCPU | {{ instance.vcpu }} | ||
| RAM | {{ instance.memory.name }} | ||
| HDD | {{ instance.volume.capacity.name }} | Path | {{ instance.volume.device_name }} |
| CD/DVD | {{ instance.disk }} | ||
| Network | |||
| MAC | {{ instance.mac }} | ||
| IP | {{ instance.network.ip }} | ||
| Network | {{ instance.network.network.network }} | ||
| Gateway | {{ instance.network.network.gateway }} | ||
| Netmask | {{ instance.network.network.netmask }} | ||
| Broadcast | {{ instance.network.network.broadcast }} |


Michelle Lee
About
Education
Courses
Projects
Skills
Experience
Interests
Gallery
×
Food
Cities
Activities


We are the destination for cars in Nigeria. Find out what makes us different
Start Selling TodayView Cars
Find the best cars at cheaper deals from all over Nigeria
Buy Online
Buy Cars online at 100% trust and refund rate
Fast Car Shipping
Have your ordered car shipped to you at lightning speed


Toggle navigation
Hello, Jeff Rothkirch
Summary
messages
Deep Focus
Keep Crushing it.
Total Messages:
3
Important Messages:
1
Last Updated:
May 5th 8:19 pm
Summary
Important Messages
Here's the summary of who have contacted you
Back to Home
Messages
Text Message
5/7 10:32 AM
Rothkirch: Hey, checkout this blue bike
8:42AM
Rothkirch: Why aren't you replying to my messages?
Voicemail
5/7 3:32 PM
Julia: Hi Sweetie! I got us our reservation at Tarintino.
Email
10:42AM
From: TechCrunch Subject: Sign up for Tech Crunch
5/7 10:55AM
From: Google Subject: Congratulations on your job offer!


| pgpool-II 4.0.3 Documentation | |||
|---|---|---|---|
| Prev | Up | Appendix A. Release Notes | Next |
Release Date: 2016-12-26
Tightening up the watchdog security. (Muhammad Usama)
Now wd_authkey uses the HMAC SHA-256 hashing.
Add pgpool_adm extension in Pgpool-II RPM. (Bo Peng)
Fix occasional segfault when query cache is enabled. (bug 263) (Tatsuo Ishii)
Fix packet kind does not match error in extended protocol. (bug 231) (Tatsuo Ishii)
According to the bug231, the bug seem to bite you if all of following conditions are met:
Streaming replication mode
Load balance node is not node 0
Extended protocol is used
SELECT is executed, the statement is closed, then a transaction command is executed
The sequence of how the problem bites is:
SELECT executes on statement S1 on the load balance node 1
Frontend send Close statement
Pgool-II forward it to backend 1
Frontend sends Parse, Bind, Execute of COMMIT
Pgool-II forward it to backend 0 & 1
Frontend sends sync message
Pgool-II forward it to backend 0 & 1
Backend 0 replies back Parse complete ("1"), while backend 1 replies back close complete ("3") because of #3.
Kind mismatch occurs
The solution is, in #3, let Pgpool-II wait for response from backend 1, but do not read the response message. Later on Pgpool-II's state machine will read the response from it before the sync message is sent in #6. With this, backend 1 will reply back "1" in #8, and the kind mismatch error does not occur.
Also, fix not calling pool_set_doing_extended_query_message() when receives Close message. (I don't know why it was missed).
New regression test "067.bug231" was added.
Fix a race condition in a signal handler per bug 265. (Tatsuo Ishii)
In child.c there's signal handler which calls elog. Since the signal handler is not blocked against other signals while processing, deadlock could occur in the system calls in the pgpool shutdown sequence. To fix the problem, now the signal handler is blocked by using POOL_SETMASK.
Ideally we should avoid calling elog in signal handlers though.
Back porting the improved failover command propagation mechanism from Pgpool-II 3.6 (Muhammad Usama)
Overhauling the design of how failover, failback and promote node commands are propagated to the watchdog nodes. Previously the watchdog on pgpool-II node that needs to perform the node command (failover, failback or promote node) used to broadcast the failover command to all attached pgpool-II nodes. And this sometimes makes the synchronization issues, especially when the watchdog cluster contains a large number of nodes and consequently the failover command sometimes gets executed by more than one pgpool-II.
Now with this commit all the node commands are forwarded to the master/coordinator watchdog, which in turn propagates to all standby nodes. Apart from above the commit also changes the failover command interlocking mechanism and now only the master/coordinator node can become the lock holder so the failover commands will only get executed on the master/coordinator node.
Do not cancel a query when the query resulted in an error other than in native replication mode. (Tatsuo Ishii)
It was intended to keep the consistency, but there's no point in other than native replication mode.
Remove obsoleted option "-c" in pgpool command. (Tatsuo Ishii)
Also fix typo in the help message.
Fix authentication failed error when PCP command is cancelled. (bug 252) (Muhammad Usama)
Change the default value of search_primary_node_timeout from 10 to 300. (Tatsuo Ishii)
Prior default value 10 seconds is sometimes too short for a standby to be promoted.
Fix the case when all backends are down then 1 node attached. (bug 248) (Tatsuo Ishii)
When all backends are down, no connection is accepted. Then 1 PostgreSQL becomes up, and attach the node using pcp_attach_node. It successfully finishes. However, when a new connection arrives, still the connection is refused because pgpool child process looks into the cached status, in which the recovered node is still in down status if mode is streaming replication mode (native replication and other modes are fine). Solution is, if all nodes are down, force to restart all pgpool child.
Fix for: [pgpool-general: 4997] Avoiding downtime when pgpool changes require a restart (Muhammad Usama)
To fix this, The verification mechanism of configuration parameter values is reversed, previously the standby nodes used to verify their parameter values against the respective values on the master pgpool-II node and when the inconsistency was found the FATAL error was thrown, now with this commit the verification responsibility is delegated to the master pgpool-II node. Now the master node will verify the configuration parameter values of each joining standby node against its local values and will produce a WARNING message instead of an error in case of a difference. This way the nodes having the different configurations will also be allowed to join the watchdog cluster and the user has to manually look out for the configuration inconsistency warnings in the master pgpool-II log to avoid the surprises at the time of pgpool-II master switch over.
Add compiler flag "-fno-strict-aliasing" in configure.ac to fix compiler error. (Tatsuo Ishii)
Do not use random() while generating MD5 salt. (Tatsuo Ishii)
random()
should not be used in security related applications. To
replace random()
, import PostmasterRandom()
from PostgreSQL. Also
store current time at the start up of Pgpool-II main process for later
use.
Don't ignore sync message from frontend when query cache is enabled. (Tatsuo Ishii)


Choose any photo from your phone or computer and customize a museum-quality frame to fit. We'll print your photo,handcraft the frame and deliver it ready to hang within days. It's the perfect way to remember your favorite moments or create an unforgettable gift. We take expert care of each image entrusted to us, transforming the digital file into a handcrafted, custom framed photo designed to look great and last for decades.
Whether it's a bedroom, living room, home office, kitchen or hallway, framed photos will transform and brighten up the space. They can complement any decor and add a unique, personal touch to your home. Deck the walls in your own personal style with family portraits, beloved pets, school photos, epic travels and other moments you can enjoy every day.
We've made it easy to frame your photos in just a few steps. Upload an image from your phone or computer, select the print size, and design the perfect frame style to match. Within a week, your professionally printed and custom framed picture will be securely packed and shipped directly to you.
If a photo means something to you, it means the world to us. We carefully prepare each image for printing to ensure the best possible print quality, and stand by all of our work with a Happiness Guarantee. Our goal is to be a trusted partner on your next printing and framing project, and on many more to come.


Javascript is gaining lots of popularity for several important reasons. It works on practically all devices and browsers which reduces the amount of work programmers need to do. Imagine having to build a tool once versus one for each type of device. That's more efficient right? It's pretty easy to learn. It runs on the client side which saves on bandwith and reduces loads on servers. What does that mean for a user? It means speedier pages. You don't need a special computer program to run it, just a good ole plain text editor and a browser. Above all, the amount of resources available is mind blowing. There are lots of libraries like JQuery where you can grab code from instead of having to reinvent the wheel. With the addition of node, JS also allows a programmer to work on the backend. How cool is that?
As amazing as JS is, there are some pitfalls to discuss. It's reliant on browsers and therefore has limitations based on them. There are numerous browsers available to users and each has a different JS engine. That means JS code might be interpreted differently from one to another. A programmer can keep descrepancies as a minimum by testing on all major browsers. Speaking of users earlier, did you know that some speakers turn off JS? Yes, JS can be disabled. A JS heavy website might just be inoperable if that happens. One of the reasons why users disable it is because there are possible security issues. How? Third party hackers can inject JS into your site and control what the users do.


We supply a range of Bonded Stores such as Imported Beer, Cigarettes & Tobaccoes, Imported spirits/Liqueur and Soft drinks. We also provide sweets, chocolates and snacks.
We supply Cloth & Linen products such as Acrylic Blankets, Bed Sheets, Bed Spreads, Bow Ties, Wool Blankets, Mattresses, Pillows, etc.
We supply all kinds of utensils such as spoons, saucepans, glasses, plates and all other kitchen equipment included traditional Indian utensils.
We supply all kinds of Boilersuits, Gloves, Coveralls, Working Jackets, Working Trousers etc.
We supply provisions ranging from local products and authentic Indian products. Our range of provisions include Vegetables, Beans, Meat, Biscuits, Dairy products and all types of Indian Provisions.
We supply Bathroom Equipment, Bathroom Shelve, Combination Wall Faucet w/Overhead Swivel Spout, Combination Wall Faucet w/Underside Swivel Spout, Waste w/S-trap
Our Technical Department delivers all deck, engine, electrical stores, stationery, medical supplies or nautical equipment: Ropes/hawsers, marine paint/painting equipment, pneumatic/electrical tools, machinery equipment, screws/nuts, measuring tools and all kinds of nautical equipment.
We supply Electrical stores such as Pneumatic Lights, Flood Lights, Pilot lamps, Torches, Insulation Testers, Switches, Cables, Plugs and many more.
The range of Engines and Equipment for which we supply include the following:
EDTECH LIFE SAVING / FIRE FIGHTING PRODUCTS
1. Ms Wendy Wong, Marketing Executive
Tel: +65 6397 5980
Fax: +65 6397 5981
2. Mr Jagjit Singh, Director
HP: +65 98289531
EDTECH STORES / SPARES
SUPPLY
1. Ms Llanie, Purchase Manager
Tel: +65 6397 5980
Fax: +65 6397 5981
2. Mr Jagjit Singh, Director
HP: +65 98289531
EDTECH ENGINEERING / SAFETY & AUTOMATION
Mr Saini Singh, Engineer
Tel: +65 6397 5980
Fax: +65 6397 5981
EDTECH AGENCY/IT
SERVICES
1.Mr LP Singh, Agency Manager / IT Specialist
Tel: +65 6397 5980
Fax: +65 6397 5981
2.Mr Jagjit Singh, Director
HP: +65 98289531


Grid System
20 equal boxes of at least 1024 pixels wide.
10 equal boxes of at least 1024 pixels wide.
9 equal boxes of at least 1024 pixels wide.
8 equal boxes of at least 1024 pixels wide.
7 equal boxes of at least 1024 pixels wide.
6 equal boxes of at least 1024 pixels wide.
5 equal boxes of at least 1024 pixels wide.
4 equal boxes of at least 1024 pixels wide.
3 equal boxes of at least 1024 pixels wide.
2 equal boxes of at least 1024 pixels wide.
1 box of at least 1024 pixels wide.


{% extends "base.html" %} {% block content %}
Drug Domain: {{ collaborator }} proprietary compounds and public compounds.


Troubleshooting
Node Version Requirements
Client v2.0 and above uses node.js 0.12.x
and below.
Using node.js 0.10.x
Upgrade to latest stable version of node.js
(>= 0.12.x
— see "Using node.js 0.12.x
" section below)
Client v2.0 and above uses node.js 0.12.x
and below.
Upgrade to latest stable version of node.js
(>= 0.12.x
— see "Using node.js 0.12.x
" section below)


Type some more text into the textbox and see how the text in the box above is automagically updated.
Add a second textbox with the label "Lastname"
Can you make the text entered in the "Lastname" textbox appear behind your firstname in the box above?
Can you make the information box below appear only when the "Lastname" textbox has a value?


Grave Robber Leader Kanemika:
Yuk yuk! I am Kanemika, leader of these grave robbers. You look strong enough, eh? How about doing me a favor?
"What is is?"


CodeMash TestSuite - Tests demoed during the CodeMash presentation.
Selenium TestRunner - Select a test suite to run in Selenium
Acceptance tests: These test-suites demonstrate/exercise the functionality of Selenium.
Unit-tests: Use JsUnit to test Selenium internals.


This is a collection of all currently open issues for active templates on the Telegram IV contest for domains without winners. Last refreshed at 01.01.1970 00:00 UTC. This site will be refreshed every 2 hours.
There is a total of 0 issues. Your filter returned 0 issues.


Croatia
Zagreb
Armenia
Yerevan
Nauru
Yaren
Morocco
Rabat
Philippines
Manila
New Zealand
Wellington
Poland
Warsaw
Japan
Tokyo
Sweden
Stockholm


Constructor
new Interface(settings) → {Interface}
Define an Interface by creating an instance of this class.
Parameters:
| Name | Type | Description |
|---|---|---|
settings |
Object | Configuration values. |
Properties:
| Name | Type | Description |
|---|---|---|
status |
String | Human-friendly value representing the Interface's current State. |
- Source:
Returns:
Instance of the Interface.
- Type
- Interface
Extends
- EventEmitter
Methods
(async) cycle(val)
Ticks the clock with a named Cycle.
Parameters:
| Name | Type | Description |
|---|---|---|
val |
String | Name of cycle to scribe. |
- Source:
log(…inputs)
Log some output to the console.
Parameters:
| Name | Type | Attributes | Description |
|---|---|---|---|
inputs |
any |
<repeatable> |
Components of the message to long. Can be a single {@link} String, many String objects, or anything else. |
- Source:
now() → {Number}
Returns current timestamp.
- Source:
Returns:
- Type
- Number
(async) start()
Start the Interface.
- Source:
(async) stop()
Stop the Interface.
- Source:


U.P. to set up 218 fast track courts for speedy disposal of cases of sexual crimes against women, children
State has 42,389 pending cases of sexual offences against children and 25,749 cases of rape and sexual crimes against women
by Omar RashidAmid the outrage over the death of the Unnao rape victim, the Uttar Pradesh government on Monday announced that it would set up 218 fast track courts for the speedy disposal of sexual crimes against women and children.
The decision was taken by the State Cabinet, a day after the last rites of the Unnao victim were performed in her native village, 75 km from here.
The State at present has 42,389 pending cases of sexual offences against children and 25,749 pending cases of rape and sexual crimes against women, said U.P. Law Minister Brajesh Pathak.
Given the high number of pending cases and for their speedy disposal, 218 new fast track courts would be set up, including 144 for sexual crimes against women, he said.
“Out of this, 144 will be regular courts and will hear only rape cases. And for crimes against children, called the POCSO (Protection of Children from Sexual Offences), we are going to open 74 such new courts,” Mr. Pathak said.
New posts of judges of the level of the additional sessions judge would be created in all 218 courts.
The government had estimated a budget of ₹75 lakh per court, said Mr. Pathak.
The Central government would bear 60% of the costs and the State the remaining 40%, he said.


Welcome to ccOutils
ccOutils is an extension to Java API which provides you either extra features or simplify the use of existing ones. It is made of several small utilities classes which provides functions such as CLI, Factory, Corba servant, pair etc..
The main classes are :
- Console Console line can be useful either to use your code inside scripts.
- Factory Provide 2 kind of abstract Factory, one very generic with less code to write and another more powerful by letting you writing your own factory interface and implementation. Check out your needs and choose one of this
- Corba Servant, At first Corba is a bit difficult to get in from its rich features. ccTools will help you by simplifying servant creation.
Getting started
The easiest way is to download the ccOutils_samples.zip. Unzip it in any directory and from Eclipse, select the menu "file/import.../General/Existing Projects into Workspace" then press "next" and "Browse" to select the sample directory. If you are interested in Factory there is also an article on it.
Get involved
ccOutils is an sub project of C³ open source project. It is included inside C³. Sources are available on GitHub, at the following link : github.com/CapCaval/c3


Parts Selector
The Parts Selector can be used to choose items from one list, then add to another.
Available items
Bolt
Nut
Screw
Washer
Add
Remove
Chosen items
Source code


Dynamic ART
Dynamic ART is a graphical programming environment on iPad. It's easy to create amazing
artwork, animations, interactions and music with Dynamic ART. You can also share your creations with your
friends.
You don't need to study complex syntax of computer languages. You just drag and drop a set of blocks and
connect them together. It will be a fun way to build your own programs.
It can be used for beginners to learn and practice mathematical, computational ideas and creative thinking.
If you have any questions or suggestions, please sent e-mails to<EMAIL_ADDRESS>- Multi-programs management.
- Graphical programming by dragging and dropping.
- Program executing flow control and sub-block-sequence reuse.
- Arithmetic operations, simple math functions (abs, sqrt, sin, cos, tan, asin, acos, atan, ln, log, round, floor, ceil, etc.).
- List operations.
- Turtle drawing similar to Logo Language.
- 2-D sketching (points, lines, rectangles, ellipses, polygens, arcs and Bezier curves).
- RGBA and HSBA color palette.
- Detect the beginning, movement and ending of user touch.
- Play sound and music.

You can try some examples first. Please click button "Open in Dynamic ART" to import the first example.


{{ define "main"}}
Ahh! seems like this link is broken! Or the intended page does not exist at all! If it can be fixed, I will do it as soon as possible.


Privacy Policy
Privacy
Looper.com provides this Privacy Policy to inform users of our policies and procedures regarding the collection, use and disclosure of personally identifiable information received from users of Looper's website, located at the domain Looper.com (the "Looper Website"). Please note that this Privacy Policy only applies to the Looper Website.
Information Collection and Use
It is not necessary to provide Looper with your personally identifiable information to use the Looper Website, and Looper does not collect personally identifiable information in connection with the operation of the Looper Website. If you contact Looper by email through the Looper Website, Looper may keep a record of your contact information and correspondence, and may use your email address, and any information that you provide to Looper in your message, to respond to you. Looper treats this information as it would treat any other unsolicited business correspondence, and has no obligation to keep this information confidential, nor to take any security measures to protect this information.
When you visit the Looper Website, Looper's servers automatically record information that your browser sends whenever you visit a website ("Log Data"). This Log Data may include information such as your IP address, browser type or the domain from which you are visiting. For most users accessing the Internet from an Internet service provider, the IP address will be different every time you log on. Looper uses Log Data to monitor use of the Looper Website and the services we offer via the Looper Website and for the Looper Website's technical administration.
Cookies
Like many websites, Looper also uses "cookie" technology to collect additional website usage data and to improve the Looper Website and the services offered via the Web Site. A cookie is a small data file that Looper's servers transfer to your computer's hard disk. Looper does not use cookies to collect personally identifiable information. However, IP addresses are collected by the use of cookies.
Looper mainly uses "session cookies", which enable certain features of the Looper Website and services offered via the Looper Website, to better understand how you interact with the Web Site and services we offer via the Looper Website, to monitor aggregate usage by our users and web traffic routing on the Looper Website, and to improve the Looper Website and services offered via the Looper Website. Session cookies should be deleted from your computer when you disconnect from or leave the Looper Website.
Looper also uses a persistent cookie that stays on your computer after you leave the Looper Website, for the sole purpose of ensuring that you receive a variety of Looper content (also called "frequency-capping").
Most Internet browsers automatically accept cookies. You can instruct your browser, by editing its options, to stop accepting cookies or to prompt you before accepting a cookie from the websites you visit.
Information Sharing and Disclosure
Looper cooperates with government and law enforcement officials or private parties, to enforce and comply with the law. Looper may disclose any information about you to government or law enforcement officials or private parties as Looper, in its sole discretion, believes necessary or appropriate to respond to claims, legal process (including subpoenas), to protect the property and rights of Looper or a third party, the safety of the public or any person, to prevent or stop any illegal, unethical, or legally actionable activity, or to comply with the law.
If any or all of the assets of Looper are acquired by, or merged with another entity, Looper will share with this entity some or all of the information collected through the Looper Website.
Security
Because Looper does not collect any personally identifiable information from the Looper Website, Looper does not take any specific security measures to protect the information we do collect.
Links to Other Sites
The Looper Website may contain links to other web sites ("Linked Sites") operated by Looper or third parties. Linked Sites may place their own cookies or other files on your computer, collect data or solicit personal information from you. This Privacy Policy addresses only the use and disclosure of information that Looper collects through the Looper Website. Other sites follow different rules regarding the use or disclosure of the personal information you submit to them. Looper does not exercise control over third party Linked Sites. Your use of any Linked Site operated by Looper is subject to the terms and conditions provided by Looper for such Linked Site. Looper encourages you to read the privacy policies or statements of the other websites you visit.
Our Policy Towards Children
The Looper Website is not directed to children under 18. If a parent or guardian becomes aware that his or her child has provided Looper with personally identifiable information without their consent, he or she should contact Looper at<EMAIL_ADDRESS>If Looper becomes aware that a child under 13 has provided Looper with personally identifiable information, Looper will remove such information from our files.
Changes to this Privacy Policy
Looper reserves the right to change this policy at any time without prior notice. Any changes to this policy will be posted here. You are advised to consult this Privacy Policy regularly for any changes. If you have any questions or comments about this Privacy Policy, please contact us at info@Looper.com.


Module: ActiveSupport::Testing::TimeHelpers
| Included in: | ActiveSupport::TestCase |
| Defined in: |
Overview
Containing helpers that helps you test passage of time.
Instance Method Summary collapse
-
#travel(duration, &block)
Changes current time to the time in the future or in the past by a given time difference by stubbing
Time.now
andDate.today
. -
#travel_back
Returns the current time back to its original state, by removing the stubs added by
travel
andtravel_to
. -
#travel_to(date_or_time)
Changes current time to the given time by stubbing
Time.now
andDate.today
to return the time or date passed into this method.
Instance Method Details
#travel(duration, &block)
Changes current time to the time in the future or in the past by a given
time difference by stubbing Time.now
and Date.today
.
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day
Time.current # => Sun, 10 Nov 2013 15:34:49 EST -05:00
Date.current # => Sun, 10 Nov 2013
This method also accepts a block, which will return the current time back to its original state at the end of the block:
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel 1.day do
User.create.created_at # => Sun, 10 Nov 2013 15:34:49 EST -05:00
end
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
60 61 62
# File 'activesupport/lib/active_support/testing/time_helpers.rb', line 60 def travel(duration, &block) travel_to Time.now + duration, &block end
#travel_back
Returns the current time back to its original state, by removing the stubs
added by travel
and travel_to
.
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.new(2004, 11, 24, 01, 04, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
travel_back
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
120 121 122
# File 'activesupport/lib/active_support/testing/time_helpers.rb', line 120 def travel_back simple_stubs.unstub_all! end
#travel_to(date_or_time)
Changes current time to the given time by stubbing Time.now
and
Date.today
to return the time or date passed into this method.
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.new(2004, 11, 24, 01, 04, 44)
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
Date.current # => Wed, 24 Nov 2004
Dates are taken as their timestamp at the beginning of the day in the
application time zone. Time.current
returns said timestamp,
and Time.now
its equivalent in the system time zone.
Similarly, Date.current
returns a date equal to the argument,
and Date.today
the date according to Time.now
,
which may be different. (Note that you rarely want to deal with
Time.now
, or Date.today
, in order to honor the
application time zone please always use Time.current
and
Date.current
.)
Note that the usec for the time passed will be set to 0 to prevent rounding errors with external services, like MySQL (which will round instead of floor, leading to off-by-one-second errors).
This method also accepts a block, which will return the current time back to its original state at the end of the block:
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
travel_to Time.new(2004, 11, 24, 01, 04, 44) do
Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
end
Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
# File 'activesupport/lib/active_support/testing/time_helpers.rb', line 93 def travel_to(date_or_time) if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime) now = date_or_time.midnight.to_time else now = date_or_time.to_time.change(usec: 0) end simple_stubs.stub_object(Time, :now, now) simple_stubs.stub_object(Date, :today, now.to_date) if block_given? begin yield ensure travel_back end end end


Our Mission
"Join hands together, to become a symbol of excellence through continuous students satisfaction in maths, technology, quality improvement, cost reduction and time management."
Our Vision
"Helping maximum no. of stundents in any subject."


Form Elements
Individual form controls automatically receive some global styling
Basic Form Elements
This elements automatically will be changed in your panel
Radio, Checkbox & File Buttons
This default elements was styled, and need some markup changes
Bootstrap Select
Styled select element, powered by Bootstrap Select plugin.
Bootstrap Date & Time picker
Powerful date & time picker plugin, with a big count of settings.
Spectrum Color Picker
One of the greatest colorpickers ever, with a big count of settings
Switch Buttons
Checkboxes & Radio buttons can be changed on switch button.
Tags Input
Gives you a possibility to get many values separated by coma.
Input Groups
Extend form controls by adding text or buttons before, after, or on both sides.
Form States
Can be used to highlight validation states in forms
Has Error
Add class .has-error
to .form-group
to get error state
Has Success
Add class .has-success
to .form-group
to get error state
Has Warning
Add class .has-warning
to .form-group
to get error state


| 1 | /* =========================================================== | |
| 2 | * JFreeChart : a free chart library for the Java(tm) platform | |
| 3 | * =========================================================== | |
| 4 | * | |
| 5 | * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. | |
| 6 | * | |
| 7 | * Project Info: http://www.jfree.org/jfreechart/index.html | |
| 8 | * | |
| 9 | * This library is free software; you can redistribute it and/or modify it | |
| 10 | * under the terms of the GNU Lesser General Public License as published by | |
| 11 | * the Free Software Foundation; either version 2.1 of the License, or | |
| 12 | * (at your option) any later version. | |
| 13 | * | |
| 14 | * This library is distributed in the hope that it will be useful, but | |
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
| 16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public | |
| 17 | * License for more details. | |
| 18 | * | |
| 19 | * You should have received a copy of the GNU Lesser General Public | |
| 20 | * License along with this library; if not, write to the Free Software | |
| 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, | |
| 22 | * USA. | |
| 23 | * | |
| 24 | * [Java is a trademark or registered trademark of Sun Microsystems, Inc. | |
| 25 | * in the United States and other countries.] | |
| 26 | * | |
| 27 | * ---------------------- | |
| 28 | * QuarterDateFormat.java | |
| 29 | * ---------------------- | |
| 30 | * (C) Copyright 2005-2008, by Object Refinery Limited and Contributors. | |
| 31 | * | |
| 32 | * Original Author: David Gilbert (for Object Refinery Limited); | |
| 33 | * Contributor(s): -; | |
| 34 | * | |
| 35 | * Changes: | |
| 36 | * -------- | |
| 37 | * 01-Mar-2005 : Version 1 (DG); | |
| 38 | * 10-May-2005 : Added equals() method, and implemented Cloneable and | |
| 39 | * Serializable (DG); | |
| 40 | * ------------- JFREECHART 1.0.x --------------------------------------------- | |
| 41 | * 08-Jun-2007 : Added Greek symbols, and support for reversing the date - see | |
| 42 | * patch 1577221 (DG); | |
| 43 | * | |
| 44 | */ | |
| 45 | ||
| 46 | package org.jfree.chart.axis; | |
| 47 | ||
| 48 | import java.io.Serializable; | |
| 49 | import java.text.DateFormat; | |
| 50 | import java.text.FieldPosition; | |
| 51 | import java.text.NumberFormat; | |
| 52 | import java.text.ParsePosition; | |
| 53 | import java.util.Arrays; | |
| 54 | import java.util.Calendar; | |
| 55 | import java.util.Date; | |
| 56 | import java.util.GregorianCalendar; | |
| 57 | import java.util.TimeZone; | |
| 58 | ||
| 59 | /** | |
| 60 | * A formatter that formats dates to show the year and quarter (for example, | |
| 61 | * '2004 IV' for the last quarter of 2004. | |
| 62 | */ | |
| 63 | public class QuarterDateFormat extends DateFormat | |
| 64 | implements Cloneable, Serializable { | |
| 65 | ||
| 66 | /** For serialization. */ | |
| 67 | private static final long serialVersionUID = -6738465248529797176L; | |
| 68 | ||
| 69 | /** Symbols for regular quarters. */ | |
| 70 | public static final String[] REGULAR_QUARTERS = new String[] {"1", "2", | |
| 71 | "3", "4"}; | |
| 72 | ||
| 73 | /** Symbols for roman numbered quarters. */ | |
| 74 | public static final String[] ROMAN_QUARTERS = new String[] {"I", "II", | |
| 75 | "III", "IV"}; | |
| 76 | ||
| 77 | /** | |
| 78 | * Symbols for greek numbered quarters. | |
| 79 | * | |
| 80 | * @since 1.0.6 | |
| 81 | */ | |
| 82 | public static final String[] GREEK_QUARTERS = new String[] {"\u0391", | |
| 83 | "\u0392", "\u0393", "\u0394"}; | |
| 84 | ||
| 85 | /** The strings. */ | |
| 86 | private String[] quarters = REGULAR_QUARTERS; | |
| 87 | ||
| 88 | /** A flag that controls whether the quarter or the year goes first. */ | |
| 89 | private boolean quarterFirst; | |
| 90 | ||
| 91 | /** | |
| 92 | * Creates a new instance for the default time zone. | |
| 93 | */ | |
| 94 | public QuarterDateFormat() { | |
| 95 | this(TimeZone.getDefault()); | |
| 96 | } | |
| 97 | ||
| 98 | /** | |
| 99 | * Creates a new instance for the specified time zone. | |
| 100 | * | |
| 101 | * @param zone the time zone (null not permitted). | |
| 102 | */ | |
| 103 | public QuarterDateFormat(TimeZone zone) { | |
| 104 | this(zone, REGULAR_QUARTERS); | |
| 105 | } | |
| 106 | ||
| 107 | /** | |
| 108 | * Creates a new instance for the specified time zone. | |
| 109 | * | |
| 110 | * @param zone the time zone (null not permitted). | |
| 111 | * @param quarterSymbols the quarter symbols. | |
| 112 | */ | |
| 113 | public QuarterDateFormat(TimeZone zone, String[] quarterSymbols) { | |
| 114 | this(zone, quarterSymbols, false); | |
| 115 | } | |
| 116 | ||
| 117 | /** | |
| 118 | * Creates a new instance for the specified time zone. | |
| 119 | * | |
| 120 | * @param zone the time zone (null not permitted). | |
| 121 | * @param quarterSymbols the quarter symbols. | |
| 122 | * @param quarterFirst a flag that controls whether the quarter or the | |
| 123 | * year is displayed first. | |
| 124 | * | |
| 125 | * @since 1.0.6 | |
| 126 | */ | |
| 127 | public QuarterDateFormat(TimeZone zone, String[] quarterSymbols, | |
| 128 | boolean quarterFirst) { | |
| 129 |
1
1. |
if (zone == null) { |
| 130 | throw new IllegalArgumentException("Null 'zone' argument."); | |
| 131 | } | |
| 132 | this.calendar = new GregorianCalendar(zone); | |
| 133 | this.quarters = quarterSymbols; | |
| 134 | this.quarterFirst = quarterFirst; | |
| 135 | ||
| 136 | // the following is never used, but it seems that DateFormat requires | |
| 137 | // it to be non-null. It isn't well covered in the spec, refer to | |
| 138 | // bug parade 5061189 for more info. | |
| 139 | this.numberFormat = NumberFormat.getNumberInstance(); | |
| 140 | ||
| 141 | } | |
| 142 | ||
| 143 | /** | |
| 144 | * Formats the given date. | |
| 145 | * | |
| 146 | * @param date the date. | |
| 147 | * @param toAppendTo the string buffer. | |
| 148 | * @param fieldPosition the field position. | |
| 149 | * | |
| 150 | * @return The formatted date. | |
| 151 | */ | |
| 152 | public StringBuffer format(Date date, StringBuffer toAppendTo, | |
| 153 | FieldPosition fieldPosition) { | |
| 154 |
1
1. format : removed call to java/util/Calendar::setTime → NO_COVERAGE |
this.calendar.setTime(date); |
| 155 | int year = this.calendar.get(Calendar.YEAR); | |
| 156 | int month = this.calendar.get(Calendar.MONTH); | |
| 157 |
1
1. format : Replaced integer division with multiplication → NO_COVERAGE |
int quarter = month / 3; |
| 158 |
1
1. format : negated conditional → NO_COVERAGE |
if (this.quarterFirst) { |
| 159 | toAppendTo.append(this.quarters[quarter]); | |
| 160 | toAppendTo.append(" "); | |
| 161 | toAppendTo.append(year); | |
| 162 | } | |
| 163 | else { | |
| 164 | toAppendTo.append(year); | |
| 165 | toAppendTo.append(" "); | |
| 166 | toAppendTo.append(this.quarters[quarter]); | |
| 167 | } | |
| 168 |
1
1. format : mutated return of Object value for org/jfree/chart/axis/QuarterDateFormat::format to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return toAppendTo; |
| 169 | } | |
| 170 | ||
| 171 | /** | |
| 172 | * Parses the given string (not implemented). | |
| 173 | * | |
| 174 | * @param source the date string. | |
| 175 | * @param pos the parse position. | |
| 176 | * | |
| 177 | * @return null, as this method has not been implemented. | |
| 178 | */ | |
| 179 | public Date parse(String source, ParsePosition pos) { | |
| 180 |
1
1. parse : mutated return of Object value for org/jfree/chart/axis/QuarterDateFormat::parse to ( if (x != null) null else throw new RuntimeException ) → NO_COVERAGE |
return null; |
| 181 | } | |
| 182 | ||
| 183 | /** | |
| 184 | * Tests this formatter for equality with an arbitrary object. | |
| 185 | * | |
| 186 | * @param obj the object (null permitted). | |
| 187 | * | |
| 188 | * @return A boolean. | |
| 189 | */ | |
| 190 | public boolean equals(Object obj) { | |
| 191 |
1
1. equals : negated conditional → KILLED |
if (obj == this) { |
| 192 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return true; |
| 193 | } | |
| 194 |
1
1. equals : negated conditional → KILLED |
if (!(obj instanceof QuarterDateFormat)) { |
| 195 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → NO_COVERAGE |
return false; |
| 196 | } | |
| 197 | QuarterDateFormat that = (QuarterDateFormat) obj; | |
| 198 |
1
1. equals : negated conditional → KILLED |
if (!Arrays.equals(this.quarters, that.quarters)) { |
| 199 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 200 | } | |
| 201 |
1
1. equals : negated conditional → KILLED |
if (this.quarterFirst != that.quarterFirst) { |
| 202 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return false; |
| 203 | } | |
| 204 |
1
1. equals : replaced return of integer sized value with (x == 0 ? 1 : 0) → KILLED |
return super.equals(obj); |
| 205 | } | |
| 206 | ||
| 207 | } | |
Mutations | ||
| 129 |
1.1 |
|
| 154 |
1.1 |
|
| 157 |
1.1 |
|
| 158 |
1.1 |
|
| 168 |
1.1 |
|
| 180 |
1.1 |
|
| 191 |
1.1 |
|
| 192 |
1.1 |
|
| 194 |
1.1 |
|
| 195 |
1.1 |
|
| 198 |
1.1 |
|
| 199 |
1.1 |
|
| 201 |
1.1 |
|
| 202 |
1.1 |
|
| 204 |
1.1 |