text:
June 15, 2015 - September 6, 2015

dionyziz for the Ting team.

Ting is a chat platform. It runs on ting.gr. This document specifies how it works.

# Workflow
People on ting exchange messages. Messages can be exchanged either in channels
(known as "tings"), or privately. Channels are public and can be looked at by
anyone, where they can see the messages exchanged. Privates are messages
exchanged directly between two people and can only be viewed by these people.
Channels and privates are collectively referred to as conversations.

Ting is a website that works both on desktop and on mobile.

Ting consists of serveral screens:

* The login screen
* The chat screen
* The settings screen

These are described below. When the user enters the URL ting.gr on their
browser, they are taken to the Login screen. If they enter www.ting.gr, they
are redirected to ting.gr and appropriate URL parameters are appended.

When the user enters the URL ting.gr/channel, where channel is any
valid channel name, the user is taken to the Login screen with the active
conversation set to the channel specified in the URL. When the user enters
the URL ting.gr/u/user, where user is any valid user name, the user is taken
to the Login screen with the active conversation set to a private with the
user specified.

However, if the user has stored credentials, then the Login screen is skipped
and the user is taken directly to the Chat screen.

The active conversation remains until the web page is refreshed, a different
URL is visited, or the active channel is manually changed. When the active
conversation is changed, the URL is changed to reflect that.

Once a user enters ting, they can then see who is online on the platform among
the recent people they had a conversation with.

The users can exchange messages in multiple channels. Messages exchanged are
per-channel. Each message sent to a channel is delivered only to the selected
channel.

Message history is stored in a per-conversation basis. When a user makes a
conversation active, they are shown some of the messages history.

# Channels
If no conversation is specified in the URL, the default channel name is used,
which is the channel name "ting". Channel names are validated as follows upon
visiting a ting URL:

1. The channel name is at least 1 character and at most 20.
2. The channel name must consist of only the following characters:
 - The lower-case and upper-case latin characters a-z and A-Z.
 - The numbers 0-9.
 - The symbols _ . -

If an invalid channel is specified, the user is redirected to the default
channel and the URL shown is ting.gr without a channel name. The same applies
if an invalid username is specified.

There is no notion of creating or destroying a channel. A channel exists purely
because of the messages exchanged within it.

# UX foundation
The UX is in Greek. The text towards the user will be informal. Singular
form is used for everything. Informal words are preferred over formal words.
For example, the word "πληκτρολόγησε" should be replaced by "γράψε". The goal
is to make the user feel at ease, relaxed, and in a friendly environment.

# Target audience
The target audience for Ting is teenagers from Greece aged 12 - 21 years old.
The purpose of the chat is to bring people close together and allow strangers
who live in the same country and are of similar age to get to know each other.
We should make it a point in the UX to avoid the purpose of many other chat
rooms which is romantic or sexual interest, and focus on directing the user to
make friendly, public conversations.

# Login screen
Ting users are authenticated by having their machine remember their credentials
when they register and when they login. Registering is done by entering only a
username.

If a user wants to keep their username, they have to enter a password by
editing their user account through the Settings screen.

The Login screen can be either a Simple Login screen or a Password Login
screen. The Simple Login screen is shown by default.

## Simple Login

The Simple Login screen consists of only a modal window with the heading
"Ting", a textbox, a button, and a link.

![Login screen](http://i.imgur.com/FirJeIL.jpg)
*Image: The simple login screen*

The placeholder text in the textbox is "Διάλεξε ένα ψευδώνυμο". The textbox is
focused by default when the screen is visited. The placeholder text is hidden
when the user starts typing some text, unless the text is cleared. Pressing the
Enter key when the keyboard is focused on the textbox is equivalent to pressing
the button.

The button has the text "Μπες". Upon clicking the button, the username entered
is verified as follows:

1. The username is at least 1 character and at most 20.
2. The username must consist of only the following characters:
 - The lower-case and upper-case latin characters a-z and A-Z.
 - The lower-case and upper-case greek characters α-ω and Α-Ω.
 - The numbers 0-9.
 - The symbols . , / ? ~ ! @ # $ % ^ & * ( ) - _ = + [ ] { } \ | ' " ` ; :
3. The username must not be reserved.

The username is also validated for form, but not for reservation, as the
username is being typed.

All usernames are not reserved by default. If the username is valid, the
username is reserved and the user is taken to the Chat screen. The username is
then associated with that user. The user's credentials are then stored on the
machine they used to login. The next time the user accesses ting, the
credentials are used to skip the Login screen. Once a username becomes
reserved, no other user is allowed to use it, even if the user is not currently
online. If the user does not use ting for two weeks and has not set a password
then the username stops being reserved.

When the user logs in with an unreserved username, they are assigned a random
avatar from a predefined set of avatars. They can later modify this avatar from
the settings page.

If the username is invalid, the textbox border is changed to red, the
content text color is changed to red and an appropriate error is displayed as
follows:

1. If the username field is empty, the error message is "Γράψε ένα ψευδώνυμο."
2. If the username field is too large, the error message is "Το ψευδώνυμο
   πρέπει να είναι έως 20 γράμματα."
3. If the username field contains forbidden characters, the error message is
   "Το ψευδώνυμο πρέπει να περιλαμβάνει μόνο γράμματα, αριθμούς ή σύμβολα."
4. If the username is reserved, the error message is "Το ψευδώνυμο
   το έχει άλλος."

The error message is displayed above the textbox.

![Simple login screen error](http://i.imgur.com/se80ce8.jpg)
*Image: An error logging in using the simple login screen*

Below the username textbox, a link allowing the user to login with their
reserved username is displayed, entitled "Έχω ήδη ψευδώνυμο". Clicking that
link changes the Simple Login screen into the Password Login screen.

## Password Login

The Password Login screen allows the user to login with a username and a
password of a reserved username. It is identical to the Simple Login screen,
except it contains a password input underneath the username input and it
doesn't contain a link at the bottom. The placeholders for the input boxes here
are "Το ψευδώνυμό σου" for the username input and "Ο κωδικός σου" for the
password input.

![Password login screen](http://i.imgur.com/L47eF0G.jpg)
*Image: The password login screen*

The username is validated as above for form, but not for reservation. In
addition:

1. If the username is reserved but the password is incorrect, the error message
   is "Ο κωδικός είναι λάθος."
2. If the username is not reserved, the error message is "Το ψευδώνυμο δεν
   υπάρχει. [Χρησιμοποίησέ το]".

Clicking the link in the non-reservation case logs the user in with the
unreserved username without a password, similar to the way they would have
logged in using the Simple Login screen.

![Password login screen error](http://i.imgur.com/vBdQAZ5.jpg)
*Image: An error logging in using the password login screen*

If the username and password combination is correct, the user is logged in with
the reserved username. Notice that it is possible to login with the same
reserved username in different devices simultaneously.

## Mobile Login

On mobile, the whole screen is used to display the login windows for both the
simple and the password login screens.

![Mobile login screen](http://i.imgur.com/nUfvfVz.jpg)
*Image: The mobile login screen*

On mobile, care should be taken to ensure the button is visible while the
username is being entered.

# Chat screen
The chat screen consists of the following elements:

1. A top bar
2. A recent conversations list
3. A chat history
4. A message area

![Chat screen](http://i.imgur.com/4kl8upL.jpg)
*Image: The chat screen*

## Top bar

The top bar is located at the top and takes up the whole screen horizontally.
On mobile, there is no top bar.

On the top left, it has the text "ting".
On the right, it has an icon with the avatar of the user.

![User menu](http://i.imgur.com/WoPGg2s.jpg)
*Image: The user menu*

Clicking the avatar icon pops up a menu with two options: Settings and Log out.
Clicking on Settings takes the user to the Settings screen.

## Logging out

Clicking Log out in the user menu logs the user out and wipes their user
credentials from their machine.

If the user has a password associated with their account, then the username
remains reserved. If no password is associated with their account, then Log out
also frees up the username for future use. However, before wiping out the
account, the user is shown a modal giving them a last chance of reserving their
username.

The user reservation modal has a label, a textbox, a button, a link, all
appearing the one below the other.

![User reservation modal](http://i.imgur.com/0SxifIu.jpg)
*Image: The user reservation modal*

Hitting the ESC key or pressing the browser back button closes the modal and
cancels the log out procedure. The label states "Κράτα το ψευδώνυμό σου". The
textbox has a placeholder of "Διάλεξε έναν κωδικό" and the button has a title
of "Αποθήκευση". Typing a password and clicking "Αποθήκευση" permanently
reserves the username with the password entered and logs the user out. The form
can also be submitted by hitting the Enter key. If the form is submitted
without entering a password, the following error message appears above the
password textbox:

"Πληκτρολόγησε έναν κωδικό."

The link below the textbox is labelled "Όχι τώρα". Clicking the link logs the
user out without reserving the username.

After logging out, the Ting application is replaced with the following text:

"Τα λέμε! [Ξαναμπές]"

Clicking the button takes the user back to the Ting application and allows them
to start over with logging in anew.

![Logged out](http://i.imgur.com/EIn4gJw.jpg)
*Image: Logged out of ting*

## Main chat screen

Below the top bar, the screen is split in two areas vertically. The left area
contains the recent list and the right area is split horizontally in two
smaller areas. The top portion is the larger and is the chat history. The
bottom portion is the message area. The portions are not resizable. If the
active conversation is a private message, there is an additional area above the
message area, the user information area.

## Recent conversations

The recent conversations list contains a list of recently used channels and
recently accessed private message partners. Recent conversations are shown from
most recent to least recent, one below the other. There is one currently active
conversation at a time. That conversation may not always be shown at the top of
the recent conversation list; see the rules below for the ordering of recent
conversations. Recent conversations that are channels simply display the
channel name. Recent conversations that are privates display the person's
avatar, their name, and their online status. The online status is displayed
with a green dot on the right of their name in case they are online.

Recent conversations are reordered based on the following strategy: Initially,
when a user first uses ting, the recent conversations list only includes the
conversation they are accessing, usually the Ting channel. A new item is added
to the conversation list when a new conversation becomes active. If a
conversation that becomes active when it's already in the list, it is brought
to the top of the list. If a new conversation is added to the list and the list
contains more than 50 items, then the oldest conversation is removed from the
recent conversations list ("milk" strategy).

A conversation becomes active and is either added to the list or reordered to
be at the top in the following events:

1. When the user activates the conversation by clicking it and remains within
the conversation for 4 seconds.
2. When a message of user-interest is received in a conversation (see below).
3. When the user starts typing a message within the conversation even if they
do not send the message.

If the list of conversations is too long to fit, a vertical scrollbar is
displayed on the right-hand side of the nick list.

## Searching conversations

At the top of the recent conversations list is a searchbox. The searchbox
allows the user to type in order to filter items from the recent conversation
list. When no text is entered in the search box, the text box has the
placeholder text "Βρες ανθρώπους ή tings". As soon as the user starts typing,
the placeholder text disappears unless they clear their text. While there is
text in the search textbox, an "X" is shown at the right of the textbox, which
allows the user to clear their search text. While typing, the recent
conversations list is filtered by the search text through a prefix-match test.

## Unread messages and messages of interest

Conversations with unread messages are also highlighted, but in a different
color. Unread messages are any messages of user-interest which have not been
viewed by the user yet. Activating a conversation with unread messages marks
their messages as read. Messages of user-interest are defined as any received
message in a private conversation, or any message mentioning the user's name
prefixed with an `@` in a channel.

If there are unread messages in the active conversation when the user is not
active (has switched to another tab or window), the window title gets prepended
with the count of unread messages in parentheses. When the user is active
again, the count is removed from the title and the previously unread messages
are marked as read.

## Message history

The message history contains a list of messages posted by everyone in the
active conversation. The messages are displayed in chronological order from top
to bottom. When the user enters a conversation, the message history consists of
the most recent 100 messages exchanged by the users priorly and is stored on
the server.

If there are less messages than the chat history can fit, the messages are
displayed at the bottom of the chat history area. Otherwise, a vertical
scrollbar is shown.

Every time a message is posted by someone, a new chat message is appended to
the bottom of the chat history area, and the area is scrolled towards the
bottom to make the new message visible. This happens unless the user has
scrolled upwards into the history enough to read older messages. In that case,
a new message being posted does not affect the scrolling position of the
history area.

When the user scrolls upwards and reaches the top of the displayed messages,
there is a button with the prompt "Δες παλαιότερα μυνήματα" if there are older
messages to show. In case there are not older messages to show, the button
should not appear. Clicking the button diplays 100 older messages (if more than
100 older messages exist), otherwise it displays the remaining of older
messsages.

For efficiency reasons, very old messages can be removed from the chat history.

## Message formatting

Each message posted has the following form: "[avatar] [username] Message",
where username contains the username of the person making the post and Message
contains the text posted. The message is displayed in a comicbook-like bubble
indicating that someone is speaking. Messages of user-interest in channels are
highlighted in orange. Messages sent and received are displayed in different
style; sent messages are displayed in blue and received messages are shown in
gray.

If a text is too long to fit in one line, it is wrapped around to the next
line. No horizontal scrollbar is ever displayed in the history area.

## User information

The user information area is shown above the message history area in case the
currently active conversation is a private. The user information area shows the
partner's avatar and username. Below the username, the age, the sex, and the
location of the user are shown, if they are available.

## Sending a message

The message area is a textbox. The textbox is focused by default when the user
enters the Chat screen. The textbox has the placeholder "Γράψε ένα μήνυμα...".
When the user starts typing some text, the placeholder is hidden, unless the
text the user entered is deleted, in which case the placeholder text reappears.
If a user enters a long message, the text is wrapped within the textbox.
Horizontal scrollbars never appear in the message area.

When a user enters a non-empty message and presses the Enter key, the message
is sent. There is no separate button to send a chat. When a message is sent by
a user, it is delivered to everyone else who is currently online in the chat in
the active channel. The textbox in the message area is then cleared, but
remains focused. The message appears immediately on the side of the sending
party.

## Mobile

On mobile, the chat screen is separated into two different screens. These are
the recent conversations screen and the mobile chat screen. The semantics are
similar to the above desktop version, with the mobile differences described
below.

In the recent conversations screen, the text "Ting" is displayed at the top.
Next to it, on the right, is a cog icon. Clicking the cog icon displays a
pop-up menu with two options, Settings and Log out, with similar semantics as
the desktop top bar.

Below the mobile top bar, a list of recent conversations appears. While in the
recent conversations screen on mobile, no active conversation is highlighted.
Tapping a recent conversation changes it to the active conversation and
switches to the mobile chat screen.

![Mobile recent conversations screen](http://i.imgur.com/YuXy3Ra.jpg)
*Image: The mobile recent conversations screen*

In the screen above, you can see a list of recent conversations, of which the
most recent conversation is the channel "chicken", and the second most recent
conversation is the channel "ting". The next two more recent conversations are
two private conversations with the users "gtklocker", who is online, and
"vitsalis", who is offline. The least recent conversation is the channel
"party".

In the mobile chat screen, a list of messages appears, which is rendered
similar to the desktop version. At the top of the list, the name of the
conversation appears in a separate title bar, along with a back button on the
left, which allows the user to return to the recent conversation list screen.

![Mobile chat screen](http://i.imgur.com/jECW8Jn.jpg)
*Image: The mobile chat screen*

# Message Formatting

In messages, smileys are replaced by their respective images. The list of
supported emoticons is
[taken from Skype](https://github.com/kof/emoticons/blob/master/support/skype/emoticons.json).

Web links are formatted to be clickable.

Dragging and dropping an image file from the user's computer into the messages
history or into the message form allows the user to upload an image. While
dragging the file over the website, the history and the message form are
overlayed with a screen with the following text indicating that the user can
drop the image to upload it:

"Άφησε την εικόνα για να την ανεβάσεις"

Dropping the image over this area uploads the image and immediately sends it as
a separate message. This does not affect any text the user may be currently
entering on the text box.

![Image Uploader](http://i.imgur.com/GDkryfj.jpg)
*Image: Image Uploader*

# Typing
Ting provides a different approach from usual chat platforms when it comes to
notifications about typing. Users can see each other typing in real time. This
works as follows.

Messages in ting are separated into persistent and non-persistent. Persistent
messages are messages that have been sent. Non-persistent messages are messages
that are currently being typed, but have not been sent yet (the Enter key has
not been pressed by the user.). A non-persistent message of a user that disconnects
is deleted. Users can see both persistent and non-persistent
messages and both are communicated on the network in real time.

When a user starts typing a message in a channel, they reserve a position in
the channel's history. Figuring out this position is critical for a smooth user
experience and is determined by the following rules.

* This position is maintained among other people who are currently typing, as
well as persistent messages that have been sent. When nobody is typing and a
user starts typing, this position becomes the end of the existing persistent
messages.

* When several users are typing and a user starts typing, their position becomes
at the end among the existingly typing users and after all persistent messages.

* When a user stops typing and erases their typed message, their position is
lost and their message is not persisted.

* When a user makes a message persistent by hitting the enter key, that
message's position in the history remains as-is among other users who are
typing. That is, it is not posted at the end of persistent messages, but
potentially among messages that have not yet been made persistent yet.

The user interface for this algorithm is different depending on whether the
current user or a remote user is typing. The non-persisted message of the
current user is displayed as "..." in the history portion of the chat. The full
message is displayed in the textarea as it is being typed. The "..." servers to
indicate to the user their current position among other typing users. Remote
non-persistent messages are displayed by the text being added in real time as
the user types, in their designated location.

Non-persistent messages are differentiated from persistent messages by showing
them as "ghosts", in a more transparent color. Additionally, the text of a
non-persistent message is slowly flashing by becoming more and less trasparent
to indicate that the message is ephemeral and currently changing.

![Desktop chat typing](http://i.imgur.com/9MdtAgp.jpg)
*Image: Desktop chat screen while typing*

![Mobile chat typing](http://i.imgur.com/IjDrJlY.jpg)
*Image: Mobile chat screen while typing*

# Settings screen
The settings screen allows a user to specify details about their user profile.

It consists of a form at the top and a save button with the title "Αποθήκευση"
at the bottom.

The form has the user's avatar displayed on the left. Below it is a button with
the title "Αλλαγή της εικόνας μου". Clicking it pops up a window allowing the
user to select a new avatar. The avatar is uploaded and displayed in the avatar
location within the settings. Before displaying it, the avatar is first cropped
into a square and then resized to fit the avatar size.

It is also possible for the user to upload an avatar by dragging a file onto
their avatar within their settings. While dragging a file over the screen, the
avatar location is changed into the text "Άφησε την εικόνα εδώ".

If the uploaded file is not a valid avatar, then the error message "Δοκίμασε
κάποια άλλη εικόνα" is displayed.

Next to the avatar, the username is displayed.

Below the avatar and the username, there are several form elements. The first
element concerns changing the user's password. The rest of the elements pertain
to various settings and consist of a label and a respective input.  The inputs
are prefilled with the settings the user has entered previously.

The password changing section is a single button. If the user has not set a
password, then the button is entitled "Ορισμός κωδικού". In that case, a
warning text (in yellow or red) appears above the label and the field stating:
"Διάλεξε έναν κωδικό ώστε να μην χάσεις την πρόσβαση στο λογαριασμό σου".
When the button is clicked, a modal form appears. The modal form consists of
two labels and their respective input fields entitled "Νέος κωδικός" and "Νέος
κωδικός (ξανά)" and a button captioned "Ορισμός κωδικού". The form also has an
X button on the top right allowing the user to cancel setting the password,
which hides the modal form. Entering an unmatching password shows the warning
text "Οι κωδικοί δεν ταιριάζουν" above the two passwords. If the user sets a
password correctly, then the modal form disappears. In the underlying settings
page, the warning text is now changed into a success text (in blue or green)
above the password setting button, reading "Το όνομα XXX είναι πλέον δικό σου."
where XXX is the username of the user. The button is then changed to read
"Αλλαγή κωδικού".

If the user has already set a password, then the button is entitled "Αλλαγή
κωδικού". Clicking that button shows a similar modal form, except that now it
has three elements consisting of a label and an input text each. They are
captioned "Παλιός κωδικός", "Νέος κωδικός", "Νέος κωδικός (ξανά)". The form has
a similar action button entitled "Αλλαγή κωδικού" and a similar X button as
before. Mismatching passwords show the same error. An incorrect old password
shows the error "Ο παλιός κωδικός σου δεν είναι σωστός." Changing the password
successfully hides the form and shows a success message (in blue or green)
above the password changing button, reading "Ο κωδικός σου άλλαξε."

The next label is "E-mail" with a text box input.

The next label for the date of birth is "Ημερομηνία γέννησης". The input
consists of three select fields, for the day, the month, and the year. All
fields contain the range of valid numbers for days, months, and years
respectively, as well as the "-" option. The days allow selecting from 1 to 31
ascending, the months from 1 to 12 ascending, and the years from 1920 to the
current year descending.

The next label for the gender is "Φύλο". The input consists of a select field
with three options "Αγόρι", "Κορίτσι" and "-".

The next label for the location is "Περιοχή". The input is a select box
listing all the major cities of Greece as well as the option "-".

Clicking the save button validates the form as follows:

1. The e-mail address is validated for form with a simple validation algorithm
and not exhaustively. It must contain an `@` symbol. It must contain at least
one alphanumeric character before the `@` sumbol. It must contain at least
three characters after the `@` symbol, one of which must be a `.`. The e-mail
must be at most 128 characters. The user can also leave the e-mail address
empty if they do not wish to associate an e-mail address with their account.

2. The date of birth must be a valid date.

If the form fails to validate, the following error messages are displayed above
their respective fields and the fields are highlighted in red:

1. "Γράψε ένα έγκυρο e-mail" if the e-mail address is invalid.
2. "Δώσε μία έγκυρη ημερομηνία γέννησης" if the date of birth is invalid.

Otherwise, the form is saved and the user is taken back to the Chat screen.

Notice that multiple users can share the same e-mail address.

# TODO
This specification is limited. It will be extended with the following features in future editions:

* Voice
* Channel moderation
* Subscription to channels
* Timestamps


text:
package model

// Audit member audit info
type Audit struct {
	Mid      int64 `json:"mid"`
	BindTel  bool  `json:"bind_tel"`
	BindMail bool  `json:"bind_mail"`
	Rank     int64 `json:"rank"`
	Blocked  bool  `json:"blocked"`
}

// PassportDetail passportDetail
type PassportDetail struct {
	Mid      int64  `json:"mid"`
	Email    string `json:"email"`
	Phone    string `json:"telphone"`
	Spacesta int8   `json:"spacesta"`
	JoinTime int64  `json:"join_time"`
}

redpajama_set_name: RedPajamaGithub


text:
import {Component, OnInit, TemplateRef, ViewChild, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
import {ActivityManagerService} from './activity-manager.service';
import {Observable} from 'rxjs/Observable';
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';

import {
  startOfDay,
  endOfDay,
  subDays,
  addDays,
  endOfMonth,
  isSameDay,
  isSameMonth,
  addHours,
  startOfWeek,
  endOfWeek,
  startOfMonth,
  isSameWeek
} from 'date-fns';

import {
  CalendarEvent, CalendarEventTitleFormatter
} from 'angular-calendar';

import {Subject} from 'rxjs/Subject';
import {TranslateService} from 'ng2-translate';
import {MainDateFormatter} from './date-formatter.provider';
import {EventTitleFormatter} from './event-formatter';

@Component({
  selector: 'app-activity',
  templateUrl: './activity.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
  styleUrls: ['./activity.component.scss'],
  encapsulation: ViewEncapsulation.None,
  providers: [{
    provide: CalendarEventTitleFormatter,
    useClass: EventTitleFormatter
  }]
})
export class ActivityComponent implements OnInit {
  @ViewChild('modalContent') modalContent: TemplateRef<any>;

  view: string = 'day';

  viewDate: Date = new Date(2017, 4, 22);

  lastViewDate: Date = this.viewDate;

  modalData: {
    action: string,
    event: CalendarEvent
  };

  refresh: Subject<any> = new Subject();

  activeDayIsOpen: boolean = true;

  weekStartsOn: number = 1;

  events$: Observable<any>;

  constructor(private modal: NgbModal,
              private translate: TranslateService,
              private activityService: ActivityManagerService) {
    const browserLang: string = translate.getBrowserLang();
    translate.use(browserLang.match(/en|ro/) ? browserLang : 'en');
  }

  ngOnInit() {
    this.fetchEvents(false);
  }

  fetchEvents(check: boolean = true): void {
    const date = startOfWeek(
      this.viewDate,
      {weekStartsOn: 1}
    );

    const lastViewWeekEndDate = startOfWeek(this.lastViewDate, {weekStartsOn: 1});

    if (
      lastViewWeekEndDate.getDate() === date.getDate() &&
      lastViewWeekEndDate.getMonth() !== date.getMonth() && check) {
      return;
    }

    const pr = this.activityService.getActivitiesForCurrentUserOnDate(date);

    this.events$ = Observable.fromPromise(pr)
      .map(res => {
        return res.json().map((activity) => {
          this.lastViewDate = this.viewDate;
          return this.activityService.activityToCalendarObject(activity, date);
        });
      });
  }

  dayClicked({date, events}: { date: Date, events: CalendarEvent[] }): void {

    if (isSameMonth(date, this.viewDate)) {
      if (
        (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
        events.length === 0
      ) {
        this.activeDayIsOpen = false;
      } else {
        this.activeDayIsOpen = true;
        this.viewDate = date;
      }
    }
  }

  handleEvent(action: string, event: CalendarEvent): void {
    this.modalData = {event, action};
    this.modal.open(this.modalContent, {size: 'lg'});
  }

  get getCurrntLang() {
    return this.translate.currentLang;
  }

  goToDay($event) {
    this.viewDate = $event.day.date;
    this.view = 'day';
  }
}


text:
import {
  getFormValues,
  isValid,
  getFormMeta,
  getFormSyncErrors
} from 'redux-form'

import valueSelectors from '../value/selectors'

const FormSelectors = {
  values: (state, name) => getFormValues(name)(state),
  valid: (state, name) => isValid(name)(state),
  meta: (state, name) => getFormMeta(name)(state),
  errors: (state, name) => getFormSyncErrors(name)(state),
  list: {
    selected: (state, id) => valueSelectors.get(state, `${id}_selected`) || [],
    deleteWindow: (state, id) => valueSelectors.get(state, `${id}_deleteWindow`) ? true : false,
    itemWindow: (state, id) => valueSelectors.get(state, `${id}_itemWindow`) ? true : false,
    itemIndex: (state, id) => valueSelectors.get(state, `${id}_itemIndex`),
  }
}

export default FormSelectors


text:
#include <aws/route53-recovery-cluster/model/UpdateRoutingControlStatesRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::Route53RecoveryCluster::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;

UpdateRoutingControlStatesRequest::UpdateRoutingControlStatesRequest() :
    m_updateRoutingControlStateEntriesHasBeenSet(false)
{
}

Aws::String UpdateRoutingControlStatesRequest::SerializePayload() const
{
  JsonValue payload;

  if(m_updateRoutingControlStateEntriesHasBeenSet)
  {
   Array<JsonValue> updateRoutingControlStateEntriesJsonList(m_updateRoutingControlStateEntries.size());
   for(unsigned updateRoutingControlStateEntriesIndex = 0; updateRoutingControlStateEntriesIndex < updateRoutingControlStateEntriesJsonList.GetLength(); ++updateRoutingControlStateEntriesIndex)
   {
     updateRoutingControlStateEntriesJsonList[updateRoutingControlStateEntriesIndex].AsObject(m_updateRoutingControlStateEntries[updateRoutingControlStateEntriesIndex].Jsonize());
   }
   payload.WithArray("UpdateRoutingControlStateEntries", std::move(updateRoutingControlStateEntriesJsonList));

  }

  return payload.View().WriteReadable();
}

Aws::Http::HeaderValueCollection UpdateRoutingControlStatesRequest::GetRequestSpecificHeaders() const
{
  Aws::Http::HeaderValueCollection headers;
  headers.insert(Aws::Http::HeaderValuePair("X-Amz-Target", "ToggleCustomerAPI.UpdateRoutingControlStates"));
  return headers;

}


text:
<title>strtol - Untitled</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Untitled">
<meta name="generator" content="makeinfo 4.11">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Stdlib.html#Stdlib" title="Stdlib">
<link rel="prev" href="strtod.html#strtod" title="strtod">
<link rel="next" href="strtoll.html#strtoll" title="strtoll">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">
<meta http-equiv="Content-Style-Type" content="text/css">

Next: strtoll,
Previous: strtod,
Up: Stdlib

2.35 strtol—string to long

Synopsis

     #include <stdlib.h>
     long strtol(const char *<var>s</var>, char **<var>ptr</var>,int <var>base</var>);

     long _strtol_r(void *<var>reent</var>,
         const char *<var>s</var>, char **<var>ptr</var>,int <var>base</var>);

Description

The function strtol converts the string *<var>s</var> to
a long. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
of characters resembling an integer in the radix specified by <var>base</var>;
and a trailing portion consisting of zero or more unparseable characters,
and always including the terminating null character. Then, it attempts
to convert the subject string into a long and returns the
result.

If the value of <var>base</var> is 0, the subject string is expected to look
like a normal C integer constant: an optional sign, a possible `0x'
indicating a hexadecimal base, and a number. If <var>base</var> is between
2 and 36, the expected form of the subject is a sequence of letters
and digits representing an integer in the radix specified by <var>base</var>,
with an optional plus or minus sign. The letters a–z (or,
equivalently, A–Z) are used to signify values from 10 to 35;
only letters whose ascribed values are less than <var>base</var> are
permitted. If <var>base</var> is 16, a leading 0x is permitted.

The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
non-whitespace character.  If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
permissible letter or digit, the subject string is empty.

If the subject string is acceptable, and the value of <var>base</var> is zero,
strtol attempts to determine the radix from the input string. A
string with a leading 0x is treated as a hexadecimal value; a string with
a leading 0 and no x is treated as octal; all other strings are
treated as decimal. If <var>base</var> is between 2 and 36, it is used as the
conversion radix, as described above. If the subject string begins with
a minus sign, the value is negated. Finally, a pointer to the first
character past the converted subject string is stored in <var>ptr</var>, if
<var>ptr</var> is not NULL.

If the subject string is empty (or not in acceptable form), no conversion
is performed and the value of <var>s</var> is stored in <var>ptr</var> (if <var>ptr</var> is
not NULL).

The alternate function _strtol_r is a reentrant version.  The
extra argument <var>reent</var> is a pointer to a reentrancy structure.

Returns

strtol returns the converted value, if any. If no conversion was
made, 0 is returned.

strtol returns LONG_MAX or LONG_MIN if the magnitude of
the converted value is too large, and sets errno to ERANGE.

Portability

strtol is ANSI.

No supporting OS subroutines are required.


text:
const Stripe = require('stripe');
const pug = require('pug');
const wkhtmltopdf = require('wkhtmltopdf');
const moment = require('moment');
const path = require('path');
const fs = require('fs');
const sizeOf = require('image-size');

const template = require(`./templates/default`);

module.exports = (key, config = {}) => async (invoiceId, data = {}) => {
  const stripe = new Stripe(key);
  if(!invoiceId) {
    throw new Error('missing_invoice_id');
  }
  const invoice = await stripe.invoices.retrieve(invoiceId);
  const tpld = template(Object.assign({
    currency_symbol: '$',
    label_invoice: 'invoice',
    label_invoice_to: 'invoice to',
    label_invoice_by: 'invoice by',
    label_due_on: 'Due on',
    label_invoice_for: 'invoice for',
    label_description: 'description',
    label_unit: 'unit',
    label_price: 'price ($)',
    label_amount: 'Amount',
    label_subtotal: 'subtotal',
    label_total: 'total',
    label_vat: 'vat',
    label_invoice_by: 'invoice by',
    label_invoice_date: 'invoice date',
    label_company_siret: 'Company SIRET',
    label_company_vat_number: 'Company VAT N°',
    label_invoice_number: 'invoice number',
    label_reference_number: 'ref N°',
    label_invoice_due_date: 'Due date',
    company_name: 'My company',
    date_format: 'MMMM Do, YYYY',
    client_company_name: 'Client Company',
    number: '12345',
    currency_position_before: true,
    language: 'en',
  }, invoice, config, data));
  return wkhtmltopdf(pug.compileFile(tpld.body)(Object.assign(tpld.data, {
    moment,
    path,
    fs,
    sizeOf
  })), { pageSize: 'letter' });
}


text:
package com.zimbra.soap.admin.message;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlRootElement;

import com.zimbra.common.soap.AdminConstants;
import com.zimbra.soap.admin.type.AdminAttrsImpl;

/**
 * @zm-api-command-auth-required true
 * @zm-api-command-admin-auth-required true
 * @zm-api-command-description Returns all data sources defined for the given mailbox.  For each data source, every
 * attribute value is returned except password.
 * <br />
 * Note: this request is by default proxied to the account's home server
 */
@XmlAccessorType(XmlAccessType.NONE)
@XmlRootElement(name=AdminConstants.E_GET_DATA_SOURCES_REQUEST)
public class GetDataSourcesRequest extends AdminAttrsImpl {

    /**
     * @zm-api-field-tag existing-account-id
     * @zm-api-field-description Account ID for an existing account
     */
    @XmlAttribute(name=AdminConstants.E_ID, required=true)
    private final String id;

    /**
     * no-argument constructor wanted by JAXB
     */
    @SuppressWarnings("unused")
    private GetDataSourcesRequest() {
        this((String) null);
    }

    public GetDataSourcesRequest(String id) {
        this.id = id;
    }

    public String getId() { return id; }
}


text:
{{title}}

Home

Find a Room

Find a Room


text:
package gov.nist.registry.common2;

public interface MetadataTypes {
    final static int METADATA_TYPE_UNKNOWN = 0;
    final static int METADATA_TYPE_R       = 1;
    final static int METADATA_TYPE_PR      = 2;
    final static int METADATA_TYPE_Q       = 3;
    final static int METADATA_TYPE_SQ      = 4;
    final static int METADATA_TYPE_Rb      = 5;
    final static int METADATA_TYPE_RET     = 6;
    final static int AUDIT_LOG             = 7;

}


text:
package com.google.gapid.models;

import static com.google.gapid.proto.service.memory.Memory.PoolNames.Application_VALUE;
import static com.google.gapid.util.Paths.command;
import static com.google.gapid.util.Paths.commandTree;
import static com.google.gapid.util.Paths.lastCommand;
import static com.google.gapid.util.Paths.observationsAfter;
import static com.google.gapid.widgets.Widgets.submitIfNotDisposed;
import static java.util.logging.Level.FINE;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.SettableFuture;
import com.google.gapid.models.ApiContext.FilteringContext;
import com.google.gapid.proto.device.Device.Instance;
import com.google.gapid.proto.service.Service;
import com.google.gapid.proto.service.api.API;
import com.google.gapid.proto.service.path.Path;
import com.google.gapid.rpc.Rpc;
import com.google.gapid.rpc.RpcException;
import com.google.gapid.rpc.UiCallback;
import com.google.gapid.server.Client;
import com.google.gapid.util.Events;
import com.google.gapid.util.Loadable;
import com.google.gapid.util.MoreFutures;
import com.google.gapid.util.Paths;

import org.eclipse.swt.widgets.Shell;

import java.util.concurrent.ExecutionException;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Logger;

/**
 * Model containing the API commands of the capture.
 */
public class CommandStream
    extends DeviceDependentModel.ForPath<CommandStream.Node, Void, CommandStream.Listener>
    implements ApiContext.Listener, Capture.Listener, Devices.Listener {
  protected static final Logger LOG = Logger.getLogger(CommandStream.class.getName());

  private final Capture capture;
  private final ApiContext context;
  private final ConstantSets constants;
  private CommandIndex selection;

  public CommandStream(Shell shell, Analytics analytics, Client client, Capture capture,
      Devices devices, ApiContext context, ConstantSets constants) {
    super(LOG, shell, analytics, client, Listener.class, devices);
    this.capture = capture;
    this.context = context;
    this.constants = constants;

    capture.addListener(this);
    devices.addListener(this);
    context.addListener(this);
  }

  @Override
  public void onCaptureLoadingStart(boolean maintainState) {
    if (!maintainState) {
      selection = null;
    }
    reset();
  }

  @Override
  public void onCaptureLoaded(Loadable.Message error) {
    if (error == null && selection != null) {
      selection = selection.withCapture(capture.getData().path);
      if (isLoaded()) {
        resolve(selection.getCommand(), node -> selectCommands(selection.withNode(node), true));
      }
    }
  }

  @Override
  public void onReplayDeviceChanged(Instance dev) {
    if (selection != null && selection.getNode() != null) {
      // Clear the node, so the selection will be re-resolved once the context has updated.
      selection = selection.withNode(null);
    }
  }

  @Override
  public void onContextsLoaded() {
    onContextSelected(context.getSelectedContext());
  }

  @Override
  public void onContextSelected(FilteringContext ctx) {
    if (selection != null && selection.getNode() != null) {
      // Clear the node, so the selection will be re-resolved once the context has updated.
      selection = selection.withNode(null);
    }
    load(commandTree(capture.getData().path, ctx), false);
  }

  @Override
  protected ListenableFuture<Node> doLoad(Path.Any path, Path.Device device) {
    return MoreFutures.transformAsync(client.get(path, device),
        tree -> MoreFutures.transform(client.get(commandTree(tree.getCommandTree().getRoot()), device),
            val -> new RootNode(
                device, tree.getCommandTree().getRoot().getTree(), val.getCommandTreeNode())));
  }

  public ListenableFuture<Node> load(Node node) {
    return node.load(shell, () -> MoreFutures.transformAsync(
        client.get(commandTree(node.getPath(Path.CommandTreeNode.newBuilder())), node.device),
        v1 -> {
          Service.CommandTreeNode data = v1.getCommandTreeNode();
          if (data.getGroup().isEmpty() && data.hasCommands()) {
            return MoreFutures.transform(loadCommand(lastCommand(data.getCommands()), node.device),
                cmd -> new NodeData(data, cmd));
          }
          return Futures.immediateFuture(new NodeData(data, null));
        }));
  }

  public ListenableFuture<API.Command> loadCommand(Path.Command path, Path.Device device) {
    return MoreFutures.transformAsync(client.get(command(path), device), value ->
        MoreFutures.transform(constants.loadConstants(value.getCommand()), ignore ->
            value.getCommand()));
  }

  public void load(Node node, Runnable callback) {
    ListenableFuture<Node> future = load(node);
    if (future != null) {
      Rpc.listen(future, new UiCallback<Node, Node>(shell, LOG) {
        @Override
        protected Node onRpcThread(Rpc.Result<Node> result)
            throws RpcException, ExecutionException {
          return result.get();
        }

        @Override
        protected void onUiThread(Node result) {
          callback.run();
        }
      });
    }
  }

  public ListenableFuture<Service.FindResponse> search(
      CommandStream.Node parent, String text, boolean regex) {
    SettableFuture<Service.FindResponse> result = SettableFuture.create();
    client.streamSearch(searchRequest(parent, text, regex), result::set);
    return result;
  }

  private static Service.FindRequest searchRequest(
      CommandStream.Node parent, String text, boolean regex) {
    return Service.FindRequest.newBuilder()
        .setCommandTreeNode(parent.getPath(Path.CommandTreeNode.newBuilder()))
        .setText(text)
        .setIsRegex(regex)
        .setMaxItems(1)
        .setWrap(true)
        .setConfig(Path.ResolveConfig.newBuilder()
            .setReplayDevice(parent.device))
        .build();
  }

  @Override
  protected void fireLoadStartEvent() {
    listeners.fire().onCommandsLoadingStart();
  }

  @Override
  protected void fireLoadedEvent() {
    listeners.fire().onCommandsLoaded();
    if (selection != null) {
      selectCommands(selection, true);
    }
  }

  public CommandIndex getSelectedCommands() {
    return (selection != null && selection.getNode() != null) ? selection : null;
  }

  public void selectCommands(CommandIndex index, boolean force) {
    if (!force && Objects.equal(selection, index)) {
      return;
    } else if (!isLoaded()) {
      this.selection = index;
      return;
    }

    RootNode root = (RootNode)getData();
    if (index.getNode() == null) {
      resolve(index.getCommand(), node -> selectCommands(index.withNode(node), force));
    } else if (!index.getNode().getTree().equals(root.tree)) {
      // TODO
      throw new UnsupportedOperationException("This is not yet supported, needs API clarification");
    } else {
      selection = index;
      listeners.fire().onCommandsSelected(selection);
    }
  }

  private void resolve(Path.Command command, Consumer<Path.CommandTreeNode> cb) {
    RootNode root = (RootNode)getData();
    Rpc.listen(client.get(commandTree(root.tree, command), root.device),
        new UiCallback<Service.Value, Path.CommandTreeNode>(shell, LOG) {
      @Override
      protected Path.CommandTreeNode onRpcThread(Rpc.Result<Service.Value> result)
          throws RpcException, ExecutionException {
        Service.Value value = result.get();
        LOG.log(FINE, "Resolved selection to {0}", value);
        return value.getPath().getCommandTreeNode();
      }

      @Override
      protected void onUiThread(Path.CommandTreeNode result) {
        cb.accept(result);
      }
    });
  }

  public ListenableFuture<Service.Memory> getMemory(Path.Device device, CommandIndex index) {
    return MoreFutures.transform(
        client.get(observationsAfter(index, Application_VALUE), device), v -> {
          return v.getMemory();
        });
  }

  /**
   * An index into the command stream, representing a specific "point in time" in the trace.
   */
  public static class CommandIndex implements Comparable<CommandIndex> {
    private final Path.Command command;
    private final Path.CommandTreeNode node;
    private final boolean group;

    private CommandIndex(Path.Command command, Path.CommandTreeNode node, boolean group) {
      this.command = command;
      this.node = node;
      this.group = group;
    }

    /**
     * Create an index pointing to the given command and node.
     */
    public static CommandIndex forNode(Path.Command command, Path.CommandTreeNode node) {
      return new CommandIndex(command, node, false);
    }

    /**
     * Create an index pointing to the given command, without knowing the tree node.
     * The tree nodes is then resolved when it is needed.
     */
    public static CommandIndex forCommand(Path.Command command) {
      return new CommandIndex(command, null, false);
    }

    /**
     * Same as {@link #forCommand}, except that group selection is to be preferred when
     * resolving to a tree node.
     */
    public static CommandIndex forGroup(Path.Command command) {
      return new CommandIndex(command, null, true);
    }

    public CommandIndex withNode(Path.CommandTreeNode newNode) {
      return new CommandIndex(command, newNode, group);
    }

    public CommandIndex withCapture(Path.Capture capture) {
      return new CommandIndex(command.toBuilder().setCapture(capture).build(), null, group);
    }

    public Path.Command getCommand() {
      return command;
    }

    public Path.CommandTreeNode getNode() {
      return node;
    }

    public boolean isGroup() {
      return group;
    }

    @Override
    public String toString() {
      return command.getIndicesList().toString();
    }

    @Override
    public int hashCode() {
      return command.getIndicesList().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      } else if (!(obj instanceof CommandIndex)) {
        return false;
      }
      return command.getIndicesList().equals(((CommandIndex)obj).command.getIndicesList());
    }

    @Override
    public int compareTo(CommandIndex o) {
      return Paths.compare(command, o.command);
    }
  }

  public static class Node extends DeviceDependentModel.Data {
    private final Node parent;
    private final int index;
    private Node[] children;
    private Service.CommandTreeNode data;
    private API.Command command;
    private ListenableFuture<Node> loadFuture;

    public Node(Path.Device device, Service.CommandTreeNode data) {
      super(device);
      this.parent = null;
      this.index = 0;
      this.data = data;
    }

    public Node(Node parent, int index) {
      super(parent.device);
      this.parent = parent;
      this.index = index;
    }

    public Node getParent() {
      return parent;
    }

    public int getChildCount() {
      return (data == null) ? 0 : (int)data.getNumChildren();
    }

    public Node getChild(int child) {
      return getOrCreateChildren()[child];
    }

    public Node[] getChildren() {
      return getOrCreateChildren().clone();
    }

    private Node[] getOrCreateChildren() {
      if (children == null) {
        Preconditions.checkState(data != null, "Querying children before loaded");
        children = new Node[(int)data.getNumChildren()];
        for (int i = 0; i < children.length; i++) {
          children[i] = new Node(this, i);
        }
      }
      return children;
    }

    public boolean isLastChild() {
      return parent == null || (parent.getChildCount() - 1 == index);
    }

    public Service.CommandTreeNode getData() {
      return data;
    }

    public API.Command getCommand() {
      return command;
    }

    public Path.CommandTreeNode.Builder getPath(Path.CommandTreeNode.Builder path) {
      return parent.getPath(path).addIndices(index);
    }

    public CommandIndex getIndex() {
      return (data == null) ? null : CommandIndex.forNode(data.getRepresentation(),
          getPath(Path.CommandTreeNode.newBuilder()).build());
    }

    public ListenableFuture<Node> load(Shell shell, Supplier<ListenableFuture<NodeData>> loader) {
      if (data != null) {
        // Already loaded.
        return null;
      } else if (loadFuture != null && !loadFuture.isCancelled()) {
        return loadFuture;
      }

      return loadFuture = MoreFutures.transformAsync(loader.get(), newData ->
        submitIfNotDisposed(shell, () -> {
          data = newData.data;
          command = newData.command;
          loadFuture = null; // Don't hang on to listeners.
          return Node.this;
        }));
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      } else if (!(obj instanceof Node)) {
        return false;
      }
      Node n = (Node)obj;
      return index == n.index && parent.equals(n.parent);
    }

    @Override
    public int hashCode() {
      return parent.hashCode() * 31 + index;
    }

    @Override
    public String toString() {
      return parent + "/" + index +
          (data == null ? "" : " " + data.getGroup() + data.getCommands().getToList());
    }
  }

  private static class RootNode extends Node {
    public final Path.ID tree;

    public RootNode(Path.Device device, Path.ID tree, Service.CommandTreeNode data) {
      super(device, data);
      this.tree = tree;
    }

    @Override
    public Path.CommandTreeNode.Builder getPath(Path.CommandTreeNode.Builder path) {
      return path.setTree(tree);
    }

    @Override
    public String toString() {
      return "Root";
    }

    @Override
    public boolean equals(Object obj) {
      if (obj == this) {
        return true;
      } else if (!(obj instanceof RootNode)) {
        return false;
      }
      RootNode n = (RootNode)obj;
      return device.equals(n.device) && tree.equals(n.tree);
    }

    @Override
    public int hashCode() {
      return device.hashCode() * 31 + tree.hashCode();
    }
  }

  private static class NodeData {
    public final Service.CommandTreeNode data;
    public final API.Command command;

    public NodeData(Service.CommandTreeNode data, API.Command command) {
      this.data = data;
      this.command = command;
    }
  }

  public interface Listener extends Events.Listener {
    /**
     * Event indicating that the tree root has changed and is being loaded.
     */
    public default void onCommandsLoadingStart() { /* emtpy */ }

    /**
     * Event indicating that the tree root has finished loading.
     */
    public default void onCommandsLoaded() { /* empty */ }

    /**
     * Event indicating that the currently selected command range has changed.
     */
    @SuppressWarnings("unused")
    public default void onCommandsSelected(CommandIndex selection) { /* empty */ }
  }
}


text:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>R Markdown on Fresh Rots</title>
    <link>https://freshrots.co.za/tags/r-markdown/</link>
    <description>Recent content in R Markdown on Fresh Rots</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>&copy; 2017 Morgan Brand</copyright>
    <lastBuildDate>Fri, 08 Sep 2017 00:00:00 +0000</lastBuildDate>

	<atom:link href="https://freshrots.co.za/tags/r-markdown/index.xml" rel="self" type="application/rss+xml" />

    <item>
      <title>Banana Production</title>
      <link>https://freshrots.co.za/project/banana_production/03-bananas/</link>
      <pubDate>Fri, 08 Sep 2017 00:00:00 +0000</pubDate>

      <guid>https://freshrots.co.za/project/banana_production/03-bananas/</guid>
      <description>Introduction to the project Canaan bananas Loading the data Setting date  Investigating by bunch Bunches per month Statistics  Investigating by field Cumulative bunches per field Cumulative weight per field  Production per hectare   Introduction to the project I am now farming bananas and with that I have aquired some farm data. We used a portion of the data from banana production in an introductory workshop for R, RStudio and Github at the World Aquaculture conference in Cape Town.</description>
    </item>

    <item>
      <title>Banana Production</title>
      <link>https://freshrots.co.za/project/banana_production/banana_prod/</link>
      <pubDate>Fri, 08 Sep 2017 00:00:00 +0000</pubDate>

      <guid>https://freshrots.co.za/project/banana_production/banana_prod/</guid>
      <description>Introduction to the project Canaan bananas Loading the data Setting date  Investigating by bunch Bunches per month Statistics  Investigating by field Cumulative bunches per field Cumulative weight per field  Production per hectare   Introduction to the project I am now farming bananas and with that I have aquired some farm data. We used a portion of the data from banana production in an introductory workshop for R, RStudio and Github at the World Aquaculture conference in Cape Town.</description>
    </item>

    <item>
      <title>LME</title>
      <link>https://freshrots.co.za/project/phd/lme/</link>
      <pubDate>Fri, 08 Sep 2017 00:00:00 +0000</pubDate>

      <guid>https://freshrots.co.za/project/phd/lme/</guid>
      <description>Why nlme model I have decided to run with the nlme package after spending more time than I wish to recount trying to figure out lmer. My core reasons for this decision are:
 Henning helped me with some of the initial code required to build models lme is able to handle heteroscadasic data in a way that lmer cannot  The analysis will be performed on the raw data found in ~/content/projects/PhD/data/ulva.</description>
    </item>

  </channel>
</rss>


text:
// Copyright 2014 The Rector & Visitors of the University of Virginia
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Xamarin.Forms;

namespace Sensus.UI.Inputs
{
	public class ButtonGridView : Grid
	{
		protected readonly List<ButtonWithValue> _buttons;

		public ButtonGridView(int columnCount, EventHandler defaultClickEvent) : base()
		{
			_buttons = new List<ButtonWithValue>();

			ColumnCount = columnCount;

			if (defaultClickEvent != null)
			{
				DefaultClickEvent = defaultClickEvent;
			}
		}

		public ButtonGridView() : this(1, null)
		{

		}

		public int ColumnCount { get; private set; }

		public EventHandler DefaultClickEvent { get; set; }

		public ButtonWithValue AddButton(string text, string value)
		{
			return AddButton(text, value, null);
		}
		public ButtonWithValue AddButton(string text, string value, EventHandler clicked)
		{
			ButtonWithValue button = new ButtonWithValue
			{
				Text = text,
				Value = value
			};

			if (AutoSize)
			{
				button.HeightRequest = -1;
			}

			if (DefaultClickEvent != null)
			{
				button.Clicked += DefaultClickEvent;
			}

			if (clicked != null)
			{
				button.Clicked += clicked;
			}

			_buttons.Add(button);

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color)
		{
			ButtonWithValue button = AddButton(text, value, null);

			button.BackgroundColor = color;

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color, Color textColor)
		{
			ButtonWithValue button = AddButton(text, value, null);

			button.BackgroundColor = color;
			button.TextColor = textColor;

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color, Color textColor, Color borderColor)
		{
			ButtonWithValue button = AddButton(text, value, null);

			button.BackgroundColor = color;
			button.TextColor = textColor;
			button.BorderColor = borderColor;

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color, EventHandler clicked)
		{
			ButtonWithValue button = AddButton(text, value, clicked);

			button.BackgroundColor = color;

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color, EventHandler clicked, Color textColor)
		{
			ButtonWithValue button = AddButton(text, value, clicked);

			button.BackgroundColor = color;
			button.TextColor = textColor;

			return button;
		}
		public ButtonWithValue AddButton(string text, string value, Color color, EventHandler clicked, Color textColor, Color borderColor)
		{
			ButtonWithValue button = AddButton(text, value, clicked);

			button.BackgroundColor = color;
			button.TextColor = textColor;
			button.BorderColor = borderColor;

			return button;
		}

		public IEnumerable<ButtonWithValue> Buttons => _buttons.ToArray();

		public bool AutoSize { get; set; }

		protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
		{
			if (propertyName == nameof(IsEnabled))
			{
				foreach (ButtonWithValue button in _buttons)
				{
					button.IsEnabled = IsEnabled;
				}
			}

			base.OnPropertyChanged(propertyName);
		}

		public void Arrange()
		{
			ColumnDefinitions.Clear();
			RowDefinitions.Clear();
			Children.Clear();

			int columnCount = ColumnCount;

			if (columnCount <= 0 || _buttons.Count < columnCount)
			{
				columnCount = _buttons.Count;
			}

			for (int column = 0; column < columnCount; column++)
			{
				ColumnDefinitions.Add(new ColumnDefinition());
			}

			int rowCount = (int)Math.Ceiling((double)_buttons.Count / columnCount);

			for (int row = 0; row < rowCount; row++)
			{
				RowDefinitions.Add(new RowDefinition());
			}

			for(int button = 0; button < _buttons.Count; button++)
			{
				Children.Add(_buttons[button], button % columnCount, button / columnCount);
			}
		}
	}
}


text:
package badger

import (
	"sync"
	"sync/atomic"

	"github.com/dgraph-io/badger/v3/pb"
	"github.com/dgraph-io/badger/v3/trie"
	"github.com/dgraph-io/badger/v3/y"
	"github.com/dgraph-io/ristretto/z"
)

type subscriber struct {
	id        uint64
	matches   []pb.Match
	sendCh    chan *pb.KVList
	subCloser *z.Closer
	// this will be atomic pointer which will be used to
	// track whether the subscriber is active or not
	active *uint64
}

type publisher struct {
	sync.Mutex
	pubCh       chan requests
	subscribers map[uint64]subscriber
	nextID      uint64
	indexer     *trie.Trie
}

func newPublisher() *publisher {
	return &publisher{
		pubCh:       make(chan requests, 1000),
		subscribers: make(map[uint64]subscriber),
		nextID:      0,
		indexer:     trie.NewTrie(),
	}
}

func (p *publisher) listenForUpdates(c *z.Closer) {
	defer func() {
		p.cleanSubscribers()
		c.Done()
	}()
	slurp := func(batch requests) {
		for {
			select {
			case reqs := <-p.pubCh:
				batch = append(batch, reqs...)
			default:
				p.publishUpdates(batch)
				return
			}
		}
	}
	for {
		select {
		case <-c.HasBeenClosed():
			return
		case reqs := <-p.pubCh:
			slurp(reqs)
		}
	}
}

func (p *publisher) publishUpdates(reqs requests) {
	p.Lock()
	defer func() {
		p.Unlock()
		// Release all the request.
		reqs.DecrRef()
	}()
	batchedUpdates := make(map[uint64]*pb.KVList)
	for _, req := range reqs {
		for _, e := range req.Entries {
			ids := p.indexer.Get(e.Key)
			if len(ids) == 0 {
				continue
			}
			k := y.SafeCopy(nil, e.Key)
			kv := &pb.KV{
				Key:       y.ParseKey(k),
				Value:     y.SafeCopy(nil, e.Value),
				Meta:      []byte{e.UserMeta},
				ExpiresAt: e.ExpiresAt,
				Version:   y.ParseTs(k),
			}
			for id := range ids {
				if _, ok := batchedUpdates[id]; !ok {
					batchedUpdates[id] = &pb.KVList{}
				}
				batchedUpdates[id].Kv = append(batchedUpdates[id].Kv, kv)
			}
		}
	}

	for id, kvs := range batchedUpdates {
		if atomic.LoadUint64(p.subscribers[id].active) == 1 {
			p.subscribers[id].sendCh <- kvs
		}
	}
}

func (p *publisher) newSubscriber(c *z.Closer, matches []pb.Match) subscriber {
	p.Lock()
	defer p.Unlock()
	ch := make(chan *pb.KVList, 1000)
	id := p.nextID
	// Increment next ID.
	p.nextID++
	active := uint64(1)
	s := subscriber{
		active:    &active,
		id:        id,
		matches:   matches,
		sendCh:    ch,
		subCloser: c,
	}
	p.subscribers[id] = s
	for _, m := range matches {
		p.indexer.AddMatch(m, id)
	}
	return s
}

// cleanSubscribers stops all the subscribers. Ideally, It should be called while closing DB.
func (p *publisher) cleanSubscribers() {
	p.Lock()
	defer p.Unlock()
	for id, s := range p.subscribers {
		for _, m := range s.matches {
			p.indexer.DeleteMatch(m, id)
		}
		delete(p.subscribers, id)
		s.subCloser.SignalAndWait()
	}
}

func (p *publisher) deleteSubscriber(id uint64) {
	p.Lock()
	defer p.Unlock()
	if s, ok := p.subscribers[id]; ok {
		for _, m := range s.matches {
			p.indexer.DeleteMatch(m, id)
		}
	}
	delete(p.subscribers, id)
}

func (p *publisher) sendUpdates(reqs requests) {
	if p.noOfSubscribers() != 0 {
		reqs.IncrRef()
		p.pubCh <- reqs
	}
}

func (p *publisher) noOfSubscribers() int {
	p.Lock()
	defer p.Unlock()
	return len(p.subscribers)
}


text:
First

Previous

1

2

3

4

Next

Last


text:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ExactOnline.Client.Sdk.UserAcceptanceTests.UserLevel
{
	[TestClass]
	public class UpdateAccountAutomatically184246
	{
		[TestMethod, Ignore]
		[TestCategory("User Acceptance Tests")]
		public void UpdateAccountAutomatically()
		{
			//var toc = new TestObjectsCreator();
			//APIConnection conn = new APIConnection(toc.ApiConnector(), toc.UriCrmAccount());
			//Controller ac = new Controller(conn);

			//// Get Account from EOL to alter
			//var accounts = ac.Get("Name+eq+'Test Name UAT2'");
			//var testAccount = (Account)accounts[0];
			//Guid testAccountGuid = testAccount.ID;

			//// Alter name of the testaccount
			//testAccount.Name = "Test Name Auto Update";
			//System.Threading.Thread.Sleep(5000); // In this time the controller must update the entity itself

			//var updatedAccount = (Account)ac.GetEntity(testAccountGuid.ToString());
			//if (!updatedAccount.Name.Equals("Test Name Auto Update"))
			//{
			//	throw new Exception("The Account is not automatically updated");
			//}

			throw new Exception("This functionality is not implemented yet");
		}
	}
}


text:
package main

import (
	"math/rand"
)

type BotStarter struct{}

func (bs *BotStarter) GetMove(state *BotState, timeout int) *Move {
	state.Timebank = timeout

	moves := state.AvailableMoves()
	moveCount := len(moves)

	if moveCount <= 0 {
		return nil
	} else {
		return moves[rand.Intn(moveCount)]
	}
}


text:
package com.mikepenz.actionitembadge.library;

import android.app.Activity;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.view.Display;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.mikepenz.actionitembadge.library.utils.BadgeDrawableBuilder;
import com.mikepenz.actionitembadge.library.utils.BadgeStyle;
import com.mikepenz.actionitembadge.library.utils.UIUtil;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.iconics.typeface.IIcon;

/**
 * Created by mikepenz on 23.07.14.
 */
public class ActionItemBadge {
    public enum BadgeStyles {
        GREY(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#e0e0e0"), Color.parseColor("#c7c7c7"), Color.BLACK)),
        DARK_GREY(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#606060"), Color.parseColor("#3e3e3e"), Color.WHITE)),
        RED(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#FF4444"), Color.parseColor("#CC0000"), Color.WHITE)),
        BLUE(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#33B5E5"), Color.parseColor("#0099CC"), Color.WHITE)),
        GREEN(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#99CC00"), Color.parseColor("#669900"), Color.WHITE)),
        PURPLE(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#AA66CC"), Color.parseColor("#9933CC"), Color.WHITE)),
        YELLOW(new BadgeStyle(BadgeStyle.Style.DEFAULT, R.layout.menu_action_item_badge, Color.parseColor("#FFBB33"), Color.parseColor("#FF8800"), Color.WHITE)),
        GREY_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#e0e0e0"), Color.parseColor("#c7c7c7"), Color.BLACK)),
        DARK_GREY_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#606060"), Color.parseColor("#3e3e3e"), Color.WHITE)),
        RED_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#FF4444"), Color.parseColor("#CC0000"), Color.WHITE)),
        BLUE_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#33B5E5"), Color.parseColor("#0099CC"), Color.WHITE)),
        GREEN_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#99CC00"), Color.parseColor("#669900"), Color.WHITE)),
        PURPLE_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#AA66CC"), Color.parseColor("#9933CC"), Color.WHITE)),
        YELLOW_LARGE(new BadgeStyle(BadgeStyle.Style.LARGE, R.layout.menu_action_item_badge_large, Color.parseColor("#FFBB33"), Color.parseColor("#FF8800"), Color.WHITE)),;

        private BadgeStyle style;

        BadgeStyles(BadgeStyle style) {
            this.style = style;
        }

        public BadgeStyle getStyle() {
            return style;
        }
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, int badgeCount) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), BadgeStyles.DARK_GREY.getStyle(), null);
        } else {
            update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), BadgeStyles.DARK_GREY.getStyle(), String.valueOf(badgeCount));
        }
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, String badgeCount) {
        update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), BadgeStyles.DARK_GREY.getStyle(), badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, BadgeStyles style, int badgeCount) {
        update(act, menu, icon, style.getStyle(), badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, BadgeStyle style, int badgeCount) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), style, null);
        } else {
            update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), style, String.valueOf(badgeCount));
        }
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, BadgeStyle style, String badgeCount) {
        update(act, menu, new IconicsDrawable(act, icon).color(Color.WHITE).actionBar(), style, badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, int iconColor, int badgeCount) {
        update(act, menu, icon, iconColor, BadgeStyles.DARK_GREY.getStyle(), badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, int iconColor, BadgeStyles style, int badgeCount) {
        update(act, menu, icon, iconColor, style.getStyle(), badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, int iconColor, BadgeStyle style, int badgeCount) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(act, menu, new IconicsDrawable(act, icon).color(iconColor).actionBar(), style, null);
        } else {
            update(act, menu, new IconicsDrawable(act, icon).color(iconColor).actionBar(), style, String.valueOf(badgeCount));
        }
    }

    public static void update(final Activity act, final MenuItem menu, IIcon icon, int iconColor, BadgeStyle style, String badgeCount) {
        update(act, menu, new IconicsDrawable(act, icon).color(iconColor).actionBar(), style, badgeCount);
    }

    public static void update(final Activity act, final MenuItem menu, Drawable icon, BadgeStyles style, int badgeCount) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(act, menu, icon, style.getStyle(), null);
        } else {
            update(act, menu, icon, style.getStyle(), String.valueOf(badgeCount));
        }
    }

    public static void update(final Activity act, final MenuItem menu, Drawable icon, BadgeStyles style, String badgeCount) {
        update(act, menu, icon, style.getStyle(), badgeCount);
    }

    public static void update(final MenuItem menu, int badgeCount) {
        update(menu, null, badgeCount);
    }

    public static void update(final MenuItem menu, String badgeCount) {
        update(menu, null, badgeCount);
    }

    public static void update(final MenuItem menu, Drawable icon, int badgeCount) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(null, menu, icon, (BadgeStyle) null, null);
        } else {
            update(null, menu, icon, (BadgeStyle) null, String.valueOf(badgeCount));
        }
    }

    public static void update(final MenuItem menu, Drawable icon, String badgeCount) {
        update(null, menu, icon, (BadgeStyle) null, badgeCount);

    }

    public static void update(final Activity activity, final MenuItem menu, Drawable icon, BadgeStyle style, int badgeCount) {
        update (activity, menu, icon, style, badgeCount, null);
    }

    public static void update(final Activity activity, final MenuItem menu, Drawable icon, BadgeStyle style, int badgeCount, ActionItemBadgeListener listener) {
        if (badgeCount == Integer.MIN_VALUE) {
            update(activity, menu, icon, style, null, listener);
        } else {
            update(activity, menu, icon, style, String.valueOf(badgeCount), listener);
        }
    }

    /**
     * update the given menu item with icon, badgeCount and style
     *
     * @param activity   use to bind onOptionsItemSelected
     * @param menu
     * @param icon
     * @param style
     * @param badgeCount
     */
    public static void update(final Activity activity, final MenuItem menu, Drawable icon, BadgeStyle style, String badgeCount) {
        update(activity, menu, icon, style, badgeCount, null);
    }

    /**
     * update the given menu item with icon, badgeCount and style
     *
     * @param activity   use to bind onOptionsItemSelected / and to display the toast
     * @param menu
     * @param icon
     * @param style
     * @param badgeCount
     * @param listener
     */
    public static void update(final Activity activity, final MenuItem menu, Drawable icon, BadgeStyle style, String badgeCount, final ActionItemBadgeListener listener) {
        if (menu == null) return;

        FrameLayout badge;
        TextView badgeView;
        ImageView imageView;

        if (style == null) {
            badge = (FrameLayout) menu.getActionView();
        } else {
            badge = (FrameLayout) menu.setActionView(style.getLayout()).getActionView();
        }

        badgeView = (TextView) badge.findViewById(R.id.menu_badge);
        imageView = (ImageView) badge.findViewById(R.id.menu_badge_icon);

        //Display icon in ImageView
        if (imageView != null && icon != null) {
            imageView.setImageDrawable(icon);
        }

        //Bind onOptionsItemSelected to the activity
        if (activity != null) {
            badge.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    boolean consumed = false;
                    if (listener != null) {
                        consumed = listener.onOptionsItemSelected(menu);
                    }
                    if (!consumed) {
                        activity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, menu);
                    }
                }
            });

            badge.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View v) {
                    Display display = activity.getWindowManager().getDefaultDisplay();
                    Point size = new Point();
                    display.getSize(size);
                    int width = size.x;
                    Toast toast = Toast.makeText(activity, menu.getTitle(), Toast.LENGTH_SHORT);
                    toast.setGravity(Gravity.TOP, width / 5, UIUtil.convertDpToPx(activity, 48)); //your width and height
                    toast.show();
                    return true;
                }
            });
        }

        //Apply style if it's set
        if (style != null) {
            UIUtil.setBackground(badgeView, new BadgeDrawableBuilder().corners(style.getCorner()).color(style.getColor()).colorPressed(style.getColorPressed()).strokeColor(style.getStrokeColor()).stroke(style.getStroke()).build(activity));
            badgeView.setTextColor(style.getTextColor());
        }

        //Manage min value
        if (badgeCount == null) {
            badgeView.setVisibility(View.GONE);
        } else {
            badgeView.setVisibility(View.VISIBLE);
            badgeView.setText(badgeCount);
        }

        menu.setVisible(true);
    }

    /**
     * hide the given menu item
     *
     * @param menu
     */
    public static void hide(MenuItem menu) {
        menu.setVisible(false);
    }

    public interface ActionItemBadgeListener {
        boolean onOptionsItemSelected(MenuItem menu);
    }
}


text:
Installs `traceroute` The `traceroute` utility displays the route used by IP packets on their way to a specified network (or Internet) host.

# REQUIREMENTS

## Supported Platforms

The following platforms are supported by this cookbook, meaning that the recipes run on these platforms without error:

* Ubuntu
* Debian

# RECIPES

* `traceroute` - The default recipe.

# USAGE

This cookbook installs the traceroute components if not present, and pulls updates if they are installed on the system.

# ATTRIBUTES

None

## Basic Settings

None

## Contributing

1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Added some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

## License

**chef-traceroute**

* Freely distributable and licensed under the [MIT license](http://phlipper.mit-license.org/2012/license.html).
* Copyright (c) 2012 Phil Cohen (github@phlippers.net) [![endorse](http://api.coderwall.com/phlipper/endorsecount.png)](http://coderwall.com/phlipper)
* http://phlippers.net/


text:
import { Pipe, Type } from '@angular/core';
import { CompileReflector } from './compile_reflector';
/**
 * Resolve a `Type` for {@link Pipe}.
 *
 * This interface can be overridden by the application developer to create custom behavior.
 *
 * See {@link Compiler}
 */
export declare class PipeResolver {
    private _reflector;
    constructor(_reflector: CompileReflector);
    isPipe(type: Type<any>): boolean;
    /**
     * Return {@link Pipe} for a given `Type`.
     */
    resolve(type: Type<any>, throwIfNotFound?: boolean): Pipe | null;
}


text:
module T7145a ( Applicative(pure) ) where

import Control.Applicative ( Applicative(pure) )


text:
describe('pdiffy', function(){
	this.timeout(5000); // Set 5s timeout on all these async tests

	describe('#compareTo() on identical images', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_original).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_original).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.00");
				done();
			});
		})
	})

	describe('original #compareTo() missing link', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_about_link_missing).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should NOT return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_about_link_missing).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.04");
				done();
			});
		})
	})

	describe('original #compareTo() transparency over missing link', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_about_link_transparent).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_original).compareTo(testdata.google_about_link_transparent).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.00");
				done();
			});
		})
	})

	describe('transparency over missing link #compareTo() original', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_about_link_transparent).compareTo(testdata.google_original).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_about_link_transparent).compareTo(testdata.google_original).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.00");
				done();
			});
		})
	})

	describe('transparency over missing link #compareTo() missing link', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_about_link_transparent).compareTo(testdata.google_about_link_missing).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_about_link_transparent).compareTo(testdata.google_about_link_missing).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.00");
				done();
			});
		})
	})

	describe('missing link #compareTo() transparency over missing link', function(){
		it('should return true on data.isSameDimensions', function(done){
			pdiffy(testdata.google_about_link_missing).compareTo(testdata.google_about_link_transparent).onComplete(function(data) {
				expect(data.isSameDimensions).to.equal(true);
				done();
			});
		})
		it('should return 0.00 on data.misMatchPercentage', function(done){
			pdiffy(testdata.google_about_link_missing).compareTo(testdata.google_about_link_transparent).onComplete(function(data) {
				expect(data.misMatchPercentage).to.equal("0.00");
				done();
			});
		})
	})

	// missing e in 'Google' test
	// data.getImageDataUrl() comparisons
})


text:
'use strict';

var express = require('express'),
    request = require('supertest'),
    server = require('../../../server/server'),
    should = require('should'),
    fuzzer = require('fuzzer'),
    otFuzzer = require('ot-fuzzer'),
    EmergencyContact = require('../../../server/models/emergencyContact');

    describe('Ranks', function() {
        var app;

        before(function(beforeDone) {

            if (server.app) {
                app = server.app;
                fuzzer.seed(0);
                return beforeDone();
            }

            server.run(function(server) {

                app = server;
                beforeDone();

            }, {
                useDb: 'test',
                mode: 'test',
                initialize: true
            });

        });

        var cookie = null;

        describe('login to application', function(loginToApplicationDone) {
            it('should login successfully', function(shouldLoginSuccessfullyDone) {
                request(app)
                    .post('/login')
                    .send({
                        username: 'administrator',
                        password: 'password'
                    })
                    .expect(function(res) {
                        console.log(res.headers['set-cookie']);
                        cookie = res.headers['set-cookie'];
                    })
                    .expect(200, shouldLoginSuccessfullyDone);
            });

        });

        var classes = [];
        var rank;
        describe('Post Data', function(postDone){
            it('should post rank', function(rankPostDone){
                    request(app)
                    .post('/api/ranks')
                    .send({
                        rankOrder: otFuzzer.randomInt(Number.MAX_VALUE),
                        name: otFuzzer.randomWord(),
                    })
                    .set('Accept', 'application/json')
                    .set('Cookie', cookie)
                    .set('Content-Type', 'application/json')
                    .expect(function(res){
                        rank = res.body;
                    })
                    .expect(201,rankPostDone)
                });
        });

        describe('CRUD ranks', function() {

            describe('Create a rank', function() {

                it('should have a valid name', function(nameDone) {
                    request(app)
                        request(app)
                        .get('/api/ranks/'+rank._id)
                        .set('Accept', 'application/json')
                        .set('Cookie', cookie)
                        .set('Content-Type', 'application/json')
                        .expect(function(res) {
                            res.body.name.should.be.type('string');
                            res.body.name.should.match(/[a-zA-Z0-9]/);
                            res.body.name.should.not.match(/[!@#$%^&*()_+={},.<>|?`~]/);
                            res.body.name.length.should.not.be.below(2);
                            res.body.name.length.should.not.be.above(64);
                            res.body.name.should.match(rank.name);
                        })
                        .expect(200, nameDone);
                });

                it('should have a valid rank order', function(orderDone) {
                    request(app)
                        request(app)
                        .get('/api/ranks/')
                        .set('Accept', 'application/json')
                        .set('Cookie', cookie)
                        .set('Content-Type', 'application/json')
                        .expect(function(res) {
                            var orders = new Set()
                            for(var r in res.body){
                                orders.has(r.rankOrder).should.be.false;
                                r.rankOrder.should.be.above(0);
                                orders.add(r.rankOrder);
                            }
                        })
                        .expect(200, orderDone);
                });
            });

            describe('Read a rank from the database', function() {
                it('should be that url_id matches ranks_id', function(readDone) {
                    request(app)
                        .get('/api/ranks/'+rank._id)
                        .set('Accept', 'application/json')
                        .set('Cookie', cookie)
                        .set('Content-Type', 'application/json')
                        .expect(function(res) {
                            res.body._id.should.match(rank._id);
                        })
                        .expect(200, readDone);
                });
            });

            describe('Update an existing rank', function() {
                it('should change ranks order', function(orderDone){
                    request(app)
                        .get('/api/ranks'+rank._id)
                        .put({
                            rankOrder: otFuzzer.randomInt(Number.MAX_VALUE)
                        })
                        .expect(function(res){
                            res.body.rankOrder.should.not.match(rank.rankOrder);
                        })
                        .expect(201,orderDone);
                });
            });

            describe('List all ranks', function(listDone){
                    it('should be a list', function(shouldListDone) {
                        request(app)
                            .get('/api/ranks')
                            .set('Accept', 'application/json')
                            .set('Cookie', cookie)
                            .set('Content-Type', 'application/json')
                            .expect(function(res) {
                                (res.body instanceof Array).should.be.true;
                            })
                            .expect(200, shouldListDone);
                    });
                });

            describe('Delete an existing rank', function() {
                it('should be that url_id has no matching rank_id', function(deleteDone) {
                    request(app)
                        .delete('/api/ranks/'+rank._id)
                        .set('Accept', 'application/json')
                        .set('Cookie', cookie)
                        .set('Content-Type', 'application/json')
                        .expect(function(res) {
                            rank._id.should.not.match(res.body._id);
                        })
                        .expect(200, deleteDone);
                    });
            });

        });
    });


text:
@interface CALayer (Border)

// Interface builder does not allow to pass CGColor, so need to make proxy property for using in IB, in runtime attributes when setting border color
@property (nonatomic, strong) UIColor *borderUIColor;

@end


text:
package yacc.entity;

import java.util.*;

public class Symbols {
    private HashSet<Integer> terminalIndexes, nonTerminalIndexes;
    private HashMap<String, Integer> symbols;
    private HashMap<Integer, String> invertedSymbols;
    private int indexes;
    final static private int START_AUG = -3;
    final static private int END = -2;
    final static private int ERROR = -1;

    public Symbols() {
        terminalIndexes = new HashSet<>();
        nonTerminalIndexes = new HashSet<>();
        symbols = new HashMap<>();
        invertedSymbols = new HashMap<>();
        indexes = 257;
    }

    public int addTerminal(String terminal) {
        return addSymbol(terminalIndexes, terminal, indexes++);
    }

    private int addSymbol(HashSet<Integer> symbolIndexes_, String symbol, int idx) {
        if (!symbols.containsKey(symbol)) {
            symbolIndexes_.add(idx);
            symbols.put(symbol, idx);
            invertedSymbols.put(idx, symbol);
            return idx;
        }
        return -1;
    }

    public int addNonTerminal(String nonTerminal) {
        return addSymbol(nonTerminalIndexes, nonTerminal, indexes++);
    }

    public int addChar(char ch) {
        return addSymbol(terminalIndexes, String.valueOf(ch), (int) ch);
    }

    // TODO? end
    public boolean isTerminal(int symbolIndex) {
        return terminalIndexes.contains(symbolIndex);
    }

    // TODO? START_AUG
    boolean isNonTerminal(int symbolIndex) {
        return nonTerminalIndexes.contains(symbolIndex);
    }

    public boolean contains(String symbol) {
        return symbols.containsKey(symbol);
    }

    public int getStartAug() {
        return START_AUG;
    }

    public int getEnd() {
        return END;
    }

    public int getError() {
        return ERROR;
    }

    public int getSymbolIndex(String symbol) {
        return symbols.get(symbol);
    }

    public String getInvertedSymbol(int index) {
        return invertedSymbols.get(index);
    }

    public Set<Integer> getTerminalIndexes() {
        return terminalIndexes;
    }

    public Set<Integer> getNonTerminalIndexes() {
        return nonTerminalIndexes;
    }

    public Collection<Integer> getSymbolIndexes() {
        return symbols.values();
    }

    public Map<String, Integer> getSymbols() {
        return symbols;
    }

    public Map<Integer, String> getInvertedSymbols() {
        return invertedSymbols;
    }
}


text:
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE PolyKinds            #-}
{-# LANGUAGE ScopedTypeVariables  #-}
{-# LANGUAGE UndecidableInstances #-}

module Type.Show where

import Prelude
import Data.Typeable
import Data.Monoid
import GHC.TypeLits
import Text.Show.Pretty (ppValue, parseValue)
import Text.PrettyPrint (Doc, text)
import GHC.Exts         (Constraint)

--showType :: Typeable a => a -> String
--showType (a :: a) = showProxyType (Proxy :: Proxy a)

--showProxyType :: Typeable (Proxy a) => Proxy a -> String
--showProxyType = clear . drop 6 . show . typeOf where
--    clear = \case ('(':s)     -> init  s
--                  ('*':' ':s) -> clear s -- PolyKinded Proxies are shown as "Proxy *"
--                  s           -> s

class TypeShow a where showType :: Proxy (a :: k) -> String

printType :: TypeShow a => Proxy a -> IO ()
printType = putStrLn . showType

ppPrintType :: TypeShow a => Proxy a -> IO ()
ppPrintType = putStrLn . ppShowType

ppShowType :: TypeShow a => Proxy a -> String
ppShowType = show . ppTypeDoc

ppTypeDoc :: TypeShow a => Proxy a -> Doc
ppTypeDoc a = case parseValue txt of
            Just v  -> ppValue v
            Nothing -> text txt
  where txt = showType a

-- === Basic Instances === --

instance KnownNat n               => TypeShow (n :: Nat) where showType _ = show $ natVal (Proxy :: Proxy n)
instance ListElemsShow a          => TypeShow (a :: [k]) where showType _ = "[" <> showListElems (Proxy :: Proxy a) <> "]"
instance (TypeShow a, TypeShow b) => TypeShow '(a,b)     where showType _ = "(" <> showType (Proxy :: Proxy a) <> ", " <> showType (Proxy :: Proxy b) <> ")"

-- === List Helpers === --

class                                                           ListElemsShow a         where showListElems :: Proxy a -> String
instance {-# OVERLAPPABLE #-}                                   ListElemsShow '[]       where showListElems _ = ""
instance {-# OVERLAPPABLE #-}  TypeShow a                    => ListElemsShow '[a]      where showListElems _ = showType (Proxy :: Proxy a)
instance {-# OVERLAPPABLE #-} (TypeShow a, ListElemsShow as) => ListElemsShow (a ': as) where showListElems _ = showType (Proxy :: Proxy a) <> ", " <> showListElems (Proxy :: Proxy as)


text:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">

	<link rel="icon" href="favicon.ico">
	<title>Relay Alert</title>

  <link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">

	<link href="css/control.css" rel="stylesheet">

          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            Toggle navigation

          </button>
          Smart Relay

Data

Control

CSV Dump

Alert Settings

Cut-off Settings

Email Alert Settings

Adjust values for when you will receive an email alert.
First box is lower threshold second box is upper.

			<form method="post" action="/setup2">

						Voltage:
						<input type="number" class="form-control" name="voltage_l" placeholder={{ voltage_l }}>

						Voltage Upper
						<input type="number" class="form-control" name="voltage_h" placeholder={{ voltage_h }}>

						Temperature:
						<input type="number" class="form-control" name="temperature_l" placeholder={{ temperature_l }}>

						Temperature Upper
						<input type="number" class="form-control" name="temperature_h" placeholder={{ temperature_h }}>

						Humidity:
						<input type="number" class="form-control" name="humidity_l" placeholder={{ humidity_l }}>

						Humidity Upper
						<input type="number" class="form-control" name="humidity_h" placeholder={{ humidity_h }}>

						Current:
						<input type="number" class="form-control" name="current_l" placeholder={{ current_l }}>

						Current Upper
						<input type="number" class="form-control" name="current_h" placeholder={{ current_h }}>

						Battery Voltage:
						<input type="number" class="form-control" name="battery_voltage_l" placeholder={{ battery_voltage_l }}>

						Battery Voltage Upper
						<input type="number" class="form-control" name="battery_voltage_h" placeholder={{ battery_voltage_h }}>

						Frequency:
						<input type="number" class="form-control" name="frequency_l" placeholder={{ frequency_l }}>

						Frequency Upper
						<input type="number" class="form-control" name="frequency_h" placeholder={{ frequency_h }}>

				<button type="submit" class="btn btn-default">Update Settings</button>
			</form>