text:
Russia 'is trying to salvage a military fiasco'
By ALEXANDER WARD, JONATHAN LEMIRE and QUINT FORGEY
In this photo taken from video released by the Russian Defense Ministry Press Service on Thursday, March 3, 2022, a Russian soldier points a gun from a Russian military truck as it drives through an undisclosed location in Ukraine. | Russian Defense Ministry Press Service via AP
With help from Paul McLeary
Send tips | Subscribe here | Email Alex | Email Quint
The White House today reacted with deep skepticism to Russia's promise to reduce violence in Ukraine as a means of paving the way for possible peace talks, with government officials suggesting that the Kremlin was simply redirecting, not ending, its invasion.
Negotiations in Istanbul between Ukrainian and Russian officials seemed to yield some progress to a possible meeting between Ukraine's VOLODYMYR ZELENSKYY and Russia's VLADIMIR PUTIN. As for a direct discussion between Putin and President JOE BIDEN himself, White House officials firmly underscored that Moscow would need to take more convincing steps toward curtailing the war before any such talk would take place, according to two administration officials not authorized to speak publicly about private deliberations.
The reaction from the White House was a veritable dousing of cold water on what, hours earlier, seemed like one of the first, sincere potential diplomatic breakthroughs more than a month into the bloody conflict. At the talks in Turkey, both Ukrainian and Russian sides said moves were being made toward a leaders' summit, as Kyiv for the first time signaled a willingness to hold negotiations over territory seized by Moscow. Russian Deputy Defense Minister ALEXANDER FOMIN said his military planned to "fundamentally cut back" military activity near the Ukrainian capital of Kyiv and another northern city in an effort "to increase trust" around the peace talks.
But Biden administration officials cautioned that while they had seen a recent reduction in Russian attacks around Kyiv and Chernihiv, violence had continued unabated and even grown elsewhere, particularly in southern and eastern Ukraine. Moreover, the officials said that the pause near Kyiv may be a ruse to resupply troops and that the violence could ramp up at any time.
"I've not seen anything to suggest that this is moving forward in an effective way because we have not seen signs of real seriousness" from Russia, said Secretary of State ANTONY BLINKEN at a press conference in Morocco.
More vitally, even if Russia did silence its guns near the Ukrainian capital, it still very much was conducting an active assault on other regions — which would inherently undermine any sort of cease-fire, according to the U.S. officials.
Feeding the new push for diplomacy has been the growing recognition that the Russian invasion has badly stalled, with Moscow taking huge personnel and equipment losses. Biden aides, buoyed by Ukraine's military campaign to date, nevertheless scoffed at the suggestion that Putin was ending the war, instead believing he likely was temporarily focusing on a more winnable region, the officials said. The Donbas region — parts of which have been held by Kremlin-backed separatist forces since 2014 — appeared to be a particular target.
Putin's campaign has gone so unexpectedly poorly that U.S. officials have begun reviewing their own intelligence assessments to determine how they could have so badly misjudged the strength of the Russian military. Despite pouring billions of dollars into modernizing Russia's military, Putin's forces have been saddled with poor equipment, communications and morale — all leading to, so far, a stalemate against a much smaller and overmatched foe.
To that point, one U.S. official bluntly said: "The Russians really fucked this up."
Experts agreed. "It's a huge retreat from Putin's initial war aims," said JEFFREY EDMONDS, former Russia director on BARACK OBAMA's National Security Council and now adjunct senior fellow at the Center for a New American Security think tank. "This is a huge defeat to Putin's maximalist initial goals. The Russian leadership is trying to salvage a military fiasco."
Read the entirety of Alex and JONATHAN LEMIRE's piece here.
SITUATION REPORT: We will only cite official sources. As always, take all figures, assessments and statements with a healthy dose of skepticism.
War in Ukraine:
— Since the war began on Feb. 24, Russia has lost around 17,200 personnel, 597 tanks, 1,710 armored combat vehicles, 303 artillery systems, 96 multiple-launch rocket systems, 127 warplanes, 129 helicopters, seven ships and 71 drones (Ukrainian Ministry of Defense)
— "The withdrawal of certain units of the armed forces of the Russian Federation from the territory of Kyiv and Chernihiv oblasts is noted. At the same time, there is a high risk of the Russian occupiers attacking military and civilian infrastructure." (Ukrainian Ministry of Defense)
— In the Donetsk area, Russia has "activated assault actions in most directions." (Ukrainian Ministry of Defense)
— "Ukrainian Forces have continued to conduct localised counter attacks to the north west of Kyiv - including at Irpen, Bucha and Hostomel. These attacks have had some success and the Russians have been pushed back from a number of positions. However, Russia still poses a significant threat to the city through their strike capability. Russian Forces have maintained their offensive on Mariupul with continuous heavy shelling of the city, however the centre of the city remains under Ukrainian control. Elsewhere, Russian Forces are maintaining blocking positions while attempting to reorganise and reset their forces." (U.K. Ministry of Defense)
Russian forces positions as of 1400 March 29. | Janes
Global Response:
— Belgium, Ireland, the Netherlands and Czech Republic: These four countries collectively expelled 43 Russian diplomats over allegations of spying and unlawful influence activities. They have two weeks to leave the European nations.
— U.S.: Gen. TOD WOLTERS, head of U.S. European Command and NATO's supreme allied commander, said the U.S. may need to put more American service members in Europe.
— U.S.: A correction: On Monday, we made an error in saying that the six Growlers the U.S. is sending to Germany came from Washington, D.C., not Washington state. We regret the error and thank Rep. RICK LARSEN (D-Wash.), who represents the district where the Growlers came from, for pointing out our oversight.
— The Washington Post: "Russia has killed civilians in Ukraine. Kyiv's defense tactics add to the danger."
— The New York Times: "A Brutal Russian Playbook Reapplied in Ukraine"
— Institute for the Study of War: "Russian Offensive Campaign Assessment"
RUSSIA CLAIMS IT WILL CUT BACK KYIV ATTACKS: After negotiations today between the Russian and Ukrainian delegations in Istanbul — the two sides' first round of face-to-face peace talks in three weeks — Russian Deputy Defense Minister Fomin said Moscow would dramatically reduce its military offensive around Kyiv, per POLITICO's VICTOR JACK.
"The decision has been taken to fundamentally cut back military activity in the direction of Kyiv and Chernihiv," Fomin said. This would "increase mutual trust for future negotiations" in order "to agree and sign a peace deal with Ukraine," he added.
Fomin's remarks come after Colonel General SERGEI RUDSKOY, first deputy chief of Russia's General Staff, said Friday that "the main tasks of the first stage" of Russia's invasion "have been completed," and that Russian forces would focus their efforts in the breakaway Donbas region in eastern Ukraine.
UKRAINE OFFERS NEUTRALITY:Ukraine proposed a neutral status during peace talks with Russia in Turkey, an offer with hopes of reaching a cease-fire to end the war Moscow started.
"After the talks in Istanbul, Ukrainian negotiators said that their key demands included guarantees for Ukraine's security from the U.S., the U.K., France, Turkey, Germany, Canada, Poland and Israel," per The Wall Street Journal's JAMES MARSON, YAROSLAV TROFIMOV, and JARED MALSIN.
"This is the system we would like to build the future of Ukraine on," Ukrainian negotiator DAVID ARAKHAMIA told reporters after
the talks. "We want an international mechanism of security guarantees where guarantor countries will act in a similar way to NATO's article number five."
The Ukrainian position has moved away from demanding accession to NATO and softened to its current stance, clearly in an effort to compromise with Russia to stop the fighting. But few in Ukraine and elsewhere in the West believe Russia is negotiating in good faith.
EUCOM SAYS U.S. NOT TRAINING UKRAINIANS IN POLAND: Last night, Alex and PAUL McLEARY reported on Biden seeming to reveal the U.S. was training Ukrainian troops in Poland — potentially disclosing more direct U.S. assistance to help Ukrainians fight and kill Russians.
But Gen. Wolters said that's not the case today. "I do not believe that we are in the process of currently training military forces from Ukraine in Poland," he told the Senate Armed Services Committee today. "There are liaisons that are there that are being given advice, and that's different than I think you're referring to with respect to training."
In other words, American service members are verbally helping the Ukrainians, but that's far different than putting them through drills. If that's the case, it seems that the president once again made a gaffe, exaggerating the level of direct U.S. military support for Ukraine once the war began.
TOP TREASURY OFFICIAL PREVIEWS SUPPLY CHAIN SANCTIONS: Deputy Treasury Secretary WALLY ADEYEMO, speaking today in London, warned that a forthcoming round of Western sanctions against Russia will target supply chains and undermine "the Kremlin's ability to operate its war machine," per Reuters.
"In addition to sanctioning companies in sectors that enable the Kremlin's malign activities, we also plan to take actions to disrupt their critical supply chains," Adeyemo said. The goal of the measures — expected to also punish alternative military suppliers used by Russia — "is to use an integrated approach that includes export controls which will bite over time and sanctions that will bite immediately," he said.
Adeyemo went on to predict that nations such as China and India "are going to remain part of" the global financial system amid Russia's invasion, rather than economically disengage with the West. "The system has adapted and moulded to members that have come along to create huge reductions in poverty, and not just Western countries," he said, adding that "the benefits of the system far outweigh the risks."
IT'S TUESDAY:Thanks for tuning in to NatSec Daily. This space is reserved for the top U.S. and foreign officials, the lawmakers, the lobbyists, the experts and the people like you who care about how the natsec sausage gets made. Aim your tips and comments at [email protected] and [email protected], and follow us on Twitter at @alexbward and @QuintForgey.
While you're at it, follow the rest of POLITICO's national security team: @nahaltoosi, @woodruffbets, @politicoryan, @PhelimKine, @BryanDBender, @laraseligman, @connorobrienNH, @paulmcleary, @leehudson, @AndrewDesiderio and @JGedeon1.
CHINA ENTERS THE CHAT:U.S. Indo-Pacific Command chief Adm. JOHN AQUILINO has sent Congress a whopping $76 billion, five-year plan that calls for new airfields and training ranges spread across the Pacific, along with missile defense systems, long-range precision weapons, and other new capabilities to confront China.
An executive summary of the plan, obtained by McLeary(for Pros!), calls for $9 billion in fiscal 2023, with another $66.9 billion spread over the next four years.
The biggest slice of the request is $42.4 billion aimed at building a new air and missile defense system for Guam, along with deploying "electronic warfare, space, cyber, and over-the-horizon radar" systems across the region.
The document also asks for $25 billion to build new airfields and repair existing airstrips that would allow U.S. forces to spread out from megabases in places such as Guam and Okinawa, which provide juicy targets to long-range Chinese weapons. These sites would also provide new training ranges for the U.S. and its allies, and include facilities to forward-position equipment.
EUROPE TO DEFEND SWEDEN?German Chancellor OLAF SCHOLZ suggested the European Union would come to Sweden's defense if Russia attacked the non-NATO country, POLITICO's HANS VON DER BURCHARD reported.
Speaking at a joint press conference with Swedish Prime Minister MAGDALENA ANDERSSON in Berlin, Scholz noted that the EU had built a mutual assistance clause into its core treaty. He said that clause would be "taken very seriously" if it came to an attack against Sweden. "When it comes down to it, it can be relied upon," Scholz added.
Sweden and Finland, both in the European Union, say that the bloc is also defensive and that members should assist each other in their moment of need.
"Scholz's remarks indicated Berlin agrees with that assessment," per von der Burchard. "However, how much the EU could do to defend Sweden is open to question, given that — unlike NATO — it does not include the military superpower United States, or the United Kingdom, one of the Continent's few military heavyweights."
RUSSIA SAYS U.S. LAUNCHED CYBERATTACK. U.S. DENIES: The Russian Foreign Ministry claimed on its website that the U.S. launched a cyberattack on Russia's critical infrastructure — a claim the Biden administration firmly denies.
"The United States and its satellites are waging a large-scale cyberattack against Russia. Advanced information and communication technologies are being used almost every day to attack government agencies, media outlets, critical infrastructure and vital facilities," the ministry said. "The unprecedented scale of these attacks and their close coordination clearly indicate that the cyberwar waged against Russia by Ukrainian special ICT operations centres trained by US and other NATO experts is being reinforced with anonymous hackers and trolls acting on orders from the Kiev regime's Western mentors."
But EMILY HORNE, the NSC's spokesperson, said that's just not true. "The United States Government has not engaged in the activity described by Russia. Moscow's statements to the contrary amount to disinformation," she told The Hill's BRAD DRESS.
There's no evidence to support Russia's claim, and the Kremlin is known for pushing false narratives. Russia also often accuses adversaries of doing something right before it's about to do it. Last week, Biden said cyberattacks likely emanating from Russia were "coming."
BOARD GAMES:Our friends at Morning Defense (for Pros!) reported that Aerojet Rocketdyne CEO EILEEN DRAKE on Monday proposed former Air Force Secretary DEBORAH LEE JAMES and three others as replacements for WARREN LICHTENSTEIN and his slate of directors on the company's board.
In an SEC filing, Drake alleges Lichtenstein violated his fiduciary duties by launching a proxy contest for control of the company while Aerojet's now-defunct merger with Lockheed Martin was pending.
Drake's slate for the board also includes Gail Baker, a former Collins Aerospace executive; MARION BLAKEY, former head of Rolls-Royce North America and the Aerospace Industries Association; and former NASA Administrator CHARLIE BOLDEN.
Lichtenstein's list includes Heidi Wood, an executive vice president for business development at CAE; AIMEE NELSON, a "finance professional"; and JOANNE MAGUIRE, a former executive vice president leading Lockheed Martin's space business.
Both factions will seek to install their picks at the upcoming annual shareholders meeting, which has not yet been scheduled.
Oh, the drama!
RAND STALLS RUSSIA TRADE BILL: Sen. RAND PAUL (R-Ky.) is yet again frustrating his fellow Republicans' foreign policy messaging, per our own BURGESS EVERETT and ANDREW DESIDERIO — this time by single-handedly delaying a revocation of normal trade relations with Moscow, thereby slowing efforts to further incapacitate Russia's economy.
Paul is refusing to allow a quick vote on the bill absent a deal to narrow presidential power to enact sanctions, even though leaders in both parties have spurned that request. On Monday, Republicans aired long-building exasperation with their Kentucky colleague; Senate Minority Whip JOHN THUNE (R-S.D.) simply threw up his arms when asked if there was anything GOP leaders could do to move him.
But some Republicans instead criticized Senate Majority Leader CHUCK SCHUMER's handling of the trade bill and dismissed suggestions that Paul's holdup undermined their unity. Schumer could have allocated enough floor time to overcome Paul's objections rather than counting on a fast-tracked process that requires unanimous support, they pointed out.
FIRST IN NATSEC DAILY –– COST OF WAR ACT: A bipartisan trio is set to unveil the "Cost of War Act," which would require the Pentagon to reveal the cost per taxpayer of any U.S. military operation since 9/11.
The legislation, introduced today by Reps. NIKEMA WILLIAMS (D-Ga.), PETER MEIJER (R-Mich.) and SARA JACOBS (D-Calif.) — modernizes a measure first put forward by the late Rep. JOHN LEWIS (D-Ga.).
"With the rising costs Americans face right now, we owe our constituents clear information on government spending. When we invest in things like schools and the infrastructure we use daily, we feel the impacts in our communities. But it's much harder to grasp the costs and impacts of our military spending," Williams said in a statement.
"This is a critical step forward in our bipartisan effort to restore congressional authority and oversight on matters of national security," Meijer added.
The Cost of War Act is supported by the NAACP and progressive groups like Just Foreign Policy, VoteVets and Foreign Policy for America.
ROMNEY WARNS TRUMP COULD TRIGGER NATO REALIGNMENT: Sen. MITT ROMNEY (R-Utah) issued more dire predictions about the foreign policy dangers posed by a potential second DONALD TRUMP term — telling CNN Plus' KASIE HUNT that if the former president is elected again in 2024, it may result in a major transformation of NATO.
Trump's "America First" brand of diplomacy "frightens" fellow NATO members, Romney said, "and they wonder: Are we committed to NATO and to our mutual defense, or are we all going to go off on our own?" Trump threatened to abandon the alliance as president if other members didn't meet certain military spending levels.
If Trump were to return to the White House now, "I think it would represent a pretty dramatic departure for the world," Romney said. NATO allies "would say that they have to really rethink their own national security and the extent to which they want to be allied with us and instead be allied with someone else."
"I've had conversations with leaders of other nations now, members of NATO," Romney said, "and they raise this question: We're happy to see you committed to our mutual defense, but we don't know whether you're just committed short-term or whether this is a long-term and permanent commitment. I think it's long-term and permanent."
PROGRESSIVES BASH PENTAGON BUDGET:In a statement on Biden's proposed FY 2023 budget, the Congressional Progressive Caucus made clear it thinks a rise in defense spending — to $813 billion — is no bueno.
"It is simply unacceptable that after the conclusion of our longest war and during a period of Democratic control of both chambers of Congress, the President is proposing record high military spending," the caucus said. "As Pentagon spending has exploded, the federal government has been forced to pinch pennies for decades when it comes to investments in working families."
Biden is now deep in one of Washington, D.C.'s most classic traps: The right thinks the president isn't proposing enough for defense, while the left thinks he wants to spend too much. The president has been in town long enough to know that many will be angry no matter what he budgets.
— VIPIN NARANG has been sworn in as principal deputy assistant secretary of Defense for space policy. He is taking a public service leave from the Massachusetts Institute of Technology, where he serves as the Frank Stanton professor of nuclear security and political science.
—MICHAEL GREEN has been appointed as the new CEO of Sydney-based United States Studies Centre. Previously, he was the senior vice president for Asia at the Center for Strategic and International Studies in Washington, D.C.
—JAYSON BROWDER and MIKE SEXTON have joined Third Way's national security program as senior policy advisers. Browder was previously the principal national security adviser to former Rep. BETO O'ROURKE (R-Texas) and Sexton was founder of the cyber program at the Middle East Institute.
— MADELEINE ALBRIGHT, The Washington Post: "Resilience of spirit, more than intellect, is the key to life"
— FRED KAPLAN, Slate: "The Gaffe Heard Round the World"
— L. GORDON CROVITZ, POLITICO Magazine: "Opinion: U.S. Law Holds a Tool to Counter Putin's Propaganda. But Officials Aren't Using It."
Tomorrow Today
— The Center for Strategic and International Studies, 9:30 a.m.: "The North Korean Missile Threat: Expert Roundtable — with JOSEPH S. BERMUDEZ JR., VICTOR CHA, MARKUS GARLAUSKAS, ANKIT PANDA and SUE MI TERRY"
— The Middle East Institute, 9:30 a.m.: "Impacts of Russia/Ukraine Crisis on North Africa's Food and Energy Security — with ROBERTA GATTI, GEOFF PORTER, MICHAEL TANCHUM and INTISSAR FAKIR"
— House Armed Services Committee, 10 a.m.: "Full Committee Hearing: National Security Challenges and U.S. Military Activity in Europe — with CELESTE WALLANDER and TOD WOLTERS"
— Senate Homeland Security and Governmental Affairs Committee, 11 a.m.: "Business Meeting"
— New America, 12:30 p.m.: "Cronkite Global Week: Conversations Surrounding Global Challenges — with SUMMIA TORA, FAHIM ABED, ALI ADILI and CANDACE RONDEAUX"
— The U.S. Chamber of Commerce, 12:30 p.m.: "U.S. Cyberspace Solarium Commission: Accomplishments and Next Steps for U.S. Cyber Policy — with CHRIS INGLIS, JAMES LANGEVIN and MARK MONTGOMERY"
— The Air Force Association, 1 p.m.: "Air and Space Warfighters in Action: Lt. Gen. DAVID NAHOM and Lt. Gen. WILLIAM LIQUORI"
— The Hill, 1 p.m.: "Future of Defense Summit — with JAMES CLAPPER, STEVE CLEMONS, PAULA DOBRIANSKY, ROBERT GATES, KATHLEEN H. HICKS, WESLEY D. KREMER, MIKE ROGERS, REXON RYU, ADAM SMITH, STEFANIE TOMPKINS, CARLOS DEL TORO and CHRISTINE WORMUTH"
— House Armed Services Committee, 2 p.m.: "Subcommittee Hearing: Patient Safety and Quality of Care in the Military Health System — with DEZ DEL BARBA, R. SCOTT DINGLE, BRUCE L. GILLINGHAM, DERRICK LUCKEY, ROBERT I. MILLER, RONALD J. PLACE and SHARON SILAS"
— House Foreign Affairs Committee, 2 p.m.: "Subcommittee Hearing: The Ukraine Crisis: Implications for U.S. Policy in the Indo-Pacific — with DAN BLUMENTHAL, CHARLES EDEL, BONNY LIN and TANVI MADAN"
— House Homeland Security Committee, 2 p.m.: "Full Committee Hearing: Mobilizing Our Cyber Defenses: Securing Critical Infrastructure Against Russian Cyber Threats — with ADAM MEYERS, KEVIN M. MORLEY, STEVE SILBERSTEIN and AMIT YORAN"
— House Veterans' Affairs Committee, 2 p.m.: "Subcommittee Hearing: Legislative Hearing"
— Senate Foreign Relations Committee, 2 p.m.: "Subcommittee Hearing: The Assault on Freedom of Expression in Asia — with SARAH COOK, MARIA RESSA and JOEY SIU"
— The Institute of World Politics, 4:30 p.m.: "North Korea: The Continuous and Growing Threat — with JOHN SANO"
Have a natsec-centric event coming up? Transitioning to a new defense-adjacent or foreign policy-focused gig? Shoot us an email at [email protected] or [email protected] to be featured in the next edition of the newsletter.
And thanks to our editor, John Yearwood, who is never sure if we're retreating or advancing in our writing skills.
About The Author : Alexander Ward
Alex Ward is a national security reporter and anchor of "National Security Daily." Before joining POLITICO, Ward was the White House and national security reporter at Vox. He was also an associate director in the Atlantic Council's Brent Scowcroft Center on International Security where he worked on military issues and U.S. foreign policy. And he previously wrote the #NatSec2016 newsletter for War on the Rocks where he covered the 2016 presidential election and the candidates' views on national security.
About The Author : Jonathan Lemire
Jonathan Lemire is POLITICO's White House Bureau Chief.
About The Author : Quint Forgey
Quint is a breaking news reporter for POLITICO.
Quint previously worked as a digital producer and editorial intern for POLITICO, a freelancer and news intern for The Wall Street Journal, an associate producer for Louisiana Public Broadcasting, a reporting intern for The News Journal in Delaware, and a national reporting fellow for the Carnegie-Knight News21 program.
Quint graduated from Louisiana State University, where he served as editor in chief of the student newspaper, The Daily Reveille.


text:
By Allan Hunter2014-05-18T09:59:00+01:00
Diir Melanie Laurent. France. 2014. 91mins
Breathe (Respire) offers ample evidence of the growing confidence and skill of Melanie Laurent as a director. Her second feature is an assured, carefully calibrated adaptation of the bestselling novel by Anne-Sophie Brasme, published in 2001 when the author was just seventeen. It depicts turbulent adolescent emotions and insecurities with an understanding on a par with the films of Celine Sciamma and Katell Quillevere.
Laurent has a good eye for casting. Rising star and Cesar winner Lou de Laage has the look of a young Jeanne Moreau and is effective as the callous Sarah.
It allies that to a Single White Female/ The Page Turner style scenario of an intense friendship twisted by jealousy, instability and betrayal. The result is an intriguing and ultimately compelling psychological drama that overcomes any initial reservations that we have seen similar stories too often before for it to make a significant impact.
Laurent's profile as an actor and positive critical support should result in a healthy Festival life and theatrical sales in territories where Sciamma and Quillevere have proved successful. The studious, seventeen year-old Charlie (Josephine Japy) seems more susceptible than most to the offer of friendship.
The strain in her parents' relationship leaves her especially vulnerable when new girl Sarah (Lou de Laage) arrives at school. Sarah is bold and sassy, makes tall claims about her mother's humanitarian work in Nigeria and Sarah finds her completely irresistible. The familiarity with countless psycho thrillers and de Laage's slightly overstated performance will have alerted most viewers to the fact that she is not to be trusted.
The two girls are soon inseparable and Charlie starts to resent anything that comes between them or distracts from her own needs. Sarah only has to compliment Charlie's mother Vanessa (Isabelle Carre) or flirt with a boy for Charlie to feel intensely jealous. It also gives Sarah all the power in the relationship and she has no scruples about using it when she starts to play dangerous mind games with the fragile Charlie.
Breathe is guilty of being a little too obvious for its own good. A classroom discussion on passion concludes that it is harmful when it becomes excessive and one lesson focuses on a plant that sucks the life out of another to sustain its own existence. We do get the point.
In most other respects, the film is a concise and thoughtful piece of storytelling. The school world is sketched with economy and conviction. Laurent often observes scenes from a distance or a concealed vantage point lending a sense of discretion and intimacy to the story.
Once the relationship between the two teenagers takes a turn towards the destructive, the film becomes much more involving although attempts to suggest that each girl is guilty of manipulation in their own way flounder because our sympathies are so resolutely drawn towards Charlie. Laurent has a good eye for casting. Rising star and Cesar winner Lou de Laage has the look of a young Jeanne Moreau and is effective as the callous Sarah. Josephine Japy has the more demanding role and is very impressive, capturing the mental torment, physical suffering and troubling complexity of Charlie.
Production company: Move Movie, Gaumont, Mely Productions
International sales: Gaumont, www.gaumont.fr
Producer: Bruno Levy
Screenplay: Julien Lambroschini, Melanie Laurent from the novel by Anne-Sophie Brasme
Cinematograpy: Arnaud Poitier
Editor: Guerric Catala
Main cast: Lou de Laage, Josephine Japy, Isabelle Carre, Claire Keim, Roxane Duran
Critics' Week
'And Then We Danced', 'Aniara' lead winners at Sweden's 2020 Guldbagge awards
The former took best film with the latter winning best director.
Leading German filmmaker and LGBT+ activist Rosa von Praunheim: "I made a lot of difference and I was controversial"
von Praunheim will receive the inaugural Max Ophüls Prize Film Festival lifetime achievement award.

redpajama_set_name: RedPajamaCommonCrawl


text:
Plenty more to come, says Djokovic
photo by Agency photo
Serbia\'s Novak Djokovic kisses the winner\'s trophy after beating Switzerland\'s Roger Federer in the men\'s singles final match during the presentation ceremony on day thirteen of the 2014 Wimbledon Championships on Sunday.
By AFP, London
14th-Jul-2015
Novak Djokovic vowed there are more Grand Slam titles to come after he clinched a third Wimbledon and ninth career major on Sunday. After seeing off Roger Federer for the second year in succession at the All England Club, the world number one moved ahead of Andre Agassi, Jimmy Connors, Ivan Lendl, Fred Perry and Ken Rosewall, who all won eight Grand Slams. He now stands five behind the 14 captured by Rafael Nadal and Pete Sampras, although the record of 17 held by Federer may prove too distant an obstacle. Djokovic is only 28 so has time on his side, especially as Federer is still a contender even at 33. "I think there is no reason not to be satisfied with what I have achieved. If you would have asked me as a 14-year-old back in Serbia trying to find my way, that this is how I'm going to end up at 28, of course I would sign the deal and take it right away," he said. "I'm 28. I feel good. I don't feel old. I have hopefully many more years in front of me. I'm going to try to push my own limits and see how far I can go really with titles and with myself playing on this high level." Eight of Djokovic's nine Grand Slam wins have come since January 2011. But he is also fired up by having lost eight finals at the majors, three of them at the French Open in the last four years as Roland Garros continues to frustrate him. "There were a couple of Grand Slam finals that I think I could have won. But, again, having said that, everything happens for a reason," said Djokovic. "I try to learn from every experience, especially the ones that don't end up victorious for me. I'm going to keep going." - Remarkable record - Victory on Sunday took Djokovic's record in 2015 to six titles -- the Australian Open, Masters events at Indian Wells, Miami, Monte Carlo and Rome and now a third Wimbledon in four years. His match record is remarkable 48 wins against just three defeats. The most recent loss was to Stan Wawrinka in the French Open and Djokovic said he was relieved that Wimbledon came along so quickly to help him ease his misery. "If I lost this final today, obviously the situation would be entirely different and the approach would be entirely different. I'm just glad I managed to make it," he added. "It's actually good that we have Wimbledon just a few weeks after Roland Garros because I had pretty much two years the same situation, where I lose in four sets, against Nadal last year, against Wawrinka this year. "I was disappointed and heartbroken. But if there is one thing that I learned in the sport is to recover fast and to leave things behind me and move on." Sunday's win evened his career match-up with Federer at 20-20 but he has now won five of their last seven meetings at the Grand Slams. He is also 19-8 to the good against Andy Murray, winning their last eight meetings. Despite trailing Rafael Nadal 23-21, Djokovic has won six of their last seven matches. All in all, he is looking the most likely to pick up a second US Open in the year's final major in New York in August and September.


Technology has changed the way people consume information. But newsletters are not dead… when done right.
In this video, I outline some key points that will reduce unsubscribers and engage your audience long term.
Engagement happens inside an e-newsletter when someone clicks on a link you provided or contacts you as a result of receiving it.
But first, you must woo.
Tell them something useful that will improve their life. This is also a form of engagement and you do not want to lose them here.
Avoid rejection with less talk and more action.
Keeping your newsletter brief and skimmable is important for engagement. If it takes too long to get to the important stuff, or there's too much fluff to skim through, they may leave before you ever pop the question. Give them value and give it to them fast!
#Newsletter Tip: Reducing clutter and call-to-actions will simplify the reader's choice to act.
Then, and only then, add value by giving them that link to dive deeper.
You can provide a button or text link, or both in separate areas. The most important thing to remember about your button or link is that you are asking them to click it.
Instead of "Newsletter Tips" your button could say "Yes, I want to learn how to write a better newsletter!" Then when they read it, they hear themselves telling themselves what to do. This tactic has been proven to work better – give it a try and see for yourself!
#Newsletter Tip: All call-to-action should link back to your own content.
People may not be ready to pick up what you're putting down at the moment.
Maybe you sparked interest, even if they're not ready to commit. Maybe your email reminded them they wanted to check out that thing you shared a while back.
Make sure you give them every opportunity to respond to your newsletter or reach out to you on social media.
#Newsletter Tip: Provide various contact options like social links, website, phone, and location.
Show your e-newsletter some love this next go 'round.
Apply these ideas to create a more authentic inbox experience for your subscribers. Bonus points if you check your analytics or do A/B split testing for hard stats.


I know that there is nothing better for people than to be happy and to do good while they live (Ecclesiastes 3:12, NIV).
The Bible is not only God's personal love letter to His children, it is our instruction manual for life. It is the blueprint of God's plan for our lives.
You were created in response to God's plan for your life. You are not an accident. God never has to say "Oops!" Even if you were never wanted or planned by human heart and mind, you were wanted and planned in the heart and mind of God. And you were created for purpose.
How do you discover God's plan and purpose for your life? Through the Word of God and through prayer.
God's truths are both personal and practical, but it is the practical that puts truth into play.
It is truly an awesome thing when God speaks to us, directs us, or encourages us personally. It builds faith - big time.
But it is even more awesome when we do something about it – because then the truth takes on life-changing power.
Hearing the truth is only half the battle.
Obeying the truth is where the real battle begins.
Time and time again in the gospels, Jesus gave personal words of truth to those who were following Him. Many heard the truth, but turned away without acting on it.
The seed falling on rocky ground refers to someone who hears the word and at once receives it with joy. But since they have no root, they last only a short time. When trouble or persecution comes because of the word, they quickly fall away (Matthew 13:19-21).
We have all done this.
We get excited when we hear from God and "receive it with joy." But because we do not apply it, that word from God only lasts a short time in our lives. When trouble comes, we fall right back into our normal pattern. We go right back to being the same way we were before we heard God speak.
It is not hearing from God that changes our lives. It is applying what we hear from God that changes our lives.
When God speaks to us and gives us new truth, we need to ask ourselves what our next step will be.
What am I going to do about the truth God has given me?
How am I going to apply that truth?
What changes do I need to make in light of that truth?
How should I pray as I walk in that truth?
When we hear from God and think we are done – that is self-deceit.
When we hear from God and put it into practice – that is godly obedience.
The thing you should want most is God's kingdom and doing what God wants. Then all these other things you need will be given to you (Matthew 6:33, NCV).
Truth is for now. God is not impressed with good intentions. Obedience today is the greatest preparation for every tomorrow. When you hear the voice of God, when He gives you a new truth – act on it. Apply that truth to your life and see what God does in your life.
Do what you know to do today!
Father, please teach me how to pray. Help me learn to hear Your voice above every other voice in my life. I want to obey You, Lord, but sometimes my faith seems so small. Forgive me when I let fear keep me from walking in Your steps. Give me a hunger and thirst for Your Word. My heart longs to be the kind of woman who hears Your voice and then steps out in radical obedience to You alone.
Today's devotion was taken from a new E-Book, Chair Time, written by Dan Southerland, Mary's husband. Chair Timeis a simple but powerful must-read for anyone wanting to learn how to pray and hear the voice of God. Check it out!


text:
Q: Apply formulas across infinite columns, ARRAYFORMULA not working I have a google form set up to track different expenses.

The first four columns are auto-filled, the last column is generated using,
=TEXTJOIN(" ", TRUE,C2,IF(D2 = "","",": "),D2)
This works fine, but I have to apply it to the rows I want. In theory, if the form inputed thousands of rows, that would mean scrolling down and dragging the formula across all those rows.
The other method I have tried is =ARRAYFORMULA(TEXTJOIN(" ", TRUE,C2:C,IF(D2:D = "","",": "),D2:D)), however this ouputs all the text in one cell:

Are there any other solutions that will allow me to appended the two strings for each column, indefinatly across many rows.

A: I would just use simple concatenation rather than textjoin, either using concat or (as below) ampersand:
=ArrayFormula(if(A2:A="","",if(D2:D="",C2:C,C2:C&" : "&D2:D)))

redpajama_set_name: RedPajamaStackExchange


Until today, tuning drums to clear resonant sounds has been a nearly impossible task for only the best of experienced drummers and drum technicians. Finally, DrumTone has a tuning system that is so fast and easy that drummers will be waiting on the other musicians to tune up before performances. Any drummer knows how difficult it is to acheive the perfect sounding drums for a particular song or style of music, then the weather changes and so does your sound... Plus, when drums are moved all kinds of mechanical changes occure to them effecting their sound. And there are so many styles of music that are popular today that drums need to be as versitile as all other instruments, changing tones and pitches between sets and even during songs. Drums have been the foundation of music since time began. As Sting once said; "There is no good band without a good drummer". All good drummers play great sounding drums... Adding DrumTone tuning to your drums will make them sing like never before!


You will receive correspondence shortly regarding the that you have just registered for. We look forward to your attendance.
START YOUR FREE DARKTRACE PROOF OF VALUE WITH GROVE TODAY!
A Darktrace Proof of Value (POV) is an easy way to discover the value of Darktrace's unique technology for your organization.
Over 4 weeks, allow the Darktrace technology to visualize your network's activity in real time, and detect in-progress threats or anomalies that you would not otherwise know about.
Our experienced team will install a Darktrace appliance within your environment in just one day, and give you access to our groundbreaking Threat Visualizer interface.
During the POV, you will also receive detailed analysis of what Darktrace discovers, produced by our world-leading cyber analysts. You will receive three weekly Threat Intelligence Reports, explaining incidents and anomalies that have been uniquely discovered by the Enterprise Immune System. These reports will help you better understand your environment, share new intelligence within your organization, and identify potential threats before they do damage.
Learn first-hand why some of the world's leading organisations rely on Darktrace's machine learning-based technology to shine a light into their networks and detect anomalous activity that bypasses traditional security tools.
Please, keep me updated on Grove news, events and offers.
When you need to drive gut-level behavior improvements at scale through cybersecurity awareness training that makes people care - look no further than Ataata's cybersecurity training platform. With employee risk scoring- cyber risk management has has never been easier! Ataata's cybersecurity training closes the circle on performance, action, and outcomes!
This is cybersecurity training done right! Cybersecurity awareness topics that are made fun, delivered fast and have proven effective! So book your free demo with Grove today!
The Darktrace's Enterprise Immune System is best understood through a demo. In addition to showing you the technology and functionality of the Darktrace solution, a Grove expert will work with you to determine how we can best enhance your existing security services and practices.
G Suite Basic/ Business/ Enterprise is best understood through a demo. A Grove expert will not only show you G Suite's range of office suites (with its advanced controls and capabilities) but will also work with you to determine how best to enhance your existing infrastructure and see which plan works best for you.
So book your G Suite Demo with Grove today!
Right now, a race is in progress that will disrupt every industry, every market, in every way we know. A race to leverage machine learning data mining across every device, asset, tool and employee to gain seismic efficiencies from historic and real-time data insights. Grove's analytics offering combines the power of Big Data analytics and the Internet of Things (IoT) technology with prescriptive algorithms, to create a new breed of super-efficient organisations.
Take an informed Action. Turn your Data into Insight and then your Insight into Action! Book a Discovery Meeting Today!


text:
Blessings Collegiate Invitational presented by Tyson Foods returns to Blessings Golf Club October 3-5, 2022
Tournament field to feature premier men's and women's collegiate programs from across the United States
FAYETTEVILLE, Ark. – Blessings Golf Club will host the third annual Blessings Collegiate Invitational presented by Tyson Foods this fall, announced today by tournament officials. Slated for October 3-5, the event is expected to feature 11 of the top men's and women's teams from across the country, including hosts and defending tournament champions, the Arkansas Razorbacks. The tournament will be broadcast live on GOLF Channel Monday, October 3 – Wednesday, October 5 from 3:30pm – 6:30pm CT each day.
"We are honored to welcome the collegiate level's best players back to Northwest Arkansas and Blessings Golf Club for this year's Blessings Collegiate Invitational," stated John Tyson, Chairman of Tyson Foods, Inc. "The Blessings Collegiate Invitational provides an opportunity for student-athletes to display their games on a global stage, while also shining a spotlight on the Northwest Arkansas region and the world-class amenities here."
The Blessings Collegiate Invitational is a 54-hole stroke play competition, with the men's and women's teams competing on the same course and in the same conditions throughout the week. The comprehensive tournament field includes a lineup of distinguished programs from top conferences such as the AAC, ACC, Big 12, Mountain West, Pac-12 and Southeastern Conference. Participating schools include Arkansas (host), California, Central Florida, Clemson, Kansas, Louisville, Mississippi, Mississippi State, Texas A&M, UCLA and UNLV.
"We look forward to hosting a powerhouse lineup of collegiate programs at our home course this fall for another exciting edition of the Blessings Collegiate Invitational," stated University of Arkansas men's golf coach, Brad McMakin. "We encourage Razorback fans from across the region to mark their calendars to come out and support these talented student-athletes compete later this year," added University of Arkansas women's golf coach, Shauna Taylor.
The second annual Blessings Collegiate Invitational presented by Tyson Foods was held in October 2021, featuring a dominant performance from the University of Arkansas men's and women's programs. The Razorbacks captured all six tournament titles including Women's Medalist (Brooke Matthews), Men's Medalist (Luke Long), Mixed Pairs Best Ball (Brooke Matthews and Mateo Fernandez de Oliveira), Women's Team Title, Men's Team Title and Overall College Champion.
Volunteer opportunities for the tournament will be announced in the coming months, with registration expected to open in July 2022. To stay up to date with event information and news, please visit BlessingsCollegiate.com or follow the event onFacebook, Twitter, or Instagram.
Contact: Lakyn Moren – Outlyr | (870) 321-0225 | LMoren@Outlyr.com


I despair of the expensive and pointless boundary review that moves a few thousand people from one constituency to another in a misguided attempt to make every vote equal. Votes can never be equal under our first past the post system.
A Conservative voter in Manchester is effectively disenfranchised.
As a Labour supporter in Sussex, I have no representative who shares my values. People complain about voter turnout; I am amazed that it is so high. Most votes are wasted.
Voters who live in marginal constituencies have a much more powerful vote, notwithstanding the size of the constituencies.
They decide the government of the nation.
The rest of us, in Chichester and most places in the UK, are lumbered with a General Election result that is more or less a foregone conclusion, and local councillors who represent a narrow section of local people.
Perhaps we need a multi constituency, multi member system of proportional representation so Manchester can have more Conservatives, and more importantly to me, Sussex could have some socialists?


text:
Microsoft Teams will no longer work on Internet Explorer 11
Facebook acquires Kustomer- a "customer relations" startup, reportedly for a billion dollars
Published on 30 November 2020, 22:19 Asia/Kolkata
If you are an Internet Explorer (IE) user, then this is the right time to make the transition to either Microsoft's Edge or some other web browser, as Microsoft Teams will no longer work on IE 11 starting from today. Other Microsoft services will also stop working on the browser over time.
On August 17th, 2020, the company detailed the upcoming changes that will affect IE 11 and the legacy version of Edge in a blog post titled "Microsoft 365 apps say farewell to Internet Explorer 11 and Windows 10 sunsets Microsoft Edge Legacy."
As the title suggests, Microsoft 365 apps will stop working on IE 11, including Microsoft's Teams web app, which is a video conferencing service similar to Zoom. "Today, we're announcing that Microsoft 365 apps and services will no longer support Internet Explorer 11 (IE 11) by this time next year," the tech giant wrote in the blog post.
The company has provided a timeline: Microsoft Teams will stop supporting IE 11 starting from November 30, and the 365 apps will end the support from August 17, 2021. Other than the end of support for IE 11, the company is also ending its support for the legacy version of Microsoft Edge browser starting from March 9, 2021.
All these changes appear to be part of the push towards Microsoft's latest Chromium-based Edge browser, which is a successor to the Internet Explorer.
The company, however, made it clear in the post that Internet Explorer is not completely going away. "We want to be clear that IE 11 isn't going away and that our customers' own legacy IE 11 apps and investments will continue to work. Customers have made business-critical investments in IE 11 legacy apps and we respect that those apps are still functioning."
Anyone familiar with Microsoft Windows, knows about the Internet Explorer. IE was Microsoft's default browser for decades, but it was not everyone's favorite. It has gained a reputation for being extremely slow, and this continues to spawn hilarious IE memes on the internet even today.
In an attempt to fix this, Microsoft decided to get rid of IE entirely by introducing a new browser called Edge (now legacy version) and made it the default browser of Windows 10. The EdgeHTML based browser received mixed reviews, and eventually led to the creation of Chromium-based Edge which Microsoft announced on January 15.
The latest browser was well-received by both users and critics, and the move to develop a browser based on Google's Chromium was a welcome change. By ending the support of various apps on IE, the company is giving a clear indication that it wants its users to transition to the latest version of Edge.
"While we know this change will be difficult for some customers, we believe that customers will get the most out of Microsoft 365 when using the new Microsoft Edge. We are committed to helping make this transition as smooth as possible," the company wrote in the blog post.


God love you, and doesn't like to you suffer.
But what is faith, faith is trust, Can a person say I trust you and go against the advise that you give. The advise that Jesus gaves us is written in John 17: 3 This means everlasting life, their taking in knowledge of you, the only true God, and of the one whom you sent forth, Jesus Christ.
So put your trust in Jesus and you will see him again.
I also lost my dad 6 months ago. It was march 2014. And I still carry that burden. I can't move on. My family still can't let go and my mom always cry. I always ask God why. I still can't understand why it happened.
I always say 'why' in my past, from kid till now i always see bad thing, i live in bad things, meet people have really bad problem. but someday i tired to asking why, cause i never got the answer, i cant believe god again, cause i cant heard his words to answer me, i walk alone, n tried to die, but in my downfall i remember luke 11:9-> ask and it shall be given you, seek and ye shall find, so i seeking god again, and ask Him to answer. Then with many process i saw my life changed, i knew what my calling for. God told me in rome 12:16 do not set your mind on high things, but associate with the humble. Do not be wise in your opinion. after that i try to let go my load..i put it before god's feet. Thats not easy but day by day god made me understood, n i began work with Him in His work. I feel free n i can say now, yes.. WE KNOW NOW that all things work together for good to them that love god, to them who are called according to his purpose.
#^_^ in this world the person who reasonable asking to god about why is job, he lost everything in His life n get sick without made a sin.but in the end he know why god did.


Updated, crisp traditional home in booming Collier Hills - within Brandon school district. Spacious and cozy formal living room and dining room. Updated kitchen with stainless steel appliance & granite counters opens to large family room with built-in cabinetry + sunroom. Master suite with fully renovated bathroom. Large deck/patio and private backyard. Gleaming hardwoods throughout. Walk to neighborhood park. Fantastic curb appeal.


text:
Living Our Retirement Dream Kapoors Year 7: Europe/Ecuador/Peru
Kapawi EcoLodge - Day 1
We Set Off By Bus, Through The Avenue Of Volcanos, This One...
Here Two High Mountain Streams Combine To Form The Pastaza River, A...
At The Private Airport At Shell, We Were Each Weighed, Along With...
Show all 27 photos
Our Group Of Eight Was Crammed In With The Pilot And Our...
We Lifted-Off, And Before We'd Travelled Any Distance At All, We Were...
We Reached Cruising Altitude Above The Rain Forest, But Here And There...
The Trip Was Uneventful, And Before We Knew It We Were Almost...
For Some Reason, I Was Surprised To Land On A Dirt Runway,...
We Managed To Scramble Out Of The 10-Seater Plane, No Limbs Numb...
We Were Asked Not To Take Photos Of Any Of The Buildings,...
On Our Short Walk To Our Boat, Our Guide Omar Spotted A...
We Donned Life Jackets And Settled In For The One-Hour Journey To...
Along The Way We Spotted An Area Being Cleared For Cultivation By...
At Last We Arrived At Our Final Destination, Our Home For The...
The Traditional Buildings Are Set Around A Secluded Lagoon, Raised On Stilts...
We Were Assigned Hut #3, It Looked Pretty Small From The Outside
But Was Surprisingly Spacious And Roomy On The Inside, With An Attached...
After Settling In, We Headed Towards The Common Area, Here Is The...
We Walked Out On The Boardwalk Over The Lagoon For A View...
The Lodge Was Big Enough To Accommodate 35 Guests, But There Were...
Our Little Home-Away-From-Home Is On The Left, It Was A Bit Of...
When We Arrived, One Of The Kitchen Staff Was Just Unloading Yucca,...
After Lunch And A Brief Rest, We Set Out To A Muddy...
It Was Great To Walk In The Warm Mud, No Rubber Boots...
I Looked Down And Saw This Creature, We Had Clearly Invaded His...
After Dinner, Our Guide Omar Showed Us This Map, And Explained That...
Our Local Achuar Guide, Wore A Traditional Headdress Made Of Toucan Feathers
No sense in re-inventing the wheel. I'll take some of the information about the Kapawi Ecolodge and Reserve from the Digital Magazine they sent us when we booked our tour:
Kapawi Ecolodge and Reserve is one of the most remote, ecologically responsible, and culturally sensible ecolodges in the world. Your visit helps the Achuar in their job of preserving 700,000 hectares of pristine forest in the Ecuadorian Amazon.
An Achuar is a living encyclopedia that can recognize each bird and other animals with which they share the forest. From each plant and from every tree, they can explain its benefits and medical applications they have learned from their grandparents. According to them, every plant and animal also has its own soul and life.
A native Achuar guide and a formally trained naturalist guide will accompany you on your exploration of the Amazonian jungle.
Kapawi Ecolodge sits deep in Ecuador's southeastern part of the Amazon Basin, near the Peruvian border. Just a few miles from the Pastaza River, one of the major tributaries of the Amazon, the lodge was built in Achuar territory in 1993. It is a remote region, untouched by logging, mining or petroleum extraction. The closest road is a ten-day walk from the lodge. Kapawi itself is only accessible by air.
Kapawi Ecolodge and Reserve offers you the unique opportunity to visit the Achuar community and feel the experience of interacting with a culture that was isolated from the outside world until the end of the 20th century.
The Lodge was built by a team of native craftsmen who used traditional materials and techniques to incorporate more eco-friendly and low impact technologies, making it a unique Ecolodge working with sustainable principles. Since January 1, 2008, the Kapawi Ecolodge and Reserve is a legally constituted company fully owned by the Achuar and has the backing of the NAE (Achuar Nationality of Ecuador) for all its activities. More than ninety percent of the Lodge staff is composed of natives from the area with training in each work position.
The application of good practices, our policies of sustainability and quality of service has been recognized by organizations such as National Geographic Adventure as of the Top 50 Ecolodges in the World, the United Nations also granted us the Equatorial Prize 2010 as of one of the best Projects at the World Level for our work in environmental preservation and social development.
KAPOORS ON THE ROAD
I am delighted to report that Anil wrote his first-ever journal entry in the form of an email sent to our close family and friends, shortly after our return from Kapawi. I was feeling the effects of the return to high altitude and Anil knew it would be some time before I would get around to writing an entry myself. We completely switched roles on this one – I got to act as Editor and was even allowed to enter an 'Editor's Note'.
14-Day Walk
We were picked up at our apartment on Monday at 5:30 am for our five-day excursion into the Amazon jungle. There were eight of us, all from Canada. We drove down the Pan-American highway called the 'Avenue of Volcanoes' hoping to get a glimpse of the two highest volcanoes here - Cotopaxi and Chimborazo - both over 20,000 ft. No clear glimpse of them as the clouds hung low.
Five hours later we arrived at a town where we got into a small plane and flew towards the southeast corner of Ecuador, close to the border of Peru. The hour-long plane ride was thrilling and it got us to the headwaters of the Amazon River. The runway was hard packed dirt and the little children come running every time a plane lands. No buildings of any kind in sight. It was a scene out of the movies except there were no drug runners!
Then we piled into a small boat and headed down the Pastaza River. It took another thirty minutes to get to the Kapawi lodge, our home for the week. We were welcomed with the line: " It is a 14-day walk to the nearest civilization". We were truly in the Amazon jungle.
Our typical day was to be awakened at 6:00 am, a quick cup of coffee, and it was off in the boat to look at the birds. Our guide would spot unusual birds and tell us a bit about their habits. There were parrots, toucans, hawks, ospreys and a host of other birds. We even got to see pink river dolphins.
Back to the lodge for breakfast at eight and then we went for a hike in the jungle. Rubber boots were mandatory as we often slogged through muddy trails. In the jungle hike we had a native guide who pointed out unusual plants and animals. We saw pocket monkeys (cute), bullet ants (stay clear), and were lucky enough to spot a Giant Anteater. We were asked to bring a clean pair of socks for each day as nothing gets a chance to dry. Loved the boots!
Editor's Note: Anil claims he's never worn rubber boots before, and it was obviously true as he had no idea how to take them off without getting his hands muddy. I had gone straight to the shower and called instructions to him while I rinsed the shampoo out of my hair. By the time I had finished my shower and toweled off, he had managed to get one boot off and his hands were still clean!
Lunch at 1:00 followed by a short rest and then we went kayaking in the river. They hauled our kayaks upriver so the current helped us as we paddled back to the lodge. Then a swim in the river and it was time to head to our room for a shower. Plenty of cold water but on sunny days you could have a hot shower. They had a black 5-gallon bag that they left in the sun for the afternoon. By the time the sun set the water was quite warm. They would hang the bag in the bathroom and there was enough warm water for each of us to have a quick shower. One day there was no sun so we had to have ice-cold showers.
Dinner and drinks at 7:00 pm. They had a fabulous chef at the lodge and there was plenty of beer, wine, and spirits. After dinner they had an optional activity of a hike or a river cruise to see the nocturnal animals.
One afternoon we went piranha fishing. We had to fish like the natives using their bait and line but we had no luck. However, our guide and our boatman, each caught a piranha so we were able to see the sharp teeth of this fish.
On our last morning we got to try a blowgun. The natives put poisoned darts in the blowgun and they can shoot down monkeys and birds from the top of trees. The blowgun is made from plant material and is about 10-feet long. I tried, but did not have the right technique to blow hard.
On our return trip the pilot asked us if we wanted to follow the river. This seemed strange, as we had followed the Pastaza River on our inward trip. Ten minutes into the flight we reached a section of the river that was fairly straight. The pilot pointed his nose down and pretty soon we were flying over the water at tree top level. What a thrill!
It was a clear day so on the way home we were able to see snow-covered Cotopaxi and a few other volcanoes. Also, a stop at a town that is famous for their ice cream. Vicki had the coconut ice cream that was great but I decided to give the Avocado ice cream a try. It was so-so.
All in all, it was a great week but now we are exhausted and need a few days to rest and adjust to the altitude. Quito is at 9,300 feet and leaves you gasping for air. Good preparation for Cusco, in April, which is even higher.


text:
// jshint node: true

'use strict';

var RESTAURANT_TYPE = 'Restaurant';
var REVIEW_TYPE = 'Review';
var RESERVATION_TYPE = 'FoodEstablishmentReservation';

var authRequest = require('../auth/authrequest');
var utils = require('../utils');
var geocoder = require('node-geocoder')('google', 'http');
var async = require('async');
var auth = require('../auth/auth');
var tv4 = require('tv4');
var schema = require('../schema/schema');

var config = require('../config');
var fiwareHeaders = {
  'fiware-service': config.fiwareService
};

tv4.addSchema('restaurant', schema.restaurant);
tv4.addSchema('reservation', schema.reservation);
tv4.addSchema('review', schema.review);

/**
 * Restaurants
*/

/**
 * Function used to POST at /api/orion/restaurant and generate a Restaurant
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.createRestaurant = function(req, res) {
  var elementToOrion = req.body;
  var validSchema = tv4.validate(elementToOrion, 'restaurant');
  if (validSchema) {
    var address = elementToOrion.address.streetAddress + ' ' +
                  elementToOrion.address.addressLocality;
    geocoder.geocode(address)
    .then(function(geoObject) {
      elementToOrion = utils.restaurantToOrion(elementToOrion, geoObject[0]);
      return utils.sendRequest('POST', elementToOrion, null, req.headers);
    })
    .then(function(postResponse) {
      utils.responsePost(postResponse, elementToOrion, res);
    })
    .catch(function(err) {
      utils.responseError(err, res);
    });
  } else {
    utils.returnInvalidSchema(res, tv4);
  }
};

/**
 * Function used to GET a restaurant at /api/orion/restaurant/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.readRestaurant = function(req, res) {
  var occupancyLevelsObject;
  var servicePath;
  var fiwareHeaders;
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(req.params.id));
  var currentDate = new Date().toISOString();
  var filter = [];
  var queryString = {};
  var timeframe = utils.getTimeframe(currentDate);
  utils.addConditionToQuery(filter, 'startTime', '==', timeframe);
  utils.addConditionToQuery(filter, 'reservationFor', '==', req.params.id);
  utils.addConditionToQuery(filter, 'reservationStatus', '==', 'Confirmed');
  queryString.q = filter.join(';');
  utils.getListByType(RESERVATION_TYPE, null, req.headers, queryString)
  .then(function(reservations) {
    occupancyLevelsObject = utils.updateOccupancyLevels(reservations.body,
                                                        currentDate);
    return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
  })
  .then(function(restaurant) {
    servicePath = restaurant.body.department;
    fiwareHeaders = utils.completeHeaders(req.headers, servicePath);
    return utils.sendRequest('PATCH', occupancyLevelsObject, restaurantId,
                             fiwareHeaders);
  })
  .then(function(patchResponse) {
    return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
  })
  .then(function(restaurant) {
    utils.returnResponse(restaurant, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a restaurant with a given date
 * at /api/orion/restaurant/:id/date/:date
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.readRestaurantWithDate = function(req, res) {
  var occupancyLevelsObject;
  var servicePath;
  var fiwareHeaders;
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(req.params.id));
  var filter = [];
  var queryString = {};
  var timeframe = utils.getTimeframe(req.params.date);
  utils.addConditionToQuery(filter, 'startTime', '==', timeframe);
  queryString.q = filter.join(';');
  utils.getListByType(RESERVATION_TYPE, null, req.headers, queryString)
  .then(function(reservations) {
    occupancyLevelsObject = utils.updateOccupancyLevels(reservations.body,
                                                        req.params.date);
    return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
  })
  .then(function(restaurant) {
    servicePath = restaurant.body.department;
    fiwareHeaders = utils.completeHeaders(req.headers, servicePath);
    return utils.sendRequest('PATCH', occupancyLevelsObject, restaurantId,
                             fiwareHeaders);
  })
  .then(function(patchResponse) {
    return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
  })
  .then(function(restaurant) {
    utils.returnResponse(restaurant, res, req.params.date);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to PATCH a restaurant at /api/orion/restaurant/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.updateRestaurant = function(req, res) {
  var queryString = {'options': 'keyValues'};
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(req.params.id));
  utils.sendRequest('PATCH', req.body, restaurantId, req.headers, queryString)
  .then(function(patchResponse) {
    utils.returnResponse(patchResponse, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to DELETE a restaurant at /api/orion/restaurant/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.deleteRestaurant = function(req, res) {
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(req.params.id));
  utils.sendRequest('DELETE', null, restaurantId, req.headers)
  .then(function(deleteResponse) {
    utils.returnResponse(deleteResponse, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of restaurants at /api/orion/restaurants
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getRestaurants = function(req, res) {
  utils.getListByType(RESTAURANT_TYPE, null, req.headers)
  .then(function(restaurants) {
    utils.returnResponse(restaurants, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of restaurants with a given organization
 * at /api/orion/restaurants/organization/:org
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getOrganizationRestaurants = function(req, res) {
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'department', '==', req.params.org);
  queryString.q = filter.join(';');
  utils.getListByType(RESTAURANT_TYPE, null, req.headers, queryString)
  .then(function(restaurants) {
    utils.returnResponse(restaurants, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Reviews
*/

/**
 * Function used to POST at /api/orion/review and generate a Review
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.createReview = function(req, res) {
  var elementToOrion = req.body;
  var restaurantName = elementToOrion.itemReviewed.name;
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(restaurantName));
  var filter = [];
  var queryString = {};
  var servicePath;
  var fiwareHeaders;
  var aggregateRatings;
  var endResponse;
  var validSchema = tv4.validate(elementToOrion, 'review');
  if (validSchema) {
    utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers)
    .then(function(restaurant) {
      servicePath = restaurant.body.department;
      return auth.getUserDataPromise(req);
    })
    .then(function(userObject) {
      fiwareHeaders = utils.removeServicePath(req.headers);
      elementToOrion = utils.reviewToOrion(userObject, elementToOrion);
      return utils.sendRequest('POST', elementToOrion, null, fiwareHeaders);
    })
    .then(function(postResponse) {
      endResponse = postResponse;
      utils.addConditionToQuery(filter, 'itemReviewed', '==', restaurantName);
      queryString.q = filter.join(';');
      return utils.getListByType(REVIEW_TYPE, null, req.headers, queryString);
    })
    .then(function(reviews) {
      aggregateRatings = utils.getAggregateRating(reviews.body);
      fiwareHeaders = utils.completeHeaders(req.headers, servicePath);
      return utils.sendRequest('PATCH', aggregateRatings, restaurantId,
                               fiwareHeaders);
    })
    .then(function(patchResponse) {
      utils.responsePost(endResponse, elementToOrion, res);
    })
    .catch(function(err) {
      utils.responseError(err, res);
    });
  } else {
    utils.returnInvalidSchema(res, tv4);
  }
};

/**
 * Function used to GET a review at /api/orion/review/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.readReview = function(req, res) {
  var reviewId = req.params.id;
  utils.getListByType(REVIEW_TYPE, reviewId, req.headers)
  .then(function(review) {
    utils.returnResponse(review, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to PATCH a review at /api/orion/review/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.updateReview = function(req, res) {
  var reviewId = req.params.id;
  var restaurantName;
  var restaurantId;
  var userId;
  var aggregateRatings;
  var servicePath;
  var fiwareHeaders;
  var filter = [];
  var queryString = {};
  var keyValues = {'options': 'keyValues'};
  utils.getListByType(REVIEW_TYPE, reviewId, req.headers)
  .then(function(data) {
    restaurantName = data.body.itemReviewed;
    restaurantId = utils.generateId(
      utils.fixedEncodeURIComponent(restaurantName));
    userId = data.body.author;
    return auth.getUserDataPromise(req);
  })
  .then(function(userObject) {
    if (userId === userObject.id) {
      utils.sendRequest('PATCH', req.body, reviewId, req.headers, keyValues)
      .then(function(patchResponse) {
        fiwareHeaders = utils.removeServicePath(req.headers);
        utils.addConditionToQuery(filter, 'itemReviewed', '==', restaurantName);
        queryString.q = filter.join(';');
        return utils.getListByType(REVIEW_TYPE, null, fiwareHeaders,
                                   queryString);
      })
      .then(function(reviews) {
        aggregateRatings = utils.getAggregateRating(reviews.body);
        return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
      })
      .then(function(restaurant) {
        servicePath = restaurant.body.department;
        fiwareHeaders = utils.completeHeaders(req.headers, servicePath);
        return utils.sendRequest('PATCH', aggregateRatings, restaurantId,
                                 fiwareHeaders);
      })
      .then(function(patchResponse) {
        utils.returnResponse(patchResponse, res);
      })
      .catch(function(err) {
        utils.responseError(err, res);
      });
    } else {
      utils.returnForbidden(res);
    }
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to DELETE a review at /api/orion/review/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.deleteReview = function(req, res) {
  var restaurantName;
  var restaurantId;
  var aggregateRatings;
  var servicePath;
  var fiwareHeaders;
  var filter = [];
  var queryString = {};
  var finalResponse;
  var reviewId = req.params.id;
  utils.getListByType(REVIEW_TYPE, reviewId, req.headers)
  .then(function(review) {
    restaurantName = review.body.itemReviewed;
    restaurantId = utils.generateId(
      utils.fixedEncodeURIComponent(restaurantName));
    return utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers);
  })
  .then(function(restaurant) {
    servicePath = restaurant.body.department;
    return utils.sendRequest('DELETE', null, reviewId, req.headers);
  })
  .then(function(deleteResponse) {
    finalResponse = deleteResponse;
    utils.addConditionToQuery(filter, 'itemReviewed', '==', restaurantName);
    queryString.q = filter.join(';');
    return utils.getListByType(REVIEW_TYPE, null, req.headers, queryString);
  })
  .then(function(reviews) {
    aggregateRatings = utils.getAggregateRating(reviews.body);
    fiwareHeaders = utils.completeHeaders(req.headers, servicePath);
    return utils.sendRequest('PATCH', aggregateRatings, restaurantId,
                             fiwareHeaders);
  })
  .then(function(pathResponse) {
    utils.returnResponse(finalResponse, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews at /api/orion/reviews
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getReviews = function(req, res) {
  utils.getListByType(REVIEW_TYPE, null, req.headers)
  .then(function(reviews) {
    utils.returnResponse(reviews, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews of a given user
 * at /api/orion/reviews/user/:user
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getUserReviews = function(req, res) {
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'author', '==', req.params.user);
  queryString.q = filter.join(';');
  utils.getListByType(REVIEW_TYPE, null, req.headers, queryString)
  .then(function(reviews) {
    utils.returnResponse(reviews, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews of a given restaurant
 * at /api/orion/reviews/restaurant/:restaurant
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getRestaurantReviews = function(req, res) {
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'itemReviewed', '==',
                            req.params.restaurant);
  queryString.q = filter.join(';');
  utils.getListByType(REVIEW_TYPE, null, req.headers, queryString)
  .then(function(reviews) {
    utils.returnResponse(reviews, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews of a given organization
 * at /api/orion/reviews/organization/:org
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getOrganizationReviews = function(req, res) {
  var organizationReviews;
  var reviewsList;
  utils.getListByType(REVIEW_TYPE, null, req.headers)
  .then(function(reviews) {
    reviewsList = reviews;
    return utils.getListByType(RESTAURANT_TYPE, null, req.headers);
  })
  .then(function(restaurants) {
    organizationReviews = utils.getOrgReviews(req.params.org,
                                              restaurants.body,
                                              reviewsList.body);
    res.statusCode = restaurants.statusCode;
    res.json(utils.dataToSchema(organizationReviews));
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Reservations
*/

/**
 * Function used to POST at /api/orion/reservation and generate a Reservation
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.createReservation = function(req, res) {
  var elementToOrion = req.body;
  var restaurantReservations;
  var capacity;
  var currentOccupancyLevels;
  var timeframe = utils.getTimeframe(req.body.startTime);
  var filter = [];
  var queryString = {};
  var restaurantId = utils.generateId(
    utils.fixedEncodeURIComponent(req.body.reservationFor.name));
  var validSchema = tv4.validate(req.body, 'reservation');
  if (validSchema) {
    utils.getListByType(RESTAURANT_TYPE, restaurantId, req.headers)
    .then(function(restaurant) {
      elementToOrion.address = restaurant.body.address;
      capacity = restaurant.body.capacity;
      utils.addConditionToQuery(filter, 'startTime', '==', timeframe);
      utils.addConditionToQuery(filter, 'reservationStatus', '==', 'Confirmed');
      utils.addConditionToQuery(filter, 'reservationFor', '==',
                                req.body.reservationFor.name);
      queryString.q = filter.join(';');
      return utils.getListByType(RESERVATION_TYPE, null, req.headers,
                                 queryString);
    })
    .then(function(reservations) {
      currentOccupancyLevels = utils.getOccupancyLevels(reservations.body);
      if (currentOccupancyLevels + req.body.partySize < capacity) {
        auth.getUserDataPromise(req)
        .then(function(userObject) {
          elementToOrion = utils.reservationToOrion(userObject, elementToOrion);
          return utils.sendRequest('POST', elementToOrion, null, req.headers);
        })
        .then(function(postResponse) {
          utils.responsePost(postResponse, elementToOrion, res);
        })
        .catch(function(err) {
          utils.responseError(err, res);
        });
      } else {
        utils.returnConflict(res);
      }
    })
    .catch(function(err) {
      utils.responseError(err, res);
    });
  } else {
    utils.returnInvalidSchema(res, tv4);
  }
};

/**
 * Function used to GET a reservation at /api/orion/reservation/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.readReservation = function(req, res) {
  var reservationId = req.params.id;
  utils.getListByType(RESERVATION_TYPE, reservationId, req.headers)
  .then(function(reservation) {
    utils.returnResponse(reservation, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to PATCH a review at /api/orion/review/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.updateReservation = function(req, res) {
  var restaurantName;
  var userId;
  var reservationId = req.params.id;
  var keyValues = {'options': 'keyValues'};
  utils.getListByType(RESERVATION_TYPE, reservationId, req.headers)
  .then(function(reservation) {
    userId = reservation.body.underName;
    return auth.getUserDataPromise(req);
  })
  .then(function(userObject) {
    if (userId === userObject.id) {
      utils.sendRequest('PATCH', req.body, reservationId, req.headers,
                        keyValues)
      .then(function(patchResponse) {
        utils.returnResponse(patchResponse, res);
      })
      .catch(function(err) {
        utils.responseError(err, res);
      });
    } else {
      utils.returnForbidden(res);
    }
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to DELETE a reservation at /api/orion/reservation/:id
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.deleteReservation = function(req, res) {
  var reservationId = req.params.id;
  utils.sendRequest('DELETE', null, reservationId, req.headers)
  .then(function(deleteResponse) {
    utils.returnResponse(deleteResponse, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reservations at /api/orion/reservations
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getReservations = function(req, res) {
  utils.getListByType(RESERVATION_TYPE, null, req.headers)
  .then(function(reservations) {
    utils.returnResponse(reservations, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reservations of a given user
 * at /api/orion/reservations/user/:user
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getUserReservations = function(req, res) {
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'underName', '==', req.params.user);
  queryString.q = filter.join(';');
  utils.getListByType(RESERVATION_TYPE, null, req.headers, queryString)
  .then(function(reservations) {
    utils.returnResponse(reservations, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reservations of a given restaurant
 * at /api/orion/reservations/restaurant/:restaurant
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getRestaurantReservations = function(req, res) {
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'reservationFor', '==',
                            req.params.restaurant);
  queryString.q = filter.join(';');
  utils.getListByType(RESERVATION_TYPE, null, req.headers, queryString)
  .then(function(reservations) {
    utils.returnResponse(reservations, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews of a given organization
 * at /api/orion/reservations/organization/:org
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getOrganizationReservations = function(req, res) {
  var filter = [];
  var queryString = {};
  var organizationsReservations;
  var restaurantList;
  utils.addConditionToQuery(filter, 'department', '==', req.params.org);
  queryString.q = filter.join(';');
  utils.getListByType(RESTAURANT_TYPE, null, req.headers, queryString)
  .then(function(restaurants) {
    restaurantList = restaurants.body;
    return utils.getListByType(RESERVATION_TYPE, null, req.headers);
  })
  .then(function(reservations) {
    organizationsReservations = utils.getOrgReservations(restaurantList,
                                                         reservations.body);
    res.statusCode = reservations.statusCode;
    res.json(utils.dataToSchema(organizationsReservations));
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

/**
 * Function used to GET a list of reviews of a given restaurant and date
 * at /api/orion/reservations/restaurant/:restaurant/from/:from/to/:to
 *
 * @param {Object} req - Request received
 * @param {Object} res - Response
*/
exports.getReservationsByDate = function(req, res) {
  var timeframe = utils.getTimeBetweenDates(req.params.from, req.params.to);
  var filter = [];
  var queryString = {};
  utils.addConditionToQuery(filter, 'startTime', '==', timeframe);
  utils.addConditionToQuery(filter, 'reservationFor', '==',
                            req.params.restaurant);
  queryString.q = filter.join(';');
  utils.getListByType(RESERVATION_TYPE, null, req.headers, queryString)
  .then(function(reservations) {
    utils.returnResponse(reservations, res);
  })
  .catch(function(err) {
    utils.responseError(err, res);
  });
};

redpajama_set_name: RedPajamaGithub