text:
Rävinge socken i Halland ingick i Halmstads härad, ingår sedan 1974 i Halmstads kommun i Hallands län och motsvarar från 2016 Rävinge distrikt.

Socknens areal är 17,51 kvadratkilometer, varav 17,33 land. År 2000 fanns här 263 invånare.  Kyrkbyn Rävinge med sockenkyrkan Rävinge kyrka ligger i socknen.

Administrativ historik
Rävinge socken har medeltida ursprung.

Vid kommunreformen 1862 övergick socknens ansvar för de kyrkliga frågorna till Rävinge församling och för de borgerliga frågorna till Rävinge landskommun. Landskommunen inkorporerades 1952 i Getinge landskommun som sedan 1974 uppgick i Halmstads kommun.  Församlingen uppgick 2008 i Getinge-Rävinge församling.

1 januari 2016 inrättades distriktet Rävinge, med samma omfattning som församlingen hade 1999/2000.

Socknen har tillhört fögderier och domsagor enligt Halmstads härad. De indelta båtsmännen tillhörde Södra Hallands första båtsmanskompani.

Geografi
Rävinge socken ligger kring Suseån. Socknen är en slättbygd.

En sätesgård var Bårarps säteri.

Fornlämningar
Från  bronsåldern finns högar och skålgropar.

Befolkningsutveckling
Befolkningen ökade från 492 1810 till 766 1880 varefter den minskade stadigt till 290 1990.

Namnet
Namnet (1447 Räffwynghä) kommer från kyrkbyn. Efterleden är inge, 'inbyggare'. Förleden räv.

Se även
Rävinge församling
Lista över fasta fornminnen i Halmstads kommun#Rävinge

Referenser

Externa länkar

Refvinge socken i Historiskt-geografiskt och statistiskt lexikon öfver Sverige i 7 band, Stockholm 1856-1870

Socknar i Halmstads härad
Indelningar i Halmstads kommun

redpajama_set_name: RedPajamaWikipedia


text:
QTV Channel 11 revamps to GMA News TV
Posted: Monday, February 21, 2011
GMA is set to launch GMA News TV -- its new news channel replacing QTV starting February 28, 2011.
The biggest news on Philippine TV has just arrived – industry leader GMA Network launches GMA News TV on Channel 11. Continuing the tradition of Serbisyong Totoo, GMA News TV will be the window for breaking news, important live coverage, never-before-seen reality formats, documentaries, and investigative programs for a mass audience.
Who would've thought that QTV was losing money, and big money at that, 200 to 300 million pesos from previous years. I honestly thought Studio 23 would die ahead but they did get the rights to air NBA and PBA, so they are now the country's biggest free-TV sports channel.
Checking out their programming lineup shows more pre-recorded shows than live ones. They do have top of the hour news spots every hour but does news move that fast? I have been watching QTV's Balingtanghali for some time and have noticed that most of their news is a repeat of the previous evening's reports. It may end up looking like QTV again but with a different name and brand.
I was even surprised to see The Smiths. A reality show about the family of Pepe Smith ala The Osbournes.Well…I wouldn't want to be updated with their family habits round the clock, I don't know about you..
GMA NEWS TV pioneers in a reality format never before seen in the country. Following the day to day lives of fascinating and colorful personalities over a season, this reality show reveals how the famous really live. For season 1, take a peek into the life of the King of Pinoy Rock Pepe Smith as our cameras follow him and his unconventional kids 24 hours a day in The Smiths.
Even though their logo looks like Youtube's, I can't argue that GMA News and Public affairs promo videos are always clean and professionally done.
Not everyone is online and constantly being fed information by Twitter or Facebook so this is a bold step by GMA Network to offer a channel that is mainly focused on everything news to the Filipino audience. Good luck GNTV!
http://blogs.gmanews.tv/newstv/
GMA News TV's opening billboards.

redpajama_set_name: RedPajamaCommonCrawl


Two Transition Year students, Rebecca O'Keeffe and Megan D'arcy will represent the school at the BT Young Scientist competition. Under the guidance of the Science Department and in particular their Science teacher, Ms Brady, the two students have compiled an intriguing and extremely relevant project which looks at the drinking culture in Ireland, with a particular focus on underage drinking.
Best of luck to the girls who will present their project this week.


Colorful fruits and other nutritious foods boost wellness during menstruation.
While a healthy diet is always valuable, it is particularly important during your period. Many women experience some level of pain, inflammation, bloating and tiredness during menstruation. While a poor diet that is low in nutrients or high in added sugars or unhealthy fats can worsen these symptoms, a nutritious, balanced diet can help reduce them. Emphasizing certain foods and nutrients may provide exceptional benefits. If your symptoms are severe or long-lasting, seek guidance from your doctor.
Fish and poultry provide rich amounts of protein, which supports blood sugar and appetite control. Fish and skinless, white-meat poultry also provide healthy alternatives to fatty meats, such as steak and fried chicken, which can increase inflammation. The omega-3 fatty acids in cold-water fish, such as salmon, mackerel and albacore tuna, can help reduce inflammation and, potentially, menstrual pain. As iron-rich foods, fish and poultry can help prevent low iron levels. This is important because, according to the Illinois Department of Public Health, women lose an average of 15 to 20 milligrams of iron during menstruation. This amount is more if you bleed heavily. Iron deficiency can cause headaches, dizziness, foggy thinking and fatigue. Chicken liver provides 11 milligrams of iron per 3-ounce serving. Light tuna canned in water and roasted poultry provide roughly 1 to 2 milligrams per 3-ounce serving.
Legumes, such as beans, lentils and split peas, provide valuable amounts of fiber, protein, calcium and antioxidants. The University of Maryland Medical Center recommends eating antioxidant and calcium-rich foods for reduced menstrual pain. Legumes are also rich in iron. Boiled soybeans provide 8.8 milligrams per cup. Cooked lentils provide 6.6 milligrams per cup. Because plant-derived iron is less easily absorbed by your body, pair it with meat or vitamin C-rich foods, such as citrus fruits, which improve absorption. As low-glycemic foods, legumes can also help ensure positive blood sugar and energy levels between meals.
Colorful fruits and vegetables tend to contain significant amounts of antioxidants. Varieties particularly rich in the antioxidant vitamin C include oranges, strawberries, squash, dark leafy greens, bell peppers and tomatoes. Fruits and vegetables also provide fiber and water, which can help reduce bloating and reduce pain. Fruit salads, smoothies and sweet potatoes provide naturally sweet alternatives to sugary sweets, such as candy, which can worsen menstrual pain.
Low-fat dairy products are top sources of calcium and vitamin D. Although findings are mixed, according to the UMMC, calcium may help reduce pain during your period. Vitamin D could help minimize inflammation. Avoid high-fat dairy products, such as whole milk and high-fat cheeses, however, which can have the opposite effect. Nutritious dishes based on low-fat dairy products include smoothies made with fruit and low-fat milk, low-fat yogurt parfaits, and lasagna made with whole grain noodles -- a valuable source of B-vitamins -- lean ground turkey instead of beef, and low-fat cottage cheese instead of high-fat ricotta cheese. If you don't consume or tolerate dairy products, choose soy-based alternatives for similar benefits.


Highview Capital, LLC ("Highview") today announced that it has completed the acquisition of specialized food service distributor Good Source Solutions ("Good Source" or "the Company") from Evergreen Pacific Partners. The investment will drive continued growth for Good Source in partnership with the existing management team, which has decades of experience in food distribution.
Good Source, founded in 1989, provides a broad range of food distribution and product solutions to value-focused end markets including education, corrections, non-profit, business & industry and healthcare.
The Company also provides value-added services such as packaging, labeling and menu planning to address the unique and complex needs of its customers. Good Source has strong relationships with over 500 global, leading food manufacturers, and its sophisticated procurement system links suppliers with over 2,500 customers across the United States. The Company generates over $200 million in revenue annually.


A lifesaver, especially if you've got kids. Even just a little bit of extra room will feel like acres when it comes time to deal with school uniforms, piles of dirty towels or grass-stained Little League jerseys. Plus, it will allow space for an upgrade to the latest and greatest washer and dryer combo.
This is the sort of thing you never knew you needed until the kids got hot glue all over your kitchen table or a sheet of newspaper wasn't enough to keep a science fair volcano from turning your counters into Pompeii. A perfect space for making student council posters or birthday cards. And it's not just for the kids. An arts & crafts area is also perfect for finishing that scrapbook or framing those old photos.
You'll never have to head over to the local dive again if you've got your own sports bar right in the lower level. With a nice television or two you'll have the best seat around on any given Sunday, whether you're hosting friends or relaxing with family.
A big one. With coat hooks and closet space. A bench to take off snow-covered boots. Think of your poor hardwood floors and how happy they would be if all that dirt and mud never made it into the kitchen. Do it for them.
Sometimes it's easy to forget how much time we spend in the bathroom. It's something you'll be using every single day, so why not make it incredible? Maybe instead of just a shower you add a whirlpool tub, too. Or maybe a dual vanity to make getting ready in the morning less like a game of Twister with your significant other. You'll be surprised how much stress a nice bathroom will remove from your life.
These are just some of the dream home splurges that we hear our customers asking about every day.
And we offer all of them here at Bielinski.


text:
| Flash Fiction | Sci-fi | Masquerade
Darren Lester || Michael Ilkiw
Her mask shifted, ever so slightly, as the final client of the day left the room. She could hear the crunching and clunking of the white rings as they rubixed their way around her face, but she could never quite tell if everyone heard the noise or whether it was because of how tightly the mask hugged her head. The lips of the mask were the last to crunk into place, forming a rouged smile, wide and beaming.
"Doctor Ketch?" The tinny voice of her receptionist came through the intercom. Whether the tininess was the intercom itself or the natural timbre of the receptionist's voice was long forgotten to the good doctor. "I'm going home now. Is there anything else that you need?"
"No thank you, Marionette," Doctor Ketch replied, shocked slightly by the gaiety of her own voice. "Your work today has been wonderful. Thank you very much. I shall see you tomorrow." The sound of that statement shocked her on a daily basis, but her face only ever looked like this to offer platitudes to the receptionist. As soon as Marionette had said her goodnights and the doctor had heard the surgery door slam, the mask twisted again to become its default resting form, emotionless and serene.
"Evenin' love. What can I getcha?"
"Good evening, Swazzle." Demurely, Doctor Ketch perched on a bar stool and waited patiently while the mask arranged itself into a small, seductive smile. "Gin and tonic, please."
"Gin and tonic," Swazzle laughed, busying himself behind the bar with the preparations for her drink.
"What was the laugh for?" the doctor asked, the bottom half of her face resting in the smile white the top half rearranged itself to be quizzical, eyebrows cocked.
"Nah, nothin'. Laughing at myself as much as anything. You've come in here every night…well, every night that I've worked at least…for the last six months and ordered the exact same thing. I dunno why I ask any more."
"Oh." The mask whirred again, eyebrows unknotting. "Don't most people who come into such places drink the same thing? The usual, I believe it's called."
"Right you are," Swazzle answered, handing her the small glass. "See old Jack over there?" Swazzle leaned across the bar, close enough for Judith to recognise that he smelled of alcohol and crackling fire. Close enough for her to be thankful, perhaps for the first time ever, that the mask had nostril openings allowing her to smell the world. "He has a Blood and Sand."
"Really?" Judith asked, her mask once again swirling around her head into its quizzical look. "He doesn't look the type."
"Aren't you a psychiatrist?" Swazzle asked, pulling himself back across the bar and beginning to wipe it down. "You should know better than that."
"Touché," she chuckled, conscious of the slight lag before the mask twisted and turned into a grin. Conscious of the slight flicker of confusion across Swazzle's face. "Battery is running low," she explained through gritted teeth. "I'll charge it when I get home."
"Now you, my dear man. What's your usual?"
"Me? Oh, simple tastes here, love. House draught is all I need." The mask twisted again, behaving itself this time as it contorted into its demure smile and a wink.
"On me."
At precisely 22:00, Dr Ketch settled onto her brown, leather couch and switched on The Nature Channel.
"The usual," she smiled to herself. Swazzle had once called it boring, but what did he know? Being a psychiatrist was stressful and she welcomed the soothing comfort of her routine. The mask twisted once more, from the smile back to rest, and the loud crunching and grinding ringing in her ears reminded her of the blip from earlier that evening. "Display battery," she commanded, happy as everything went dark but slightly agitated when the glowing red icon didn't fill her vision. "Display battery," she commanded again, her tone sharper. This time, a red glow did flood her eyes, but it wasn't the familiar battery shape. "Warning : Battery Undetected." She swore slightly under her breath. "Damn thing can't fail. I can't afford a new one." She unclasped the buckled resting on her neck and gently pulled at the mask, bringing it away in two pieces from her head. She carried them over to the wall-mounted charger and gingerly placed them in, holding her breath until the red charging light turned green. "So, the battery's fine." The mask clunked a little, normal residue from the neural transmitters before it realised it wasn't attached to her head anymore. "Please don't let it break," she begged no-one in particular. "I can't afford for it to break."
All of a sudden, there were three sharp knocks on the front door, and Judith's heart froze. This didn't happen. This wasn't part of the routine.
"It's Swazzle!" a voice called through the hallway. Dr Ketch knew that she should have felt better, that identifying the person should make it better, but she was startled and started to tremble.
"Go away please," she stuttered. "I will see you at the bar tomorrow. What you need can wait."
"No, it can't," Swazzle persisted. "I've got your coinpurse here. You left it in the bar." Judith cursed under her breath again.
"Put it through the letter box, please." She heard the flaps rattle, and then a grunt of frustration.
"It won't fit." A beat. "Please, just come and get it."
"I can't," Judith replied. "I'm not decent."
"Please, just put on a dressing gown or something and come and get it. I'm tired and I want to go home to bed."
Judith looked down at herself, fully clothed, and took a deep breath. She knew Swazzle. She could trust Swazzle. As she approached the door, she shook her head back and forth and chanted to herself "I don't like it. I don't like it." Deliberately, and as quickly as she could, she pulled open the door. Swazzle looked at her face and smiled.
About Darren Lester
Darren Lester is a teacher of many things in the south-west of England, who writes to clear out his single brain cell every evening before it refills the next day.
>> Darren Lester's author page
Legionnaire
by Joseph Stephens
Born to Play
by W.A. Fix


text:
Ace Attorney Turnabout Collection
Buy Games
This Month on PlayStation
PS Gear
PSN Status
PS4Turnabout Collection
Offline play enabled
DUALSHOCK 4 vibration
Fear, Language, Violence
Turnabout Collection
Phoenix Wright: Ace Attorney Trilogy
Get ready to yell "Objection!" across 5 individual games in the courtrooms of the past and present in "The Great Ace Attorney Chronicles" and the 2019 release "Phoenix Wright: Ace Attorney Trilogy".
Play the original 14 episodes of the trilogy that started it all as Phoenix Wright and go back in time to experience the 10 episodes of his ancestor Ryunosuke Naruhodo's duology.
Individual titles included:
The Great Ace Attorney: Adventures
The Great Ace Attorney 2: Resolve
Phoenix Wright: Ace Attorney - Justice For All
Phoenix Wright: Ace Attorney - Trials and Tribulations
*The content of "Phoenix Wright: Ace Attorney Trilogy" is the same as in its previous release.
-The Great Ace Attorney Chronicles:
Screen Languages:
-Phoenix Wright: Ace Attorney Trilogy:
Chinese, English, French (France), German, Japanese, Korean
Chinese (Simplified), Chinese (Traditional), English, French (France), German, Japanese, Korean
To play this game on PS5, your system may need to be updated to the latest system software. Although this game is playable on PS5, some features available on PS4 may be absent. See PlayStation.com/bc for more details.
©CAPCOM CO., LTD. 2021 ALL RIGHTS RESERVED.
©CAPCOM CO., LTD. 2014, 2019 ALL RIGHTS RESERVED.
CE EUROPE LIMITED Privacy Policy & EULA
Country/Region: United Kingdom
Modern Slavery Transparency Act Statement
© 2022 Sony Interactive Entertainment Europe Ltd. All rights reserved.


text:
Q: How to fasten week dates adding in pandas? Im adding week dates to big dataframes baset on day dates. It takes up to hours when working with 5 mln rows.
Here is my code:
import datetime
import pandas as pd

pd.DataFrame(data = ['2022-05-01','2021-05-01','2022-02-15'])
df,col,interval_shift,pivot_index,kwargs = pd.DataFrame(data = ['2022-05-01','2021-05-01','2022-02-15']),0,0,'Week start date',{}
date_col_format = kwargs['date_col_format'] if 'date_col_format' in kwargs else '%Y-%m-%d'

print('Week Number starts',datetime.datetime.now())
df['Week Number'] = df[col].apply(lambda x: ((datetime.datetime.strptime(x, date_col_format) - (pd.DateOffset(days=interval_shift))).strftime('%Y') + '-'+(datetime.datetime.strptime(x, date_col_format)- (pd.DateOffset(days=interval_shift))).strftime('%V')))
print('Week Number ready',datetime.datetime.now())
df[pivot_index] = df['Week Number'].apply(lambda y: (pd.to_datetime(y + '-1', format='%G-%V-%u') + pd.DateOffset(days=interval_shift)).strftime('%Y-%m-%d'))
print('Week pivot_index ready',datetime.datetime.now())
df

I need both cols: week number and date of weeks mondays.
output

0
Week Number
Week start date

0
2022-05-01
2022-17
2022-04-25

1
2021-05-01
2021-17
2021-04-26

2
2022-02-15
2022-07
2022-02-14

explanation for interval_shift is nececity to shift week forward and backward and get number and start date of shifted week (from friday to thurstay for example)

A: There are two questions that can help you

*

*Week number link

*Week start date link
import pandas as pd
# data
df = pd.DataFrame(
    data=['2022-05-01','2021-05-01','2022-02-15'],
    columns=["date"])
df["date"] = df["date"].astype("M8")

# Week number
df["Week number"] = df['date'].dt.strftime('%Y-%U')

# Week start date
df["Week start date"] = (
    df["date"] -
    df['date'].dt.weekday.astype('timedelta64[D]'))

Test Performances
generate a 5M row df
import pandas as pd
# this has 50_000 rows
df = pd.DataFrame(
{"date": pd.date_range("1900-01-01", periods=50_000)})
# so we duplicate 100 times
df = pd.concat([df for i in range(100)], ignore_index=True)
# we save a copy for further tests
df_bk = df.copy()

Timing initial code
%%time
df["Week number"] = df['date'].dt.strftime('%Y-%U')
df["Week start date"] = (
    df["date"] -
    df['date'].dt.weekday.astype('timedelta64[D]'))

CPU times: user 16 s, sys: 228 ms, total: 16.2 s
Wall time: 16.2 s

Timing using other approach
Here the most likely thing is that we have duplicated dates. So why don't just use our snippet on unique dates and then merge back to the original df?
# data
df1 = df_bk.copy()

%%time
# extract unique dates
df = pd.DataFrame({"date": df1["date"].unique()})
# We use same snippet as above
df["Week number"] = df['date'].dt.strftime('%Y-%U')
df["Week start date"] = (
    df["date"] -
    df['date'].dt.weekday.astype('timedelta64[D]'))
# We merge to the result
df = pd.merge(df1, df, on="date")

CPU times: user 685 ms, sys: 59.4 ms, total: 744 ms
Wall time: 744 ms

Which is a 20x speedup compared to the previous code.

redpajama_set_name: RedPajamaStackExchange


text:
Sign-InRegister
HOME BUYER SEMINAR REGISTRATION
Contact Facey Realty
Sort By Sort By Price (highest) Price (lowest) SQFT (highest) SQFT (lowest) Year Built (newest) Year Built (oldest) DOM (newest) DOM (oldest)
Map Photo Gallery
City Port Saint Lucie
Duplex Condo
Single Family Townhouse
Villa Manufactured
Residential Lot & Land
Residential Income Residential Rental
Bedrooms Min: Bedrooms Max:
Any 1 2 3 4 5 6 to Any 1 2 3 4 5 6
Bathrooms Min: Bathrooms Max:
Min Sq. Ft.: Max Sq. Ft.:
Any 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000 to Any 500 1000 1500 2000 2500 3000 3500 4000 4500 5000 5500 6000
Price Min: Price Max:
Any $100,000 $150,000 $200,000 $250,000 $300,000 $350,000 $400,000 $450,000 $500,000 $550,000 $600,000 $650,000 $700,000 $750,000 $800,000 $900,000 $1,000,000 $2,000,000 $3,000,000 $4,000,000 $5,000,000 to Any $100,000 $150,000 $200,000 $250,000 $300,000 $350,000 $400,000 $450,000 $500,000 $550,000 $600,000 $650,000 $700,000 $750,000 $800,000 $900,000 $1,000,000 $2,000,000 $3,000,000 $4,000,000 $5,000,000 $10,000,000
Acres Min: Acres Max:
Any 1 2 3 4 5 6 7 8 9 10 to Any 1 2 3 4 5 6 7 8 9 10
Floors Min: Floors Max:
Any 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 to Any 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Min Year Built: Max Year Built:
Any202120202019201820172016201520142013201220112010200920082007200620052004200320022001200019991998199719961995199419931992199119901989198819871986198519841983198219811980197919781977197619751974197319721971197019691968196719661965196419631962196119601959195819571956195519541953195219511950194919481947194619451944194319421941 to Any202120202019201820172016201520142013201220112010200920082007200620052004200320022001200019991998199719961995199419931992199119901989198819871986198519841983198219811980197919781977197619751974197319721971197019691968196719661965196419631962196119601959195819571956195519541953195219511950194919481947194619451944194319421941
Garage Space: Days on market:
Any 1+ 2+ 3+ 4+ 5+ to Any 1 3 7 14 30 60 80+
Viewing: 1 - 12 of 836
Courtesy of ERL Realty Services
View Details Share
Courtesy of Real Estate Solutions Today
Courtesy of BHHS Florida Realty
Courtesy of Masters Realty Associates
Manderlie
Courtesy of Mattamy Real Estate Services Inc
Midport Place 1
Courtesy of Nex Gen Realty & Property Mgnt
Courtesy of Keller Williams Realty of PSL
0 /Acre
There are currently no active listings that match your search criteria.
<% if( mlsposition >= "0" ) { %>
/Acre
Team Facey
2833 SW Brighton Street
Port St Lucie, FL 34953
© 2021 All Rights Reserved - Powered by REfindly | Site Administration
Send a copy of this message to me
Do you want to learn about the features?
Saved Search Failed
Save This Search We will send you new properties that match your search criteria as they come on the market.
Name this search:
You must be signed-in to access this page.
Why create a free account ? Sign up for Free
We provide you
Favorite & Saved Searches
Instant Property Updates
Enhanced Client Dashboard
And it's Totally Free !
Already Registered? Login using your email below.


"A very commendable service was provided."
Analogue telephone lines are traditional telephone lines and can work with an ordinary telephone.
Unfortunately, there is no single consistent way in which analogue telephone lines are presented at customer premises and connected to telephone systems. Not all the ways that have been used in the past lend themselves to easy testing by someone without specialist knowledge and test equipment. Many analogue telephone lines are, however, presented on an analogue line NTE like the one shown above.
If your telephone lines are presented in this way, you should be able to test them yourself. You will need a working analogue telephone and a small screwdriver. By 'analogue telephone', we mean one that works on an ordinary phone line, like the line you probably have at home. If you are not sure, try plugging a phone into your broadband line. If it works there, it is suitable for these tests.
Look for 1 or more analogue line NTEs labelled with the telephone number you are having problems with. There should be 1 NTE for each line you have on the number, so if you have 3 lines, there will be 3 NTEs.
If there is a cable plugged into the NTE, unplug it, being careful to note which cable was in which NTE so you know where to put the cables back when you have finished.
Remove the 2 small screws on the front, and remove the front section of the NTE. You will see another phone socket behind the front section of the NTE.
Plug a phone into the socket and see if you have dial tone.
If you do get dial tone, try making a phone call, say to your mobile phone. If you can make a successful call, the line is working. If you cannot make a call, the line is faulty.
You can also try dialling 17070 (line on the BT network) or 174 (line on the Virgin Media network). On lines from most providers, this will result in an automated announcement of the telephone number associated with the line.
Replace the front section of the NTE and plug the cable back in, if you removed one in step 2.
Repeat steps 2-5 for the other lines.
Any faulty lines should be reported to your line provider. When you report the fault, explain the tests you have carried out.
If all the lines are working correctly, you might have a problem with your telephone system. Contact your telephone system maintainer for help. We can provide help with the products we support.
ISDN 2 is a means of providing telephone lines to a telephone system. Each NTE provides 2 lines, so if you have 4 lines, there will be 2 NTEs.
Generally, ISDN 2 is used for between 2 and 8 lines, with ISDN 30 used for between 8 and 30 lines. However, this is not always the case and it is possible to have more than 8 lines using ISDN 2.
You can find out if you have ISDN 2 lines by looking for the NTE (pictured above), which should be near your telephone system, and could be loose inside the data cabinet, if you have one, or mounted on the wall. There should be a cable between each NTE and your telephone system.
If some or all of your telephone lines are not working and they are ISDN 2 lines, carry out the following checks before reporting the problem to your line provider.
Check the green light on the NTE.
If the light is off, this indicates a fault with the ISDN 2 connection. Report the fault to your line provider and tell them that the green light on the NTE is off. The fact that the light is off definitely indicates that this is a line fault no matter what BT or your line provider tell you.
If the light is flashing bright and dim rapidly, this indicates that the connection between the NTE and the BT telephone exchange is being initialised. If this continues for longer than a few seconds, report the fault to your line provider.
If the light is flashing bright and dim slowly, this indicates a problem with either the telephone system, or the cable between the NTE and the telephone system.
Check the cable between the NTE and the telephone system. Make sure the plugs are pushed into the NTE and the telephone system properly. The plugs have a locking tab so it should not be possible to pull them out without pressing the locking tab to release it.
If the cable is connected properly, it might be faulty. Try a different Cat 5 cable.
If the cable is missing and you cannot locate the cable that should be connected to the NTE, call your telephone system maintainer for help.
If the light is on and the lines are still not working, this could indicate a problem with either the line or the telephone system.
The light on some NTEs does not flash when the cable is unplugged. Unplug the cable and check that the light starts to flash bright and dim slowly. If the light does not start to flash, reconnect it and follow the steps above for checking the cable is connected properly.
Report the fault to your line provider and ask them to test the lines and reset the ISDN 2 connection. Sometimes the test followed by a reset is enough to fix the problem. At this point, the line provider will tell you either that the test shows a problem or that the lines are testing OK. Note that the test is not perfect and sometimes lines that are faulty pass the line test.
If the lines are still not working, call your telephone system maintainer for help. We can provide help with the products we support.
An ISDN 30 NTE (side view).
ISDN 30 provides between 8 and 30 lines, or multiples of 30 lines over a digital connection. ISDN 30 requires specialist knowledge and test equipment to diagnose and rectify faults. Please call us for further assistance.
SIP trunks are not physical telephone lines as with analogue and ISDN, and instead route calls over the internet using VoIP (Voice over Internet Protocol). They are connected to your telephone system via either the same internet connection used for your computers, or a dedicated internet connection used just for your SIP trunks.
If you are having problems with your telephone lines and you know or suspect they are SIP trunks, the first thing to consider is whether you are also having problems accessing the internet from your computers. If you have SIP trunks that have either stopped working, or are working intermittently or with poor speech quality, and you are also having problems accessing the internet, the first thing to do is investigate your internet connection problems with your IT provider or internet service provider.
If the problem is with call quality, the problem might be that your internet connection is not up to the job. If calls start to break up (some customers describe this as sounding like the caller is underwater) when you are downloading, or uploading in particular, large amounts of data, it could be that your computers and telephone system share an internet connection and it might be better to have a separate dedicated internet connection for the SIP trunks.
Hosted telephony, also called hosted VoIP, is a telephone system with the system itself hosted in a data centre somewhere with just the telephones in your office. Typically you pay a monthly fee per telephone. The telephones connect over the internet and are therefore subject to the same possible problems as SIP trunks, above. If you are having problems with your hosted VoIP telephones, follow the advice given above for SIP trunks.
If you can't resolve the problem or need more help, please call us for advice.


text:
Death mystery fuels JFK movie, book industry
LOS ANGELES - The enduring mystery surrounding John F. Kennedy's assassination has drawn generations of writers, commentators and filmmakers, though some have been more successful than others.
The 50th anniversary of the killing of America's 35th president has inevitably renewed the spotlight on the events in Dallas on November 22, 1963, even if the story has been recounted in innumerable films, TV series and books.
"JFK's life and death have been chronicled in myriad ways, and I would expect this to continue for generations to come," said Shaye Areheart, a publishing expert at New York's Columbia University.
"That he died so young, at the hands of an assassin, before he had a chance to spend more than a thousand days in office, also makes him an infinitely tragic and romantic figure."
His dashing charm, and notorious womanizing, have also fueled a veritable cultural industry built up around him.
But it was the manner of his death - allegedly at the hands of lone gunman Lee Harvey Oswald, shooting him dead as the presidential motorcade sped through a Dallas plaza - which produced the irresistible JFK myth.
"JFK and his untimely demise is probably one of the greatest unsolved mysteries of all-time, which is why the story can never really be put to bed, even 50 years later," said film expert Jeff Bock.
"His life had "all the elements of a compelling Hollywood movie -- high stakes, intrigue, infidelity and lots and lots of good-looking people," Bock, of box office tracker Exhibitor Relations, told AFP.
US director Oliver Stone, whose film "JFK" starring Kevin Costner was a blockbuster hit, said the reason it continues to generate interest "is because it has never been truly solved."
The Warren Commission, the official inquiry into the killing, "is a myth at best," he told AFP.
"As a result people who are intelligent must question it and have repeatedly over 50 years. It has never been solved to a satisfactory degree without admitting the presence of a second gunman in front of Kennedy."
Nelson McCormick, who made the TV movie "Killing Kennedy" for the National Geographic Channel, said the killing is "a murder case that the more you investigate it, the more questions it produces than answers."
"So as long as we feel the desire to keep looking for new clues, there will be new books, movies, TV and documentary shows on the many facets of this fascinating period of history," he said.
"It reminded me of the Titanic story. We know how it's going to end, and yet it is riveting to watch."
Stone, who came back to the Kennedy story in the TV documentary series "The Untold History of the United States" last year, said his 1991 film was clearly aimed at calling into question the official version of events.
"It was decided that Oswald was the guilty party and the evidence was made in order to fit that thesis," he said, adding: "It was a dramatic film and not a documentary.
"I had to combine characters and some of the plot situations to bring it down to a three-hour movie."
But Kennedy, however admired he was, is not a guarantee of success for storytellers, whether in writing or on screen.
"There are no sure bets in publishing or movies," said Professor Richard Walter, of the University of California, Los Angeles (UCLA) School of Theater, Film, and Television.
"It's not enough for a book or a movie to be about JFK. It also has to be good. By good I mean engaging instead of boring," he said.
While Stone's "JFK" made $205 million globally, the film "Parkland," released last month, made only $650,000 at the North American box office.
"Like anything else in Tinseltown, it often comes down to what kind of spin you're putting on the story and who the attached talent is," said Bock of Exhibitor Relations. "I'm not sure JFK is bankable per se."
The next big JFK hit could be an adaptation of Stephen King's novel "11-22-63" -- the date he died -- which was published in 2011 and describes a time travel attempt to prevent the assassination taking place.
Studio giant Warner Bros has bought the rights, and plans to make a TV series. The project "could do big business as it is an entirely different take on the events," said Bock.
"And that event in question, is undoubtedly one of the darkest times in America, and thus is sort of a wellspring of dark drama to tap into."


text:
Q: Error when JSON contains Chinese AsyncHttpClient POSTs JSON data, if I have Chinese in the JSON the response is
http 400 The request sent by the client was syntactically incorrect ()
My server is a Rest server. Can anyone tell me how this error happened as my server can receive Chinese correctly?
    StringEntity entity =null;
    try {
        entity = new StringEntity(jsonEntity==null ?null : jsonEntity.toString());
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    client.post(context, getAbsoluteUrl(url), entity, "application/json", responseHandler);


__able is an investment fund focused on supporting visionary, early stage brands in the positive, healthy living space.
We aim to support and nourish passionate entrepreneurs and inspiring brands that will make the daily lives of people healthier, happier, and more enlightened. We're guided by our own experiences as entrepreneurs, and we view all of our investments as partnerships—working with the founders to reach their unique goals. As individual investors, we are open to different paths to growth and exit strategies, and this flexibility is central to the promise we make our brands: we're here to help you win big.
Lisa has spent the last decade as an active angel investor focused on consumer businesses, often in the health, wellness and active lifestyle space with a particular interest in supporting women-led entrepreneurial ventures. Previously, Lisa co-founded VitalJuice.com, a daily email newsletter on healthy living tips and trends that was acquired by Tasting Table. She also helped build and launch Portero, an online luxury goods auction platform sold to Richemont. She has experience building businesses from the ground up with partners such as AOL, Amazon, Kleiner Perkins and The Pilot Group. Lisa started her career as a producer at CNN. She is a Board Member of The New York Public Library, KIPP New York, and The Mount Sinai Parenting Center. Lisa also sits on the Steering Committee of the Leadership Now Project, a membership organization of business professionals committed to renewing democracy. She has a B.A. from Duke University and an M.B.A. from Harvard Business School. Lisa lives in New York City with her husband and three children.
We've been supporting and investing in female founders for the last decade.
As an early investor in The Wing, we decided to join forces to accelerate the talented Wing community with our incubator program, Wingable.


TV glitches can be a nightmare. In most cases, they're simply annoying, but sometimes they're a hypnotizing and surreal works of art.
Some of it is relaxing.
Director: Charlie McDowell. Starring: Mark Duplass, Elisabeth Moss, Ted Danson. USA, 2014. Budget: $100,000. Box office: $513,447. IMDb: 7.1. My rating: 3/4. Witty dissection of a couple relationship wrapped in a sci-fi puzzle.
– Let's say you buy a gorilla.
– Let's say you buy a gorilla, Ethan.
– You can't buy a gorilla.
you buy an aardvark, okay?
What I especially liked about "The One I Love" is that it's a smart and small movie that is not trying to be pretentious and artsy – of those kind that are slow and hard to watch, burdened with their artistry and attempt to say something deep (like beautiful but soulles "High-Rise"). While somebody could criticize it for not digging as profoundly as it could, I'd rather say that it intelligently leaves you enough space to analyze it by yourself. From one hand, it's still some kind of a weird story dark romantic comedy about a couple in crisis. But it's also a psychological minimal science fiction with witty plot and unusual approach. And as you start to understand what is actually happening in the movie, it can get pretty creepy. In short, "The One I Love" is a micro-budget ($100,000) film about a couple in crisis with lingering and memorable aftertaste. Last but not least, it's a puzzle.
If you have seen an indie with Mark Duplass ("Cyrus", "Safety Not Guaranteed"), a one man orchestra, then you'd probably know at least vaguely what to expect from "The One I Love". Intimate atmosphere, unorthodox script and dialogues, warm human touch imbue almost all of his works. In case you are not familiar with his works, this movie could be a good reason to do it. It's also was a curious case when the critics were asked not mention the plot of the movie since it's pretty difficult to write about it without spoiling anything. Before the release, it had two kinds of a test screening – where the audience knew the main idea of the plot and where it didn't (the second screening did much better).
"The One I Love" is pretty minimal, basically, it's a theater with two actors – Mark Duplass and Elisabeth Moss ("Mad Men", "High-Rise"). Almost everything is happening in one location. But thanks to an original idea with some very good acting the film keeps you glued to the screen. It's also a debut movie by Charlie McDowell, the son of legendary Malcolm McDowell ("A Clockwork Orange"). It seems Mark Duplass has really a distinctive flair for revealing talent in young directors. He was contacted by McDowell who wanted to make something "relationship-oriented" and during three weeks they with Justin Lader build up a very detailed 50 page script, where everything was described with smallest details – everything except for the dialogues, that were improvised by Moss and Duplass right during the filming to make the story more alive and real. 9 weeks later the movie done. Pretty quick even for such a small movie.
But small doesn't mean that it offers little, right? You could draw some parallels between "The One I Love" and brilliant "Coherence" (a must-see!). Some other wonderful movies like "Closer" and "Sliding Doors" also come to my mind. But while the "Coherence" was more about our choices and character formation in general, "The One I Love" is rather a dissection of a couple relationship using science fiction to approach the question from an unexpected angle. It is an intimate story about something very private though still an experience almost all of us had. So I would rather rather leave you to analyze the movie by yourself. For those who are already in a relationship – go on and watch it together, it may be pretty thought-provoking for a good discussion.
What I liked less. Still, a movie deserves some criticism as well. While Duplass' passion for micro-budget-oriented movies is indeed adorable – he even said that it's actually easier to make money with a movie that has a budget of $500,000 rather than $5,000,000, I wish the film showed us the story from a bigger view. I suppose it's not only a budget question though, but more of time and organizational matters since the movie was made barely in 3 months. At times I felt like the movie is a little bit too tight in its minimal setting for what it wants to explore.
The recepton. It's always a pleasure to note that such small independent movies can gain good recognition – 80% on Rotten Tomatoes, 7.1 with 27k IMDb votes and a Saturn Award nomination as Best Independent Film.
Worth watching? "The One I Love" is a curious dissection of a couple relationship. If you love sci-fi puzzle and Charlie Kaufman-like movies, definitely check it out. It leaves enough space for psychological depth, while remaining a pretty quick-paced and at times creepy puzzle. The plot is sturdy and witty. So yes – instead of an endless array of various kind of romantic comedies whatever, watch "The One I Love". I don't like this cliched definition, but it's a thought-provoking movie indeed. While not perfect and probably a little bit too minimal (I still prefer "Coherence", which I consider a low-budget cinema masterpiece, but it was also heavier and darker), "The One I Love" is an interesting, refreshing and original psychologic puzzle about all of us.
Watch also: Other great low-budget sci-fi movies set in a minimal setting: "The Man From Earth", "Exam", "The Cube", "10 Cloverfield Lane", "Moon", "Coherence", "Version 1.0".
P. S. Read here Q&A with the Duplass brothers.


CHEQUE. BANCO ESPIRITO SANTO. FOLHA DE 3 CHEQUES.
QF.1955-2$50 - MOÇAMBIQUE (SAO 2 MOEDAS) M. B. C.
QF.1966-20$00-PONTE SALAZAR-S O B E R B A / F. D. C.
QF.1965-2$50 - MOÇAMBIQUE (SAO 2 MOEDAS) M. B. C.
QF.1965-2$50 - MOÇAMBIQUE (SAO 2 MOEDAS) . M.B.. C.


text:
Q: Can you use a TempVar in MS Access VBA linking to a element on an sub-report I have created an Access report, with a sub report.
When emailing the report, the email button on the report removes the "sample" watermark before emailing a PDF copy. My VBA works fine on the main report, but I'm struggling to get it working on the sub-report when not hard-coding the report name.
The main report shows pages 1 and 2, the sub-report is for page 3 (p3).
The following is working to hide the watermark on the sub-report:
Me.rptTermsReport1_p3.Report.imgSample3.Visible = False

Since I have about 40 reports, I don't want to hard-code the sub-report names, but use a TempVar for the report name (e.g. rptTermsReport1 & append (_p3)
I have tried the following (and a few variations), but the TempVars and the concatenated _p3 is not working:
Report ("[TempVars]![ReportName]" & "_p3") & .imgSample3.Visible = False

The error is: "Compile error: invalid or unqualified reference" and it's the [reportname] that's highlighted.
Any ideas how you can use a TempVar with a concatenated string (_p3) linking to a field on a sub-report?

A: Don't put "" around variables.
.<Control> mustn't be concatenated, but used directly.
To access a variable report, use the Reports collection
If these aren't subreports, this should work:
Reports([TempVars]![ReportName] & "_p3")!imgSample3.Visible = False

If they are subreports, see:
Refer to Form and Subform properties and controls
(just replace Forms by Reports)


text:
/**
 *
 */
package com.trendrr.strest.server.routing;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.trendrr.oss.StringHelper;

/**
 *
 * Creates a tree of uri mappings for fast lookup.
 *
 * will handle named wildcards in the rails style:
 *
 * /object/:name/:id
 *
 * will match
 * /object/my_object/2009
 *
 * Wildcards will only match on / boundaries.  so /my_object:id will not work.
 *
 *
 * lookup should be constant time, no matter how many routes are in the system
 *
 *
 * @author Dustin Norlander
 * @created Jan 14, 2011
 *
 */
public class RouteMatcher {

	protected static Log log = LogFactory.getLog(RouteMatcher.class);

	protected TreeNode tree = new TreeNode();
	protected HashMap<String, UriMapping> nonWildcardRoutes = new HashMap<String, UriMapping>();

	protected HashSet<UriMapping> all = new HashSet<UriMapping>();

	public static void main(String ...strings) {

		RouteMatcher tree = new RouteMatcher();
//
//		tree.addMapping(new UriMapping("/", DummyController.class));
//		tree.addMapping(new UriMapping("/dustin", DummyController.class));
//		tree.addMapping(new UriMapping("/billie", DummyController.class));
//		tree.addMapping(new UriMapping("/dustin/:id", DummyController.class));
//		tree.addMapping(new UriMapping("/dustin/:name/:id", DummyController.class));
//		tree.addMapping(new UriMapping("/", DummyController.class));
//
//		System.out.println(tree.find("/dustin/blah"));
//		System.out.println(tree.find("/dustin/blah/asdf"));
//		System.out.println(tree.find("/"));
//

	}

	/**
	 * Finds the matched route.
	 *
	 * returns null if no match is found.
	 *
	 * if multiple matches are found, first one is returned (no guarentee on ordering).
	 *
	 * if uri ends with .extension then that is trimmed and put as return_type into the params
	 * @param uri
	 * @return
	 */
	public MatchedRoute find(String uri) {

		MatchedRoute m = new MatchedRoute();
		String u = StringHelper.trim(uri, "/");
		String extension = null;
		{
			String tmp[] = u.split("\\.");
			if (tmp.length == 2) {
				u = tmp[0];
				extension = tmp[1];
			}
		}
		UriMapping route = this.nonWildcardRoutes.get(u);
		if (route == null) {
			//check wildcard matches.
			List<UriMapping> found = new ArrayList<UriMapping>();
			List<String> words = new ArrayList<String>();
			for (String w : u.split("\\/")) {
				words.add(w);
			}

			tree.find(found, words);
			if (found.isEmpty()) {
				return null;
			}
			route = found.get(found.size()-1);
			m.setParams(route.getWildCardMatches(words));
		}

		m.setMapping(route);

		if (extension != null) {
			m.getParams().put("return_type", extension);
		}

		return m;
	}

	/**
	 * adds a route mapping.
	 *
	 * TODO: this is synchronized, but not technically threadsafe, as a concurrent find could be happening. Should fix
	 *
	 * @param mapping
	 */
	public synchronized void addMapping(UriMapping mapping) {
		if (!mapping.isWildCard()) {
			this.nonWildcardRoutes.put(mapping.getRoute(), mapping);
		}else if (mapping.getRoute().isEmpty()) {
			tree.setMapping(mapping);
		} else {
			tree.addChildNode(mapping, mapping.getTokens());
		}
		this.all.add(mapping);
	}

	/**
	 * returns a list of all the mapped uris
	 * @return
	 */
	public Collection<UriMapping> getAll() {
		return this.all;
	}
}

redpajama_set_name: RedPajamaGithub


text:
Tag Archives: dogs
New JHBS: Mine Detection Dogs, Memory Improvement, Robert Owen, & the Street Corner Society
2014.01.07 JournalsAlan Collins, dogs, JHBS, memory, Robert Owen, sociology, William Foote WhyteJacy Young
The winter 2014 issue of the Journal of the History of the Behavioral Sciences is now online. Included in this issue are articles describing the development of mine detector dogs during World War Two, late-nineteenth century advice on improving natural memory, parallels between debates over Robert Owen's role in the history of sociology and contemporary sociology, and the roots of sociologist William Foote Whyte's Street Corner Society. Full titles, authors, and abstracts follow below.
"In Dogs We Trust? Intersubjectivity, Response-Able Relations, and the Making of Mine Detector Dogs," by Robert G. W. Kirk. The abstract reads,
The utility of the dog as a mine detector has divided the mine clearance community since dogs were first used for this purpose during the Second World War. This paper adopts a historical perspective to investigate how, why, and to what consequence, the use of minedogs remains contested despite decades of research into their abilities. It explores the changing factors that have made it possible to think that dogs could, or could not, serve as reliable detectors of landmines over time. Beginning with an analysis of the wartime context that shaped the creation of minedogs, the paper then examines two contemporaneous investigations undertaken in the 1950s. The first, a British investigation pursued by the anatomist Solly Zuckerman, concluded that dogs could never be the mine hunter's best friend. The second, an American study led by the parapsychologist J. B. Rhine, suggested dogs were potentially useful for mine clearance. Drawing on literature from science studies and the emerging subdiscipline of "animal studies," it is argued that cross-species intersubjectivity played a significant role in determining these different positions. The conceptual landscapes of Zuckerman and Rhine's disciplinary backgrounds are shown to have produced distinct approaches to managing cross-species relations, thus explaining how diverse opinions on minedog can coexist. In conclusion, it is shown that the way one structures relationships between humans and animals has profound impact on the knowledge and labor subsequently produced, a process that cannot be separated from ethical consequence.
"Advice for Improving Memory: Exercising, Strengthening, and Cultivating Natural Memory, 1860–1910," by Alan F. Collins. The abstract reads,
The idea that human memory can be improved appears to be as ancient as the concept of memory itself. Continue reading New JHBS: Mine Detection Dogs, Memory Improvement, Robert Owen, & the Street Corner Society →


text:
/**
 * @fileoverview Unit tests for WebChannelBase.@suppress {accessControls}
 * Private methods are accessed for test purposes.
 */

goog.module('goog.labs.net.webChannel.webChannelBaseTest');
goog.setTestOnly();

const ChannelRequest = goog.require('goog.labs.net.webChannel.ChannelRequest');
const ForwardChannelRequestPool = goog.require('goog.labs.net.webChannel.ForwardChannelRequestPool');
const MockClock = goog.require('goog.testing.MockClock');
const PropertyReplacer = goog.require('goog.testing.PropertyReplacer');
const Stat = goog.require('goog.labs.net.webChannel.requestStats.Stat');
const StructsMap = goog.require('goog.structs.Map');
const Timer = goog.require('goog.Timer');
const Uri = goog.requireType('goog.Uri');
const WebChannelBase = goog.require('goog.labs.net.webChannel.WebChannelBase');
const WebChannelBaseTransport = goog.require('goog.labs.net.webChannel.WebChannelBaseTransport');
const WebChannelDebug = goog.require('goog.labs.net.webChannel.WebChannelDebug');
const Wire = goog.require('goog.labs.net.webChannel.Wire');
const XhrIo = goog.requireType('goog.net.XhrIo');
const asserts = goog.require('goog.testing.asserts');
const dom = goog.require('goog.dom');
const functions = goog.require('goog.functions');
const googArray = goog.require('goog.array');
const googJson = goog.require('goog.json');
const netUtils = goog.require('goog.labs.net.webChannel.netUtils');
const requestStats = goog.require('goog.labs.net.webChannel.requestStats');
const testSuite = goog.require('goog.testing.testSuite');

/** Delay between a network failure and the next network request. */
const RETRY_TIME = 1000;

/** A really long time - used to make sure no more timeouts will fire. */
const ALL_DAY_MS = 1000 * 60 * 60 * 24;

const stubs = new PropertyReplacer();

let channel;
let deliveredMaps;
let handler;
let mockClock;
let gotError;
let numStatEvents;
let lastStatEvent;
let numTimingEvents;
let lastPostSize;
let lastPostRtt;
let lastPostRetryCount;

// Set to true to see the channel debug output in the browser window.
const debug = false;
// Debug message to print out when debug is true.
let debugMessage = '';

function debugToWindow(message) {
  if (debug) {
    debugMessage += `${message}<br>`;
    dom.getElement('debug').innerHTML = debugMessage;
  }
}

/**
 * Stubs netUtils to always time out. It maintains the
 * contract given by netUtils.testNetwork, but always
 * times out (calling callback(false)).
 * stubNetUtils should be called in tests that require it before
 * a call to testNetwork happens. It is reset at tearDown.
 */
function stubNetUtils() {
  stubs.set(netUtils, 'testLoadImage', (url, timeout, callback) => {
    Timer.callOnce(goog.partial(callback, false), timeout);
  });
}

/**
 * Stubs
 * ForwardChannelRequestPool.isSpdyOrHttp2Enabled_ to
 * manage the max pool size for the forward channel.
 * @param {boolean} spdyEnabled Whether SPDY is enabled for the test.
 */
function stubSpdyCheck(spdyEnabled) {
  stubs.set(
      ForwardChannelRequestPool, 'isSpdyOrHttp2Enabled_', () => spdyEnabled);
}

/**
 * Mock ChannelRequest.
 * @final
 */
class MockChannelRequest {
  constructor(
      channel, channelDebug, sessionId = undefined, requestId = undefined,
      retryId = undefined) {
    this.channel_ = channel;
    this.channelDebug_ = channelDebug;
    this.sessionId_ = sessionId;
    this.requestId_ = requestId;
    this.successful_ = true;
    this.lastError_ = null;
    this.lastStatusCode_ = 200;

    // For debugging, keep track of whether this is a back or forward channel.
    this.isBack = !!(requestId == 'rpc');
    this.isForward = !this.isBack;

    this.pendingMessages_ = [];

    this.postData_ = null;
    this.requestStartTime_ = null;
  }

  /** @param {?Object} extraHeaders The HTTP headers. */
  setExtraHeaders(extraHeaders) {}

  /** @param {number} timeout The timeout in MS for when we fail the request. */
  setTimeout(timeout) {}

  /**
   * @param {number} throttle The throttle in ms. A value of zero indicates no
   *     throttle.
   */
  setReadyStateChangeThrottle(throttle) {}

  /**
   * @param {?Uri} uri The uri of the request.
   * @param {?string} postData The data for the post body.
   * @param {boolean} decodeChunks Whether to the result is expected to be
   *     encoded for chunking and thus requires decoding.
   */
  xmlHttpPost(uri, postData, decodeChunks) {
    this.channelDebug_.debug(`---> POST: ${uri}, ${postData}, ${decodeChunks}`);
    this.postData_ = postData;
    this.requestStartTime_ = Date.now();
  }

  /**
   * @param {?Uri} uri The uri of the request.
   * @param {boolean} decodeChunks Whether to the result is expected to be
   *     encoded for chunking and thus requires decoding.
   * @param {?string} hostPrefix The host prefix, if we might be using a
   *     secondary domain. Note that it should also be in the URL, adding this
   *     won't cause it to be added to the URL.
   */
  xmlHttpGet(uri, decodeChunks, hostPrefix) {
    this.channelDebug_.debug(
        `<--- GET: ${uri}, ${decodeChunks}, ${hostPrefix}`);
    this.requestStartTime_ = Date.now();
  }

  /** @param {?Uri} uri The uri to send a request to. */
  sendCloseRequest(uri) {
    this.requestStartTime_ = Date.now();
  }

  /** Cancel. */
  cancel() {
    this.successful_ = false;
  }

  /** @return {boolean} */
  getSuccess() {
    return this.successful_;
  }

  /** @return {?ChannelRequest.Error} The last error. */
  getLastError() {
    return this.lastError_;
  }

  /** @return {number} The status code of the last request. */
  getLastStatusCode() {
    return this.lastStatusCode_;
  }

  /** @return {string|undefined} The session ID. */
  getSessionId() {
    return this.sessionId_;
  }

  /** @return {string|number|undefined} The request ID. */
  getRequestId() {
    return this.requestId_;
  }

  /** @return {?string} The POST data provided by the request initiator. */
  getPostData() {
    return this.postData_;
  }

  /**
   * @return {?number} The time the request started, as returned by Date.now().
   */
  getRequestStartTime() {
    return this.requestStartTime_;
  }

  /** @return {?XhrIo} Any XhrIo request created for this object. */
  getXhr() {
    return null;
  }

  /**
   * @param {!Array<?Wire.QueuedMap>} messages The pending messages for this
   *     request.
   */
  setPendingMessages(messages) {
    this.pendingMessages_ = messages;
  }

  /** @return {!Array<?Wire.QueuedMap>} The pending messages for this request. */
  getPendingMessages() {
    return this.pendingMessages_;
  }

  /** @return {boolean} true if X_HTTP_INITIAL_RESPONSE has been handled. */
  isInitialResponseDecoded() {
    return false;
  }

  /** Decodes X_HTTP_INITIAL_RESPONSE if present. */
  setDecodeInitialResponse() {}
}

function getSingleForwardRequest() {
  /** @suppress {visibility} suppression added to enable type checking */
  const pool = channel.forwardChannelRequestPool_;
  if (!pool.hasPendingRequest()) {
    return null;
  }
  return pool.request_ || pool.requestPool_.getValues()[0];
}

/**
 * Helper function to return a formatted string representing an array of maps.
 */
function formatArrayOfMaps(arrayOfMaps) {
  const result = [];
  for (let i = 0; i < arrayOfMaps.length; i++) {
    const map = arrayOfMaps[i];

    if (Object.getPrototypeOf(map.map) === Object.prototype) {  // Object map
      for (const key in map.map) {
        const tmp =
            key + ':' + map.map[key] + (map.context ? ':' + map.context : '');
        result.push(tmp);
      }
    } else if (
        typeof map.map.keys === 'function' &&
        typeof map.map.get === 'function') {  // MapLike
      for (const key of map.map.keys()) {
        const tmp = key + ':' + map.map.get(key) +
            (map.context ? ':' + map.context : '');
        result.push(tmp);
      }
    } else {
      throw new Error('Unknown input type for map: ' + String(map));
    }
  }
  return result.join(', ');
}

/**
 * @param {number=} serverVersion
 * @param {string=} hostPrefix
 * @param {string=} opt_uriPrefix
 * @param {boolean=} spdyEnabled
 */
function connectForwardChannel(
    serverVersion = undefined, hostPrefix = undefined, opt_uriPrefix,
    spdyEnabled = undefined) {
  stubSpdyCheck(!!spdyEnabled);
  const uriPrefix = opt_uriPrefix || '';
  channel.connect(`${uriPrefix}/bind`, null);
  mockClock.tick(0);
  completeForwardChannel(serverVersion, hostPrefix);
}

/**
 * @param {number=} serverVersion
 * @param {string=} hostPrefix
 * @param {string=} uriPrefix
 * @param {boolean=} spdyEnabled
 */
function connect(
    serverVersion = undefined, hostPrefix = undefined, uriPrefix = undefined,
    spdyEnabled = undefined) {
  connectForwardChannel(serverVersion, hostPrefix, uriPrefix, spdyEnabled);
  completeBackChannel();
}

function disconnect() {
  channel.disconnect();
  mockClock.tick(0);
}

/**
 * @param {number=} serverVersion
 * @param {string=} hostPrefix
 */
function completeForwardChannel(
    serverVersion = undefined, hostPrefix = undefined) {
  const responseData = '[[0,["c","1234567890ABCDEF",' +
      (hostPrefix ? `"${hostPrefix}"` : 'null') +
      (serverVersion ? `,${serverVersion}` : '') + ']]]';
  channel.onRequestData(getSingleForwardRequest(), responseData);
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

/** @suppress {visibility} suppression added to enable type checking */
function completeBackChannel() {
  channel.onRequestData(channel.backChannelRequest_, '[[1,["foo"]]]');
  channel.onRequestComplete(channel.backChannelRequest_);
  mockClock.tick(0);
}

function responseDone() {
  channel.onRequestData(getSingleForwardRequest(), '[1,0,0]');  // mock data
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

/**
 * @param {number=} lastArrayIdSentFromServer
 * @param {number=} outstandingDataSize
 */
function responseNoBackchannel(
    lastArrayIdSentFromServer = undefined, outstandingDataSize = undefined) {
  const responseData =
      googJson.serialize([0, lastArrayIdSentFromServer, outstandingDataSize]);
  channel.onRequestData(getSingleForwardRequest(), responseData);
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

function response(lastArrayIdSentFromServer, outstandingDataSize) {
  const responseData =
      googJson.serialize([1, lastArrayIdSentFromServer, outstandingDataSize]);
  channel.onRequestData(getSingleForwardRequest(), responseData);
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

/** @suppress {visibility} suppression added to enable type checking */
function receive(data) {
  channel.onRequestData(channel.backChannelRequest_, `[[1,${data}]]`);
  channel.onRequestComplete(channel.backChannelRequest_);
  mockClock.tick(0);
}

function responseTimeout() {
  getSingleForwardRequest().lastError_ = ChannelRequest.Error.TIMEOUT;
  getSingleForwardRequest().successful_ = false;
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

/** @param {number=} statusCode */
function responseRequestFailed(statusCode = undefined) {
  getSingleForwardRequest().lastError_ = ChannelRequest.Error.STATUS;
  getSingleForwardRequest().lastStatusCode_ = statusCode || 503;
  getSingleForwardRequest().successful_ = false;
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

function responseUnknownSessionId() {
  getSingleForwardRequest().lastError_ =
      ChannelRequest.Error.UNKNOWN_SESSION_ID;
  getSingleForwardRequest().successful_ = false;
  channel.onRequestComplete(getSingleForwardRequest());
  mockClock.tick(0);
}

/**
 * Enum for map types to test.
 * @enum {number}
 */
const MapTypes = {
  OBJECT_MAP: 0,
  STRUCTS_MAP: 1,
  ES6_MAP: 2,
};

/**
 * @param {string} key
 * @param {string} value
 * @param {string=} context
 * @param {!MapTypes=} mapType
 */
function sendMap(
    key, value, context = undefined, mapType = MapTypes.OBJECT_MAP) {
  let map;
  if (mapType == MapTypes.OBJECT_MAP) {
    map = {};
    map[key] = value;
  } else if (mapType == MapTypes.STRUCTS_MAP) {
    map = new StructsMap();
    map.set(key, value);
  } else if (mapType == MapTypes.ES6_MAP) {
    map = new Map();
    map.set(key, value);
  } else {
    throw new Error('Unsupported map type :)');
  }

  channel.sendMap(map, context);
  mockClock.tick(0);
}

function hasForwardChannel() {
  return !!getSingleForwardRequest();
}

/** @suppress {visibility} suppression added to enable type checking */
function hasBackChannel() {
  return !!channel.backChannelRequest_;
}

/** @suppress {visibility} suppression added to enable type checking */
function hasDeadBackChannelTimer() {
  return channel.deadBackChannelTimerId_ != null;
}

function assertHasForwardChannel() {
  assertTrue('Forward channel missing.', hasForwardChannel());
}

function assertHasBackChannel() {
  assertTrue('Back channel missing.', hasBackChannel());
}

/**
 * @param {!MapTypes=} mapType
 */
function sendMapOnce(mapType = MapTypes.OBJECT_MAP) {
  assertEquals(1, numTimingEvents);
  sendMap('foo', 'bar', /* context= */ undefined, mapType);
  responseDone();
  assertEquals(2, numTimingEvents);
  assertEquals('foo:bar', formatArrayOfMaps(deliveredMaps));
}

function sendMapTwice() {
  sendMap('foo1', 'bar1');
  responseDone();
  assertEquals('foo1:bar1', formatArrayOfMaps(deliveredMaps));
  sendMap('foo2', 'bar2');
  responseDone();
  assertEquals('foo2:bar2', formatArrayOfMaps(deliveredMaps));
}

/** @suppress {visibility} suppression added to enable type checking */
function setFailFastWhileWaitingForRetry() {
  assertEquals(1, numTimingEvents);

  sendMap('foo', 'bar');
  assertNull(channel.forwardChannelTimerId_);
  assertNotNull(getSingleForwardRequest());
  assertEquals(0, channel.forwardChannelRetryCount_);

  // Watchdog timeout.
  responseTimeout();
  assertNotNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);

  // Almost finish the between-retry timeout.
  mockClock.tick(RETRY_TIME - 1);
  assertNotNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);

  // Setting max retries to 0 should cancel the timer and raise an error.
  channel.setFailFast(true);
  assertNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);

  // We get the error immediately before starting to ping google.com.
  assertTrue(gotError);
  assertEquals(0, deliveredMaps.length);

  // Simulate that timing out. We should not get another error.
  gotError = false;
  mockClock.tick(netUtils.NETWORK_TIMEOUT);
  assertFalse('Extra error after network ping timed out.', gotError);

  // Make sure no more retry timers are firing.
  mockClock.tick(ALL_DAY_MS);
  assertNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);
  assertEquals(1, numTimingEvents);
}

/** @suppress {visibility} suppression added to enable type checking */
function setFailFastWhileRetryXhrIsInFlight() {
  assertEquals(1, numTimingEvents);

  sendMap('foo', 'bar');
  assertNull(channel.forwardChannelTimerId_);
  assertNotNull(getSingleForwardRequest());
  assertEquals(0, channel.forwardChannelRetryCount_);

  // Watchdog timeout.
  responseTimeout();
  assertNotNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);

  // Wait for the between-retry timeout.
  mockClock.tick(RETRY_TIME);
  assertNull(channel.forwardChannelTimerId_);
  assertNotNull(getSingleForwardRequest());
  assertEquals(1, channel.forwardChannelRetryCount_);

  // Simulate a second watchdog timeout.
  responseTimeout();
  assertNotNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(2, channel.forwardChannelRetryCount_);

  // Wait for another between-retry timeout.
  mockClock.tick(RETRY_TIME);
  // Now the third req is in flight.
  assertNull(channel.forwardChannelTimerId_);
  assertNotNull(getSingleForwardRequest());
  assertEquals(2, channel.forwardChannelRetryCount_);

  // Set fail fast, killing the request
  channel.setFailFast(true);
  assertNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(2, channel.forwardChannelRetryCount_);

  // We get the error immediately before starting to ping google.com.
  assertTrue(gotError);

  // Simulate that timing out. We should not get another error.
  gotError = false;
  mockClock.tick(netUtils.NETWORK_TIMEOUT);
  assertFalse('Extra error after network ping timed out.', gotError);

  // Make sure no more retry timers are firing.
  mockClock.tick(ALL_DAY_MS);
  assertNull(channel.forwardChannelTimerId_);
  assertNull(getSingleForwardRequest());
  assertEquals(2, channel.forwardChannelRetryCount_);
  assertEquals(1, numTimingEvents);
}

function requestFailedClosesChannel() {
  assertEquals(1, numTimingEvents);

  sendMap('foo', 'bar');
  responseRequestFailed();

  assertEquals(
      'Should be closed immediately after request failed.',
      WebChannelBase.State.CLOSED, channel.getState());

  mockClock.tick(netUtils.NETWORK_TIMEOUT);

  assertEquals(
      'Should remain closed after the ping timeout.',
      WebChannelBase.State.CLOSED, channel.getState());
  assertEquals(1, numTimingEvents);
}

/** @suppress {visibility} suppression added to enable type checking */
function outgoingMapsAwaitsResponse() {
  assertEquals(0, channel.outgoingMaps_.length);

  sendMap('foo1', 'bar');
  assertEquals(0, channel.outgoingMaps_.length);
  sendMap('foo2', 'bar');
  assertEquals(1, channel.outgoingMaps_.length);
  sendMap('foo3', 'bar');
  assertEquals(2, channel.outgoingMaps_.length);
  sendMap('foo4', 'bar');
  assertEquals(3, channel.outgoingMaps_.length);

  responseDone();
  // Now the forward channel request is completed and a new started, so all maps
  // are dequeued from the array of outgoing maps into this new forward request.
  assertEquals(0, channel.outgoingMaps_.length);
}

testSuite({
  shouldRunTests() {
    return ChannelRequest.supportsXhrStreaming();
  },

  /**
   * @suppress {invalidCasts} The cast from MockChannelRequest to
   * ChannelRequest is invalid and will not compile.
   */
  setUpPage() {
    // Use our MockChannelRequests instead of the real ones.
    ChannelRequest.createChannelRequest =
        (channel, channelDebug, opt_sessionId, opt_requestId, opt_retryId) => {
          return /** @type {!ChannelRequest} */ (new MockChannelRequest(
              channel, channelDebug, opt_sessionId, opt_requestId,
              opt_retryId));
        };

    // Mock out the stat notification code.
    requestStats.notifyStatEvent = (stat) => {
      numStatEvents++;
      lastStatEvent = stat;
    };

    requestStats.notifyTimingEvent = (size, rtt, retries) => {
      numTimingEvents++;
      lastPostSize = size;
      lastPostRtt = rtt;
      lastPostRetryCount = retries;
    };
  },

  setUp() {
    numTimingEvents = 0;
    lastPostSize = null;
    lastPostRtt = null;
    lastPostRetryCount = null;

    mockClock = new MockClock(true);
    /** @suppress {checkTypes} suppression added to enable type checking */
    channel = new WebChannelBase('1');

    gotError = false;

    handler = new WebChannelBase.Handler();
    handler.channelOpened = () => {};
    handler.channelError = (channel, error) => {
      gotError = true;
    };
    handler.channelSuccess = (channel, request) => {
      deliveredMaps = googArray.clone(request.getPendingMessages());
    };

    /**
     * @suppress {checkTypes} The callback function type declaration is
     * skipped.
     */
    handler.channelClosed = (channel, opt_pendingMaps, opt_undeliveredMaps) => {
      // Mock out the handler, and let it set a formatted user readable string
      // of the undelivered maps which we can use when verifying our assertions.
      if (opt_pendingMaps) {
        handler.pendingMapsString = formatArrayOfMaps(opt_pendingMaps);
      }
      if (opt_undeliveredMaps) {
        handler.undeliveredMapsString = formatArrayOfMaps(opt_undeliveredMaps);
      }
    };
    handler.channelHandleMultipleArrays = () => {};
    handler.channelHandleArray = () => {};

    channel.setHandler(handler);

    // Provide a predictable retry time for testing.
    /** @suppress {visibility} suppression added to enable type checking */
    channel.getRetryTime_ = (retryCount) => RETRY_TIME;

    const channelDebug = new WebChannelDebug();
    channelDebug.debug = (message) => {
      debugToWindow(message);
    };
    channel.setChannelDebug(channelDebug);

    numStatEvents = 0;
    lastStatEvent = null;
  },

  tearDown() {
    mockClock.dispose();
    stubs.reset();
    debugToWindow('<hr>');
  },

  testFormatArrayOfMaps() {
    // This function is used in a non-trivial test, so let's verify that it
    // works.
    const map1 = new Map();
    map1.set('k1', 'v1');
    map1.set('k2', 'v2');
    const map2 = new Map();
    map2.set('k3', 'v3');
    const map3 = new Map();
    map3.set('k4', 'v4');
    map3.set('k5', 'v5');
    map3.set('k6', 'v6');

    // One map.
    const a = [];
    a.push(new Wire.QueuedMap(0, map1));
    assertEquals('k1:v1, k2:v2', formatArrayOfMaps(a));

    // Many maps.
    const b = [];
    b.push(new Wire.QueuedMap(0, map1));
    b.push(new Wire.QueuedMap(0, map2));
    b.push(new Wire.QueuedMap(0, map3));
    assertEquals(
        'k1:v1, k2:v2, k3:v3, k4:v4, k5:v5, k6:v6', formatArrayOfMaps(b));

    // One map with a context.
    const c = [];
    c.push(new Wire.QueuedMap(0, map1, new String('c1')));
    assertEquals('k1:v1:c1, k2:v2:c1', formatArrayOfMaps(c));
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testConnect() {
    connect();
    assertEquals(WebChannelBase.State.OPENED, channel.getState());
    // If the server specifies no version, the client assumes the latest version
    assertEquals(Wire.LATEST_CHANNEL_VERSION, channel.channelVersion_);
    assertFalse(channel.isBuffered());
  },

  testConnect_backChannelEstablished() {
    connect();
    assertHasBackChannel();
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testConnect_withServerHostPrefix() {
    connect(undefined, 'serverHostPrefix');
    assertEquals('serverHostPrefix', channel.hostPrefix_);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testConnect_withClientHostPrefix() {
    handler.correctHostPrefix = (hostPrefix) => 'clientHostPrefix';
    connect();
    assertEquals('clientHostPrefix', channel.hostPrefix_);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testConnect_overrideServerHostPrefix() {
    handler.correctHostPrefix = (hostPrefix) => 'clientHostPrefix';
    connect(undefined, 'serverHostPrefix');
    assertEquals('clientHostPrefix', channel.hostPrefix_);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testConnect_withServerVersion() {
    connect(8);
    assertEquals(8, channel.channelVersion_);
  },

  testConnect_notOkToMakeRequestForTest() {
    handler.okToMakeRequest = functions.constant(WebChannelBase.Error.NETWORK);
    channel.connect('/bind', null);
    mockClock.tick(0);
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());
  },

  testConnect_notOkToMakeRequestForBind() {
    channel.connect('/bind', null);
    mockClock.tick(0);
    handler.okToMakeRequest = functions.constant(WebChannelBase.Error.NETWORK);
    completeForwardChannel();
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());
  },

  testSendMap_withObjectMap() {
    connect();
    sendMapOnce(MapTypes.OBJECT_MAP);
  },

  testSendMap_withStructsMap() {
    connect();
    sendMapOnce(MapTypes.STRUCTS_MAP);
  },

  testSendMap_withEs6Map() {
    connect();
    sendMapOnce(MapTypes.ES6_MAP);
  },

  testSendMapWithSpdyEnabled() {
    connect(undefined, undefined, undefined, true);
    sendMapOnce();
  },

  testSendMap_twice() {
    connect();
    sendMapTwice();
  },

  testSendMap_twiceWithSpdyEnabled() {
    connect(undefined, undefined, undefined, true);
    sendMapTwice();
  },

  testSendMap_andReceive() {
    connect();
    sendMap('foo', 'bar');
    responseDone();
    receive('["the server reply"]');
  },

  testReceive() {
    connect();
    receive('["message from server"]');
    assertHasBackChannel();
  },

  testReceive_twice() {
    connect();
    receive('["message one from server"]');
    receive('["message two from server"]');
    assertHasBackChannel();
  },

  testReceive_andSendMap() {
    connect();
    receive('["the server reply"]');
    sendMap('foo', 'bar');
    responseDone();
    assertHasBackChannel();
  },

  testBackChannelRemainsEstablished_afterSingleSendMap() {
    connect();

    sendMap('foo', 'bar');
    responseDone();
    receive('["ack"]');

    assertHasBackChannel();
  },

  testBackChannelRemainsEstablished_afterDoubleSendMap() {
    connect();

    sendMap('foo1', 'bar1');
    sendMap('foo2', 'bar2');
    responseDone();
    receive('["ack"]');

    // This assertion would fail prior to CL 13302660.
    assertHasBackChannel();
  },

  testTimingEvent() {
    connect();
    assertEquals(1, numTimingEvents);
    sendMap('', '');
    assertEquals(1, numTimingEvents);
    mockClock.tick(20);
    let expSize = getSingleForwardRequest().getPostData().length;
    responseDone();

    assertEquals(2, numTimingEvents);
    assertEquals(expSize, lastPostSize);
    assertEquals(20, lastPostRtt);
    assertEquals(0, lastPostRetryCount);

    sendMap('abcdefg', '123456');
    expSize = getSingleForwardRequest().getPostData().length;
    responseTimeout();
    assertEquals(2, numTimingEvents);
    mockClock.tick(RETRY_TIME + 1);
    responseDone();
    assertEquals(3, numTimingEvents);
    assertEquals(expSize, lastPostSize);
    assertEquals(1, lastPostRetryCount);
    assertEquals(1, lastPostRtt);
  },

  /**
   * Make sure that dropping the forward channel retry limit below the retry
   * count reports an error, and prevents another request from firing.
   */
  testSetFailFastWhileWaitingForRetry() {
    stubNetUtils();

    connect();
    setFailFastWhileWaitingForRetry();
  },

  testSetFailFastWhileWaitingForRetryWithSpdyEnabled() {
    stubNetUtils();

    connect(undefined, undefined, undefined, true);
    setFailFastWhileWaitingForRetry();
  },

  /**
   * Make sure that dropping the forward channel retry limit below the retry
   * count reports an error, and prevents another request from firing.
   */
  testSetFailFastWhileRetryXhrIsInFlight() {
    stubNetUtils();

    connect();
    setFailFastWhileRetryXhrIsInFlight();
  },

  testSetFailFastWhileRetryXhrIsInFlightWithSpdyEnabled() {
    stubNetUtils();

    connect(undefined, undefined, undefined, true);
    setFailFastWhileRetryXhrIsInFlight();
  },

  /**
   * Makes sure that setting fail fast while not retrying doesn't cause a
   *      failure.
   * @suppress {visibility} suppression added to enable type checking
   */
  testSetFailFastAtRetryCount() {
    stubNetUtils();

    connect();
    assertEquals(1, numTimingEvents);

    sendMap('foo', 'bar');
    assertNull(channel.forwardChannelTimerId_);
    assertNotNull(getSingleForwardRequest());
    assertEquals(0, channel.forwardChannelRetryCount_);

    // Set fail fast.
    channel.setFailFast(true);
    // Request should still be alive.
    assertNull(channel.forwardChannelTimerId_);
    assertNotNull(getSingleForwardRequest());
    assertEquals(0, channel.forwardChannelRetryCount_);

    // Watchdog timeout. Now we should get an error.
    responseTimeout();
    assertNull(channel.forwardChannelTimerId_);
    assertNull(getSingleForwardRequest());
    assertEquals(0, channel.forwardChannelRetryCount_);

    // We get the error immediately before starting to ping google.com.
    assertTrue(gotError);
    // We get the error immediately before starting to ping google.com.
    // Simulate that timing out. We should not get another error in addition
    // to the initial failure.
    gotError = false;
    mockClock.tick(netUtils.NETWORK_TIMEOUT);
    assertFalse('Extra error after network ping timed out.', gotError);

    // Make sure no more retry timers are firing.
    mockClock.tick(ALL_DAY_MS);
    assertNull(channel.forwardChannelTimerId_);
    assertNull(getSingleForwardRequest());
    assertEquals(0, channel.forwardChannelRetryCount_);
    assertEquals(1, numTimingEvents);
  },

  testRequestFailedClosesChannel() {
    stubNetUtils();

    connect();
    requestFailedClosesChannel();
  },

  testRequestFailedClosesChannelWithSpdyEnabled() {
    stubNetUtils();

    connect(undefined, undefined, undefined, true);
    requestFailedClosesChannel();
  },

  testStatEventReportedOnlyOnce() {
    stubNetUtils();

    connect();
    sendMap('foo', 'bar');
    numStatEvents = 0;
    lastStatEvent = null;
    responseUnknownSessionId();

    assertEquals(1, numStatEvents);
    assertEquals(Stat.ERROR_OTHER, lastStatEvent);

    numStatEvents = 0;
    mockClock.tick(netUtils.NETWORK_TIMEOUT);
    assertEquals('No new stat events should be reported.', 0, numStatEvents);
  },

  testStatEventReportedOnlyOnce_onNetworkUp() {
    stubNetUtils();

    connect();
    sendMap('foo', 'bar');
    numStatEvents = 0;
    lastStatEvent = null;
    responseRequestFailed();

    assertEquals(
        'No stat event should be reported before we know the reason.', 0,
        numStatEvents);

    // Let the ping time out.
    mockClock.tick(netUtils.NETWORK_TIMEOUT);

    // Assert we report the correct stat event.
    assertEquals(1, numStatEvents);
    assertEquals(Stat.ERROR_NETWORK, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testStatEventReportedOnlyOnce_onNetworkDown() {
    stubNetUtils();

    connect();
    sendMap('foo', 'bar');
    numStatEvents = 0;
    lastStatEvent = null;
    responseRequestFailed();

    assertEquals(
        'No stat event should be reported before we know the reason.', 0,
        numStatEvents);

    // Wait half the ping timeout period, and then fake the network being up.
    mockClock.tick(netUtils.NETWORK_TIMEOUT / 2);
    channel.testNetworkCallback_(true);

    // Assert we report the correct stat event.
    assertEquals(1, numStatEvents);
    assertEquals(Stat.ERROR_OTHER, lastStatEvent);
  },

  testOutgoingMapsAwaitsResponse() {
    connect();
    outgoingMapsAwaitsResponse();
  },

  testOutgoingMapsAwaitsResponseWithSpdyEnabled() {
    connect(undefined, undefined, undefined, true);
    outgoingMapsAwaitsResponse();
  },

  testUndeliveredMaps_doesNotNotifyWhenSuccessful() {
    /**
     * @suppress {checkTypes} The callback function type declaration is
     * skipped.
     */
    handler.channelClosed = (channel, opt_pendingMaps, opt_undeliveredMaps) => {
      if (opt_pendingMaps || opt_undeliveredMaps) {
        fail('No pending or undelivered maps should be reported.');
      }
    };

    connect();
    sendMap('foo1', 'bar1');
    responseDone();
    sendMap('foo2', 'bar2');
    responseDone();
    disconnect();
  },

  testUndeliveredMaps_doesNotNotifyIfNothingWasSent() {
    /**
     * @suppress {checkTypes} The callback function type declaration is
     * skipped.
     */
    handler.channelClosed = (channel, opt_pendingMaps, opt_undeliveredMaps) => {
      if (opt_pendingMaps || opt_undeliveredMaps) {
        fail('No pending or undelivered maps should be reported.');
      }
    };

    connect();
    mockClock.tick(ALL_DAY_MS);
    disconnect();
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testUndeliveredMaps_clearsPendingMapsAfterNotifying() {
    connect();
    sendMap('foo1', 'bar1');
    sendMap('foo2', 'bar2');
    sendMap('foo3', 'bar3');

    assertEquals(
        1, channel.forwardChannelRequestPool_.getPendingMessages().length);
    assertEquals(2, channel.outgoingMaps_.length);

    disconnect();

    assertEquals(
        0, channel.forwardChannelRequestPool_.getPendingMessages().length);
    assertEquals(0, channel.outgoingMaps_.length);
  },

  /** @suppress {missingProperties} suppression added to enable type checking */
  testUndeliveredMaps_notifiesWithContext() {
    connect();

    // First send two messages that succeed.
    sendMap('foo1', 'bar1', 'context1');
    responseDone();
    sendMap('foo2', 'bar2', 'context2');
    responseDone();

    // Pretend the server hangs and no longer responds.
    sendMap('foo3', 'bar3', 'context3');
    sendMap('foo4', 'bar4', 'context4');
    sendMap('foo5', 'bar5', 'context5');

    // Give up.
    disconnect();

    // Assert that we are informed of any undelivered messages; both about
    // #3 that was sent but which we don't know if the server received, and
    // #4 and #5 which remain in the outgoing maps and have not yet been sent.
    assertEquals('foo3:bar3:context3', handler.pendingMapsString);
    assertEquals(
        'foo4:bar4:context4, foo5:bar5:context5',
        handler.undeliveredMapsString);
  },

  /** @suppress {missingProperties} suppression added to enable type checking */
  testUndeliveredMaps_serviceUnavailable() {
    // Send a few maps, and let one fail.
    connect();
    sendMap('foo1', 'bar1');
    responseDone();
    sendMap('foo2', 'bar2');
    responseRequestFailed();

    // After a failure, the channel should be closed.
    disconnect();

    assertEquals('foo2:bar2', handler.pendingMapsString);
    assertEquals('', handler.undeliveredMapsString);
  },

  /** @suppress {missingProperties} suppression added to enable type checking */
  testUndeliveredMaps_onPingTimeout() {
    stubNetUtils();

    connect();

    // Send a message.
    sendMap('foo1', 'bar1');

    // Fake REQUEST_FAILED, triggering a ping to check the network.
    responseRequestFailed();

    // Let the ping time out, unsuccessfully.
    mockClock.tick(netUtils.NETWORK_TIMEOUT);

    // Assert channel is closed.
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());

    // Assert that the handler is notified about the undelivered messages.
    assertEquals('foo1:bar1', handler.pendingMapsString);
    assertEquals('', handler.undeliveredMapsString);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseNoBackchannelPostNotBeforeBackchannel() {
    connect(8);
    sendMap('foo1', 'bar1');

    mockClock.tick(10);
    assertFalse(
        channel.backChannelRequest_.getRequestStartTime() <
        getSingleForwardRequest().getRequestStartTime());
    responseNoBackchannel();
    assertNotEquals(Stat.BACKCHANNEL_MISSING, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseNoBackchannel() {
    connect(8);
    sendMap('foo1', 'bar1');
    response(-1, 0);
    mockClock.tick(WebChannelBase.RTT_ESTIMATE + 1);
    sendMap('foo2', 'bar2');
    assertTrue(
        channel.backChannelRequest_.getRequestStartTime() +
            WebChannelBase.RTT_ESTIMATE <
        getSingleForwardRequest().getRequestStartTime());
    responseNoBackchannel();
    assertEquals(Stat.BACKCHANNEL_MISSING, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseNoBackchannelWithNoBackchannel() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertNull(channel.backChannelTimerId_);
    channel.backChannelRequest_.cancel();
    /** @suppress {visibility} suppression added to enable type checking */
    channel.backChannelRequest_ = null;
    responseNoBackchannel();
    assertEquals(Stat.BACKCHANNEL_MISSING, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseNoBackchannelWithStartTimer() {
    connect(8);
    sendMap('foo1', 'bar1');

    channel.backChannelRequest_.cancel();
    /** @suppress {visibility} suppression added to enable type checking */
    channel.backChannelRequest_ = null;
    /** @suppress {visibility} suppression added to enable type checking */
    channel.backChannelTimerId_ = 123;
    responseNoBackchannel();
    assertNotEquals(Stat.BACKCHANNEL_MISSING, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseWithNoArraySent() {
    connect(8);
    sendMap('foo1', 'bar1');

    // Send a response as if the server hasn't sent down an array.
    response(-1, 0);

    // POST response with an array ID lower than our last received is OK.
    assertEquals(1, channel.lastArrayId_);
    assertEquals(-1, channel.lastPostResponseArrayId_);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseWithArraysMissing() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);

    // Send a response as if the server has sent down seven arrays.
    response(7, 111);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    mockClock.tick(WebChannelBase.RTT_ESTIMATE * 2);
    assertEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testMultipleResponsesWithArraysMissing() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);

    // Send a response as if the server has sent down seven arrays.
    response(7, 111);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    sendMap('foo2', 'bar2');
    mockClock.tick(WebChannelBase.RTT_ESTIMATE);
    response(8, 119);
    mockClock.tick(WebChannelBase.RTT_ESTIMATE);
    // The original timer should still fire.
    assertEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testOnlyRetryOnceBasedOnResponse() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);

    // Send a response as if the server has sent down seven arrays.
    response(7, 111);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    assertTrue(hasDeadBackChannelTimer());
    mockClock.tick(WebChannelBase.RTT_ESTIMATE * 2);
    assertEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
    assertEquals(1, channel.backChannelRetryCount_);
    mockClock.tick(WebChannelBase.RTT_ESTIMATE);
    sendMap('foo2', 'bar2');
    assertFalse(hasDeadBackChannelTimer());
    response(8, 119);
    assertFalse(hasDeadBackChannelTimer());
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseWithArraysMissingAndLiveChannel() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);

    // Send a response as if the server has sent down seven arrays.
    response(7, 111);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    mockClock.tick(WebChannelBase.RTT_ESTIMATE);
    assertTrue(hasDeadBackChannelTimer());
    receive('["ack"]');
    assertFalse(hasDeadBackChannelTimer());
    mockClock.tick(WebChannelBase.RTT_ESTIMATE);
    assertNotEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseWithBigOutstandingData() {
    connect(8);
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);

    // Send a response as if the server has sent down seven arrays and 50kbytes.
    response(7, 50000);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    assertFalse(hasDeadBackChannelTimer());
    mockClock.tick(WebChannelBase.RTT_ESTIMATE * 2);
    assertNotEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testResponseInBufferedMode() {
    connect(8);
    /** @suppress {visibility} suppression added to enable type checking */
    channel.enableStreaming_ = false;
    sendMap('foo1', 'bar1');
    assertEquals(-1, channel.lastPostResponseArrayId_);
    response(7, 111);

    assertEquals(1, channel.lastArrayId_);
    assertEquals(7, channel.lastPostResponseArrayId_);
    assertFalse(hasDeadBackChannelTimer());
    mockClock.tick(WebChannelBase.RTT_ESTIMATE * 2);
    assertNotEquals(Stat.BACKCHANNEL_DEAD, lastStatEvent);
  },

  testResponseWithGarbage() {
    connect(8);
    sendMap('foo1', 'bar1');
    channel.onRequestData(getSingleForwardRequest(), 'garbage');
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());
  },

  testResponseWithGarbageInArray() {
    connect(8);
    sendMap('foo1', 'bar1');
    channel.onRequestData(getSingleForwardRequest(), '["garbage"]');
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());
  },

  testResponseWithEvilData() {
    connect(8);
    sendMap('foo1', 'bar1');
    channel.onRequestData(
        getSingleForwardRequest(),
        'foo=<script>evil()<\/script>&' +
            'bar=<script>moreEvil()<\/script>');
    assertEquals(WebChannelBase.State.CLOSED, channel.getState());
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testPathAbsolute() {
    connect(8, undefined, '/talkgadget');
    assertEquals(channel.backChannelUri_.getDomain(), window.location.hostname);
    assertEquals(
        channel.forwardChannelUri_.getDomain(), window.location.hostname);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testPathRelative() {
    connect(8, undefined, 'talkgadget');
    assertEquals(channel.backChannelUri_.getDomain(), window.location.hostname);
    assertEquals(
        channel.forwardChannelUri_.getDomain(), window.location.hostname);
  },

  /** @suppress {visibility} suppression added to enable type checking */
  testPathWithHost() {
    connect(8, undefined, 'https://example.com');
    assertEquals(channel.backChannelUri_.getScheme(), 'https');
    assertEquals(channel.backChannelUri_.getDomain(), 'example.com');
    assertEquals(channel.forwardChannelUri_.getScheme(), 'https');
    assertEquals(channel.forwardChannelUri_.getDomain(), 'example.com');
  },

  testCreateXhrIo() {
    let xhr = channel.createXhrIo(null);
    assertFalse(xhr.getWithCredentials());

    assertThrows(
        'Error connection to different host without CORS',
        goog.bind(channel.createXhrIo, channel, 'some_host'));

    channel.setSupportsCrossDomainXhrs(true);

    xhr = channel.createXhrIo(null);
    assertTrue(xhr.getWithCredentials());

    xhr = channel.createXhrIo('some_host');
    assertTrue(xhr.getWithCredentials());
  },

  testSpdyLimitOption() {
    const webChannelTransport = new WebChannelBaseTransport();
    stubSpdyCheck(true);
    const webChannelDefault = webChannelTransport.createWebChannel('/foo');
    assertEquals(
        10,
        webChannelDefault.getRuntimeProperties().getConcurrentRequestLimit());
    assertTrue(webChannelDefault.getRuntimeProperties().isSpdyEnabled());

    const options = {'concurrentRequestLimit': 100};

    stubSpdyCheck(false);
    const webChannelDisabled =
        webChannelTransport.createWebChannel('/foo', options);
    assertEquals(
        1,
        webChannelDisabled.getRuntimeProperties().getConcurrentRequestLimit());
    assertFalse(webChannelDisabled.getRuntimeProperties().isSpdyEnabled());

    stubSpdyCheck(true);
    const webChannelEnabled =
        webChannelTransport.createWebChannel('/foo', options);
    assertEquals(
        100,
        webChannelEnabled.getRuntimeProperties().getConcurrentRequestLimit());
    assertTrue(webChannelEnabled.getRuntimeProperties().isSpdyEnabled());
  },
});