CM – The tiger mother and the hornets nest

0

It’s supposed to be haunted, « says Amy Chua happily as she leads me into the cave-like anteroom of the house in New Haven that she shares with her colleague from Yale Law School, Jed Rubenfeld. Chua helped me find the sprawling Tudor Gothic stone building by noting its « strange chimneys and griffins. » This is the house from which Chua and Rubenfeld – Chubenfeld, as they are half-heartedly called on campus – once held court. Yale Law, the country’s front runner, is both the intellectual greenhouse and graduation school of the American elite, and for the past two decades the couple have been « the institution’s self-proclaimed social center, » as a former faculty friend puts it. « You had the ability to create spectacles, to make yourself the center of a conversation. » Yale Law isn’t just the place where Bill and Hillary Clinton met and the four Supreme Court justices did their PhD. It promises intimacy and is half-jokingly referred to as the Montessori Law School. Only 200 students enroll each year, less than half of Harvard’s 1L class. These students, in turn, are put into the water on even smaller boats of 16 to 18 students – the « small group » – led by a single faculty member who introduces them to the world of law and Yale Law School.

There Rubenfeld was, as his wife says, “the great constitutional golden boy star” and she was the live wire, the embodiment of her bestseller Battle Hymn of the Tiger Mother from 2011: ready to outrage, but also to make herself the one Butt of the joke. In a place where everyone had brilliant credentials and longed for a way to stand out, the students believed that Chubenfeld’s favor, especially that of Chua, could pave their way to the top or at least to the trainee lawyers Upper class are obsessed. Both students and faculty flocked here for dinner and her big annual Harvard Yale party, and sometimes more glamorous gatherings like one she put on for Wendi Murdoch, who befriended her after the Wall Street Journal excerpted an excerpt from Tiger Mother had published. (« She raised two daughters, » says Chua, « and always wanted advice. » Murdoch was later photographed in New York with a dashing Yale law student on his arm.)

« I’m done, » says Chua. « I mean, these are some great memories, but the whole thing was so painful. » Now this house is the location of so much of what has recently made Chua, 58, and Rubenfeld, 62, pariah. Rubenfeld is halfway through a two-year unpaid ban after a university committee found he sexually molested at least three former students. The complainants I spoke to believe that at least seven of them have gone through the process. During this time Rubenfeld was blocked from contact with students and the course of a compulsory course. But recently, Chua has been the one on the public defensive.

It turns out that Chua was also being investigated by a law school fact-finder who investigated allegations that she was abusing her power over the clerkship , made inappropriate comments and “drank excessively” with students. In 2019, Chua suffered a « substantial fine », according to a letter received by the applicants. accepted limits when dealing with pupils; and apologized to the complainants for « comments I made jokingly or out of frustration that could be misinterpreted in ways that made them seem hurtful or intimidating ».

This was all secret until April earlier this year, the Yale Daily News reported that Chua would no longer teach a small group. Among other things, the students had gone to the administration with screen messages between students with used reports about being together at Chua’s house, which were then distributed via e-mail and subsequently republished on the blog Above the Law. Such gatherings also violated COVID-19 security protocols.

Chua has said she has been caught by the story and denies breaking agreements or throwing parties, despite admitting to inviting students to her home to to look after them as a mentor. “I was publicly humiliated with a total falsehood,” she tells me, “and I was treated in a humiliating way.”

Initially, she intended to keep calm, she says, until her daughter Lulu (the rebellious boy in Tiger Mother , now a law student herself) encouraged her to defend herself publicly. Chua posted a 67-page PDF of glowing letters from students, some of whom she thought would be graded by her, and her own angry letters to faculty. She tweeted her way from New Haven into the national demolition culture martyrdom defended by the likes of Bari Weiss and Megyn Kelly, who claimed Chua was really being punished for standing up for Brett Kavanaugh.

The text messages show Students who believed they were going to Chua’s house would get them a clerkship. Faculty members I’ve spoken to have mixed feelings. “There is a strange division among students where they want the place to be absolutely transparent and absolutely fair,” said someone sympathetic to this criticism, “but they also want to keep the prestige and privileges that the place offers . ”Three other professors told me that Chua is the victim of overzealous zoomers who have mistaken the natural hierarchy of achievement – and Chua’s right to favor whoever it pleases – for an outrage over social justice. « There are a lot of mediocre students at Yale who were superstars in their little fairs and now they’re in the Kentucky Derby and they don’t win their races and they feel unfair because other students are doing better, » says a faculty member who said the Opinion is that the dean, Heather Gerken, was too deferential to the students for how she handled the small group issue. « As dean, I have the responsibility to create a community in which all of our students can develop, » said Gerken through a spokesman. « When a faculty member breaks our rules and norms, it undermines all the good that comes from an environment where the faculty respects and supports our students. »

While Chua and I speak, I may take steps from time to time hear, but it is possible they belong to an aging Samoyed whom Chua regularly grooms and scolds. Finally, I ask if Rubenfeld, who has already declined an interview for this story, is at home. Chua hesitates. “He was outside earlier. But maybe he’s back. But I don’t think I can get him to talk, ”she says. Does she think he should? “We just live our own lives,” she replies. « I think it’s just his decision. »

Rubenfeld was more talkative last August when I wrote about his suspension. On the phone, he « absolutely, unequivocally » denied having sexually or verbally molested anyone, and attributed his punishment to a backlash against his scholarship. « I believe after I wrote some controversial articles about sexual assault, » he said, « I became the target of people making false accusations against me. » (One of the complainants calls Rubenfeld « the Louis C. K. the legal one. » Science “.)

The actual allegations and the proceedings were kept strictly confidential. This frustrates many faculty members. « I don’t know if he got away with anything or if he got the death penalty for jaywalking, » says one. « Maybe you do. I don’t. »

In the past few months I have read hundreds of pages of confidential documents from several sexual harassment lawsuits against Rubenfeld and spoken to some of the prosecutors who have gone through the Title IX Trial. The oldest formal allegation against him relates to events 20 years ago and as recently as 2017. They reported verbal harassment, unwanted touch and attempted kissing; complainants also include women who have never joined the public opposition to his work on sexual assault The documents show that several Yale faculty members refused to participate in the investigation « because they feared retaliation from Rubenfeld and / or Professor Amy Chua. »

Chua, who chose to keep me in my old shirt and the Hitting her daughter’s leggings with a hole in her knee says that she is not in this depiction again recognizes. « It was really a change to suddenly see myself as this incredibly connected, ruthless, powerful person who wields so much power in the clerkship process, » says Chua. “A lot of the things that I was encouraged and complimented to do 20 years ago, like making the house intimate for small groups that felt like they weren’t going anywhere else, became something that – and that’s what I’ll take care of Responsibility “- I didn’t really get that, oh my god, some people are not comfortable in this area or there is more competition than you thought for these spots. That’s not how I imagined it to be. « She adds, » My own perception of myself is kind of an underdog. « 

When Chua describes herself as an outsider, it refers to her husband. In Tiger Mother she writes that she “I was always concerned that the law wasn’t really my calling,” adding, “I didn’t care about the rights of criminals like others, and I froze when a professor called me.” To Rubenfeld, whom she addressed from Harvard Law School and married in 1988, she writes, « He wrote a 100-page article about privacy rights for fun – it just gushed out of it. » It was published in the Harvard Law Review, a coup for a recent corporate law graduate, and Yale called him in 1990.

« He was hired in what was seen as the old boys’ network for a young man, » says a colleague. Chua came a decade ago t later after she said she had bombed the interview and ended up with Duke in the meantime. Yale Law School students had started organizing around the fact that there was only one woman of color on the career path, and they hugged Chua, who playfully plunged into the mentoring and speaking process.

Chua’s insecurity about her place in law school was not unfounded, although many of her colleagues seem impressed with her public profile. « Jed is an important figure in the school’s intellectual life, » says one professor. « Amy, not at all. Was there ever a Yale law professor more famous than Amy Chua? No. On the other hand, she has no capital in law school because she is not a major academic. ”(She was an excellent party host, he admitted.)

Rubenfeld took on the role of the young genius turned provocateur. In class, he liked long eye contact, Socratic cold calling, and fancy hypotheses. He had studied with Juilliard and often left the room dramatically at the end of a lecture. Says one colleague, « He makes a living from the fact that the classroom is an erotic place where it’s so exciting to get involved in a risky exploration of ideas that continues with the risky exploration of all kinds of boundaries. » Around the time When the Obama administration began to urge universities to tackle sexual misconduct, Rubenfeld began exploring new territory in 2011: criticizing the rape law. “The Riddle of Rape-by-Deception and the Myth of Sexual Autonomy” appeared in the Yale Law Journal in 2013 and kept him busy in class.

“He would give these examples that were okay at first, and they would go on and on continue to lead. He asked if it was okay to penetrate a baby, ”told me a student who was in his small group in the fall of 2014. « Then he said, ‘You’re using a spoon to feed a baby. » « One of her classmates stared blankly at him as he did this, but she decided she was going to push back. « I think he liked it when people let themselves into the madness of his arguments, » she says.

Before Rubenfeld’s student walked onto Yale campus at the age of 25, she felt she had a sense of it have what fancy institutions looked like; she had attended small private schools all her life. The Gothic collegiate hall was lined with the portraits of Yale’s eminences, who at the time numbered 74 men and six women, all women except Eleanor Holmes Norton knows. Yale Law’s first black woman, Tracey Meares, had sent an email to encourage the student to attend law school by contacting accepted color students. At the time, the young woman’s ambitions were vague, but she liked the challenge of the law. “I think the law school culture really pushes people into clerkship,” she says. She and her fellow students would not be graded this first semester, which meant that the judges, who had already started recruiting valuable trainee positions this summer, relied heavily on the professors’ confirmation.

Professors in small Groups are budgeted for socializing, and most of these small-group meetings were held in bars or in a drinking house. Not all the small groups drank together – some picked apples or played stickball – but that was not unusual in itself. Rubenfeld often sent emails with the subject « emergency drinks » and there were many emergencies. He would buy the first round. One night the student ordered scotch in Cask Republic. She liked scotch, but now she says that her choice, if she’s honest with herself, was also an accomplishment, a show of toughness. Rubenfeld, impressed, ordered a second round of whiskey just for the two of them. When he drank, she recalls, Rubenfeld leaned over, touched her arm or back when he joined a conversation, or stared into her eyes.

She had heard rumors that Rubenfeld slept with students. When the Guardian asked Rubenfeld last summer if he had sexual relations with Yale students, he replied, « I have never had sexual relations with any of my students. » (The university did not ban such relations until the late 1990s. )

And she had heard of Chua’s reputation for getting trainee lawyers – that she walked her through the process, including how to sell yourself and to whom, and that judges looked out for her for her open views with students . Almost half of Yale’s law school staff, but not all trainee lawyers are created equal. So-called feeder judges in federal courts are most valued for providing the clearest pipeline for the Supreme Court bailiff, which is not only prestigious but also lucrative: the typical signing bonus for such a clerk in a law firm is $ 400,000, not counting the six-figure starting salary. Six of the nine incumbent judges were active at the court themselves. The student did not shrink from Rubenfeld’s touch.

Another evening, says the student, she was sitting at one end of the table when Rubenfeld asked the students about rape. He said he was working on a commentary for the New York Times on how rape is condemned, especially on campus, and that he wanted to know how they feel about it. If they were drunk, would they have sex with someone who was also drunk? What would you do if your partner wanted you to do something during a sexual encounter that you are not comfortable with? The statistics that every fifth woman was raped – was that true in your experience?

« I was very upset at the time, » the student tells me. « The fact that he questioned things like: Does sexual assault occur in the way it is reported? » But the point of Yale Law School, she was told, was to get close to professors, and later she told the Title IX committee that at that moment she understood, okay, I think to get close to professors, one has going out drinking with them and having intrusive and strange conversations about your sex life. (At that Title IX hearing, Rubenfeld denied ever getting drunk around students or asking specific questions about her sex life. Had he asked her those questions? He “would not have done it if she hadn’t brought it up first « )

On October 23, 2014 Rubenfeld held a party in his house for his former and current students in small groups. The party took place upstairs in the more casual attic on the third floor, where she noticed that many of the books on Rubenfeld’s shelves appeared to be written. He and Chua had just co-authored The Triple Package, which argued that certain ethnic groups succeeded through a combination of superiority complex, insecurity and self-control.

The student was late and was still wearing the low-backed blue peplum dress, that she had chosen for a banquet the night before. She had had a glass of wine at the event, but when she got there everyone had been drinking a lot and she thought Rubenfeld looked drunk. A few hours later it was time to leave. As she descended from the attic, her stiletto heel caught on the narrow spiral staircase and she fell with a rattling impact. First came the embarrassment: would people think she had drunk more than she had? Next came the feeling when Rubenfeld rushed in, helped her to her feet and, as she says, « rocked me ».

As much as the conversations about sexual assault had excited her, she says: « I had that too Feels like he was in good faith. ”That ended when his face was only inches away from hers. « The basis of my complaint about Title IX is that he tried to kiss me, » she says. “At that point I realized it wasn’t theoretical.”

Rubenfeld’s comment in the New York Times appeared under the headline “Mishandling Rape” three weeks later. He started by denouncing rape, then accusing universities of inflating their definition of sexual autonomy as a guiding principle. Universities had adopted a consent standard that required « conditions free from coercion, intoxication, and power imbalances, » he wrote, but « in fact, having sex with someone under the influence is not automatically rape. » All this « redefinition of consent », he wrote, would lead to « people seeing themselves as victims of sexual assault when there was no assault ».

His choice of topics caused a sensation among his colleagues. « The conspirators among us see this as strategically defensive, » says Doug Kysar, law professor.

Rubenfeld clearly loved this kind of blurring of lines in his work. Students whispered about how his first novel, the thriller The Interpretation of Murder, moved a sexualized murder in a Manhattan building in Ansonia where he and Chua own an apartment. An alum told me that the students jokingly referred to this as a « rape apartment » because of the fictional assault that took place at fictional Balmoral. (No rape is reported to have taken place in the Ansonia apartment.) This book had sold well in the UK, but it was nothing compared to Chua’s Tiger Mother’s PR supernova. The triple package, on the other hand, was a commercial and critical disappointment.

The couple’s daughter, Sophia, then a student at Harvard, told The New Yorker that her sister “always reads these tweets and says, ‘The tiger mom is back, and she’s still racist! ”It actually sends my mother into depression. But my father lives totally from confrontation. He says: ‘Overshadowed by my wife again! Why am I not also called a racist? ‘ « In an extensive review of The Triple Package in Time, Suketu Mehta lamented: » It is a pity that this book and this whole argument is taken seriously – among my relatives, for example – when all the scholars I have consulted laugh about it.  » In June, the Times hosted a party on the Opinion page. There, Mehta tells me, Rubenfeld put his hand on his shoulder in a way that Mehta found threatening and threatened to « kill » him. (Rubenfeld wrote in an email at the time that he told Mehta he wouldn’t hit him. At the same party, Mehta said: Chua put out a hand in a very friendly manner and said, ‘I know you didn’t like my book, but I love your novels. ”And I said,“ I haven’t written any. ”“)

Students angrily debated Rubenfeld’s Times-Op-ed on the campus listserv. Two students, including feminist organizer Alexandra Brodsky – who had joined a Title IX complaint against Yale College three years earlier as a student – circulated an open letter saying that Rubenfeld’s « formulation of the problem was both from the reality of the. » Victim is disconnected on the screen « . Cause and Wrong on the Law. ”Almost 100 students signed and a town hall was held to discuss the issues raised in the statement. Rubenfeld left.

He also emailed his small group apologetically: “I want you all to know that I know I made it difficult for you this week. You didn’t ask to have a professor who wrote what I wrote in the Times last Sunday. ”He said he wanted students to feel comfortable about disagreeing with him publicly, and added added: « Of course it goes without saying – but I’ll say it anyway – but things like references or recommendations are in no way influenced by anything someone says or does Don’t say on this topic. »

Not all took it for granted, though they were more concerned that Chua might get revenge. Two people told Slate in 2018 that they heard them say at a drinks event around this time that they would « call any Supreme Court judge » to block one of the letter organizers from doing a clerkship there. (Chua, who presented a confidential document from the dean confirming that she was acquitted of retribution charges against students, now says, « I’ve helped more students who signed on my husband than the rest of the faculty combined . « )

The small group student saw Rubenfeld’s email to the group as manipulation. « He loved the small group because we were there as his # 1 fans, » she says. “It was so obvious to me that he needed this confirmation. I gave that to him. « Your email in response to his threaded the needle: » I wanted you to know that I have thought about this situation and that I stand by you. Still, I come from the same perspective as many of your most spirited opponents. ”After setting out her views – she was frustrated that the survivors’ concerns were minimized, but careful with institutional responses approved by both the courts and the university – she wrote: « Ultimately, I wanted to say that I never felt that you had to apologize to me as a student in your small group. » Her goal, she said later, was to get him to stop talking about it .

Amy Chua had her own ideas on how to bond between classmates. In the fall of 2017, she had all of her small group students sit in a circle in her living room and invited everyone to tell their most embarrassing story. Her favorites were known as Chua Pets; among her mentees were J. D. Vance and Ronan Farrow. It could be magnetic. “You were loud. Direct. Feminine, ”wrote a former Chua Pet in a letter to her professor that was later circulated on Wall, a law school list server. “You did not hesitate to point out the power structures at YLS and to criticize them.”

Nobody denies that Chua did everything possible to help students whom she regards as outsiders. Other professors had office hours; She had closed entire afternoons to students. But she wasn’t alone. « The idea that Amy Chua is the only YLS faculty member supporting and mentoring color students here is offensive to a lot of the people doing this job, » says Meares, including the untrained and clinical faculty.

The student who wrote the letter to Chua said she was drawn to her confidence, willingness to divulge “institutional secrets” – not just about barriers to under-represented students, but also about the professors who had married their own students . Soon, however, « I began to see and hear things from you that I couldn’t justify, although I have no hesitation in expressing my love for you. » Chua, the student wrote, speculating about the sexuality of her students, sometimes gave revealed private details from the lives of professors and one day mimicked a student with a disability in class.

Chua firmly denies all of this. But in general it’s not that different from the way she describes herself in Tiger Mother: “quick-tempered, viper-tongued, quick to forgive” and “obsessively cruel”. (Rubenfeld appears some distance away in the book and appears occasionally to gently tell his wife that she might want to fire the girls.)

At the end of November 2017, the letter writer joined her professor and several other students in the private club Mory’s on. The world was in an uproar over abusive men being held accountable, and Chua asked her students if they thought the Me Too Bill would stand up for justice. « You also mentioned that a judge named Kavanaugh had a penchant for handsome employees, » the student wrote. « You said, however, that you would not worry about your daughter, his future employee, because she would never put up with such behavior. »

Later that fall, she accepted an invitation to a party that Chua and Rubenfeld were hosting at the Beekman in New York City, where they had just bought an apartment. There, she wrote, her teacher told her that her « ‘big brown beautiful eyes » were distracting because of my continued eye contact during class and invited Jed to comment on my appearance (of course I didn’t think you were hitting) on ​​me: Me would characterize my reaction as ‘jeez, how doesn’t she know better?’). « Chua says, » I’m just saying that I remember every single event she describes differently than hers. « 

Less than a year later, in July, Donald Trump nominated Kavanaugh to the Supreme Court. « Many of us knew him, he had taught for us and we had read his opinions, » says Kysar, who was the deputy dean at the time. “He was a respected voice from this ideological wing of judges. And we had no idea of ​​the wrongdoing and allegations that would surface against him. ”

Chua says,“ It’s hard to imagine now, but then Judge Kavanaugh was something of a Yale Law School darling. ”

The Deanery issued a press release quoting professors in praise of Kavanaugh, similar to those it issued for its alum colleagues Samuel Alito and Sonia Sotomayor. The idea, says Kysar, was « Let’s make a lukewarm statement saying that one of our own has been nominated for the Supreme Court » and not much more. This distinction was lost among some of the student body. “The students saw this as a deep betrayal of the values ​​for which the institution stands,” he says. „Vielleicht haben sie die Teeblätter besser gesehen als wir. Im Nachhinein lassen Trumps Usurpation der Bundesjustiz und des größeren Justizapparats und die Ereignisse vom 6. Januar diesen Glauben, den wir an die Ideale vernünftiger Meinungsverschiedenheiten und Respekt vor Normen hatten, einfach so verdammt naiv erscheinen.“

Chua sah keinen Grund, nicht zu feiern. Sie kehrte zu den Seiten des Wall Street Journal zurück, um ihn zu unterstützen. „In den letzten zehn Jahren habe ich geholfen, zehn Studenten der Yale Law School bei Richter Kavanaugh zu vermitteln, darunter acht Frauen“, schrieb sie. „Heutzutage ist die Presse voller Geschichten über mächtige Männer, die weibliche Angestellte ausbeuten oder missbrauchen. Umso beeindruckender ist es, wenn die weiblichen Angestellten von Richter Kavanaugh von seinem Anstand und seiner Rolle als leidenschaftliche Verfechterin ihrer Karriere sprechen.“ Sie gab bekannt, dass ihre Tochter Sophia, eine kürzlich Absolventin der Rechtswissenschaften in Yale, bereits als Sachbearbeiterin für ihn beim Berufungsgericht eingestellt worden war. „Und nur um das klarzustellen, weil es so viele Fehlinformationen gibt“, erzählt mir Chua, „ich habe mich von dem ganzen Prozess zurückgezogen. Das war wahrscheinlich auch eine schlechte Entscheidung, aber nur für sie, überhaupt an die Yale Law School zu kommen. Sie hätte wahrscheinlich eine andere juristische Fakultät besuchen sollen.“

Als Christine Blasey Ford Kavanaugh beschuldigte, sie als Teenager angegriffen zu haben, „habe ich meine Unterstützung für ihn nicht zurückgezogen“, erzählt mir Chua. « Ich glaube, alle anderen haben es getan. » Ich frage, ob sie Ford glaubt. „So habe ich mir das nicht vorgestellt“, antwortet sie. „Ich hatte definitiv das Gefühl, dass ihr etwas Schreckliches passiert war, aber ich wusste einfach, dass ich zehn Jahre lang sehr eng mit dieser Person zusammengearbeitet hatte, und ich kann nur sagen, dass ich zu dem stehe, was ich im Wall Street Journal geschrieben habe. Das ist alles. »

Tage nachdem Ford sich gemeldet hatte, berichteten HuffPost und der Guardian über Chuas Äußerungen bei Mory’s über die Attraktivität von Kavanaughs Angestellten und stellten fest, dass eine Studentin sagte, Rubenfeld habe ihr gesagt, der Richter mag Angestellte mit einem « bestimmten Blick », während Chua ihr riet, « zu und ‘outgoing’ anziehen “ und bot an, sich Fotos von Outfits anzuschauen. (Ich habe dies mit dem Studenten bestätigt.) Zu der Zeit sagte Chua: „Alles, was über die Ratschläge gesagt wird, die ich Studenten gebe, die sich bei Brett Kavanaugh – oder einem Richter – bewerben, ist empörend, 100 Prozent falsch und das genaue Gegenteil von allem, wofür ich in den letzten 15 Jahren gestanden und gesagt habe.“

Im Laufe der Jahre hat sich Chuas Leugnung abgeschwächt. Sie sagt, dass sie, als sie diese Erklärung schrieb, gerade wegen Komplikationen einer Divertikulitis ins Krankenhaus eingeliefert worden war und sich mehreren Operationen unterzogen hatte, « und es war wahrscheinlich wieder schlecht beraten ». Sie sagt: „Ich habe den Studenten dummerweise gesagt, wie gut seine Angestellten in einem Jahr aussahen. Aber ich sagte gleich danach: ‚Aber daran war absolut nichts auszusetzen.‘ Und ich sagte, dass jeder einzelne Schüler, den ich zu ihm geschickt hatte, alle davon schwärmte, was für ein anständiger, engagierter und inspirierender Mentor er war. Sonst hätte ich diesen Kommentar ein Jahr später nicht über ihn geschrieben. Das ist das Beste, was ich tun kann, um dies zu klären.“ Sie schaut über ihre Schulter. « Warte, lass mich nur Wasser für diesen Hund holen. »

Kavanaugh wurde natürlich bestätigt und bezeichnet sich immer noch als Champion der Frauen. Ihre Tochter Sophia twitterte: „Werde sich in absehbarer Zeit nicht bei SCOTUS bewerben, da sie in der Armee sein wird. Ich bin wie immer stolz auf meine tapfere Mama.“ Ein Jahr später war sie Referendarin für Kavanaugh am Obersten Gerichtshof.

Rubenfeld sagte mir im vergangenen August: „Ich habe ironischerweise über die Unzuverlässigkeit der Verfahren von Titel IX auf dem Campus geschrieben. Ich hätte nie gedacht, dass ich selbst eine davon durchmachen würde.“ Im Frühsommer 2018 stellte die juristische Fakultät einen eigenen Ermittler ein, der anonyme Beschwerden außerhalb des formellen Prozesses von Yale hören konnte, jedoch ohne die Autorität der Universität, ihn zu disziplinieren. « Ich wurde einer Fischereiuntersuchung unterzogen, wie ich glaube, dass noch kein Professor an der Yale University jemals zuvor gewesen ist », sagte er. „Eine E-Mail ging an 20 oder 30 Jahre alte Alumni der Schule und fragte, ob jemand Geschichten über Professor Rubenfeld hätte, die er teilen möchte.“

Die E-Mails, die die Leute darüber informierten, dass gegen Rubenfeld ermittelt wurde, kamen nicht von der Verwaltung der juristischen Fakultät, sondern von der Yale Law Women, einer Studentenorganisation, und von einer der ehemaligen Studentinnen, die ihn angezeigt hatten. Sie glaubte, dass es sich nach Jahrzehnten der Untätigkeit der Schule « wie jetzt oder nie anfühlte, die Leute dazu zu bringen, sich zu melden ». Es stimmt, dass die Einstellung des Ermittlers mehr ist, als die juristische Fakultät zuvor getan hatte. Laut Material, das ich mir angesehen habe, hatten mindestens zwei Dekane der juristischen Fakultät Rubenfeld vor seinem Verhalten gewarnt – Harold Koh im Jahr 2006 und Robert Post im Jahr 2015. Diese Gespräche waren geheim an mich aus und ließ jeden möglichen Beschwerdeführer in Silos.

Das war bis Februar 2019, als das universitätsweite Komitee (UWC), das die Befugnis hat, Professoren zu disziplinieren, zustimmte, Rubenfelds Verhalten als Muster zu testen, in dem der Anspruch jeder Frau auf ein ungleiches Bildungsumfeld der anderen Glaubwürdigkeit verleihen könnte. Rubenfeld würde endlich die Namen und Anschuldigungen seiner Ankläger kennen und das Recht haben, widerlegende Beweise vorzulegen und sie ins Kreuzverhör zu nehmen.

Obwohl sie bereits mit dem Ermittler der juristischen Fakultät über den versuchten Kuss gesprochen hatte, erfuhr Rubenfelds Kleingruppenstudentin von 2014 zufällig, dass die Untersuchung an die UWC gegangen war. Ihr ehemaliger Dozent in kleiner Gruppe rief an und sagte, Rubenfeld argumentiere gegenüber der UWC, dass er nie in der Nähe von Studenten betrunken gewesen sei. Erinnerte sie sich daran? Sie tat es, und sie stimmte zu, eine Erklärung abzugeben.

Der Dozent war auch einst Rubenfelds Kleingruppenstudent. Was sie erlebt hatte, war subtil – zunächst entnervende Blicke oder Rubenfeld, der auf einer Party in J. D. Vances Haus zu lange zu nah bei ihr saß oder Wege fand, sich alleine zu treffen. „Das verursacht Stress bei mir“, schrieb sie einer Freundin. „Alle Dinge, die jr. stresst.“ Bei einem nächtlichen Treffen, um eine Arbeit zu besprechen, wechselte Rubenfeld das Thema, fragte sie, warum sie nicht verheiratet sei, und sagte, sie müsse das hübscheste Mädchen in ihrer High School gewesen sein und dass „es mit den Jungs hart gewesen sein muss, weil sie“ ein kluges Mädchen. » (Rubenfeld sagte in der Anhörung, er habe „väterliches“ Interesse an ihr.) Zum ersten Mal erzählte sie einer anderen Freundin und ihrem Partner, sie wünschte sich, sie wäre ein Mann. Sie bekam die Empfehlung und das angesehene Referendariat, dann bot ihr Rubenfeld eine Stelle als Lehrbeauftragte an. Trotz ihrer Bedenken akzeptierte sie. Sie wollte am Obersten Gerichtshof arbeiten. Sie sagte sich, sie könnte die 1Ls beschützen.

Der Sturz, den sie als seine Lehrassistentin gedient hatte, sagte sie, Rubenfeld schien außer Kontrolle zu geraten. Bei einer Veranstaltung in kleiner Gruppe rüttelte er sie, indem er seinen Arm um ihre Taille schlang und ihn im Vorbeigehen drückte. Es erfül lte sie mit Scham, dass sie nichts sagte, und sie machte sich Sorgen darüber, was die Schüler denken würden. Sie ärgerte sich auch über die Schülerin, die sie um eine Stellungnahme gebeten hatte, und schickte ihre Kollegin im Dezember 2014 per E-Mail, „sie von Rubenfeld fernzuhalten“.

Der Lehrer war voller Schuldgefühle, weil er nicht genug getan hatte. Sie war zweimal zu Titel-IX-Koordinatoren an der juristischen Fakultät gegangen, aber jedes Mal unternahm sie die Schritte, die sie zu Rubenfeld identifizieren würden. Drei Jahre später, im Dezember 2017, erfuhr sie, dass ein aktueller Student erwägt, einen Bericht über Rubenfeld einzureichen, und sie erklärte sich bereit, mit einem weiteren Titel-IX-Koordinator zu sprechen. Nun, die Nachbeben von Me Too – und die Tatsache, dass Yale Law seine erste weibliche Dekanin hatte – ließen sie denken, dass es diesmal anders sein könnte.

Die Kleingruppenschülerin stimmte zu, ihrem ehemaligen Lehrerkollegen eine Erklärung abzugeben, die den versuchten Kuss beinhaltete. Sie war in einer Berufswelt gelandet, in der Yale sich weit weg fühlte, und sie sagt: « Ich fühlte mich in meiner Position bei der Arbeit so sicher, dass wenn sie für mich kommen, sie für mich kommen. » „Sie“, stellt sie klar, meinten Chua und Rubenfeld. Und als die UWC-Mitglieder ihre Erklärung lasen und fragten, ob sie einen eigenen Bericht abgeben wolle, dachte sie noch einmal nach. „Ich verteidige Menschen, denen Sexualverbrechen vorgeworfen werden“, sagt sie. „Letztendlich kommt es darauf an, dass seine Freiheit nicht auf dem Spiel steht. Wir reden nicht davon, dass jemand ins Gefängnis kommt. Wir sprechen über seine Fähigkeit, Macht über Menschen auszuüben.“

Rubenfeld bestritt bei der Anhörung, mit der ehemaligen Studentin geflirtet oder sie angestarrt zu haben; wenn überhaupt, behauptete er, es sei umgekehrt. Er zeigte die E-Mail, die sie ihm nach dem Kommentar geschickt hatte, und sagte, sie stehe bei ihm, sowie E-Mails ihrer Klassenkameraden, die sagten, sie könnten sich nicht vorstellen, dass er etwas Unangemessenes tue. In ihrem eigenen Kreuzverhör fragte sie Rubenfeld, ob er diesen Studenten zu einem Referendariat verholfen habe. (Zwei von ihnen, sie erinnert sich, dass er sagte, und an den dritten erinnerte er sich nicht.) Er griff auch die Worte auf, die sie benutzt hatte, als sie ihre Schwester am Tag nach der Party anrief – dass sie „ziemlich sicher“ ihr Professor war hatte versucht, sie zu küssen. „Als Verteidigerin würde ich natürlich dasselbe sagen“, sagte sie. Rubenfeld machte andere Abwehrmanöver. Auf die Beschwerde eines dritten Studenten antwortete er: « Sie ist nicht jemand, den ich attraktiv nennen würde. »

Rubenfeld verlor die Beherrschung. Er sagte, er glaube, die ehemalige Studentin habe sich nur wegen „jemandem mit einer Agenda“ gemeldet, der sie dazu gebracht habe, mit einer falschen Erinnerung zu erscheinen: dem Dozenten, der sein Mentee gewesen war und seinen Kommentar nicht unterzeichnet oder öffentlich abgelehnt hatte . Seine Wut erinnerte den Studenten an Kavanaugh bei seinen Nominierungsanhörungen. „In diesem Gerede ließ er durchgehen, dass dies nicht die erste Frau ist, die behauptete, er habe versucht, sie zu küssen“, erinnert sie sich. « Er hat einfach zugegeben, dass es schon einmal passiert ist. » Am Ende stellte das Gremium fest, dass Rubenfeld alle drei Frauen sexuell belästigt hatte, als sie seine Schüler waren. Wie viele Beschwerdeführer es insgesamt gab, können sie aus den Unterlagen nur erahnen, da das Verfahren darauf angelegt war, sie voreinander geheim zu halten.

Jede Beschwerdeführerin erhielt einen Anhang, in dem anonymisierte Konten zitiert wurden, die ihren ähnlich waren. Mindestens sechs Beschwerdeführer hatten Rubenfelds übermäßigen Alkoholkonsum gemeldet, und sechs sagten, sie glaubten, er habe mit ihnen geflirtet. Gemeinsam beschrieben sie, weniger im Unterricht zu sprechen; ihre Kurspläne umstellen, um Rubenfelds Unterricht zu vermeiden, selbst wenn sie an den Themen interessiert waren; Paranoia erleben, sich anderen Professoren zu nähern; und fragte sich, ob sie es an der Yale Law School schaffen könnten. Einer sagte: « Er lenkte unsere Gespräche wiederholt von meiner Zeitung weg, hin zu meinem Aussehen, meinem Privatleben und sexuellen Dingen. »

Als der Lehrer das las, dachte sie einen Moment, es sei ihre eigene Geschichte. Der Prozess hatte sie Hunderte von Stunden ihres Lebens und Zehntausende Dollar an Anwaltskosten gekostet. Jetzt wusste sie zumindest, dass es nicht nur sie war.

In der Amtszeit der Fakultät ist eine zweijährige Suspendierung von Bedeutung, aber einige aktuelle Studenten waren unzufrieden. Die Yale Law Women veröffentlichten einen Bericht, in dem sie die Universität aufforderten, „Jed Rubenfeld dauerhaft vom Campus zu entfernen und Informationen über die Art der Anschuldigungen und Ergebnisse der Untersuchung herauszugeben“. (Dabei waren sie sich mit ihren ideologischen Gegensätzen einig.) Sie forderten „ein System zur Verfolgung anonymer Meldungen, das es Überlebenden ermöglicht, eine anonyme Aufzeichnung von Fehlverhalten zu erstellen und benachrichtigt zu werden, wenn andere Anzeigen für denselben Täter eingereicht werden“ und das kostenlos Rechtsvertretung für Studierende, die das Verfahren durchlaufen. Die Universität ist ungerührt. In Yale kann die Entlassung eines ordentlichen Professors nur durch den Universitätspräsidenten veranlasst werden, und Peter Salovey hat dies bisher abgelehnt. Ein Sprecher der Universität sagte, dass die Vertraulichkeit „dazu beiträgt, unsere Community-Mitglieder zur Teilnahme zu ermutigen und mit den Datenschutzgesetzen des Bundesstaates und des Bundes vereinbar ist“.

Rubenfelds neue Sache besteht darin, Facebook im Namen der gemeinnützigen Organisation des Anti-Vaxxer Robert F. Kennedy zu verklagen und sagt, das Unternehmen habe gegen den First Amendment verstoßen, der für Regierungen gilt, weil es Regierungsstandards für Fehlinformationen verwendet habe. Zuvor argumentierte Rubenfeld, dass Universitäten auch zu staatlichen Akteuren werden, wenn sie beispielsweise die Regeln des Titels IX zu sexuellem Fehlverhalten gegenüber Professoren durchsetzen.

Zu Hause erzählt mir Chua, dass sie ihre Vereinbarung mit dem Dekan unter Zwang getroffen hat. „Ich wollte mit vielen Dingen nicht einverstanden sein. Ich fühlte mich irgendwie missverstanden und ich fühlte mich selbst ein bisschen angegriffen“, sagt sie. „Ich hatte das Gefühl, dass manche Dinge völlig unfair waren. Aber im Interesse des Weitermachens haben wir sowohl die Bedauernserklärung als auch einige Strafen ausgehandelt. Ich habe diese Briefe nicht einmal sehr sorgfältig gelesen; Ich weiß, dass ich Anwältin werden soll.“ Angegriffen wie? „Ich sollte nicht sagen, angegriffen. Ich fühlte mich vieler Dinge zu Unrecht beschuldigt.“

Als sie nach der medizinischen Auszeit auf den Campus zurückkehrte, sagte sie sich, sagte sie sich: „Ich weiß, dass viele Leute wegen meiner Unterstützung für Kavanaugh immer sehr sauer auf mich sein werden. Und manche Leute werden immer sehr sauer auf mich sein, weil ich mit meinem Mann verheiratet bin. Aber ich kann einfach den Kopf unten lassen und einfach das machen, was ich gut kann.“

Sie sagt, sie wisse immer noch nicht, warum ihr die kleine Gruppe entzogen wurde, und dass jede Diskussion über die Verletzung von COVID-Protokollen eine rückwirkende Rechtfertigung sei. „Das Haus selbst war nicht Teil eines Verbots?“ Ich frage. Schließlich war auch Rubenfeld eingeschränkt, und er lebt hier. „Nein“, sagt sie. « Nichts dergleichen. »

Später wird sie mir einige Dokumente schicken, um ihre Punkte zu untermauern, darunter einen Brief an den Dekan, der so dünn geschwärzt ist, dass er wie Lidschatten aussieht. Ein Teil des redigierten Textes lautet: „Während ich bei unserem Treffen zugestimmt habe, die Schüler auf absehbare Zeit nicht zu mir nach Hause oder zu einem Drink einzuladen …“ Als ich sie danach frage, antwortet sie, dass sie glaubt, dass „die absehbare Zukunft“ vorüber sei als sie überhaupt gebeten wurde, eine kleine Gruppe zu unterrichten.

Die jetzigen Studenten, mit denen ich sprach, die sich gegen Chua als Erstklässler organisiert hatten, dachten, dass sie es war, die den Wahn des Referendariats geschürt hatte. „Sie übertreibt oder verewigt die Ängste, die die Leute denken lassen, dass sie sie brauchen“, sagte mir eine aktuelle Studentin. « Ich glaube nicht, dass Sie mit Ihrem Professor zusammen sein müssen, um beruflich erfolgreich zu sein. » Die Studenten, die ohne Verbindungen kamen, schlug diese Person vor, waren diejenigen, die geschröpft wurden.

Gegen Ende unserer drei gemeinsamen Stunden wirkt Chua müde. „Viele der Dinge, die für mich als Mitglied dieser Familie schreckliche Erfahrungen machen, sind meiner Meinung nach gut für die Gesellschaft“, sagt sie. Chua und ihre Freundinnen haben sich unterhalten: „Und wir alle dachten: ‚Ich kann nicht glauben, was wir am Arbeitsplatz als normal akzeptiert haben.’ “ Nun, sagt sie, würde sie niemals sagen: „Oh, das ist nett Haarschnitt.“ Das würde ich nie mehr sagen. Ich würde nie sagen: ‚Schöne Ohrringe.‘ “ Ich denke, das ist nicht die Art von Dingen, über die sich die Leute aufregen. Manchmal, sagt sie, ist es so.

Einige von Chuas Verbündeten sahen sie einst als weiteres Opfer von Rubenfeld, aber das gemeinsame Exil des Paares aus Yales Wohlwollen hätte sie vielleicht näher zusammengebracht. Chua sagt, Yale Law habe sich nie wie zu Hause gefühlt, aber sie sagt auch nicht, dass sie gehen wird. „Nun, ich will nicht verjagt werden“, sagt sie. In ihrem ersten Semester nach der Kavanaugh-Explosion, sagt sie, waren ihre Kurse überbucht. Trotzdem wird es nicht immer dasselbe sein. « Angesichts des ganzen Gepäcks um mich herum denke ich, dass es meine eigene Politik sein wird, hier keine Partys zu veranstalten », sagt Chua. Nach einer Pause fügt sie hinzu: „Ich werde sehen. Ich meine, vielleicht. Ich würde gerne darüber hinwegkommen. » Und vielleicht wird sie das. Im Herbst kommt ein neuer Schülerstamm.

US-Ermittler haben Kryptowährungen in Millionenhöhe wiedererlangt, die als Lösegeld an Hacker gezahlt wurden, deren Angriff letzten Monat die Schließung der wichtigsten Ostküstenpipeline veranlasste, so die in dieser Angelegenheit informierten Personen.

Es wird erwartet, dass das Justizministerium am Montag Details der vom FBI in Zusammenarbeit mit dem Betreiber der Colonial Pipeline geleiteten Operation bekannt gibt, sagten die Personen, die über die Angelegenheit informiert wurden.

Die Rückforderung von Lösegeld ist ein seltenes Ergebnis für ein Unternehmen, das im boomenden kriminellen Geschäft mit Ransomware einem schwächenden Cyberangriff zum Opfer gefallen ist.

Es war ein rekordverdächtiges Wochenende, an dem Dutzende von täglichen Rekordhochs in Teilen der unteren 48, die sich von den Northern Plains bis zum Nordosten erstrecken, erreicht wurden. Als Sioux Falls, South Dakota, am Samstag über 100 Grad stieg, war es der heißeste Tag seit neun Jahren. In der Zwischenzeit hat Milwaukee drei Tage in Folge Rekordhochs aufgestellt.

Diese rekordverdächtige Hitze geht am Montag weiter, wo mehr als ein Dutzend Rekordhochs in den Northern Plains und Neuengland aufgestellt werden könnten. Ungefähr 19 Millionen Menschen sind am Montag unter Hitzewarnungen aufgewacht, die Teile des oberen Mittleren Westens, des Nordostens und Neuenglands abdecken. Die Hitzeberatung umfasste Minneapolis, Philadelphia und Boston. Die Temperaturen sollten um mehr als 20 Grad über dem Durchschnitt steigen, was zu Höchstständen in den oberen 80er und niedrigen 90er Jahren führte.

Der frühere Präsident Donald Trump sprang am Samstagabend in North Carolina in eine kompetitive Senatsvorwahl und unterstützte den Abgeordneten Ted Budd für einen heiß umkämpften Sitz bei den Wahlen 2022. Trumps überraschende Billigung – die er dem Kongressabgeordneten etwa 15 Minuten vor dem Betreten der Bühne in einem Kongresszentrum hier mitteilte – kam wenige Minuten, nachdem seine Schwiegertochter Lara Trump sagte, sie werde nicht für den Sitz in North Carolina kandidieren. Seit einem Monat kursierten Gerüchte über einen möglichen Senatsantrag von Lara Trump, den sie angeheizt hatte. Sie sagte am Samstagabend, dass sie « vorerst nein » sei, nachdem sie von ihrem Schwiegervater auf die Bühne gerufen worden war, und erklärte, dass ihre Entscheidung hauptsächlich getroffen wurde, weil sie zwei kleine Kinder hat.

Budd tritt gegen mindestens zwei weitere prominente Republikaner an: den US-Abgeordneten Mark Walker und den ehemaligen Gouverneur von North Carolina, Pat McCrory, und das Nicken des ehemaligen Präsidenten wird Budd wahrscheinlich Auftrieb geben.

Die US-Wirtschaft hat im Mai 559.000 Arbeitsplätze geschaffen, das jüngste Zeichen einer sich verstärkenden Erholung, da die Impfungen zunehmen und die Covid-Beschränkungen landesweit nachlassen.

Die Arbeitslosenquote ging laut dem monatlichen Bericht des Bureau of Labor Statistics leicht von 6,1 Prozent auf 5,8 Prozent zurück.

Die Zuwächse wurden stark durch neue Arbeitsplätze in Restaurants, Bars und anderen Gastronomiebetrieben angetrieben, die im Monat 186.000 Arbeitnehmer hinzufügten.

Already a subscriber?
Log in or link your magazine subscription

Already a subscriber?
Log in or link your magazine subscription

Already a subscriber?
Log in or link your magazine subscription

Already a subscriber?
Log in or link your magazine subscription

= 0? (u = f.substr (0, v), c = f.substr (v 1)) 🙁 u = f, c = «  »), i = decodeURIComponent (u), l = decodeURIComponent (c), hasOwnProperty (o, i)? isArray (o [i])? o [i] .push (l): o [i] = [o [i], l]: o [i] = l } return o}; var isArray = Array.isArray || function (r) {return « [Object-Array] » === Object.prototype.toString.call (r)};
}, {}];
window.modules [« 1190 »] = [function (require, module, exports) {« use strict »; var stringifyPrimitive = function (r) {switch (typeof r) {case « string »: return r; case « boolean » : return r? « true »: « false »; case « number »: return isFinite (r)? r: «  »; default: return «  »}}; module.exports = function (r, e, t, n) {return e = e || « & », t = t || « = », null === r&& (r = void 0), « object » == typeof r? map (objectKeys (r), function (n ) {var i = encodeURIComponent (stringifyPrimitive (n)) t; return isArray (r [n])? map (r [n], function (r) {return i encodeURIComponent (stringifyPrimitive (r))}). join (e ): i encodeURIComponent (stringifyPrimitive (r [n]))}). join (e): n? encodeURIComponent (stringifyPrimitive (n)) t encodeURIComponent (stringifyPrimitive (r)): «  »}; var isArray = Array.isArray | | function (r) {return « [object Array] » === Object.prototype.toString.call (r)}; function map (r, e) {if (r.map) return r.map (e); for (var t = [], n = 0; n0&&a [a.length-1]) && (6 === i [0] || 2 === i [0])) {o = 0; next} if (3 === i [0] && (! a || i [1]> a [0] &&i [1] « : » akbar-men « , » ∑ « : » majmou « , » ¤ « : » omla « }, az: {}, ca: { » ∆ « : » delta « , » ∞ « : » infinit « , » ♥ « : » amor « , » & « : » i « , » | « : » o « , » « : » mes que « , » ∑ « : » suma dels « , » ¤ « : » moneda « }, cz: { » ∆ « : » delta « , » ∞ « : » nekonecno « , » ♥  » : « laska », « & »: « a », « | »: « nebo », «  »: « vice jako », « ∑ »: « soucet », « ¤ »: « mena »}, de: { » ∆ « : » delta « , » ∞ « : » infinite « , » ♥ « : » Love « , » & « : » and « , » | « : » or « , » « : » greater than « , » ∑  » : « Sum of », « ¤ »: « Currency »}, dv: {« ∆ »: « delta », « ∞ »: « kolunulaa », « ♥ »: « loabi », « & »: « aai », « | »: « noonee », «  »: « ah vure bodu », « ∑ »: « jumula », « ¤ »: « faisaa »}, en: {« ∆ »: « delta », « ∞ »:  » infinite « , » ♥ « : » love « , » & « : » and « , » | « : » or « , » « : » greater than « , » ∑ « : » sum « , » ¤ « : » currency  » }, es: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amor », « & »: « y », « | »: « u », «  »: « mas que « , » ∑ « : » suma de los « , » ¤ « : » moneda « }, fr: { » ∆ « : » delta « , » ∞ « : » infinite « , » ♥ « : » Amour « , » & « : » et « , » | « : » ou « , » « : » superieure a « , » ∑ « : » somme des « , » ¤ « : » monnaie « }, gr: {}, hu: { » ∆ « : » delta « , » ∞ « : » vegtelen « , » ♥ « : » szerelem « , » & « : » es « , » | « : » vagy « , » « : » nagyobb mint « , » ∑ « : » szu mma « , » ¤  » : « penznem »}, it: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amore », « & »: « e », « | »: « o »,  » « : » maggiore di « , » ∑ « : » somma « , » ¤ « : » moneta « }, lt: {}, lv: { » ∆ « : » delta « , » ∞ « : » bezgaliba « , » ♥ « : » milestiba « , » & « : » un « , » | « : » vai « , » « : » lielaks neka « , » ∑ « : » summa « , » ¤ « : » valuta « }, my: { « ∆ »: « kwahkhyaet », « ∞ »: « asaonasme », « ♥ »: « akhyait », « & »: « nhin », « | »: « tho », «  »: « kyithaw », « ∑ » : « paungld », « ¤ »: « ngwekye »}, mk: {}, nl: {« ∆ »: « delta », « ∞ »: « oneindig », « ♥ »: « fielde », « & »: « en », « | »: « of », «  »: « groter dan », « ∑ »: « som », « ¤ »: « valuta »}, pl: {« ∆ »: « delta », « ∞ « : » nieskonczonosc « , » ♥ « : » milosc « , » & « : » i « , » | « : » lub « , » « : » wieksze niz « , » ∑ « : » suma « , » ¤ « : « waluta »}, pt: {« ∆ »: « delta », « ∞ »: « infinito », « ♥ »: « amor », « & »: « e », « | »: « ou », «  » : « maior que », « ∑ »: « soma », « ¤ »: « moeda »}, ro: {« ∆ »: « delta », « ∞ »: « infinite », « ♥ »: « dragoste », « & »: « si », « | »: « sau », «  »: « mai mare ca », « ∑ « : » suma « , » ¤ « : » valuta « }, ru: { » ∆ « : » delta « , » ∞ « : » beskonechno « , » ♥ « : » lubov « , » & « : » i « , « | »: « ili », «  »: « bolshe », « ∑ »: « summa », « ¤ »: « valjuta »}, sk: {« ∆ »: « delta », « ∞ »: « nekonecno » , « ♥ »: « laska », « & »: « a », « | »: « alebo », «  »: « viac ako », « ∑ »: « sucet », « ¤ »: « mena »}, sr: {}, tr: {« ∆ »: « delta », « ∞ »: « sonsuzluk », « ♥ »: « ask », « & »: « ve », « | »: « veya », «  » : « buyuktur », « ∑ »: « toplam », « ¤ »: « para birimi »}, uk: {« ∆ »: « delta », « ∞ »: « bezkinechnist », « ♥ »: « lubov », « & »: « i », « | »: « abo », «  »: « bilshe », « ∑ »: « suma », « ¤ »: « valjuta »}, vn: {« ∆ »: « delta » , « ∞ »: « vo cuc », « ♥ »: « yeu », « & »: « va », « | »: « hoac », «  »: « lon hon », « ∑ »: « tong », « ¤ »: « tien te »}}; if (« string »! = Typeof e) return «  »; if (« string » == typeof a&& (A = a), m = I.en, c = C. en, « object » == typeof a) for (g in n = a.maintainCase ||! 1, O = a.custom&& « object » == typeof a.custom? a.custom: O, u = a.truncate > 1&&a.truncate ||! 1, l = a.uric ||! 1, s = a.uricNoSlash ||! 1, r = a.mark ||! 1, S =! 1! == a.symbols&&! 1! == a.lang , A = a.separator || A, l&& (p = b.join («  »)), s&& (p = z.join («  »)), r&& (p = [« . », « ! »,  » ~ « , » * « , » ‘ », » (« , ») « ]. join ( » « )), m = a.lang&&I [a.lang] && S? I [a.lang]: S? I .en: {}, c = a.lang&&C [a.lang]? C [a.lang] :! 1 === a.lang ||! 0 == = a.lang? {}: C.en, a.titleCase&& « number » == typeof a.titleCase.length&&Array.prototype.toString.call (a.titleCase)? (a.titleCase.forEach (function (e) {O [e « } ») = e  » , t =! 0): t = !! a.titleCase, a.custom&& « number » == typeof a.custom.length&&Array.prototype.toString.call (a. custom) &&a.custom (e )ach (function.forEach) {O [e «  »] = e «  »}), Object.keys (O) .forEach (function (a) {var n; n = a.length> 1? New RegExp (« \ b » o (a ) « \ b », « gi »): new RegExp (o (a), « gi »), e = e.replace (n, O [a])}), O) p = g; for (p = o (p = A), f =! 1, y =! 1, d = 0, k = (e = e. replace (/ (^ s | s $) / g, «  »)). length; d = 0? (j = g, g = «  ») :! 0 === y? (g = U [j ] v [g], j = «  »): g = f&&v [g] .match (/ [A-Za-z0-9] /)? «  » v [g]: v [g], f =! 1 , y =! 1): g in U? (j = g, g = «  », d === k-1&& (g = U [j]), y =! 0) :! m [g] || l&&-1! == b.join («  ») .indexOf (g) || s&&-1! == z.join («  »). indexOf (g)? (! 0 === y? (g = U [j] g, j = «  », y =! 1): f&& (/ [A-Za-z0-9] /. Test (g) || E.substr (-1). match (/ A-Za-z0-9] /)) && (g = «  » g), f =! 1) 🙁 g = f || E.substr (-1) .match (/ [A-Za -z0-9] /)? A m [g]: m [g], g = void 0! == e [d 1] &&e [d 1] .match (/ [A-Za-z0-9] / )? A: «  », f =! 0), E = g.replace (new RegExp (« [^ \ w \ s » p « _-] », « g »), A); return t&& ( E = E.replace (/ ( w) ( S *) / g, function (e, a, n) {var t = a.toUpperCase () (null! == n? N: «  »); return Object.keys (O) .indexOf (t.toLowerCase ()) u&& (h = E.charAt (u) === A, E = E.slice (0, u), h || (E = E.slice (0, E.lastIndexOf (A)))), n || t || (E = E.toLowerCase ()), E}, t = function (e) {return function (a) {return n (a, e )}}, o = function (e) {return e.replace (/ [- \ ^ $ *?. () | [] {} /] / g, « \ $ & »)}, i = function (e, a) {for (var n in a) if (a [n] === e) return! 0}; if (« undefined »! = typeof module&&module.exports) module.exports = n, module .exports.createSlug = t; else if (« undefined »! = typeof define&&define.amd) define ([], function () {return n}); else try {if (e.getSlug || e.createSlug) throw  » Speakingurl: globals exists / (getSlug | c reateSlug) / « ; e.getSlug = n, e.createSlug = t} catch (e) {}} (this);
}, {}];
window.modules [« 1220 »] = [function (require, module, exports) {var namespace = « expire_mixin »; function expirePlugin () {var e = this.createStore (this.storage, null, this._namespacePrefix namespace); return {set: function (t, n, a, r) ​​{this.hasNamespace (namespace) || e.set (n, r); return t ()}, get: function (e, n) {this.hasNamespace (namespace) || t.call (this, n); return e ()}, remove: function (t, n) {this.hasNamespace (namespace) || e.remove (n); return t ()}, getExpiration: function (t, n) {return e.get (n)}, removeExpiredKeys: function (e) {var n = []; this.each (function (e, t) {n.push (t)}) ; for (var a = 0; a = 0; r -) {var l = localStorage (). key (r); e (read (l), l)}} function remove (e) {return localStorage () .removeItem (e)} function clearAll () {return localStorage (). clear ()} module.exports = {name: « localStorage », read: read, write: write, each: each, remove: remove, clearAll: clearAll };
}, {« 1222 »: 1222}];
window.modules [« 1224 »] = [function (require, module, exports) {module.exports = {name: « memoryStorage », read: read, write: write, each: each, remove: remove, clearAll: clearAll} ; var memoryStorage = {}; function read (e) {return memoryStorage [e]} function write (e, r) {memoryStorage [e] = r} function each (e) {for (var r in memoryStorage) memoryStorage.hasOwnProperty (r) &&e (memoryStorage [r], r)} function remove (e) {delete memoryStorage [e]} function clearAll (e) {memoryStorage = {}}
}, {}];
window.modules [« 1245 »] = [function (require, module, exports) {! function (e) {var t = function (e) {return new y (e)}; t.version = « 0.6.8 » , « undefined »! = typeof module&&module.exports? module.exports = t: « function » == typeof define&&define.amd? define (function () {return t}): e.typogr = t; var n = function (e , t) {return new RegExp (e, t)}, s = /] *> / i, r = t.amp = function (e) {var t = / ( s |) (& | & | & # 38;) ( s |) / g; if (e || « string » == typeof e) return e.replace (/ ()? ([^)? / G, function (e, n, r, a) {return a = a || «  », (n = n || «  »). match (s)? nra: n (r = r.replace (t, ‘$ 1& $ 3’)) a})} , a = t.ord = function (e) {if (e || « string » == typeof e) {var t, n = f (e), r = [], a =! 1, p = / ( d) (st | nd | rd | th) / g; return n.forEach (function (e) {« tag » === e.type? (r.push (e.txt), t = s.exec (e.txt), a =! (! t || void 0! == t [1])): a? r.push (e.txt): r.push (e.txt.replace (p, ‘ $ 1 $ 2 ‘))}), r.join («  »)}}, p = t.initQuotes = function (e) {var t = n (« (?: (?:] *> | ^) \ s * (?:] *> \ s *) *) (?: ( « |“ | “) | (‘|’ | ‘)) », « i »); if (e || « string » = = typeof e) return e.replace (t, functio n (e, t, n) {var s = t? « dquo »: « quo », r = t || n; return [e.slice (0, e.lastIndexOf (r)),  », r, «  »] .join («  »)})}, c = t.widont = function (e) {var t = « (?:] *?>) *? [^ \ s] (? 🙁 ?: a | em | span | strong | i | b) [^>] *?>) *? « , s = n ( » (\ s « t » \ s « t ») (?: \ s) ([^ \ s] ( ?: \ s * (?: a | em | span | strong | i | b) [^>] *?> \ s * \. *) *? (?: \ s *? (?: p | h [1-6] | li | dt | dd)> | $)) « , » gi « ); return e.replace (s, ‘$ 1 $ 2’)}, i = t.caps = function (e ) {var t, r = f (e), a = [], p =! 1, c = n (« ((\ b [AZ \ d] * [AZ] \ d * [AZ] [ AZ \ d ‘] * \ b) | (\ b [AZ] \. \ s? (?: [AZ] \. \ s?)) (?: \ s | \ b | $)) « , » g « ); return r.forEach (function (e) { » tag « === e.type? (a.push (e.txt), t = s.exec (e. txt), p =! (! t || void 0! == t [1])): p? a.push (e.txt): a.push (e.txt.replace (c, function (e, t, n, s) {var r, a; return n? ‘% s’.replace (« % s », n) 🙁 «  » === s.slice (-1)? (r = s.slice (0, -1), a = «  ») 🙁 r = s, a = «  »), ‘% s1% s2’.replace (« % s1 », r) .replace (« % s2 », a) )}))}), a.join («  »)}; t.typogrify = function (e) {var t = e; return e.jquery&&e.html&& (t = e.html ()), t = r ( t), t = c (t), t = u (t), t = i (t), t = p (t), t = a (t)}; var l, o, u = t.smartypants = Function (e) {var t, n, r = f (e), a = [], p = [], c = «  », i = «  », l =! 1, o = «  »; return r. forEach (function (e) {if (« tag » === e.type) a.push (e.txt), null! == (i = s.exec (e.txt)) && (c = i [ 2]. ToLowerCa se (), i [1]? (p.length> 0&&c === p [p.length-1] &&p.pop (), 0 === p.length&& (l =! 1)) 🙁 p. push (c), l =! 0)); else {if (n = (n = e.txt) .replace (/ (rock) ‘n’ (roll) / gi, « $ 1’n ‘$ 2 »), t = n.slice (-1) ,! l) switch (n = g (n), n = h (n), n = d (n), n = x (n)) {case « ‘ »: n = / S / .test (o)? « ‘ »: « ‘ »; Break; case ‘ »‘: n = / S / .test (o)? » «  »: «  » « ; Break; default: n = m (n)} o = t, a.push (n)}}), a.join («  »)}, f = t.tokenize = function (e) {for (var t, n = [] , s = 0, r = / ([^] *>) / gi; zero! == (t = r.exec (e));) {var a = t [1], p = t [2]; a&&n.push ({type: « text », txt: a}), n.push ({type: « tag », txt: p}), s = r.lastIndex} return r.lastIndex) / g, « $ 1 -« )}, d = t.smartEllipses = function (e) {return e.replace (/…/ g, « … »). replace (/ . . ./ g, « … »)}, x = t.smartBackticks = function (e) {return e.replace ( /« /g, » » »).replace(/« /g, «  » « )}, m = t.smartQuotes = function (e) {var t = » (? =% s \ B)  » .replace (« % s », « [!  » # \ $ \% \ ‘() *, -. \ /:;? \ @ \ [\\] \ ^ _ `{|} ~] »), s = « [^ \ \ t \ r n \ [\ {\ (\ -] », r = n (« (\ s | | – | & [mn] dash; | – | – | ȁ [34];) ‘(? = \ w) « , » g « ), a = n ( » (« s »)’ (?! \ s | s \ b | \ d) « , » g « ), p = n ( » (« s ») ‘(?! \ s | s \ b) « , » g « ), c = n (‘(\ s | | – | & [mn] dash; | – | – | ȁ [34];) « (? = \ w)’, » g « ), i = n ( ‘ »(? = \ s)’, » g « ), l = n ( » (« s’) » ‘, « g »); return e.replace (n (« ^’% s » .replace ( « % s », t), « g »), « ‘ »). replace (n (‘ ^ « % s’.replace (« % s « , t), » g « ), » «  »). replace (/ »‘(?=w)/g, » »‘ »).replace(/ ‘ »(? = w) / g, »‘ «  »). replace (/ b ‘(? = d {2} s) / g, « ‘ »). Replace (r, « $ 1′ »). Replace (a, « $ 1 ‘ »). Replace (p, « $ 1’ $ 2 »). Replace (« ‘ », « ‘ ») .replace (c, « $ 1 » « ). replace (i, » «  »). replace (l, « $ 1 » « ). replace (‘ »‘, «  » « )}, y = function (e) {this._wrapped = e}, v = function (e, n) {y.prototype [e ] = function () {return e = n.call (t, this._wrapped), this._chain? t (e) .chain (): e; var e}}; for (l in t) t.hasOwnProperty ( l) && ((o = t [l]) &CS SEANDCHARo.constructor&&o.call&&o.apply) &&v (l, t this }, y.prototype.value = function () {return this._wrapped}} (dies);
}, {}];
window.modules [« 1341 »] = [function (require, module, exports) {« use strict »; const universalAgora = require (1343), universalRest = require (20), universalQuery = require (1342), _ get = require ( 10); function searchByQueryWithRawResults (e, r) {const t = `// $ {r.site.host} $ {80! == r.site.port?`: $ {R.site.port} `: » « } $ {r.site.path} / _ agora / _search`; return universalRest.post (t, e,! 0)} function getProducts (e, r, t) {return searchByQueryWithRawResults (universalAgora.buildProductsQuery (e), r ) .then (e => {const r = universalQuery.formatSearchResult (e); return {total: e.hits.total, products: t? universalAgora.filterByLocale (r): r}})} function getMerchantsList (e) { return searchByQueryWithRawResults (universalAgora.buildMerchantsAggregation (1e6, _get (e, « site.agoraLocale »)), e) .then (universalQuery.formatAggregationResults ({aggregationName: « merchants », field: « key », subfield: « name »}) )} module.exports.getProduct = universalAgora.getProduct, module.exports.getProducts = getProducts, module.exports.getMerchantsList = getMerchantsList, module.exports.searchByCross yWith RawResults = searchByQueryWithRawResults, module.exports.buildMerchantsByUrlQuery = universalAgora.buildMerchantsByUrlQuery;
}, {« 10 »: 10, « 20 »: 20, « 1342 »: 1342, « 1343 »: 1343}];
window.modules [« 1342 »] = [function (require, module, exports) {« use strict »; const _map = require (74), _ get = require (10), _ isArray = require (173), _ set = require ( 131), _ isObject = require (110), _ cloneDeep = require (92), _ uniq = require (115); function formatSearchResult (e) {return _map (e.hits.hits, « _ source »)} function newQuery (e) { if (! e) throw new Error (« An` index` is required to create a query « ); return {index: e, type: » _ doc « , body: {query: {}}}} function addShould ( e, o) {var t = _get (e, « body.query.bool.should », void 0), r = _isArray (o); return t? r? _set (e, « body.query.bool.should « , t.concat (o)) 🙁 t.push (o), _ set (e, » body.query.bool.should « , t)): _ set (e, » body.query.bool.should « , r? o: [o]), e} function addMust (e, o) {var t = _get (e, « body.query.bool.must », void 0), r = _isArray (o); return t? r? _set (e, « body.query.bool.must », t.concat (o)) 🙁 t.push (o), _ set (e, « body.query.bool.must », t)): _ set ( e, « body.query.bool.must », r? o: [o]), e} function addMustNot (e, o) {var t = _get (e, « body.query.bool.must_not », void 0 ), r = _isArray (o); return t? r? _set (e, « body.query.bool.must_not », t .concat (o)) 🙁 t.push (o), _ set (e, « body .query.bool.must_not « , t)): _ set (e, » body.query.bool.must_not « , r? o: [o]), e} function addFilter (e, o) {var t = _get ( e, « body.query.bool.filter », void 0); if (! _ isObject (o)) throw new Error (« Filter query must be an object »); return t? _isArray (t)? (t.push ( o), _ set (e, « body.query.bool.filter », t)): _ set (e, « body .query.bool.filter », [_ cloneDeep (t), o]): _ set (e,  » body.query.bool.filter « , o), e} function addMinimumShould (e, o) {if ( » number « ! = typeof o) throw new Error ( » A number is required as a second argument « ); return _set ( e, « body.query.bool.minimum_should_match », o), e} function addSort (e, o) {var t = _get (e, « body.sort »); return _isArray (t) || _set (e, « body.sort », t = []), t.push (o), e} function addSize (e, o) {if (! o&CSSEANDC HAR0! == o) return e; if (o = parseInt (o), isNaN (o)) throw new Error (`Second argument must be a number: $ {o}`); return _set (e, « body. size « , o)} function addFrom (e, o) {if (! o&&0! == o) return e; if (o = parseInt (o), isNaN (o)) throw new Error (` Second argument must be a number be r: $ {o} `); return _set (e, » body.from « , o)} function onlyWithTheseFields (e, o) {if (! _ isArray (o)) throw new Error ( » Second argument must be an array « ); return _set (e, » body._source.include « , _ uniq (o)), e} function onlyWithinThisSite (e, o) {return o.subsiteSlug? addFilter (e, {term: {subsite: o .subsiteSlug }}) 🙁 addFilter (e, {term: {site: o.slug}}), addMustNot (e, {exists: {field: « subsite »}})), e} function onlyWithinThisDomain (e, o) { return addFilter (e, {prefix: {canonicalUrl: `http: // $ {o.host}`}}), e} function withinThisSiteAndCrossposts (e, o) {var t = {term: {}}, r = { bool: {should: [], minimum_should_match: 1}}; return t.term [« crosspost. » (o.subsiteSlug || o.slug)] =! 0, r.bool.should.push (t), o.subsiteSlug? r.bool.should.push ({term: {subsite: o.subsiteSlug}}) : (r.bool.should.push ({term: {site: o.slug}}), addMustNot (e, {exists: {field: « subsite »}})), addFilter (e, r), e} function withinThisDomainOrCrossposts (e, o) {return addShould (e, {term: {[`crosspost. $ {o.subsiteSlug || o.slug}`] :! 0}}), addShould (e, {prefix: {canonicalUrl : `http: // $ {o.host}`}}), addMinimumShould (e, 1), e} function moreLikeThis (e, o, t) {let r = {fields: [« tags »], like: {_index: e.index, _type: « _ doc », _ id: o}, include:! 1, min_term_freq: 1, max_query_terms: 12, min_doc_freq: 1}; return {more_like_this: Object.assign (r, t)}} Function addAggregation (e = {}, o) {const {body: t = {}} = e; return o? (T.aggs? _Set (e, « body.aggs », Object.assign (t.aggs, o )): _ set (e, « body.aggs », o), e): e} function formatAggregationResults ({aggregationName: e = «  », field: o = «  », subfield: t = «  », skipEmpty: r = ! 0}) {return function (s = {}) {let u = _get (s, `aggregations. $ {E} $ {t? ». « T ». « : ». « } Buckets`, []) ; return r&& (u = u.filter (e => 0! == _ get (e, « doc_cou nt « , 0))), u.map (e => e [o] || » « )}} function addGeo (e, o) {if (! _ isArray (o)) throw new Error ( » Second argument is required to be an array « ); if (2! == o.length) throw new Error ( » Array must have length 2 « ); if (o.some (isNaN)) throw new Error ( » Array may only be Contain numbers « ); return _set (e, » body.query.geo_shape.location.shape.type « , » point « ), _ set (e, » body.query.geo_shape.location.shape.coordinates « , o), e} combine functionFunctionScoreQueries (e, o) {let t = _cloneDeep (_get (e, « body.query », {})), r = _cloneDeep (_get (o, « body.query », {})), s = _get (e, « body.sort »); return _set (e, « body.query », {}), _ set (e, « body.query.function_score.functions », []), e.body.query .function_score.functions.push ({filter: t, weight: 20}), e.body.query.function_score.functions.push ({filter: r, weight: 10}), e.body.query.function_score.score_mode = « max », e.body. query.function_score.min_score = 10, _isArray (s) || _set (e, « body.sort », s = []), s.unshift ({_ score: « desc »}), e} function addNestedObjQuery (e, o, t) {if (! e) throw new Error (« There is no base query to run the addNestedObjQuery operation ion »); if (! o) throw new Error (« There is no nested object path to run the nested query » ); if (! t) throw new Error (« There is no nested query path to execute the nested query against »); return _set (e, « nested », {path: o, query: t}), e} function addMatchAll (e) {return _set (e, « body.query », {match_all: {}}), e} function addMultiMatch (e, o) {const t = _get (e, « body.query.bool.must », void 0), {fields: r, type: s, string: u} = o, i = {multi_match: {query: u, fields: r, type: s}}; return t? (t.push (i) , _set (e, « body.query.bool.must », t)): _ set (e, « body.query.bool.must », [i]), e} module.exports = newQuery, module.exports. addGeo = addGeo, module.exports.addAggregation = addAggregation, module.exports.addShould = addShould, module. exports.addFilter = addFilter, module.exports.addMust = addMust, module.exports.addMustNot = addMustNot, module.exports.addMinimumShould = addMinimumShould, module.exports.addSort = addSort, module.exports.addSize = addSize, module.exports addFrom = addFrom, module.exports.onlyWithTheseFields = only with synthesis fields, module.exports.onlyWithinThisS ite = only within this site, module.exports.onlyWithinThisDomain = only within this domain, module.exports.withinThisSiteAndCrossposts = withinThisSiteAndCrossposts, module.exports.withinThisDomainOrCrossposts = withinThisDomainOrCrossposts, module.exports.formatAggregationResults more like this , module.exports.combineFunctionScoreQueries = combineFunctionScoreQueries, module.exports.addNestedObjQuery = addNestedObjQuery, module.exports.addMatchAll = addMatchAll, module.exports.addMultiMatch = addMultiMatch;
}, {« 10 »: 10, « 74 »: 74, « 92 »: 92, « 110 »: 110, « 115 »: 115, « 131 »: 131, « 173 »: 173}];
window.modules [« 1343 »] = [function (require, module, exports) {(function (process, __ filename) {(function () {
« use strictly »; const _forEach = require (64), _ get = require (10), _ filter = require (157), _ map = require (74), _ isEmpty = require (111), urlParse = require (75), log = require (7) .setup ({file: __ filename}), queryService = require (1342), universalRest = require (20), AGORA_HOST = window.process.env.AGORA_HOST, AGORA_ELASTIC_PREFIX = window.process.env.AGORA_ELASTIC_PREFIX, =. GORA_END AGORA_HOST? `$ {AGORA_HOST} / api / v1`: null, requestHeader = { » Content-Type « : » application / json « }, PRODUCTS_INDEX = » agora-products « , AFFILIATES_INDEX = » affiliates « , RETAILERS_INDEX = » retailers « , FILTER_KEY = {merchants: » name « , affiliates: » affiliate « }, URL_RE = / ^ https?: / /.*$/; function getProducts (e, t) {const {limit: r = 100, start: a = 0, search: s = «  », sortDate: i = « desc »} = e, n = `$ {AGORA_ENDPOINT} / products? limit = $ {r} &start = $ {a} &search = $ { encodeURIComponent (s)} &sortDate = $ {i} `; return fetch (n) .then (handleResponse) .then (e => t? filterByLocale (e, t): e) .then (e => ({total: e .length, products: e})). catch (handleError (n))} function getProduct (e, t) {const r = `$ {AGORA_ENDP OI NT} / products / $ {e} `; if (! AGORA_ENDPOINT) throw new Error ( » No Agora endpoint was set « ); if ( » string « ! = Typeof e) throw new Error ( » Request must be a Specify product id « ); return fetch (r) .then (handleResponse) .then (e => t? FilterByLocale (e, t): e) .catch (handleError (r))} function postProduct (e) {const t = `$ {AGORA_ENDPOINT} / products`, r = {method: » POST « , headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError ( t))} Function putProduct (e, t) {const r = `$ {AGORA_ENDPOINT} / products / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t) }; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function patchProduct (e, t) {const r = `$ {AGORA_ENDPOINT} / products / $ {e}`, a = {method : « PATCH », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function deleteProduct (e) {const t = ` $ {AGORA_ENDPOINT} / products / $ {e} `; return fetch (t, {method: » DELETE « , headers: requestHeader}). Then (handleResponse) .catch (handleError (t))} function getMerchantList (e) { const {limit: t = 100, fields: r = «  »} = e; Return Promise.resolve ([{name: « Amazon »}]). catch (handleError («  »))} function getMerchant (e) {const t = `$ {AGORA_ENDPOINT} / merchants / $ {e}`; if (« string »! = typeof e) throw new Error (« Request must specify a merchant ID »); return fetch (t) .then (handleResponse ) .catch (handleError (t))} function patchMerchant (e, t) {const r = `$ {AGORA_ENDPOINT} / merchants / $ {e}`, a = {method: « PATCH », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function postMerchant (e) {const t = `$ {AGORA_ENDPO INT} / merchants`, r = {method: « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function putMerchant (e, t) {const r = `$ {AGORA_ENDPOINT} / merchants / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function deleteMerchant (e) {const t = `$ {AGORA_ENDPOINT} / merchants / $ {e}`; return fetch (t, {method: « DELETE », head ers: requestHeader}). Then (handleResponse) .catch (handleError (t))} function migrationMerchants (e) {const t = `$ {AGORA_ENDPOINT} / merchants / migrate-affiliate`, r = {method : « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function getRetailers (e) {const {limit: t = 100, start: r = 0} = e, a = `$ {AGORA_ENDPOINT} / retailers? limit = $ {t} &start = $ {r}`; return fetch (a) .then (handleResponse) .then ( e => ({total: e.length, retailers: e})). catch (handleError (a))} function getRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e} `; return fetch (t). then (handleResponse) .catch (handleError (t))} function postRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers`, r = {method: » POST « , headers: requestHeader, body: JSON.stringify ( e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function putRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e}`, a = {method: « PUT », headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function deleteRetailer (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e}`; return fetch (t, {method: « DELETE », headers: requestHeader}). then (handleResponse) .catch (handleError (t))} function getAffiliates (e) {const {limit: t = 100, start: r = 0} = e, a = `$ {AGORA_ENDPOINT} / affiliates? limit = $ {t} &start = $ {r}`; return fetch (a ) .then (handleResponse) .then (e => ({total: e.length, affiliates: e})). catch (handleError (a))} function getAffiliateRetailers (e) {const t = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates`; return fetch (t) .then (handleResponse) .catch (handleError (t))} function getAffiliateRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`; return fetch (r) .then (handleResponse) .catch (handleError (r))} function postAffiliateRetailer (e, t ) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates`, a = {method: » POST « , headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a ) .then (handleResponse) .catch (handleError (r))} Function putAffiliateRetailer (e, t, r) {const a = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`, s = {method: « PUT », headers: requestHeader, body: JSON.stringify (r)}; return fetch (a, s) .then (handleResponse) .catch (handleError (a))} function deleteAffiliateRetailer (e, t) {const r = `$ {AGORA_ENDPOINT} / retailers / $ {e} / affiliates / $ {t}`; return fetch (r, {method: « DELETE », headers: requestHeader}). catch (handleError (r)) } function postLocale (e) {const t = `$ {AGORA_ENDPOINT} / locales /`, r = {method: « POST », headers: requestHeader, body: JSON.stringify (e)}; return fetch (t, r) .then (handleResponse) .catch (handleError (t))} function patchLocale (e, t) {const r = `$ {AGORA_ENDPOINT} / locales / $ {e}`, a = {method: « PATCH » , headers: requestHeader, body: JSON.stringify (t)}; return fetch (r, a) .then (handleResponse) .catch (handleError (r))} function handleResponse (e) {try {return e.json () .then (t =.)> {if (e.status> = 400) {const e = _get (t, « message.details [0] .message »); throw new error (e)} back t})} catch (e) {throw again Error (e.message)}} function handleError (e) {return t => {throw log (« warn », `Failed request to $ {e}`, t), new Error (` Request to $ {e} failed `)}} Function buildProductsCross y ({search: e = » « , limit: t = 100, start: r = 0, sortDate: a = » « , filters: s, locale: i} ) {const n = queryService (PRODUCTS_INDEX), c = s&&Object .keys (s) .length? Object.keys (s) .filter (e => Array.isArray (s [e]) &&s [e] .length): [], o = {}, l = {}; if (prependElasticPrefix (n), e || c.length || i || queryService.addMatchAll (n), i&& (queryService.addMust (o, {match: {« locales.locale »: i}}), queryService. addMust (l, {match: {« merchants.locale »: i}})), e) if (isURL (e)) queryService.addMust (n, [queryService.addNestedObjQuery ({}, « merchants », {match: {« merchants.buyUrl »: e}})]); else {const t = {}; queryService.addShould (t, [{match: {« locales.productId »: e}}, {match: {« locales. name « : {query: e, boost: 2}}}]), queryService.addMinimumShould (t, 1), queryService.addMust (o, _get (t, » body.query « ))} if (c.length) {const e = {}; c.forEach (t => {const r = s [t], a = FILTER_KEY [t], i = {}; a&& (i [`merchants. $ {a}`] = r , queryService.addMust (e, {terms: i}))}), queryService.addMust (l, _get (e, « body.query »))} return _isEmpty (o) || queryServic e.addMust (n, [ queryService.addNestedObjQuery ({}, « locales », _ get (o, « body.query »))]), _ isEmpty (l) || queryService.addMust (n, [queryService.addNestedObjQuery ({}, « merchants », _ get (l, « body.query »))]), queryService.addSize (n, t), r> = 0&&q ueryService.addFrom (n, r), « desc » === a || « asc » === a? queryService.addSort (n, {updatedAt: {order: a}}): e&&queryService.addSort (n, {_ score: {order: « desc »}}), n} function prependElasticPrefix (e ) {return e.index = AGORA_ELASTIC_PREFIX? `$ {AGORA_ELASTIC_PREFIX} _ $ {e.index}`: e.index, e} function buildMerchantsAggregation (e = 1e6, t) {const r = queryService (PRODUCTS_INDEX); return prependElasticPrefix ( r), queryService.addMust (r, {match: {active:! 0}}), t&&queryService.addMust (r, queryService.addNestedObjQuery ({}, « merchants », _ get (queryService.addMust ({}, {match: {« merchants.locale »: t}}), « body.query »))), queryService.addAggregation (r, {merchants: {nested: {path: « merchants »}, aggs: {name: {terms: { field: « merchants.name », size: e}}}}}), queryService.addSize (r, 0), r} f function isURL (e) {return URL_RE.test (e)} function filterByLocale (e, t , r = {locales: « US »}) {const a = Array.isArray (e); if (_isEmpty (e)) return a? []: {}; const s = [« locales », « merchants »] , i = a? e: [e], n = Object.keys (r), c = _map (i, e => {const a = Object.assign ({}, e); return _forEach (s, s = > {if (Object .keys (a) .includes (s)) {const i = t? _filter (e [s], [« locale », t]): e [s]; a [s] = i,! i.length&&n. includes (s) && (a [s] = (_ filter (e [s], [« locale », r [s]]) || []). map (e => (e.id = null, e. locale = t, e)))}}), a.name = _get (a, « locales [0] .name », «  »), a}); return a&&c.length? c: _get (c, « [ 0] « , {})} function searchByQueryWithRawResults (e, t) {const r =` // $ {t .site.host} $ {80! == t.site.port? `: $ {T.site. port} `: » « } $ {t.site.path} / _ agora / _search`; return universalRest.post (r, e,! 0)} function buildMerchantsByUrlQuery (e) {const t = queryService (PRODUCTS_INDEX); return prependElasticPrefix (t), queryService.addNestedObjQuery (t.body.query, « merchants », {match: {« merchants. buyUrl « : e}}), t} Function getAffiliatesByLocale (e, t) {const r = quer yService (AFFILIATES_INDEX); return prependElasticPrefix (r), queryService.addMust (r, {match: {locale: e}}), queryService.addSize (r, 1e3), queryService.addSort (r, {name: « asc »}), searchByQueryWithRawResults (r, t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source », {})))} function buildRetailersQuery ({search: e = «  », limit: t = 50, start: r = 0, direction: a = « asc », locale: s = « US »}) {const i = queryService (RETAILERS_INDEX); return prependElasticPrefix (i), queryService.addMust (i, {match: {locale: s}}), e? queryService.addMultiMatch (i, { fields: [« name », « domains ^ 2 »], string: e, type: « phrase_prefix »}) 🙁 queryService.addSort (i, {« name.keyword »: a}), queryService.addSize (i, t), r> = 0&&queryService.addFrom (i, r)), i} function getRetailersList (e, t) {return searchByQueryWithRawResults (buildRetailersQuery (e), t) .then (e => ({total: _get (e, « hits.total », 0), retailers: _get (e, « hits.hits », []). map (e => _ get (e, « _ source », {}))}))} function getRetailersByAffiliateId (e , t, r) {const a = queryService (RETAILERS_INDEX); return e? (prependElasticPrefix (a), quer yService.addMust (a, {match: {locale: r}}), queryService.addMust (a, [queryService.addNestedObjQuery ({}, « affiliateRetailers « , {match: { » affiliateRetailers.affiliateId « : e}})]), queryService.addSize (a, 1e4), queryService.addSort (a, { » name.keyword « : » asc « }), searchByQueryWithRawResults (a , t) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source », {})))): Promise.reject ()} function getMerchantsList (e) {return searchByQueryWithRawResults (buildMerchantsAggregation (1e6, _get (e, « site.agoraLocale »)), e) .then (queryService.formatAggregationResults ({aggregationName: « merchants », field: « name », subfield: « name » « }))} function queryRetailersByUrl (e, t, r) {const a = urlParse (e) .host.split ( » www. « ). join ( » « ), s = queryService (RETAILERS_INDEX); return queryService.addMust (s, {match: {locale: r}}), queryService.addMust (s, {match: {domains: a}}), prependElasticPrefix (s), queryService.addSize (s, 10), searchByQueryWithRawResults (s, t ) .then (e => _ get (e, « hits.hits », []). map (e => _ get (e, « _ source « , {})))} function queryRetailersByName (e, t, r) {const a = queryService (RETAIL ERS_INDEX); return queryService.addMust (a, {match: {locale: r}}), queryService.addMust ( a, {match: {« name.keyword »: e}}), prependElasticPrefix (a), queryService.addSize (a, 10), searchByQueryWithRawResults (a, t) .then (e => _ get (e, « hits. hits « , []). map (e => _ get (e, » _ source « , {})))} require (231), module.exports = {buildProductsQuery: buildProductsQuery, buildMerchantsAggregation: buildMerchantsAggregation, getProducts: getProducts, getProduct: getProduct, postProduct: postProduct, putProduct: putProduct, patchProduct: patchProduct, deleteProduct: deleteProduct, getMerchant: getMerchantList: getMerchantList: getMerchantList:, postMerchant: postMerchant,, postMerchant: postMerchant, geterchant, geterchant, putMerchant: geterchant, puterchant, deleteMerchant, migrants: getMerchant: putMerchant: putMerchant, getMerchant: putMerchant: putMerchant, putMerchant: putMerchant: putMerchant: , getRetailersList: getRetailersList, getRetailer: getRetailer, postRetailer: postRetailer, putRetailer: putRetailer, deleteRetailer: deleteRetailer, g etRetailersByAffiliateId: getRetailersByAffiliateId, getAffiliates: getAffiliates, getAffiliateRetailers: getAffiliateRe Tailer, getAffiliateRetailer: getAffiliateRetailer, post affiliate retailer: post affiliate retailer, putAffiliateRetailer: putAffiliateRetailer, deleteAffiliateRetailer: deleteAffiliateRetailer, isURL: isURL, filterByLocale: filterByLocale, patch locale: patch locale, post locale: post locale, buildMerchantsByUrlQuery: buildMerchantsByUrlQuery, getAffiliatesByLocale : getAffiliatesByLocale, searchByQueryWithRawResults: searchByQueryWithRawResults, getMerchantsList: getMerchantsList, queryRetailersByUrl: queryRetailersByUrl, queryRetailersByName: queryRetailersByName};

}). call (this)}). call (this, require (26), « / services / universal / agora.js »)}, {« 7 »: 7, « 10 »: 10, « 20 »: 20 , « 26 »: 26, « 64 »: 64, « 74 »: 74, « 75 »: 75, « 111 »: 111, « 157 »: 157, « 231 »: 231, « 1342 »: 1342}] ;
window.modules [« 1344 »] = [function (require, module, exports) {« use strict »; const _map = require (74), _ mapValues ​​= require (226), _ reduce = require (114), _ assign = require ( 161), _ get = require (10), _ pickBy = require (162), _ find = require (67), affiliateFields = [« siteShortKey », « pageUri », « productId », « utmMedium », « utmSource », « sessionCount » , « format », « utmCampaign », « referrer », « deviceAbbreviation », « zone »], affiliateSettings = {amazon: {domains: [« amazon.com », « amazon.co.uk »], subtagKey: « ascsubtag « , maxLength: 99, delimiter: » standard « , encode:! 1}, narrative: {domains: [ » shop-links.co/ » ],subtagKey: »u1″,maxLength:99,delimiter: »standard « , encode:! 0}, rakuten: {domains: [« click.linksynergy.com/deeplink », »linksynergy.walmart.com/deeplink » ],subtagKey: »u1″,maxLength:72,delimiter: »standard »,encode :! 1}, shareasale: {domains: [« shareasale.com »], subtagKey: « afftrack », maxLength: 99, delimiter: « standard », encode:! 1}, skimlinks: {domains: [« go.redirectingat .com « ], subtagKey: » xcust « , maxLength: 50, delimiter: » alt « , encode:! 1}, impact: {domains: [], subtagKey: » subId2 « , maxLen gth: 99, delimiter: « standard », encode:! 1}, avantlink: {domains: [« avantlink.com »], subtagKey: « ctc », maxLength: 64, delimiter: « old », encode:! 1 }, cj: {domains: [« tkqlhce.com », « jdoqocy.com », « dpbolvw.net », « anrdoezrs.net », « kqzyfj.com »], subtagKey: « sid », maxLength: 64, separator : « alt », encode:! 1, joinBy: « / », assignBy: « / », positioned:! 0, position: « after », positionKey: « type / dlg / »}, partnerize: {domains: [ » prf .hn « ], subtagKey: » pubref « , maxLength: 100, delimiter: » alt « , encode:! 1, joinBy: » / « , assignBy: »: « , positioned:! 0, position: » before « , positionKey: « Target »}, pepperjam: {domains: [« gopjn.com », « pntrac.com », « pjtra.com », « pjatr.com », « pntrs.com », « pntra.com »], subtagKey: « sid », maxLength: 100, delimiter: « alt », encode:! 1}, awin: {domains: [« awin1.com »], subtagKey: « pref1 », maxLength: 100, delimiter: « alt » , encode:! 1, positioned:! 0, position: « before », positionKey: « ued »}}, subtagDictionary = {siteShortKey: «  », pageUri: « p », productId: « i », zone: « z » , device abbreviation: « d », utmSource: « s », utmMedium: « m », utmCampaign: « c », sessionCount: « u », referrer: « r », format: « t »}, d elimite rs = {standard: [« [« , « ] »], old: [« __ », « _ »]}; function parseValueFromSubtag (e, t, i) {const a = t [0] et [1] , s = i.split (a) [1] || «  »; return s? s.split (t [0]) [0]: null} function parseSubtag (e, t = delimiters.standard) {return _pickBy ( _mapValues ​​(subtagDictionary, i => parseValueFromSubtag (i, t, e)))} function generateSubtag (e, t, i = delimiters.standard, a =! 1) {const s = (e => t => `$ { e [0]} $ {t} $ {e [1]} `) (i); let n = _reduce (affiliateFields, (t, i) => {const a = s (subtagDictionary [i]), n = e [i]; return t (n? an: «  »)}, «  »); return a&& (n = encodeURIComponent (n)), n} function applySubtagMaxlength (e, t) {var i = t-3 * ( e .split (« , »). length-1 e.split (« | »). length-1); return e.substr (0, i)} function getSubtagData ({getters: e, fields: t = [] , visitState: i, locals: a, productLink: s}) {let n = {}; return t.forEach (t => {n [t] = e [t] &&e [t] ({visitState: i, locals : a, productLink: s})}), n} function parseQuery (e = «  ») {return e.split (« & »). reduce ((e, t) => {const i = t.split ( » = « ) [0], a = t.split ( » = « ) [1]; return void 0! == a&& (e [i ] = a), e}, {})} fun ction processSubtagPosition ({url: e, positionKey: t, subtagKey: i, position: a = « after », subtagString: s, joinBy: n, assignBy: o} = {}) {const [r, l] = e. split (t), u = `$ {i} $ {o} $ {s}`, g = []; if (« after » === a) {if (! l) return e; const [a, s = «  »] = l.split (`$ {i} $ {o}`), d = s.split (n) .slice (1) .join (n); g.push (`$ {r} $ {t} `, u), a&&g.push (a), d&&g.push (d)} if ( » before « === a) {const [e, a = » « ] = r.split (` $ {i} $ {o} `), s = a.split (n) .slice (1) .join (n); g.push (e), s&&g.push (s), g.push (u,` $ {t} $ {l} `)} return g.reduce ((e, t) => {return e.slice (-1) === n&& (e = e.slice (0, -1)), e.length? [e, t] .join (n): t}, «  »)} function processSubtag ({getters: e, affiliate: t, url: i, visitState: a = {}, locals: s}) {const n = affiliateFields, o = _get (affiliateSettings [t], « subtagKey »), r = _get (affiliateSettings [t], « maxLength »), l = _get (affiliateSettings [t], « encode »), u = _get (affiliateSettings [t], « delimiter »), g = _get (affiliateSettings [t], « positioned »,! 1), d = _get (affiliateSettings [t], « position »), c = _get (affiliateSettings [t ], « positionKey »), p = _get (affiliateSettings [t], « assignBy », « = »), m = _get (affiliateSettings [t], « joinBy », « & »), f = delimiters [u]; let b, y, S = i. indexOf (« ? »)> = 0? i.split (« ? »). pop (): «  », h = parseQuery (S), _ = getSubtagData ({getters: e, fields: n, visitState: a, locals: s, productLink: i}); return o&& (y = h [o] || «  », y = applySubtagMaxlength (b = generateSubtag (_ = _ assign (parseSubtag (y, f), _ pickBy (_)), t , f, l), r), h [o] = y, S = _map (h, (e, t) => `$ {t} = $ {e}`) .join (« & »), i = g? processSubtagPosition ({url: i, positionKey: c, subtagKey: o, position: d, subtagString: y, joinBy: m, assignBy: p}): i.split (« ? ») [0] `? $ {S} `), i} function getAffiliate (e) {const t = Object.keys (affiliateSettings); return _find (t, t => _ find (affiliateSettings [t] .domains, t => e.includes (t .toLowerCase ()))) || «  »} Function createSubtagProcessor (e) {return ({url: t, visitState: i, locals: a, affiliate: s}) => (s = getAffiliate (t) || s )? processSubtag ({getters: e, url: t, affiliate: s, visitState: i, locals: a}): «  »} module.exports.generateSubtag = generateSubtag, module.exports.getAffiliate = getAffiliate, module.exp orts .createSubtagProcessor = createSubtagProcessor, module.exports.processSubtag = processSubtag;
}, {« 10 »: 10, « 67 »: 67, « 74 »: 74, « 114 »: 114, « 161 »: 161, « 162 »: 162, « 226 »: 226}];
window.modules [« article-nav.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), _ throttle = require (61), $ visibility = require (5) , $ popup = require (76), $ gtm = require (3), {reportSocial: reportSocial} = require (77), auth0 = require (8); module.exports = (t => {let e = dom.find (« .page-header »), i = dom.find (« . article-content »), r = dom.find (t, « . deepscroll-headline »), o = dom.find (t, « . deepscroll -rubric « ), s = dom.find (t, ». deepscroll-rubric-sponsored « ), l = dom.find (« . article .article-header .rubric « ), n = dom.find ( » # deepscroll_center_divider « ), a = dom.find (« . clay-paragraph « ), d = dom.find (t, ». logo « ), c = dom.find (t, ». dyn-cut-logo « ), p = dom.find (t, « . article-nav-top »), u = dom.find (t, « . article-nav-deepscroll »), m = dom.find (‘link [rel = « canonical »] ‘), f = m&&m.getAttribute (« href »), g = dom.find (‘ meta [property = « og: image »] ‘)? dom.find (‘ meta [property = « og: image »] ‘ ) .getAttribute (« content »): «  », h = dom.find (‘meta [property = « og: title »]’)? dom.find (‘meta [property = « og: title »]’). getAttribute (« content »): «  », y = dom.find (t , « . share -link.facebook »), w = dom.find (t, « . share-link.twitter »), v = dom.find (t, « . share-link.pinterest »), b = t .classList.contains (« header-simple »), x = window.getComputedStyle (d, null) .getPropertyValue (« – targetFlexBasis »), L = window.getComputedStyle (d, null) .getPropertyValue (« – verticalStart » ) || 0, C = window.getComputedStyle (d, null) .getPropertyValue (« – verticalEnd ») || 0, $ =! 1, _ = 55; function k () {_ = parseInt (window.getComputedStyle ( d, null) .getPropertyValue (« – stickyTop »)) || _, C = $ visibility.getViewportWidth ()> = 1180? window.getComputedStyle (d, null) .getPropertyValue (« – verticalEndDesktop ») || C : window.getComputedStyle (d, null) .getPropertyValue (« – verticalEnd ») || C} function S () {$ =! 1, P ()} function P () {let {top: r} = t. getBoundingClientRect (), o = window.getComputedStyle (d, null) .getPropertyValue (« – baseFlexBasis »), s = ox, l = (_- e.getBoundingClientRect (). top) / _, n = Math.max ( 0, Math. min (1, l)), m = LC-2, f = Math.round (L- (m * n 2)), g = Math.ceil (os * n); if (lt? e.classList.add (« header-after-scroll »): e.classList.remove (« header-after-scroll »), p.style.transfo rm = `translateY ($ {C} px)`, u.style.transform = ` translateY ($ {C} px) `, void (d.style.flexBasis = x » px « )} window.scrollY> r? t.classList.add ( » after-scroll « ): t.classList.remove ( » after-scroll « ), window.scrollY> r? e.classList.add ( » header-after-scroll « ): e.classList .remove ( » header-after-scroll « ), p.style.transform =` translateY ($ {f} px) `, u.style.transform =` translateY ($ {f} px) `, d.style. flexBasis = g » px « , c&& (c.style.flexBasis = g » px « ) , $ visibility.getViewportWidth ()> = 1180&&i&&function () {const t = a? $ visibility.getPageOffset (a) .top-70: 0, e = $ visibility.getPageOffset (i) .top, r = Math.max ( e, t); return Math.max (window.scrollY, document.body.scrollTop)> = r} ()? t.classList .add (« deep-scroll »): t.classList.remove (« deep-scroll « )} function V (t) {var e = t.currentTarget, i = e.getAttribute ( » href « ), r = e .getAttribute ( » data- handle « ), o = $ popup.getPopupClass (e.classList), s = $ visibility.isBelowPrimaryContent (e)? » bottom « : » top « ; $ gtm.reportNow ({event: » social-share-widget « , clickLocation: s, socialNetw ork: o}), reportSocial (o), $ visibility.getViewportWidth ()> = 768&&o&& (t.preventDefault (), $ popup.popWindow (o, r, i))}! function () { const e = _throttle (P, 30); if (k (), dom.findAll (t, « . share-link »). forEach (t => t.addEventListener (« click », V)), y&& (y .href = « http: //www.facebook.com/sharer/sharer.php? u = » f « ? utm_source = fb&utm_medium = s3&utm_campaign = sharebutton-t »), w&& (w.href = « https: // twitter .com / share? text = « encodeURIComponent (h) » &url = « f »? utm_source = tw&utm_medium = s3&utm_campaign = sharebutton-t&via = « w.getAttribute ( » data-handle « )), v&C: // pinterest. com / pin / create / button /? url = « f »? utm_source = pin&utm_medium = s3&utm_campaign = sharebutton-t&description = « encodeURIComponent (h) » &media = « g) », b) return; auth0.on (« init0.on ( » init ) => {auth0.isSubscriber () &&t.classList.add (« subscribed »)}), window.addEventL istener (« scroll », e), window.addEventListener (« resize », S), window.addEventListener ( » resize « , k), l? l.classList.contains ( » rubric-sponsor-story « ) &&s? (o.classList.remove ( » visible « ), s.classList.add ( » visible « ), s.textContent = l.text || l.textContent) 🙁 o.textContent = l.text || l.textContent, o.href = l.href || « # ») 🙁 n.style.display = « none », o.style.display = « none »); S (), r.textContent = h} ()});
}, {« 3 »: 3, « 4 »: 4, « 5 »: 5, « 8 »: 8, « 61 »: 61, « 76 »: 76, « 77 »: 77}];
window.modules [« nav-search-button.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), $ gtm = require (3), {reportSearch: reportSearch } = require (77), openClass = « open », closeClass = « closed »; module.exports = (e => {const s = e, t = dom.find (e, « . nav-search-button-trigger « ), n = dom.find (e, ». nav-search-form « ), o = dom.find (e, ». search-input « ); function i () {const e = dom.find ( » body « ); s.classList.toggle (closeClass), s.classList.toggle (openClass), e.classList.toggle ( » disabled « ), e.classList.toggle ( » search-active « )} function c () {i (), s.classList.contains (openClass) &&o.focus ()} function a (e) {! s.contains (e.target) &&s.classList.contains (openClass) &&i ()} function r (e ) {27 === e.keyCode&&s.classList.contains (openClass) &&i ()} function d (e) {e.preventDefault (), $ gtm.reportCustomEvent ({category: « search », label: « on = » window.location.href, action: o.value}), reportSearch ((o.value || «  »). split («  »), () => n.submit ())}! functi on (e, s, t) {s&&s.addEventListener (« click », c); t&&t.addEventListener (« submit », d); e.addEventListener (« click », a), document.addEventListener (« keydown », r), e .addEventListener (« touchend », a), n.addEventListener (« submit », d)} (dom.find (« body »), t, dom.find (e, « . nav-search-form Submit »)) });
}, {« 3 »: 3, « 4 »: 4, « 77 »: 77}];
window.modules [« nav-dropdown-button.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), visibility = require (5), {reportSearch: reportSearch} = require (77); function getNextSiblings (e) {const t = []; let i = e; for (; i = i.nextElementSibling;) t.push (i); return t} function getMainChildren (e, t) {let i = [], n = e.firstChild; for (; n = n.nextElementSibling;) n.contains (t)? n.isSameNode (t) || (i = i.concat (getMainChildren (n, t ))): i.push (n); return i} function isMobile () {return visible.getViewportWidth () {let t; const i = e.querySelector (« . nav-dropdown-button-trigger »), n = dom.find (« body »), o = dom.find (« . top »), l = dom.find (« . confetti-list »), s = dom.find (« . nav-dropdown-button_nymag-homepage « ), r = dom.find ( » header.page-header « ) || o, c = dom.find (‘[data-editable = » main « ]’), a = dom.closest (e, ». page-header « ), d = a? a.querySelectorAll (« . confetti-image.blue « ): » « , g = a? a.querySelectorAll (« . confetti-image.green « ): » « , u = a? a.querySelectorAll (« . confetti-image.orange »): «  », f = a? a.querySelectorAll (« . confetti-image.orange2 »): «  », m = a? a.que rySe lectorAll (« . confetti-image.pink »): «  », p = a? a.querySelectorAll (« . confetti-image.purple »): «  », h = a? a.querySelectorAll (« . confetti-image . yellow « ): » « , y = e.querySelectorAll (« . dropdown-nav-search-form « ); function b (e) {let t = e.currentTarget, i = t.querySelector (« . nav-search- input « ), n = i? i.value.split ( » « ): []; e.preventDefault (), reportSearch (n, () => t.submit ())} i.addEventListener ( » click « , () => {initializeHeight (e), v ()}); for (let e = 0, t = y.length; e (function (e) {e.classList.remove (« c-right », « c -rightdown « , » c-left « , » c-leftdown « )}) (e))}, 500)} ()) 🙁 i.setAttribute ( » aria-expanded « , » true « ), t = window .scrollY), e.classList.toggle (« closed »), e.classList.toggle (« open »), n.classList.toggle (« disabled »), a&&e.isSameNode (s)? function () {if ( o.contains (e)) {const e = getMainChildren (o, s); S (e), w (o)} if (c.contains (e)) {const e = getMainChildren (c, s); o. classList.toggle (« hidden component »), w (c), S (e)} e.classList.toggle (« open-mobile »)} (): a&&! y&&r&& (w (r), function () { const i = e .classList.contains (« open »)? 0: t; window.scrollTo ({top: i})} ())} function w (e) {S (getNextSiblings (e))} function S ( e) {e .forE ach (e => {e.classList.toggle (« hidden-component »)})} n.addEventListener (« click », t => {! e.contains (t.target) &&e.classList.contains (« open « ) &&v ()}), document.addEventListener ( » keydown « , t => {27 === t.keyCode&&e.classList.contains ( » open « ) &&v ()})});
}, {« 4 »: 4, « 5 »: 5, « 77 »: 77}];
window.modules [« follow.client »] = [function (require, module, exports) {« use strict »; const _find = require (67), $ popup = require (76); DS.controller (« follow », [function () {function e (e) {this.el = e, this.handle = e.getAttribute (« data-handle »)} return e.prototype = {events: {click: « openFollow »}, openFollow: function (e) {var t, n, a = $ popup.position, o = $ popup.params, l = {}, r = {w: 780, h: 500}, s = new a (rw, rh) , c = this.el.classList; l.handle = this.handle, r.left = s.left, r.top = s.top, n = _find ([{className: « facebook », url: « https: //facebook.com/{handle} »,network: »Facebook »},{className: »pinterest »,url: »http://www.pinterest.com/ registers »,network: »Pinterest « }, {className: « instagram », url: « https://www.instagram.com/ Zonenhandle} », network: « Instagram »}, {className: « rss », url: « http: //feeds.feedburner. com / {handle} « , network: » RSS « }, {className: » twitter « , url: » https://twitter.com/intent/follow?screen_name=phiahandle Genealogie&tw_p=followbutton&variant=2.0 « , network: « Twitter »}, {className: « snapchat », url: « https://www.snapchat.com/discover/ Genealogiehandle} » , netw ork: « Snapchat »}], function (e) {return c.contains (e.className)}), l.url = n.url.replace (« {handle} », l.handle), l. network = n.network, l.name = « Follow » l.handle « on » l.network, t = new o (l, r), window.open (t.address, t.name, t.features), e. PreventDefault ()}}, e}]);
}, {« 67 »: 67, « 76 »: 76}];
window.modules [« comments-link.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), _ get = require (10), _ isFinite = require (133), ajax = require (132); DS.controller (« comments-link », [function () {var t, e = « http: // » document.documentElement.getAttribute (« data-uri ») « .html »; Function n (n) {var o; (this.el = n, this.coral_talk_root = n.getAttribute (« data-coral-talk »), this.commentsCount = dom.find (n, « . Comments-link-count « ), this.commentsText = dom.find (n, ». comments-link-text « ), this.isNavVariation = n.classList.contains ( » comments-link_article-nav « ), this.cutoffCnt = n.getAttribute ( « data-cutoffCnt ») || 1e3, t = `$ {this.coral_talk_root} /api/v1/graph/ql`,this.shouldRenderCommentStream ()) && (o = this.onCommentCountFetched.bind (this), ajax. sendReceiveJson ({method: « GET », url: t ‘? query = {asset (url: « ‘ e ‘ ») {totalCommentCount}}’, dataType: « json »}, function (t, e) {var n = _get (e, « data.asset.totalCommentCount », 0); return t? o (t): _ isFinite (n)? void o (null, n): o (« Unexpected Coral Talk response »)})) } back ck n.prototype.onCommentCountFetched = function (t, e) {if (t) return console.warn (t); e> 0&& (this.isNavVariation&&e1? « s »: «  »), this.el.classList.remove (« no comments »))}, n.prototype.shouldRenderCommentStream = function () {return-1! == e.indexOf (« @ published »)}, n}]);
}, {« 4 »: 4, « 10 »: 10, « 132 »: 132, « 133 »: 133}];
window.modules [« head-gtm.client »] = [function (require, module, exports) {« use strict »; const {getCLS: getCLS, getFID: getFID, getLCP: getLCP} = require (165), isProduction = require (9) (); function reportWebVitals (e) {isProduction || console.log (« reportWebVitals:% O », e); const t = « string » == typeof e.name?e.name.toUpperCase () : e.name; window.dataLayer = window.dataLayer || [], window.dataLayer.push ({event: « analyticsEvent », event_action: t, event_category: « Web Vitals », event_label: e.id, event_value: e .delta, eventAction: t, eventCategory: « Web Vitals », eventLabel: e.id, eventNonInt:! 0, eventValue: e.delta, nonInteraction:! 0, transport: « beacon »})} getCLS (e => { e.delta = Math.round (1e3 * e.delta), reportWebVitals (e)}), getFID (e => {e.delta = Math.round (e.delta), reportWebVitals (e)}), getLCP ( e => {e.delta = Math.round (e.delta), reportWebVitals (e)});
}, {« 9 »: 9, « 165 »: 165}];
window.modules [« concert-ads.client »] = [function (require, module, exports) {« use strict »; const customMappings = {« crime-assault »: « power », « career money productivity »: « power », « feminism-politics-identity »: « power », « culture-media »: « culture », celebrity: « culture », living: « style », fashion: « style », shopping: « style », weddings: « style. » « , Beauty: » style « , animals: » self « , » learn creativity « : » self « , » relationships-friends-family « : » self « , » mental health personality social behavior « : » self « , » learn creative  » : « Self », « health-wellness »: « self », parenting: « self », « relationships-sex-dating marriage »: « self »}, striptags = require (78); function installConcertAds () {const e = new URLSearchParams (window.location.search) .get (« concert_config_url »), t = e || window.concertConfigUrl; window._nymPermutive || console.warn (« ConcertAds is initialized without permutive »), window.concertAds = createConcertAds ( ), window.concertAds.loadRemoteConfig (t) .then (function () {window.concertAds.install ()})} function createConcertAds () {const e = getAuthS tatus (); let t = getD ata (« title »), n = window.location.href, i = getData (« section »), o = «  », a = getData (« type »), r = getData ( « vertical »); t&& (t = striptags (htmlDecode (t)). split («  »)), n = n.slice (n.lastIndexOf (« / ») 1); const l = {kw: getKeywords () , network: r, page_type: a, entry_group: i, keywords: t, pn: n}; return « Homepage » === a? o = « homepage »: « Section Page » === a&& (o = (o = window.location.pathname). replace (/ // g, «  »)), i&&-1 === i.indexOf («  ») && (o = i), customMappings [i] && (o = customMappings [i]), window.location .hostname.match (/ . aws ./ i) ​​&& (l.clay_sandbox_env = r), new window.ConcertAds ({cmd: [], slots: [], dfpVariables: l, slugPath: « / » o. replace (/ – | – / g, « -« ), loggedIn: « unauthenticated »! == e, paywallActive: getPaywallStatus (e)})} function getKeywords () {try {const e = window._nymPermutive.article.keywords ; return e&&e.length> 0&&e.some (Boolean)? e: (document.querySelector (‘meta [name = « keywords »]’) || document.querySelector (‘meta [property = « article: tag »]’) ) .getAttribute (« content »). split (« , »). map (function (e) {return e.trim ()})} catch (e) {return}} function getData (e) {if (window. _nymPermutive) {if (e in window._nymPermutive) return window._nymPermutive [e]; if (window._nymPermutive.article&&e in window._nymPermutive.article) Return window. _nymPermutive.article [e]; if (window._nymPermutive.user&&e in window._nymPermutive.user) return window._nymPermutive.user [e]}} function htmlDecode (e) {var t = document.createElement (« div »); return t.innerHTML = e, 0 === t.childNodes.length? «  »: t.childNodes [0] .nodeValue} function getAuthStatus () {const e = JSON.parse (localStorage.getItem (« auth0: profile » )), t = e? e [« http://nymag.com/app_metadata »]: null; return t? t.has_subscription? « entitled »: « unentitled »: « unauthenticated »} function getPaywallStatus (e) {const t = getData (« totalCount ») || 0; return Boolean (t> = 3&& « entitled »! == e)} window.ConcertAds? installConcertAds (): window.addEventListener (« concertAdsReady », in stallConcertAds);
}, {« 78 »: 78}];
window.modules [« curated-feed.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), lazyLoad = require (119); function lazyLoadImage (e) {const o = dom.find (e, « img [data-src] »), t = dom.findAll (e, « source [data-srcset] »), a = dom.closest (e, « . feed-item » ); if (o&&a) {new lazyLoad.LazyLoader (a, o, t) .init ()}} Function handleLazyLoad (e) {(dom.findAll (e, « . feed-item ») || []). forEach (lazyLoadImage)} module.exports = (e => {const o = e.querySelectorAll (« button.show-more »); function t (e) {const {currentTarget: o} = e; if (o) { const e = o.parentElement.parentElement; e&&e.querySelector (« . content »). classList.toggle (« collapsed »)}} o&&o.forEach (function (e) {e.addEventListener (« click », t)}) , handleLazyLoad (e)});
}, {« 4 »: 4, « 119 »: 119}];
window.modules [« coral-talk.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), store = require (139), visibility = require (5), auth0 = require (8), TALK_AUTH = « talk: auth_token »; let coralEmbed, hasEmbedScriptLoaded =! 1, hasCoralTalkRendered =! 1; function renderComments (e) {if (hasEmbedScriptLoaded&CSSEAND {{{= const! `$CoralTalkRendered) .CORAL_TALK_HOST} `, auth_token: getAuthToken (), asset_url: e.TALK_ASSET_URL}; hasCoralTalkRendered =! 0, coralEmbed = window.Coral.Talk.render (e.commentStreamContainer, t)}} function getAuthToken = e&&e [« http://nymag.com/coral_talk »] || auth0.getTalkJwt (), i = store.get (TALK_AUTH); return t? i&&t == i? i: (store.set (TALK_AUTH, t) , t) 🙁 i&&store.remove (TALK_AUTH), null)} function coralLogin () {coralEmbed.login (getAuthToken ())} function embedScript (e, t) {let i = document.createElement (« script »); i.type = « text / javascript », i.async =! 0, i.src = e, i.addEventListener (« load », () => {hasEmbedScriptLoaded =! 0, r enderComments (t)}), document .getElementsByTagName (« head ») [0] .appendChild (i)} function initVerificationMessage () {auth0.isAuthenticated () &&auth0.refresh (); let e = document.querySelector (« . coral -talk-container »); auth0 .isAuthenticated () &&! auth0.isEmailVerified () && (e.insertAdjacentHTML (« beforebegin », ‘ n n Please check your account to activate comments. Did not receive a confirmation email? Email again now send. n ‘), document.querySelector (« . activation-link »). addEventListener (« click », sendVerificationEmail))} function sendVerificationEmail () {let e = document.querySelector (« . coral-talk -verify-address « ); return fetch (` https: // $ {window.location.host} / _user / verification-email? user_id = $ {auth0.getUserID ()} `, {method: » GET « , headers: { » Content -Type « : » application / json « }}). Then (e => e) .then (t => {t&&200 == t.status? E.inn erHTML = « Confirmation email was sent successfully »: e.innerHTML = `$ {t.statusText}`}). catch (e => console.log (e))} Function attemptScriptEmbedding (e, t) {initVerificationMessage ( ), hasEmbedScriptLoaded? renderComments (t): embedScript (t .EMBED_URL, t)} function addVisibilityListener (e, t) {new Visibility.Visible (e, {preloadThreshold: 750}). on (« preload », () => attemptScriptEmbedding (e, t))} function removeSignInButton (e) {e&&e.parentNode&&dom.removeElement (e)} function init (e) {const t = e.getAttribute (« data-coral-talk-host »), i = ` $ {t} / static / embed.js`, n = `http: // $ {document.documentElement.getAttribute ( » data-uri « )}. html`, a = » true « === e.getAttribute ( « data-maintenance »), o = -1! == n.indexOf (« @ published »), r = e.querySelector (« . coral-talk-container »), s = e.querySelector (« . coral- talk-btn-signin « ), c = {CORAL_TALK_HOST: t, EMBED_URL: i, commentStreamContainer: r, signInButton: s, TALK_ASSET_URL: n}; e, c), « .addEventListener (s.addEventListener », () => auth0.showLogin ()), auth0.isAuthenticated () &&removeSignInButton (s)}), auth0.on (« login », t => {removeSignInButtonT (s)., getAuth., getAuth (t), visibility.isElementInViewport (e) &&attemptScriptEmbedding (c), hasCoralTalkRendered&&coralLogin ()}), auth0.on (« logout », () => {store.remove () => {store.remove (TALK_AUTH; module.ex)})) =} init; module.ex)
}, {« 4 »: 4, « 5 »: 5, « 8 »: 8, « 139 »: 139}];
window.modules [« choreographer.client »] = [function (require, module, exports) {« use strict »; const cookie = require (65), _ get = require (10), _ omit = require (97), {insertSpeedBumpComponents : insertSpeedBumpComponents} = require (102), {insertNewsletterSpeedBumpComponents: insertNewsletterSpeedBumpComponents} = require (101), {generateGrowl: generateGrowl} = require (100), gtm = require (3), {getLocalStorage: getLocalSorage, set = 47 ), {reportPaywall: reportPaywall} = require (77), moment = require (52), {getClientHistory: getClientHistory, updateClientHistoryWithPageData: updateClientHistoryWithPageData} = require (103), auth0 = require (8), {Scenario: Scenario} = require ( 98), cidReadyEvent = « nymcid-set », cidKey = « nymcid », isProduction = require (9) (), logger = require (96) .Logger (() => getLocalStorage (« show_choreographer_logs »)), {Verdon: Verdon} = require (99), TEST_COHORT_FLAG = « optimizeCohort »; function displayDebug (e = «  ») {if (« entitlement »! == e.split (« # »). Pop ()) return; const t = _get (window, « dataLayer [0] .userDetails », {}), o = _get (win dow, « dataLayer [0] .page Details.featureTypes « , » « ), n = o.includes ( » magazine « )? » Magazine « : » « , r = o.includes ( » feature « )? » Featured « : » « , i = » Value of the Article: « (n || r || » article « ), a = _get (JSON.parse (localStorage.getItem ( » auth0: profile « )), » http: // nymag. com / app_metadata « ), l = » Authentication status: « (a? » authenticated « : » unauthenticated « ), s = » Authorization status: « (!! a&&a.has_subscription? » entitled « : » unentitled « ), c = Object. keys (_omit (t, « newYorkMediaUserID »)). map (e => `$ {e}: $ {t [e]}`), d = document.body, g = document.createElement (« div »), u = document.createElement (« ul »); [i, l, s, … c] .map (e => {const t = document.createElement (« li »); return t.classList.add ( » debug-item « ), t.appendChild (document.createTextNode (e)), t}). forEach (e => {u.appendChild (e)}), u.classList.add ( » data-bullets « ), g.classList.add (« debug-choreographer »), g.classList.add (« display-debug-data »), g.appendChild (u), d.appendChild (g)} function initializeChoreographer (e) {const t = e.getAttribute (« data-site-slug »), o = pageShouldCountAsView (t), n = auth0.isSubscr iber (); return t? getClientId (cidKey, 8e3) .then (e => (logger.h1 ( « Choreographer initialized »), logger.log (`clientId: $ {e}`), logger.log (`page counts as view: $ {o}`), window.nymViewsResponse || (o? UpdateClientHistoryWithPageData (e, t ): ge tClientHistory (e)))). then (r => {if (logger.group (), logger .h2 (« Client history »), logger.table (r), logger.groupEnd (), isNCR ()) return; const {scenarios: i, touts: a, testCohort: l = «  »} = readJSONFromScript (e. querySelector (« script »)); if (! (l === (document.body.dataset [TEST_COHORT_FLAG] || «  »))) return; const s = i.map (e => Scenario (Object.assign ( {}, e, {history: r, siteSlug: t, isSubscriber: n}))). filter (e => (logger.group (), logger.h2 (« Evaluate scenarios »), logger.log (e) , logger.groupEnd (), e.shouldShow)). reduce ((e, {action: t, min: o, count: n}) => {const r = a.find (({value: e}) = > e === t); Return r? (e [r.type] = r, e [r.type] .viewCount = no, e): e}, {}); logger.group (), logger. h2 (« Active Touts »), logger.log (s), logger.groupEnd (), executeTouts (e, o, s, r)}). catch (console.error): console.error (« siteSlug not found. « )} Function documentInc ludesComponent (e) {return document.querySelector (` [data-uri * = « / $ {e} / »] `)} function pageShouldCountAsView (e) {const t = » strategist « === e, o = [« product », « product-grid »]. find (e => documentIncludesComponent (e)); return t ||! o} Function executeTouts (e, t, o = {}, n) {const {global : r} = n, i = {featureArticleCount: r.Feature || 0, magazineArticleCount: r.Magazine || 0, standardArticleCount: r.Article || 0, totalArticleCount: r.total || 0}, a = window. concertAds, l = window.ConcertAds; if (o [« speed-bump »] && (_get (a, « adsBlocked »,! 0)? insertSpeedBumpComponents (findTemplate (e, « speed-bump »), o [« speed- bump « ], i): a.lifecycle.listenAndPlayback (l.events.slotsInserted, () => {insertSpeedBumpComponents (findTemplate (e, » speed-bump « ), o [ » speed-bump « ], i)}) ), o [« newsletter-speed-bump »] && (_get (a, « adsBlocked »,! 0)? insertNewsletterSpeedBumpComponents (findTemplate ( e, « newsletter-speed-bump »), o [« newsletter-speed-bump »], i): a.lifecycle.listenAndPlayback (l.events.slotsInserted, () => {insertNewsletterSpeedBumpComponents (findTemplate (e, « newsletter -speed-bump « ), o [ » newsletter-speed-bump « ], i)})), o [ » branded-growl « ] &&brandedTakeoverTime (o [ » branded-growl « ]) &&t) return logger. log (« should show Branded Growl »), void GrowlManager (findTemplate (e, « branded-growl »), {baseTrackingData: i, body: o [« branded-growl »]. brandedGrowlBody, contentClass: « branded-content », cta: o [« branded-growl »]. brandedGrowlCTA, imageUrl: o [« branded-growl »]. imageUrl, link: o [« branded-growl »]. brandedGrowlLink, name: o [« branded-growl »]. name, scrollDepth: o [« branded-growl »]. brandedGrowlScrollDepth, title: o [« branded-growl »]. brandedGrowlTitle, toutType: « branded-growl »}, « # branded-growl »); if (t&&o [ » content -cliff « ]) contentCliff (findTemplate (e, » content-cliff « ), o [ » content-cliff « ], o [ » content-cliff « ]. viewsLeft, n); else {if (t&&o [ » cliff – takeover « ]) return / coronavirus news | pivot | paywall exclude / i.test (window._nymGtmPage.tags)? void (isProduction&&logger.log ( » Content cliff no-op due to excluded tag: « , window._nymGtmPage. tags)): void cliffTakeover (findTemplate (e, « paywall-reader-interface »), i, o [« cliff-takeover »]); if (o [« growl-newletter »] ||! o [« Promo- Grow l « ]) if (o [ » Baby-Growl « ]) babyGrowl (findTemplate (e, » Paywall-Reader-Interface « ), i, o [ » Baby-Growl « ]); else {if (! o [« warning-growl-2 »]) return o [« warning-growl »] &&shouldWarn ()? (setContentCliffWarningDisplayed (), logger.log (« should show a warning »), void GrowlManager (findTemplate ( e, « warning-growl »), {contentClass: « warning-content », title: o [« warning-growl »]. warningGrowlTitle, name: o [« warning-growl »]. name, scrollDepth: o [« warning -growl « ]. warningGrowlScrollDepth, cta: o [ » warning-growl « ]. warningGrowlCTA, body: o [ » warning-growl « ]. warningGrowlBody, link: o [ » warning-growl « ]. warningGrowlLink, baseTrackingData: i, toutType: « warning Growl »}, « # warning-growl »)): void 0; warningGrowl (findTemplate (e, « paywall-reader-interface »), i, o [« warning-growl-2 »])} else growlManager (findTemplate (e, « growl-message »), {contentClass: « promo-content », title: void 0, name: o [« promo- Growl »]. name, scrollDepth: o [« Promo-Growl »] .promoGrowlScrollDepth, cta: o [« Promo-Growl »]. promoGrowlCTA, body: o [« Promo-Growl »]. promoGrowlMessage, link: o [« promo-growl »]. promoGrowlLink, baseTrackingData: i, toutType: « promo Growl « }, » # growl-message « )}} functi on shouldWarn () {return! contentCliffWarningDisplayed ()} function getContentCliffWarningDisplayedKey () {const e = new Date, t = e.getMonth (); return`content-cliff-warning-displayed – $ {e.getFullYear ()} – $ {t} `} function contentCliffWarningDisplayed () {const e = getContentCliffWarningDisplayedKey (); return » true « === getLocalStorage (e)} function setContentCliffWarningDisplayed () {const e = getContentCliffWarningDisplayedKey (); return setLocalStorage (); return setLocalStorage (e) } function GrowlManager (e, {contentClass: t, scrollDepth: o, name: n, title: r, body: i, cta: a, link: l, baseTrackingData: s, toutType: c, imageUrl: d = null}, g = «  ») {const u = function () {const e = ` n n n n $ {r} n $ {d?  »: » « } n $ {i} n $ {d? « : «  »} n $ {a} n n n n `; Return document.createRange (). createContextualFragment (e)} (), p = {creative: i, id: c , name: n, position: « growl »}; u.querySelector (« a ») .addEventListener (« click », () => promotionReport (« Click », s, p)), generateGrowl (e, g, { content: u, scrollDepth: o, onShow: () => promotionReport (« View », s, p)})} Function contentCliff (e, t, o, n) {const {first_vi sit: r, global: i} = n, a = {totalArticleCount: i.total || 0, standardArticleCount: i.Article || 0, featureArticleCount: i.Feature || 0, magazineArticleCount: i.Magazine || 0} , {contentCliffBody: l} = t, s = document.importNode (e,! 0) .querySelector (« . content-cliff »), c = document.querySelector (« . article-content> .clay-paragraph »), d = {creative: l, id: « content cliff », name: « Content Cliff », position: « in-article »}; s&& (c.insertAdjacentHTML (« afterend », s.outerHTML), require (« content- cliff.client « ) (document.querySelector (.content-cliff »), {contentCliffOptions: t, viewsLeft: o, firstVisit: Number (r), onShow: () => promotionReport (« View », a, d), onClickCliff: () => promotionReport (« Click », a, d)}))} fu nction verdonFosseToutSetter (e, t, o, n, r) {const i = new Verdon ({container: « . paywall-reader- interface « , url: » https://fosse.nymag.com/fosse/v1.6.1 /index.html »}),a=e.type,l= Genealogie:auth0.getEmail(),isAuthenticated:auth0. isAuthenticated (), isSubscriber: auth0.isSubscriber ()}; n.classList.add (a), i.once (« frame: ready », () => {i.sendMessage (« tout: s how « , {readerState: l, toutType: a, toutData: e}), r&&i.sendMessage ( » frame: height « )}), i.on ( » tout: visible « , () => {promotionReport ( » View « , t, o)}), i.on ( » tout: sign-in « , () => {auth0 .showLogin (window.location.href)}), i.on ( » tout: log-out  » , () => {auth0.logout ()}), i.on (« tout: dismiss », () => {n.classList.add (« dismiss »), i.sendMessage (« tout: hide », {toutType: a, toutData: e})}), i.on (« tout: subscribe », () => {e.ctaLink = replaceQueryParams (e.ctaLink), promotionReport (« Click », t, o), window.open (e.ctaLink, « _ ​​blank »)}), i.on (« frame: height », e => {n.style.height = `$ {e.payload.currentHeight 10} px`}), i.on (« tout: view-account », () => {window.location.href = « https: / /subs.nymag.com/account »})} function promotion report (e, t, o) {const {creative: n, id: r, name: i, position: a} = o; t.event = `eec.promotion $ {e}`, t.ecommerce = {promoView: {promotions: [{creative: n.trim (), id: r, name: i, position: a}]}}, gtm.reportNow (t), reportPaywall ({creative: n.trim (), eventType: e, id: r, name: i, position: a})} Function babyGrowl (e, t, o) {const n = document.importNode (e,! 0) .q uerySelector (.paywall-reader-interface « ), r = {creative: o.babygrowlDescription, id: » babygrowl « , name: » babygrowl « , position: » growl « }; document.body.appendChild (n), o. ctaLink = o.babygrowlCtaLink, o. ctaText = o.babygrowlMessage, o.headline = o.babygrowlDescription, verdonFosseToutSetter (o, t, r, n)} function cliffTakeover (e, t, o) {const {cliffTakeoverCTA: n, cliffTakeoverCtaLink: r, cliffTakeImage. cliffTakeover: iiffTakeover : a, cliffTakeoverPromo: l, cliffTakeoverStatus: s, type: c} = o, d = document.importNode (e,! 0) .querySelector (« . paywall-reader-interface »), g = document.querySelectorAll (« . Tone paragraph « ), u = {creative: l, id: » content cliff « , name: » Content Cliff « , position: » growl « }, p = {cta: n, ctaLink: r, description: i, image : a, promo: l, status: s, type: c}; document.body.appendChild (d), g.forEach ((e, t) => {0! == t&&e.remove ()}), verdonFosseToutSetter (p, t, u, d,! 0), document.querySelector (« html »). style.overflowY = « hidden », document.body.style.position = « fixed »} function warningGrowl (e, t, o ) {const {type: n, warningGrowl2CTA: r, warningGrowl2CtaLink: i, warningGrowl2Description: a, warningGrowl2Image: l, warningGrowl2Promo: s, warningGrowl2Status: c} = o, d = document.importNode (e,! 0) .querySelector ( » .paywall-reader-interface « ), g = {creat ive: s, id: « warning Growl », name: « Warning Growl », position: « growl »}, u = {cta: r, ctaLink: i, description: a, image: l, promo: s, status: c, type: n}; document.body.appendChild (d), verdonFosseToutSetter (u, t, g, d,! 0)} function getClientId (e = «  », t = 8e3) {let o = cookie.get ( e); return o? Promise.resolve (o): new Promise ((o, n) => {const r = setTimeout (() => {n (`Key could not be found: $ {e} on cookie after $ {t} ms`)}, t); window.addEventListener (cidReadyEvent, () => {clearTimeout (r), o (cookie.get (e))})})} function readJSONFromScript (e) {try { ret urn JSON.parse (e.innerHTML)} catch (e) {return {touts: [], scenarios: []}}} function findTemplate (e, t = «  ») {const o = e&&e.querySelector (`[ data -template-id = « $ {t} »] `); return o&&o.content} function isNCR () {return / [? &] source = ncr / .test (location.search)} function brandedTakeoverTime (e) { const {startTime: t, endTime: o, startDate: n, endDate: r} = e, i = n.concat («  », t), a = r.concat («  », o), l = moment (i ), s = moment (a); return moment (). isBetween (l, s)} functionOptimiz eDebugger () {return new Promise (e => {const t = window.location.search || «  »; if (t) {const o = new URLSearchParams (t), n = o.get (« optimize-attribute- name « ) || » « , r = o.get ( » optimize-attribute-value « ) || » « , i = o.get ( » optimize-delay « ) || 0, a = o.get ( » optimize-cookie « ) ||! 1; setTimeout (() => {a&& (document.cookie = randomNymcid ()), document .body.setAttribute (` data – $ {n} `, r), e ()} , i)} else e ()})} function randomNymcid () {return`nymcid = $ {(() => ([1e7] -1e3 -4e3 -8e3 -1e11) .replace (/ [018] / g, e => (e ^ 16 * crypto.getRandomValues ​​(new Uint8Array (1)) [0] >> e / 4) .toString (16) [0])) ()} `} function replaceQueryParams (e) {const t = window.location.search || «  »; if (t) {const o = new URLSearchParams (t); if (e.includes (« ? »)) {const t = e.split (« ? »), n = new URLSearchParams (t [1]); for (let e of o.entries ()) n.set (e [0], e [1]); e = `$ {t [0]}? $ {n .toString ()} `} else e =` $ {e}? $ {o. toString ()} `} return e} module.exports = (e => new Promise (e => {auth0.on ( » init « , () => {e ()})}). then (() = > optimizeDebugger ()). then (() => {displayDebug (window.location.href), initializeChoreographer (e)}));
}, {« 3 »: 3, « 8 »: 8, « 9 »: 9, « 10 »: 10, « 47 »: 47, « 52 »: 52, « 65 »: 65, « 77 »: 77 , « 96 »: 96, « 97 »: 97, « 98 »: 98, « 99 »: 99, « 100 »: 100, « 101 »: 101, « 102 »: 102, « 103 »: 103,  » content-cliff.client « : » content-cliff.client « }];
window.modules [« growl.client »] = [function (require, module, exports) {« use strict »; require (163); const _some = require (86), dom = require (4), localStorageKeyRoot = « slideout – « , {getLocalStorage: getLocalStorage, setLocalStorage: setLocalStorage} = require (47); module.exports = ((e, t) => {const {content: o, onShow: s, scrollDepth: r = 50, dismissable: i =! 1} = t, n = Number (r || e.getAttribute (« data-display-at-page-scroll-percentage »)), a = dom.find (e, « . Modal »), l = « slideout- » (t.id || e.getAttribute (« id »)), c = getLocalStorage (l); function d () {a.classList.add (« hidden »)} function g () {setLocalStorage ( l,! 0), d ()} i&&c? e.remove () 🙁 o&&e.querySelector (« [data content] »). appendChild (o), n&&function (e = 50) {constOb = new intersection (e = 50) > {_ some (e, « isIntersecting ») && (a.style.top = « inherit », a.classList.remove (« hidden », « initial »), « function » == typeof s&&s (), t .unobserve (a))}); a.style.top = `$ {document.querySelector ( » body « ). scrollHeight / (100 / e)} px`, t.ob serve (a)} (n), e.querySelector (« . dismiss-modal »). addEventListener (« click », () => i? g (): d ()), e.addEventListener (« growl: hide « , d), e.addEventListener ( » growl: dismiss « , g))});
}, {« 4 »: 4, « 47 »: 47, « 86 »: 86, « 163 »: 163}];
window.modules [« newsletter-speed-bump.client »] = [function (require, module, exports) {« use strict »; const {loadRecaptcha: loadRecaptcha} = require (130), _ isEmpty = require (111), _ set = require (131), _ kebabCase = require (104), gtm = require (3), auth0 = require (8), visibility = require (5), COMPONENT_NAME = « newsletter-speed-bump », EMAIL_VALID_REGEX = / ^ (? : (?: [^ () [] \.,;: s @ « ] (?: . [^ () [] \.,;: s @ »]) *) | (« . »)) @ (?: (?: [[0-9] {1,3} . [0-9] {1,3} . [0-9] {1,3} . [0-9] {1,3}]) | (?: (?: [A-zA-Z -0-9] .) [A-zA-Z] {2,})) $ /, LOCAL_STORAGE_KEY_NAME = « newsletterSpeedBumpSignUpStatus _ », MAX_EMAIL_LENGTH = 50; function setClass (e, t) {e.classList.add (t)} function getRequestUrl (e) {return e.getAttribute (« action »)} function getPageType (e) {const t = e? e.getAttribute (« content »): «  »; return _kebabCase (t)} function getPayloadObject (e, t, r, s) {const n = {}; return _set (n, `vars. source _ $ {t} `,` $ {COMPONENT_NAME} _ $ {s} `), n.email = r, n.lists = {}, n.lists [t] =! 0, n.recaptcha = e, n .signuppage = `$ {document.location.href} _ $ {t}`, n [`source _ $ {t}`] = « newsleter_speedbump », n} module. exports = ((e, t) => {if (! t ||! e) return; if (« success » === window.localStorage.getItem (`$ {LOCAL_STORAGE_KEY_NAME} $ {t.newsletterSpeedBumpNewsletterId}`)) return void e.remove (); const {baseTrackingData: r, name: s, newsletterSpeedBumpCtaCopy: n, newsletterSpeedBumpDescription: i, newsletterSpeedBumpHeadline: a, newsletterSpeedBumpNewsletterId: o, newsletterSpeedBumpThankYouMessage: d = « . description = ». RECAPTCHAl_ « ), p = e.querySelector (« . input.email « ), m = e.querySelector (« . error-message « ), h = e.querySelector (« . form « ), E = e.querySelector ( » .form-container « ), y = e.querySelector (« . form-recaptcha-container « ), g = e.querySelector (« . headline « ), v = e.querySelector ( » .container « ), S = e .querySelector (« . input.newsletterId »), _ = e.querySelector (« . recaptcha-wrapper »), L = e.querySelector (« . input.submit »), w = e.querySelector (.text-container  » ), q = new visibility.Visible (e, {shownThreshold: .5}); u&& (p.removeAttribute (« required »), e.classList.add (« signed- in »)), d.innerHTML = i, g.innerHTML = a, S.value = o, L. value = n, q.on (« shown », function () {if (visibility.isElementNotHidden (e)) {const e = r; e.event = « eec.promotionView », e.ecommerce = {promoView: {promotions : [{creative: `$ {a} | $ {i}`, id: « Newsletter speed threshold », name: s, position: « in-article »}]}}, gtm.reportNow (e), q. destroy ()}}), p.addEventListener (« focus », () => {_. classList.remove (« hidden »)}), h.addEventListener (« submit », t => {t.preventDefault () ; const s = new XMLHttpRequest, n = u | | e.querySelector (« . input.email »). value, i = getPageType (document.querySelector (‘meta [name = « type »]’)); u || ! (n.length> = 50) &&EMAIL_VALID_REGEX. test (n)? loadRecaptcha (l, « newsletterSubmit »,! 0) .then (a => {s.open (« POST », getRequestUrl (h) ,! 0) , s.setRequestHeader (« Content-Type », « application / json; charset = UTF-8 »), s.addEventListener (« load », s => {const a = s.currentTarget || s.target; if ( a.status> = 200&&a.statussetClass (e, « success »)), [d, E, m, _]. forEach (e => setClass (e, « hidden »)), g.innerHTML = c.replace ( « {{email}} », n), m.innerHTML = «  »; const s = JSON.parse (a.response), l = _isEmpty (s.sailthruIds)? «  »: Object.values ​​(s.sailthruIds) [0], u = r; u.event = « eec.purchase », u.ecommerce = {purchase: {actionField: {id: l , revenue: « 0.00 »}, products: [{category: « Newsletter registration », name: S.value, quantity: 1, variant: `$ {COMPONENT_NAME} – $ {i}`}]}}, gtm. reportNow (u), setTimeout (() => {e.classList.add (« hidden »)}, 5e3), t.preventDefault ()} else m.innerHTML = « * An error has occurred. Please try again. « }), S.addEventListener ( » error « , () => {m.classList.remove ( » hidden « ), m.innerHTML = » * An error has occurred. Please try again . « }), s.send (JSON.stringify (getPayloadObject (a, o, n, i))), t.preventDefault ()}): m.innerHTML = » * Please enter a valid email address a »})});
}, {« 3 »: 3, « 5 »: 5, « 8 »: 8, « 104 »: 104, « 111 »: 111, « 130 »: 130, « 131 »: 131}];
window.modules [« speed-bump.client »] = [function (require, module, exports) {« use strict »; const gtm = require (3), visibility = require (5); module.exports = ((e , i) => {if (! i ||! e) return; const {name: o, speedbumpDescription: r, speedbumpMessage: t, speedbumpLink: n, baseTrackingData: s} = i, c = new visibility.Visible (e , {shownThreshold: .5}); e.querySelector (« . description »). innerHTML = r, e.querySelector (« . promo-link »). innerHTML = t, e.querySelector (« . promo-link ») .href = n, e.classList.remove (« collapsed »), c.on (« shown », function () {if (visibility.isElementNotHidden (e)) {let e = s; e.event = « eec. promotionView « , e.ecommerce = {promoView: {promotions: [{name: o, creative: r, id: » speed Bump « , position: » in-article « }]}}, gtm.reportNow (e), c .destroy ()}}), e.querySelector (« . promo-link »). addEventListener (« click », function () {let e = s; e.event = « eec.promotionClick », e.ecommerce = { promoClick: {promotions: [{name: o, creative: r, id: « speed bump », position: « in-article »}]}}, gtm.reportNow (e)})});
}, {« 3 »: 3, « 5 »: 5}];
window.modules [« content-cliff.client »] = [function (require, module, exports) {« use strict »; const auth0 = require (8), isProduction = require (9) (), logger = require (96 ) .Logger (() =>! IsProduction); module.exports = ((t, e) => {if (! E) return; logger.group (), logger.h2 (« Content Cliff »); const { contentCliffOptions: o, firstVisit: n, onShow: r, onClickCliff: i} = e, c = 300, l = Number (document.querySelector (« [data-components-count] »). getAttribute (« data-components-count « )), u = 3, s = [ » taboola « ], a = » # content-cliff « , f = t, d = function () {let t = 0; return document.querySelectorAll ( » [data-word -count] « ). forEach (function (e) {t = Number (e.getAttribute ( » data-word-count « ) || 0.10) || 0}), t} (), g = function ( t, e) {function o (t) {return Math.round (t.getTime () / 1e3 / 60)} const n = o (t), r = o (e); return nr} (new date, new Date (n)) {}, show: () => {r (), function () {(p = function (t = «  ») {return document.querySelectorAll (`$ {t} ~ *`)} ( a)). forEach (t => t.remove ()), function () {const {contentCliffStatus: e, contentCliffPromo: n, contentCliffCTA: r, contentCliffURL: c} = o, l = t.querySelector (« [data-Content- cliff-status] « ), u = t.querySelector ( » [data-content-cliff-promo] « ), s = t.querySelector ( » [data-content-cliff-cta] « ); s&&s. setAttribute (« href », c), s&&s.insertAdjacentHTML (« afterbegin », r), l&&l.insertAdjacentHTML (« afterbegin », e), u&&s.insertAdjacentHTML (« afterbegin », r), l&&l.insertAdjacentHTML (« afterbegin », e), u&&s.insertAdjacentHTML (« afterbegin », add&&U.insert) ), f.classList.remove (« collapsed »), e = s, e.forEach (t => {const e = document.querySelector (`[data-uri * = » / $ {t} / « ]`) ; e&&e.remove ()}), m.addEventListener (« click », () => auth0.showLogin ()); var e} ()}} [function () {if (dl) return logger.log (` Item word count $ {d} was too short for the cliff`), logger.log (`Item component count is less than $ {u} and not suitable for the cliff`), » noop « ; if (g&&isProduction) return » noop « ; g&&logger .log (`First session check was $ {g}! Show the cliff anyway: isProduction => $ {isProduction} `); if (/ coronavirus news | pivot | paywall exclude / i.test (window._nymGtmPage.tags)) return isProduction&&logger.log ( » Content cliff no-op due to excluded Tag match: « , window._nymGtmPage.tags), » noop « ; return » show « } ()], m = t.querySelector (.content-cliff-login »); let p = []; return logger .log (`should be in production due to the 30-minute window of the first session: $ {g}`), logger.groupEnd (), auth0.on (« login », () => {f.classList.add ( « collapsed »), (p = Array.prototype.slice.call (p, 0) .reverse ()). forEach (t => f.insertAdjacentElement (« afterend », t)), p = []}), « Function » == type of h? H (): void 0});
}, {« 8 »: 8, « 9 »: 9, « 96 »: 96}];
window.modules [« most-popular.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), lazyLoad = require (119); function lazyLoadImage (a) {const o = dom.find (a, « img [data-src] »), d = a&&dom.findAll (a, « source [data-srcset] »), e = o&&dom.closest (o, « . feed-image- wrap « ); if (o&&e) {new lazyLoad.LazyLoader (e, o, d) .init ()}} function handleLazyLoad (a) {(dom.findAll (a, ». most-popular-item « ) || []). forEach (lazyLoadImage)} module.exports = (a => {handleLazyLoad (a)});
}, {« 4 »: 4, « 119 »: 119}];
window.modules [« collection-package.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), Hammer = require (123), lazyLoad = require (119), _debounce = require (122), BREAKPOINT = 768, ANIMATION_DURATION = 250; module.exports = (e => {const t = dom.find (« . collection-simple_text-top »), n = e.querySelector (« . list -wrapper « ), i = e.querySelector (« . package-content « ), o = dom.findAll (e, ». article « ), r = e.classList.contains ( » carousel-layout « ); var a , s = 0, c =! 1; if (r) {if (! n) return; function d () {a.off (« swipeleft »). off (« swiperight »), s = 0, n.style .transform = « translate (0px) », window.innerWidth1? (window.cancelAnimationFrame (s), i&&i ()) 🙁 t = r (c = d) * (2-c) * a, e.style.transform = « translate ( » t « px) », window.requestAnimationFrame (s)}; n || (n = 0); window.requestAnimationFrame (s)} (n, i, ANIMATION_DURATION, function () {s = e, c =! 1})} function f () {c || s> 0&&l (s-1)} function u () {c || s {! function (e) {const t = dom.findAll (e,  » source [data-srcset] « ), n = dom.find (e, » img [data-src] « ), i = dom.find (e, ». article-img-wrap by »); if (t&&n&&i) {const e = new lazyLoad.LazyLoader (i, n, t); i.classList.add (« contains-image »), e.init ()}} (e)})});
}, {« 4 »: 4, « 119 »: 119, « 122 »: 122, « 123 »: 123}];
window.modules [« sticky-list.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), $ gtm = require (3), _ get = require (10) , stickyContainer = require (« sticky-container.client »); DS.controller (« sticky-list », [« $ window », function (t) {var e = require (241), i = 40; function s ( s) {let n, a = function (t) {let s = t [0], n = 0, a = e.height (this.contentArea), h = this.contentArea.offsetHeight; if (this.containers&&this. container.length) {if (s.target.offsetHeight) {let t = this.breakouts.findIndex (t => (function (t, e) {return t! == document.body&&t.contains (e)}) ( t, s.target.parentElement)); if (t> -1&&this.breakouts [t]) {let e = this.breakouts [t] .offsetHeight i; this.containers [t] .style.marginBottom = `$ { e} px`}} if (h! == this.currentHeigh) {const t = e.rect (this.rightRail, this.contentArea); this.currentHeight = h, this.rightRail.style.height = at.top -r (this.rightRail) « px », this.breakouts.forEach ((s, a) => {let r = e.rect (s, this.contentArea), h = e.intersection (r, t); if (h) {let e, s = h .top-t .top-n; n = s h.height i, this.containers [a] .style.height = `$ {s} px`, this.containers [a] .style.minHeight =` $ { s} px`, e = this.breakouts [a] .offsetHeight i, this.containers [a] .style.marginBottom = `$ {e} px`}})}}}. bind (this); t.innerWidth {let n = _get (e, « dataset.name », «  »), a = n.slice (-1) || « 1 », r = [« Image_Gallery », « Standard_Article », « Feature », « One_Column_Article « ] .find (t => n.includes (t)) || » « ; this.rightRail.parentElement.classList.contains ( » tertiary « ) &&r&& (e.dataset.name = parseInt (i, 10) se = == t) || 0; return i.slice (s 1) .reduce ((t, e) => t (e.offsetHeight || 0), 0) || 0} return s.prototype = {setPins: function () {const t = e.rect (this.rightRail, this.contentArea), i = e.height (this.contentArea), s = it.top-r (this.rightRail); let n, h, o , l; if (this.populatePinsList (), s1&&t.classList.add (« multi-children »), l = 0; l {const t = Array.from (e.children); let o, a, i = 0 ; for (; ia.bottom || n.righta.right)? a.bottom-n.top: 0} function getElementsOverlapAmount (e, t) {var n, a = []; return _forEach (t, function (t) {n = get ElementsVerticalOverlap (e, t), a.push (n)}), _ max (a)} function getNYMagAdChannel (e) {var t = «  »; switch (e) {case « company information »: t = « company » ; break; case « new york guides & things to do »: t = « to-do »; break; case « other »: t = e; break; case « sponsored guides »: t = « s-guides »; break; case « urbanist »: t = « urbanist »; break; default: t = «  »} return t} function appendSectionToDfpAds () {var e, t, n, a = document.querySelector (« meta [property = ‘og: site_name ‘] « ), o = document.querySelector ( » article [data-content-channel] « ), i = document.querySelectorAll (AD_NAME_SELECTOR); a&& (e = a.content), o&& (t = o.getAttribute ( » data-content-channel « ). toLowerCase ()), t&& » New York Magazine « === e&& (n = getNYMagAdChannel (t)), n&&appendToAdd (i, n)} function. appendPage eAdd (i, n) function. querySelector (« .body> div ») || {}, t = document.querySelector (« body ») || {}, n = e&&e.classList, a = n&&n.length? [… n]: [] , o = _find (a, e => e.inclu des (« feature »)), i = document.querySelectorAll (AD_NAME_SELECTOR); n&& (o? appendPageNumberPositionToDfpAds (i, « Feature »): n.contains (« lede- gallery-content « )? appendPageNumberPositionToDfpAds (i, » Image_Gallery): t.classList.contains (« one-column-layout ») ? appendPageNumberPositionToDfpAds (i, « One_Column_Article »): n.contains (« article-content ») &&appendPageNumberPositionToDfpAds (i, « Standard_Article »))} Function append .AdfpNumber, t) « const n = [ » 528 « 1×1 »]; let a = e || [], o = dom.find (« . Ad-splash »), i = dom.find (« section.wrapper »), r = dom.find (« . Secondary « ), d = dom.find (« . bottom « ), s = dom.find (« . primary « ), c = {IA: {xsMobile: {normal: 1, grid: 1}, mobile: {normal: 1, grid: 1}, tablet: {normal: 1, grid: 1}, desktop: {normal: 1, grid: 1}}, BA: {xsMobile: {normal: 1, grid: 1}, mobile: { normal: 1, grid: 1}, tablet: {normal: 1, grid: 1}, desktop: {normal: 1, grid: 1}}}; a.forEach (e => {let a, l = «  » , u = e.dataset.sizes, m = e.classList.value, p = _find (n, e => u.includes (e)), g = e.parentElement.classList.contains (« ima ge-gallery- mobile-grid-ad « ); if (u&&! p || e.setAttribute ( » data-name « , e.getAttribute ( » data-name « ) » / « t), i&&u&&! p) {let n, u ; if (o&&o.contains (e)? l = « LB »: i&&i.contains (e)? l = « IA » 🙁 r&&r.contains (e) || d&&d.contains (e) || s&&s.contains (e)) && (l = « BA »), c [l]) {if (! (u = checkForAdViewport (m))) return; g? (n = c [l] [u] .grid , c [l] [u] .grid) 🙁 n = c [l] [u] .normal, c [l] [u] .normal), a = n {e.setAttribute (« data-name », e.getAttribute (« data-name ») « / » t)})} function injectGoogleScripts () {var e = document.createElement (« script »), t = document.createElement (« script »), n = document. createDocumentFragment (); e.src = « // www.googletagservices.com/tag/js/gpt.js »,e.async= »async »,t.src= »//pagead2.googlesyndication.com/pagead/js /adsbygoogle.js »,t.async= »async »,n.appendChild(e),n.appendChild(t),document.getElementsByTagName(« body »))(0^.appendChild(n) GenealogieappendSectionToDfpAds(),app endPageTypeToDfpAds (), injectGoogleScripts (), DS.controller (« ad », [« adService », function (e) {return function (t) {var n, a, o, i = t.getAttribute (« data-offload » ), r = new $ visibility.Visible (t, {preloadThreshold: i? window.innerHeight / 4: 200}), d =! 1; function s () {window.innerWidth> = 1180&&t.parentElement.classList.contains ( « ad-repeat ») &&flaggedComponentsOnPage.length&& (a = getElementsOverlapAmount (t, flaggedComponentsOnPage), o = parseInt (t.parentElement.getAttribute = 10. oginT.opstyle (« data-gapT », « t.px.30 ») « )} Function c () {s (), e.refresh (n)} function l () {e.remove (n), d || (d =! 0, r.on ( » shown « , c) )} document.querySelector (‘script [data-name = « concert-ads »]’) || (n = e.create ( t), r.preload&& $ visibility.isElementNotHidden (t)? (e.addToPageLoadQueue (n), i&&r.on (« hidden », l)) 🙁 r.on (« preload », function () {! n. slot&& $ visibility.isElementNotHidden (t) && (s (), e.load (n))}), i&&r.on (« hidde n », l)), this.adData = n)}}]);
}, {« 4 »: 4, « 5 »: 5, « 64 »: 64, « 66 »: 66, « 67 »: 67, « 68 »: 68}];
window.modules [« article.client »] = [function (require, module, exports) {« use strict »; const $ visibility = require (5), $ gtm = require (3), ImageZoom = require (80), $ sentry = require (81); DS.controller (« article », [function () {var e = 40; function t (t) {const i = document.querySelector (« . wrapper> .tertiary »), n = t.querySelector (« . lede-image-wrapper.full-bleed »), r = t.querySelector (« . attribution.full-bleed »), o = t.querySelector (« . article-header »), l = o? o.querySelector (« img »): null, c = function () {let t = o.getBoundingClientRect (). height; n&& (t = n.getBoundingClientRect (). height 25, r&CSSEANDRect (t = r.getBounding () .height)), i.style.paddingTop = te « px »}; i&&o&& (window.innerWidtht (e)), document.addEventListener (« closeBanner », function () {i (e)}), $ sentry .initializeIDListeners ()}}]);
}, {« 3 »: 3, « 5 »: 5, « 80 »: 80, « 81 »: 81}];
window.modules [« tags.client »] = [function (require, module, exports) {« use strict »; const _forEach = require (64); DS.controller (« tags », [function () {function e ( e) {this.el = e} return e.prototype = {events: {« a.more click »: « showAll »}, showAll: function (e) {var t = e.target, o = this.el. querySelectorAll (« li.hidden »); _ forEach (o, function (e) {e.classList.remove (« hidden »)}), t.parentNode.removeChild (t), e.preventDefault ()}}, e} ]);
}, {« 64 »: 64}];
window.modules [« image-collection.client »] = [function (require, module, exports) {« use strict »; const dom = require (4); module.exports = (e => {const t = e. querySelector (« button.more-trigger »), o = e.querySelector (« . mobile .attribution »); t&&t.addEventListener (« click », function () {dom.find (o, « . shortened ») &&o. classList.toggle (« truncated »)})});
}, {« 4 »: 4}];
window.modules [« magazine-issue-tout.client »] = [function (require, module, exports) {« use strict »; const auth0 = require (8), magazineIssueTout = document.querySelector (« . magazine-issue- tout « ); auth0.on ( » init login logout refresh « , () => {auth0.isSubscriber ()? magazineIssueTout.classList.add ( » subscriber « ): magazineIssueTout.classList.remove ( » subscriber « )});
}, {« 8 »: 8}];
window.modules [« memo-pixel.client »] = [function (require, module, exports) {« use strict »; (() => {var e = document.createElement (« script »); e.async = ! 0, e.type = « text / javascript », e.src = document.location.protocol « //d16xpr36wrmcmk.cloudfront.net/js/memo.js »,(document.getElementsByTagName(« head »)[0] || document.getElementsByTagName (« body ») [0]). appendChild (e)}) (), module.exports = (() => {});
}, {}];
window.modules [« affiliate-links.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), _ includes = require (68), _ startsWith = require (72), globalClick = require (71), visit = require (70), productSubtags = require (73); Var excluded Hostnames, skimlinksBaseUrl, skimlinksId, visitState, productUrl, ignoreDataAttribute = « data-affiliate-links-ignore », article = window.document. querySelector (« article »), isSponsored = article&& « Sponsor Story » === article.getAttribute (« data-type »); function setExcludedHostnames (t) {excludedHostnames = (t.getAttribute (« data-excluded-hostnames ») | | «  »). toLowerCase (). split (« , »)} function isSkimLink (t) {return !! (skimlinksId = t.getAttribute (« data-skimlinks »))} function isExcluded (t) {return _includes (excludedHostnames , t) || _startsWith (t, « www. ») &&_includes (excludedHostnames, t.slice (4)) || isSponsored} function isUrlProtocol (t) {return 0! == t.indexOf (« mailto: ») &&0 ! == t.indexOf (« javascript: »)} function getTargetHostname (t) {return (t.ho stname || t.host || t.href || «  »). toLowerCase ()} function convertSkimlinkUrl (t) {return (skimlinksBaseUrl = skimlinksBaseUrl || skimlinksId? « // go.redirectingat.com/?xs=1&id= » skimlinksId « &sref = » encodeURIComponent (window.location.href) « CSSimEANDCHARurlSSE )} function hasIgnoreAttribute (t) {return  » true « === t (t) {var e, i, r, s = dom.closest (t.target, » a « ), n = s&&s.href; n&&n.length&&! t.defaultPreventedHargetCSSEAND! t.defaultPreventedCSSEAND (i s), (isUrlProtocol n) || isExcluded (i) || hasIgnoreAttribute (s) || productSubtags.getAffiliate (n) || (e = convertSkimlinkUrl (n)) && (productUrl = n, r = s&s. « getAffiliate » data-track-id « ), s.href = productSubtags.ensureSubtag ({url: e, productId: r, visitState: visitState, anchorEl: s})))} function revertSkimLink (t) {var e = dom.closest ( t.target, « a »), i = e&C SSEANDCHARe.href || «  »; i.includes (skimlinksBaseUrl) &&i&&i.length&&productUrl&i.length&&productUrlCSSEAND => product isitm. {visitState = t}), e&& (setExcludedHostnames (t), globalClick.addHandler (convertSkimlink, revertSkimLink))});
}, {« 4 »: 4, « 68 »: 68, « 70 »: 70, « 71 »: 71, « 72 »: 72, « 73 »: 73}];
window.modules [« gtm.client »] = [function (require, module, exports) {« use strict »; const $ gtm = require (3); DS.controller (« gtm », [function () {return function (t) {$ gtm.init (t.getAttribute (« data-container-id »), t.getAttribute (« data-site-slug »))}}]);
}, {« 3 »: 3}];
window.modules [« global-nav.client »] = [function (require, module, exports) {« use strict »; const dom = require (4), auth0 = require (8), signInButton = dom.find ( » .user-signin « ), signOutButton = dom.find (« . user-signout « ), globalNav = dom.find (‘[class ^ = » global-nav « ]’), body = dom.find ( » body  » ), dropdownItems = dom.findAll (« . dropdown-wrap »), gtm = require (3), pageUri = require (159) .getPageUri (); function closeDropdowns (e) {let n = globalNav.querySelectorAll (« . dropdown .open « ); dropdownItems.forEach (function (t) {let o = t.querySelector (« . dropdown « ) ;! n || t.contains (e.target) &&27! == e.keyCode || o. classList.remove (« open »)})} function gtmSendReport (e, n, t) {let o = {eventCategory: « ecommerce », eventAction: « componentClick », brand: e, dimension23: « global-nav », list : pageUri, pageZone: « header », variant: « nav-link »}; « global-nav-link » === t&& (o.eventLabel = n.href), gtm.reportNow (o)} function init (e ) {auth0.on (« init », () => {signInButton.addEventListener (« click », function (e) {e.preventDefault (), auth0.showLogin ()}), signOutButt on.add EventListener (« click », function (e) {e.preventDefault (), auth0.logout (), gtmSendReport (« Sign Out », e.target, « user-info-link »)}), auth0. isAuthenticated () &&e.classList.add (« signed-in »), auth0.isSubscriber () &&e.classList.add (« subscribed »), e.querySelectorAll (« . user-link »). forEach (e => { e.classList .add(« active »)})}),auth0.on(« login »,()=>{e.classList.add(« signed-in »),auth0.isSubscriber()&&e.classList. add( » subscribed »)}),auth0.on(« logout »,()=>{e.classList.remove(« signed-in »),e.classList.remove(« subscribed »)})}dropdownItems. forEach(function (e){e.addEventListener(« click »,function(){e.querySelector(« .dropdown »).classList.toggle(« open »)})}),body.addEventListener(« click », closeDropdowns), document.addEventListener(« keydown »,closeDropdowns),globalNav.addEventListener(« click »,function(e){let n=e.target;n.classList.contains(« global-nav-track »)&&gtmSendReport( n.text ,n, »global-nav-link »)}),module.exports=init;
}, {« 3″:3, »4″:4, »8″:8, »159 »:159}];
window.modules[« aaa-module-mounting.legacy »] = [function(require,module,exports){« use strict »;const eventify=require(187),_pickBy=require(162),_each=require(322),fingerprintjs2=require(321),DS=require(320);function registerGlobals(){window.DS=DS,window.Eventify=eventify,window.Fingerprint2=fingerprintjs2,DS.value(« Eventify »,eventify),DS.value(« Fingerprint2 »,fingerprintjs2),DS.value(« $document »,window.document),DS.value(« $window »,window)}function mountDollarSliceComponents(){DS.service(« components »,[« $document », »$module »,function(e,n){var r=_pickBy(n.definitions,e=>e.providerStrategy===n.providers.controller),o=Object.keys(r);function t(e){return r=>{try{n.get(e,r)}catch(e){logMountError(r,e)}}}_each(o,n=>{var r=e.querySelectorAll(‘[data-uri*= »/_components/’ n ‘/ »]’),o=e.querySelectorAll(‘[data-uri$= »/_components/’ n ‘ »]’);_each(r,t(n)),_each(o,t(n))}),this.components=o}]),DS.get(« components »)}function logMountError(e,n){const r=e.outerHTML.slice(0,e.outerHTML.indexOf(e.innerHTML));console.error(« Error attaching controller to  » r,n)}registerGlobals(),document.addEventListener(« DOMContentLoaded »,()=>{mountDollarSliceComponents()});
}, {« 162″:162, »187″:187, »320″:320, »321″:321, »322 »:322}];
window.modules[« ads.legacy »] = [function(require,module,exports){« use strict »;const _map=require(74),_forEach=require(64),_isString=require(206),_intersectionWith=require(323),_isEqual=require(212),_each=require(322),_debounce=require(122),_sortBy=require(145),page=require(159),visit=require(70);DS.service(« adService »,[« Eventify », »$cid », »$document », »$window »,function(e,t,a,i){var o,n,s,r,d,c,l,u,g,p,m={},h=this,f=[],b=visit.getQueryParamsObject([« utm_campaign »]),w=document.querySelector(‘script[data-type= »ad-a9″]’);document.querySelector(‘script[data-name= »concert-ads »]’)||(i.NYM={},i.NYM.analytics={},i.NYM.analytics.adStartTime=i.performance.now(),i.googletag=i.googletag||{},i.googletag.cmd=i.googletag.cmd||[],c=i.googletag,w&&(i.googletag.cmd=i.googletag.cmd||[],i.googletag.cmd.push(function(){i.googletag.pubads().disableInitialLoad()}),l=i.setInterval(function(){void 0!==window.apstag&&void 0!==window.apstag.timeout&&(i.clearInterval(l),window.apstag.cleared=!0,l=null)},10),setTimeout(function(){l&&(i.clearInterval(l),i.googletag.pubads().refresh(),window.apstag||console.log(« MESSAGE: Timeout for A9 load exceeded, aborting »))},500)),u=document.createElement(« script »),g=document.createDocumentFragment(),p=document.getElementsByTagName(« head »)[0],u.src= »https://z.moatads.com/voxprebidheader841653991752/moatheader.js »,g.appendChild(u),p.insertBefore(g,p.firstChild),o=function(e){var t,a,o=e.data,n=[];return o.loaded?e:(o.loaded=!0,t=null,(t=o.sizes?c.defineSlot(o.name,o.sizes,o.id).addService(c.pubads()):c.defineOutOfPageSlot(o.name,o.id).addService(c.pubads())).setTargeting(« adid »,o.id),b.hasOwnProperty(« utm_campaign »)&&t.setTargeting(« utmcamp »,b.utm_campaign),a=h.getAdCount(o.label),t.setTargeting(« label »,o.label « _ » o.site « – » a),c.display(o.id),c.pubads().addEventListener(« slotOnload »,function(){i.NYM.analytics.firstAdLoadTime||(i.NYM.analytics.firstAdLoadTime=i.performance.now(),i.NYM.analytics.firstAdLoadLabel=e.data.label)}),(n=v(o))?window.apstag&&window.apstag.cleared&&window.apstag.fetchBids({slots:[n],timeout:window.apstag.timeout},function(){c.cmd.push(function(){window.apstag.setDisplayBids(),c.pubads().refresh([t],{changeCorrelator:!1})})}):c.pubads().refresh([t],{changeCorrelator:!1}),e.slot=t,e)},n=function(e){var a,i,o,n=t(),s=e.getAttribute(« data-name »),r=e.getAttribute(« data-sizes »),d=e.getAttribute(« data-label »),c=e.getAttribute(« data-site »);n=e.id,r&&r.length?(r=r.split(« , »),a=[],_map(r,function(e){e=e.split(« x »),i=parseInt(e[0]),o=parseInt(e[1]),a.push([i,o])})):(e.classList.add(« oop »),a=!1),this.data={id:n,name:s,sizes:a,loaded:!1,label:d,site:c},m[n]=this},r=function(e){c.cmd.push(function(){var t=o(e);m[e.data.id]=t})},s=function(e){var t=[];e.slot?(t=v(e))&&window.apstag&&window.apstag.cleared&&window.apstag.fetchBids({slots:[t],timeout:window.apstag.timeout},function(){c.cmd.push(function(){window.apstag.setDisplayBids(),c.pubads().refresh([e.slot],{changeCorrelator:!1})})}):e&&r(e)},c.cmd.push(function(){var e,t,o,n=page.getMeta(« article:tag »),s=page.getMeta(« author »),r=i.location.href,d=(e=a.head.querySelector(« .head-gtm »),t=a.body.querySelector(« .gtm »),e&& »top »===e.getAttribute(« data-gtm »)? »gtmtop »:t&& »bottom »===t.getAttribute(« data-gtm »)? »gtmbottom »: » »);o=[],_forEach([n,s,d],function(e){_forEach(e.split(« , »),function(e){(e=e.trim().toLowerCase().replace(/s/g, »-« ).replace(/’|’/g, » »)).length&&o.push(e)})}),c.pubads().setTargeting(« kw »,o),c.pubads().setTargeting(« entry_group »,o),r=r.slice(r.lastIndexOf(« / ») 1),c.pubads().setTargeting(« pn »,r),c.companionAds().setRefreshUnfilledSlots(!0),c.pubads().enableAsyncRendering(),c.enableServices()}),this.load=r,this.create=function(e){return new n(e)},this.refresh=function(e){var t;_isString(e)?(t=this.getById(e),s(t)):s(e)},this.remove=function(e){var t=e.data.id;a.getElementById(t).innerHTML= » »},this.getAdCount=function(e){var t,a=0,i=Object.keys(m);return _each(i,function(i){(t=m[i]).data.loaded&&t.data.label===e&&a }),a},this.getById=function(e){return m[e]},d=_debounce(function(){var e={TopLeaderboard:1,RightColTopMPU:2,outOfPage:99, »homepageTakeover/TopLeaderboard »:1},t=_sortBy(f,function(t){return e[t.data.label]||10});_forEach(t,function(e){return e.data.sizes?r(e):i.setTimeout(function(){r(e)},2e3)}),f=[]},10),this.addToPageLoadQueue=function(e){f.push(e),d()});function v(e){var t,a=e.sizes;return a=_intersectionWith(a,[[970,250],[970,90],[728,90],[300,600],[300,250],[320,100],[320,50]],_isEqual),e.sizes&&e.sizes.length&&(t={slotID:e.id,sizes:a,slotName:e.label}),t}}]);
}, {« 64″:64, »70″:70, »74″:74, »122″:122, »145″:145, »159″:159, »206″:206, »212″:212, »322″:322, »323 »:323}];
window.modules[« cid.legacy »] = [function(require,module,exports){« use strict »;DS.service(« $cid »,function(){var r=Math.floor(100*Math.random());return function(){return »cid- » r}});
}, {}];
window.modules[« facebook.legacy »] = [function(require,module,exports){« use strict »;DS.service(« facebook »,[function(){this.fb=function(i){window.FB&&window.FB[i].apply(this,Array.prototype.slice.call(arguments,1))}}]);
}, {}];
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require== »function »&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(« Cannot find module ‘ » o « ‘ »);throw f.code= »MODULE_NOT_FOUND »,f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require== »function »&&require;for(var o=0;o typeof key === ‘string’ && key.match(/.legacy$/)).forEach(key => window.require(key));
}

function tryToMount (fn, el, name) {
To attempt {
fn (el); // init the controller
} catch (e) {
const elementTag = el.outerHTML.slice (0, el.outerHTML.indexOf (el.innerHTML));
console.error (`Error initializing controller for » $ {name} « on » $ {elementTag} « `, e);
}
}
/ **
* mount client.js component controllers
* /

function mountComponentModules () {
Object.keys (window.modules) .filter (key => typeof key === ‘string’ && key.match (/ . Client $ /)). ForEach (key => {
let controllerFn = window.require (key);

if (typeof controllerFn === ‘function’) {
const name = key.replace (‘. client’,  »),
instancesSelector = `[data-uri * = » _ components / $ {name} / « ]`,
defaultSelector = `[data-uri $ = » _ components $ {name} « ]`,
instances = document.querySelectorAll (instancesSelector),
defaults = document.querySelectorAll (defaultSelector);

for (let el of instances) {
tryToMount (controllerFn, el, name);
}

for (let el of defaults) {
tryToMount (controllerFn, el, name);
}
}
});
} // Make sure that a `window.process.env.NODE_ENV` is available in the client for any dependencies,
// services, or components that could require it
// note: the «  value is swapped for the actual environment variable in /lib/cmd/compile/scripts.js

window.process = window.process || {};
window.process.env = window.process.env || {};

if (! window.process.env.NODE_ENV) {
window.process.env.NODE_ENV =  »;
} // note: legacy controllers that require legacy services (e.g. dollar-slice) must
// wait for DOMContentLoaded to initialize themselves, as the files themselves must be mounted first

mountLegacyServices ();
mountComponentModules ();
//]]

Keywords:

Yale Law School,Amy Chua,Jed Rubenfeld,Yale University,Yale Law School, Amy Chua, Jed Rubenfeld, Yale University,,Colleges and Universities,Chua, Amy,New Haven (Conn),Yale Daily News,Yale University,Law Schools,Gerken, Heather K,Rubenfeld, Jed,Battle Hymn of the Tiger Mother (Book),,,politics, amy chua, jed rubenfeld, yale law, scotus, brett kavanaugh, power, new york magazine,

Donnez votre avis et abonnez-vous pour plus d’infos

[gs-fb-comments]

[comment]

[supsystic-newsletter-form id=4]

Vidéo du jour: