text:
On the Big Two-Hearted River
The Cadence of Grass
by Thomas McGuane
Knopf, 238 pp., $24.00
Thomas McGuane; drawing by David Levine
Here's the protean Jim Harrison—poet, novelist, essayist, screenwriter, hunter, fisherman, farmer, food-panegyrist, and gourmand—musing about Ernest Hemingway in one of the essays in his collection Just Before Dark:
…The most intelligent among us tend to be fans of some sort but we don't really want our writers to act like sports stars or screen heroes, don't want the sacred line between poet and hero to be confused.
Apropos of which, consider what the actress Elizabeth Ashley had to say when she first met Jim Harrison's good friend Tom McGuane, which happened on the set of the movie Rancho Deluxe, near Livingston, Montana, around 1975:
He was smart and funny. He could give you the back story on something in just four words. He could tell you some of the best outlaw stories ever, and in the next paragraph discuss Turgenev.
That's just my style.
He was a writer.
I've always had a weakness for writers.
He was a psychedelic cowboy.
That's right up my alley.
He was a gonzo raver.
I like them the best.
The hearty love affair which soon ensued between the lovely actress and the gonzo raver was, in Ms. Ashley's words, "the love affair I had been wanting even before I knew what a love affair was."
In the mid-Seventies, in Montana and elsewhere, Tom McGuane was so full of beans that he may not have noticed that he was dancing over the line that his friend and fishing buddy Jim Harrison would later define. Overnight, it seemed, Hollywood called and Mc-Guane answered, writing three movies that were produced in little more than a year: the appealing Rancho Deluxe (1975); the less appealing Ninety-Two in the Shade, same year (this one, his Key West story, he also directed); and The Missouri Breaks (1976). For a year or two Hollywood was rife with Tom stories, as they were called, but the films set no box offices on fire and McGuane went, in the blink of an eye, from being a quick study to being an expensive luxury, even though the last film I can remember seeing his name on, Tom Horn (1980), was the best of the lot—at least it was free of the silliness that diminishes both Rancho Deluxe and The Missouri Breaks. It was as if McGuane had ridden the up-escalator of Hollywood fame, swung his leg over, as he might when mounting a horse, and gone right back down on the down-escalator.
Fortunately, he still had Montana. In western and central Montana throughout the Seventies and Eighties the flames of talent danced high, not all of them fed by Tom McGuane. A good many interesting writers were strung out in irregular formation along the Missoula–Bozeman–Livingston axis. At the University of Montana in Missoula, the poet Richard Hugo still held sway, assisted by a covey of writers that included, at various times, the novelists James Crumley, Max Crawford, William Hjorstberg, James Welch, and others, among them the elegant essayist William Kittredge. Richard Ford was in and out of the state, writing, hunting, fishing, as was Professor Norman Mclean of the University of Chicago, author of that moving late work of fiction A River Runs Through It. Jim Harrison, too, was in and out, hauling his bird dogs around in eternal hope of feathered victims, and the painter Russell Chatham was hard at work on his somber landscapes. The old terror and one-man wild bunch Sam Peckinpah had a ranch near Livingston—it's now owned, I believe, by the actor Dennis Quaid. Peter Fonda came, and various actresses; even Jack Nicholson—in my view an unlikely countryman—was said to have put in an appearance, perhaps visiting Russell Chatham, who opened and still operates a restaurant in Livingston.
Chatham's Dark Waters, an elegant collection of (mostly) fishing reminiscences, and Jim Harrison's The Raw and the Cooked, which Ms. Ashley, should she read it, might call a gonzo food rant, both contain echoes of that time. Both books are excellent reads, though it's annoying that these two men, tolerant and occasionally even reckless in day-to-day life, become as austere as Trappists when it comes to cooking duck, a discipline not to be taken lightly in Livingston or its environs, it would seem.
Montanans, blessed as they are with an abundance of fine bars, are rarely disinclined to get rowdy; quite a few probably get a good deal rowdier than Tom McGuane, and yet in the late Seventies Tom stories continued to roll like thunderheads across the northern plains, most of them having to do with bacchanals of some sort, or great love-battles, with their attendant rancors. For details Ms. Ashley remains the most vivid source.
During some of this time I was in Montana myself, over in the unfashionable eastern part, working on a virtuous movie about the evils of strip mining. This involved hanging out in places like Lame Deer and Colstrip; the stories that drifted over from Livingston soon convinced me that there were two Montanas, and I was definitely in the wrong one. I remember trying to make conversation with a young strip miner who lived in a trailer near the big pit outside Gillette, Wyoming; he insisted on keeping both his expensive hunting rifles on his lap as we talked. When I asked him if he had a girlfriend he said, "I got one but she's just puke with lipstick," a resonant utterance delivered about the time Tom McGuane and Elizabeth Ashley began to chat about Turgenev.
From the perspective of Colstrip or Gillette, Livingston sounded practically Periclean. I thought of going there but a well-placed informant discouraged me, mainly on account of the duck. After all, I didn't even own a duck press, and had shown little aptitude even for shooting ducks, much less pressing them. It was thought that nobody would know what to say to me. Chastened, I drifted back to Texas, and the simplicity of the pinto bean.
I'm funning, of course. Livingston's not quite that haute. But the question we might ask is what effect, if any, Tom McGuane's high-plains-and-Florida-Keys flamboyance had on his writing. Flamboyance is certainly the last thing most writers need ever give a thought to. Flamboyant is what they're not. Byron, Oscar Wilde, Hemingway might have suffered occasionally from an excess of life style, but very few writers ever work up to anything that could fairly be called a life style.
Tom McGuane had one. He was flamboyant, and probably did dance over Jim Harrison's line, and it probably did adversely affect his work, as he himself, in rueful asides, here and there, has been the first to suggest. Here's one such remark, from his essay collection An Outside Chance—McGuane is on his way to British Columbia, to visit the much-admired fishing writer Roderick Haig-Brown:
Sportsman, magistrate, English prose stylist of weight, Haig-Brown seems artfully contrived to make me feel in need of a hair-cut and refurbished credentials. I wanted to withdraw my novels from publication and extirpate all the bad words, reduce the number of compliant ladies by as much as 96 percent.
That last proposition, the one about compliant ladies, takes some thinking about. Tom McGuane may indeed have had a compliant lady or ladies in his life, but you sure don't find them in his fiction, of which there are now ten volumes: nine novels and a book of short stories. One is set in Michigan, two and a fraction in Key West, and the rest mainly in Montana. When there's sex in these books it's mainly a function of hunger, not affection. His ladies are miserable, bitter, disappointed, sharp-tongued, furious, and, in some cases, murderous, fed up to the gills with the treacheries and insufficiencies of men. Tom McGuane, who loves horses and who likes to fish, has produced possibly the bleakest, most corrosive view of the relations between the sexes in our recent literature. If I had to pick one comment from hundreds to illustrate what McGuane's women feel about his men I don't think I could come up with anything more succinct than Mrs. Jarrell's remark in Nothing but Blue Skies—Mrs. Jarrell is the wife of a hired man who has just been fired:
"Eat shit," said Mrs. Jarrell. "I hope you have a stroke."
In only ten pages of McGuane's new novel The Cadence of Grass, perhaps the most eloquent of his now numerous fictions about desperation and near desperation in the West, the following signs of marital hostility appear:
Natalie was less proud of the fact that she was so unwilling to join Stuart at the things he loved. It was just that she found him so very, very tiresome.
Her musing tone successfully concealed her loathing….
She caught the shortness of his reply and fell silent, looking gloomily out upon the natural world. What use was it?
Evelyn wondered how she had befouled herself with so unsuitable a marriage….
The solution to these disharmonies, the result, as McGuane puts it, of "otherwise admirable but nonmeshing complexities of character," is usually the departure of the woman. Wives who can't be bothered to depart—Emily in Something to Be Desired and Marianne in the long story "To Skin a Cat"—clear the decks by murdering their husbands. If we start with The Bushwhacked Piano (McGuane's second novel) at the point where Ann leaves Payne, and proceed to Panama, where Catherine finally leaves Chet, narratives of wifely departure come thick and come fast. Claire and Patrick separate at the end of Nobody's Angel, though not before Claire's husband, Tio, has asphyxiated himself in his helicopter. In Something to Be Desired Suzanne leaves Lucien and Emily shoots her husband; then Astrid leaves Joe in Keep the Change, Marianne stabs Bobby in "To Skin a Cat," Gracie leaves Frank in Nothing but Blue Skies, Natalie divorces Stuart in The Cadence of Grass, and her sister Evelyn, same book, lives in fear of Paul, until, fortunately for her, he's dispatched by some drug dealers.
Opinions of course may differ, but it seems to me that these departing women usually have right on their side. With the exception of a couple of guys from the early books (Payne and Chet particularly) none of McGuane's men is particularly nice; they deserve to be abandoned, divorced, or murdered. The accumulation of gloom and malice in these novels will send some readers, as it sent me, racing for the Tolstoy diaries. The Tolstoys may have fought tooth and nail for forty-eight years, but at least they had some fun, whereas fun in Tom McGuane—or perhaps it would be better to call it peace—happens in a fishing camp, along a trout stream, on a boat in the Keys, on a hunt, on a horseback ride. It's not to be found in the master bedroom. In a way McGuane's late fiction is as domestic as Jane Austen's—hers is about the difficulty of getting married, his about the impossibility of either staying married or getting cleanly separated.
In 1982 Tom McGuane set his fifth novel, Nobody's Angel, in the invented town of Deadrock, Montana; four other novels—Something to Be Desired, Keep the Change, Nothing but Blue Skies, and now The Cadence of Grass—are set there. Read collectively, the five books present an impressive if depressing portrait of a community that's neither fully urbanized nor purely rural. Most of the characters still have a stake in a family ranch somewhere, yet many of them live in town, they know who Cézanne was, they travel. Montana remains closer to the frontier experience than any state except Alaska; the urge to reach for the Winchester when there's serious conflict still comes naturally to some. The grim marital feuding of the five Deadrock novels is not at all unconvincing; it's just that there's only so much of that kind of conviction that the normal reader can handle. McGuane's three nonfiction books, An Outside Chance, his fishing book, The Long Silence, and his horse book, Some Horses, are, by comparison, repositories of calm:
There's a yearling buck dead by the first spring, nearly devoured by coyotes who have seized intestines and backed several yards from the carcass. This is merely a boon to the coyotes, who have come by this meal as honestly as did the Pennsylvania wolves who devoured the bodies of Braddock's soldiers after the battle of Monongahela. The face of creation takes in everything with a level stare. When I was younger these manifestations of life's fury were comfortably free of premonition. Now they bear a gravity that dignifies the one-day lives of insects, the terrible slaughterhouse journey of livestock, and, of course, ourselves and our double handful of borrowed minerals. The old man I see staring from his porch rocker when I go to town is staring into a tremendous distance. As surely as homeowners pride themselves on property that fronts the beach, the lake, or the golf course, we all enjoy abyss frontage; and some, like the fellow in his rocker, seem absorbed by the view.
Tom McGuane and Jim Harrison both hail from Michigan. Both are sportsmen. They bird hunt, they fly-fish, and McGuane at least goes regularly to the Florida Keys for more and different fishing. To judge from their writing, McGuane and Harrison enjoy these activities as much, and as legitimately, as Ernest Hemingway did, but Hemingway was enjoying them before either of the younger men was born. When they were born it was beneath the sign of the Big Two-Hearted River, whose author produced some of the best English prose of the twentieth century. This creates an especially acute difficulty for writers who come from Hemingway country and do so many of the things he did. They work, like it or not, in an echo chamber; evading that great, never-silenced shade cannot be easy. One way to read McGuane's second novel, The Bushwhacked Piano, is as a desperate end run around Hemingway, in the course of which the author wanders as far afield as proctology. The detailed hemorrhoid operation near the end of the book probably does edge into territory Hemingway would not have cared to compete for; but the novel also contains a bull fight and a visit to Key West, both mainline Hemingway sites.
Probably it's good that Tom McGuane is now so passionate about horses and Jim Harrison about food, subjects less likely to produce unwelcome echoes. At the end of "Brokeback Mountain," Annie Proulx's great Wyoming story, the bereaved cowboy Ennis del Mar, having lost the love of his life, has this reflection:
There was some open space between what he knew and what he tried to believe, but nothing could be done about it, and if you can't fix it you've got to stand it.
So it is with the ever-larger looming fact of Ernest Hemingway, not merely in the careers of Tom McGuane and Jim Harrison but in the careers of many other writers, or of several generations and different nationalities. Evelyn Waugh himself acknowledged it, in his Paris Review interview, and Anthony Powell, in his Journals, seconds the opinion: the man's just there, like a mountain, or as a grief. You can't fix it so you've got to stand it.
More by Larry McMurtry
What Woody Wrote
On the rediscovered 'House of Earth'
The Star Attraction
A Great Day for Books
Larry McMurtry's novels include The Last Picture Show, Terms of Endearment, Lonesome Dove (winner of the 1986 Pulitzer Prize for Fiction), Folly and Gloryand Rhino Ranch. His nonfiction works include a biography of Crazy Horse, Walter Benjamin at the Dairy Queen, Paradise, Sacagawea's Nickname: Essays on the American West and Custer.
Irving Howe
V. S. Pritchett, 1900–1997
'Animal Farm': What Orwell Really Meant
Midge Decter


Evan Hanczor, head chef at Brooklyn neighborhood favorite Egg, shares his dead-simple sweet corn soup recipe, along with additional #nowaste ideas for how to use up a sweet corn surplus.
Sweet corn season is finally in full swing, and we couldn't be happier to be munching our way through pyramids of barely boiled ears, annointed with just a gloss of butter and a flurry of salt. But spurred on by fears of long winter months devoid of fresh corn, you might just find yourself overdoing it a bit at the farmers' market, coming home flush with more ears than you could possibly eat. It's a blessed dilemma with which Evan Hanczor, head chef at Brooklyn neighborhood favorite Egg, is familiar. Hanczor's go-to trick is to turn his extra ears into a dead simple and healthy corn soup that uses corn cob stock as a base. Here, Hanczor shares that recipe, along with additional #nowaste ideas for how to use up a sweet corn surplus.
I think most people have fewer problems using up the kernels of corn—it's mainly the cobs and husks that get left behind. The best use for husks is to make tamales with them or, in a similar way, use them to wrap fish or vegetables and then grill the packages for a smoky flavor but a gentle, almost steamed style of cooking.
We've tested making tisanes out of the husks and the flavor is good, very mild but a little sweet and corn-y. You can make it even sweeter with honey.
Our best uses of the corn cobs start with corn stock (see recipe below), which can be used as a base for any kind of soup. If you concentrate the stock by boiling it down further than you would for soup, you can add sugar to make the base of a corn sorbet or granita. For a twist, we often smoke the cobs before boiling them for stock. We smoke them over woodchips on the stovetop, but you could easily char them on a grill for a similar effect. I highly recommend using that smoky corn liquid as the base for a simple syrup, which is a great addition to a bourbon-based cocktail. The charred corn flavor echoes the bourbon's foundational flavors really beautifully.
Corn stock, whether made with fresh or roasted cobs, is great for cooking polenta and grits. It really intensifies that dried corn flavor with a fresher, sweeter note.
If one does find him or herself with so great a glut of corn that it can't possibly be consumed in various on-the-cob, salad, or soup-y preparations, both vinegar pickled and lacto-fermented corn products are delicious and cool to play with. There are plenty of recipes out there for these techniques, but I'd recommend, as I usually do in this department, looking to Sandor Katz for fermenting advice (The Art of Fermentation is the bible on the subject).
Shuck the corn. Trim a sliver off the base of each shucked cob so you have a flat surface to stand the corn upon. Stand the corn on a cutting board (or on a towel set into a large mixing bowl if you're worried about kernels going everywhere) and slicing vertically downward from the tapered tip of the corn to the base, remove the kernels on all sides. Reserve the kernels for the soup.
In a medium stock pot, combine the cobs, shallot and water. Bring to a boil and reduce to a simmer. Simmer for 20 minutes until the stock smells richly sweet with corn aroma. Strain out the cobs and shallot and reserve the broth.
Combine the kernels and the corn stock in a medium pot and bring to a simmer. Cook for 20 to 30 minutes, until the kernels are tender. Remove the pot from the heat and process the soup in batches in a blender, pureeing until the mixture is completely smooth. When all the soup is pureed, stick a sprig of thyme in it and allow the flavor to infuse for 5 minutes. Remove the thyme. Add the vinegar and season to taste with salt, remembering to overseason a bit since the soup, when cold, will need more salt to maintain a pronounced, balanced flavor. If the soup is too thick, thin with a little extra corn stock.
The soup can take many directions. Garnish with sour cherries and basil for a very light take, or with a salty cheese and black pepper for more of a kick. Smoked paprika, spanish chorizo, cilantro and jalapeño—try out a number of additions! The soup can, of course, also be served hot, folded into grits or polenta for added flavor, or used as the base of a pasta sauce if you want to get creative with it.


Browse by Last Name · A B C D E. She is especially interested in health system issues and research related to health financing, poverty. Bowser, Diana, Laura Krech, David Mabirizi, Angela Y. Chang and Thomas Bossert. Working Paper A Costing Analysis of Two Community Health Worker Programs in Mozambique.


Esteem Entertainment has a number of professional dancers available for any type of occasion!
Professional dancers will liven up any party with a stunning show that will add an extra element of entertainment to your event! Our most popular dancers are Country Line Instructors, Hawaiian Dancers, Italian Dancers, Persian Belly Dancers, and pop and hip hop dancers for teen parties!


We're a business who know the need to return on the road as soon as possible with minimum of fuss in the event of a breakdown. We are a frequent sight in the Templeogue area and locals are used to seeing our breakdown assistance travelling from and to, in and around Templeogue. Our reputation for fast answers when there is a car in need of attention is the thing that keeps people coming back time and time again.
About being a local business, the great thing is being able to call upon residents and previous clients for reliable recommendations. We place a high value on getting the work done correctly the first time. Whether you are just passing through or a newcomer to the area, you may make sure our first class support is equally like our reputation indicates.
Our team also specialise in breakdown assistance. Being involved in an accident on the road is a less than pleasant experience. Our response team will be on hand to assist you when you need it as soon as we have police clearance we'll deal with the elimination of your automobile so that it may be analyzed and repaired as appropriate.
As with breakdown assistance companies we strive to restore van or your car then and , getting you back to your way and in the street. Should the vehicle want the interest of a garage we will ensure that your automobile is fast and efficiently packed onto the transporter (even though occasionally towing is a choice ) so you might get your car fixed and yourself home.
With no car a lot of people would find themselves seriously inconvenienced. Public transportation is unreliable and people enjoy the idea of hanging round a train station late at night. Being on independent and the road is far more convenient, until something goes wrong. You're in the Templeogue region and In case the worst should happen you needn't worry as help is at hand.
One of the reasons our company has decided to concentrate mainly on the Templeogue region is that we would like to be able to minimise the time you are left also because it's our regional area and stood around. We believe in good old fashioned customer service and treating our clients how they need to be treated. When you end up in need of breakdown assistance you are at a disadvantage and might even feel vulnerable. Towing 247 friendly professional approach will set you at ease and not having to wait for hours on end for somebody to come out to you will produce the incident not as traumatic.
When it comes to limiting the nuisance that accompanies being involved at a breakdown in or around we are the specialists. Get in touch with us when you want us so that you know that in the event you want us, our number is still close at hand, and save our details in your car or truck.


text:
Het eerste triumviraat was een politiek bondgenootschap, in 59 v. Chr. gesloten door Gaius Julius Caesar, Gnaeus Pompeius Magnus en Marcus Licinius Crassus, ondanks het onderlinge wantrouwen. Wat hen verenigde was de wens om de invloed van de senaat aan banden te leggen. Niets in de Romeinse politiek zou dan zonder hun instemming gebeuren.

Het eerste driemanschap was ontstaan in eind jaren 60 voor Christus. Het was niet een officiële bekrachtiging, maar meer een privé-afspraak. De drie mannen maakten verschillende afspraken. Zo zou Caesar consul worden tijdens de verkiezingen van 59 v. Chr.. Hij moest in die functie ervoor zorgen dat de oorlogsveteranen van Pompeius een stukje land kregen. Verder zou Caesar na zijn consulschap voor vijf jaar gouverneur worden van Gallia Cisalpina (Noord-Italië), Gallia Transalpina (Deel van Gallië dat aan de overzijde van de alpen lag) en een deel van Illyria (voormalig Joegoslavië). Hierdoor zou hij zijn vurigste wens kunnen vervullen: zijn eigen legers stichten, nieuwe gebieden inlijven en eeuwige roem behalen. Al gauw zou blijken dat Caesar het grootste voordeel uit dit Driemanschap wist te halen.

De afspraken stopten toen Crassus sneuvelde in de strijd tegen de Parthen in 53 v. Chr.. Dat was in het nadeel voor Pompeius. En de strijd was acuut toen Pompeius "consul zonder collega" werd en daarmee feitelijk alleen de macht had gekregen. Caesar kreeg op 7 januari 49 v.Chr. de opdracht zijn commando neer te leggen. Pompeius werd tegelijkertijd bevolen de Republiek te verdedigen. Caesar trok de Rubicon, de grens tussen zijn mandaatgebied en Italië, over met de woorden "alea iacta est" (de teerling is geworpen) en gaf daarmee openlijk te kennen op een staatsgreep uit te zijn. Pompeius had geen tijd een behoorlijk leger op de been te brengen en kon alleen nog maar naar het Oosten vluchten. De burgeroorlog was nu echt. Om de macht van Pompeius te breken, trok Caesar allereerst naar Spanje. Vervolgens zette hij de achtervolging van Pompeius in. Eerst werd hij door het goed georganiseerde leger van Pompeius verslagen. Maar later werd Pompeius verslagen en in Egypte vermoord, waar Ptolemaeus XIII Theos Philopator aan de macht was. Hij liet Pompeius vermoorden en bood Caesar het hoofd van Pompeius aan om bij hem in de gunst te vallen.

Zie ook
 Tweede triumviraat

Triumviraat 1
Triumviraat 1

redpajama_set_name: RedPajamaWikipedia


Mummy Duck: Goodbye to the last one.
Our little Miss had her "interview" for preschool today, she's due to start next year. I am sad.
It feels like I'm letting go of all my children, all at once, with her, the last, taking that first step away. Right now I know everything she does, everywhere she goes, who she talks to, who she yells at and who she cuddles.
I have full faith in the preschool she's going to, they're about as caring as I think one could get in that environment. I have no qualms that her preschool teachers aim to raise their class just as we try to as parents at home – with the right amount of strictness, inspiration and, most importantly, caring.
And boy, at the moment, I could probably do with the space because are our kids driving me c-razy! The noise… urgh….and she's the noisiest of them all! But I usually relish the chaos kid's cause. So I still don't want her to go.
I'm frightened of the silent space which will greet me when I come home alone. Getting in the car alone. Doing the food shopping with no one in the trolley seat to giggle with…. even though I might actually get some of the things that are on my list this way.
I'm not so good with 'me time', I like to be busy, and a 2 year old certainly fills that need. I will work, but it's 'from home' work, which will be in that empty silent space, by my empty silent self.
I know it's not ground breaking stuff, every mother's gone through it, and their life has gone on – nay, they say they even enjoy it! So I will think of all you mums: How you can now go and help in reading groups with your other kids at school, how you can get your hair done in longer than 10 minutes whilst shovelling food into someone trying to climb out of the trolley. I can't think of anything else, but I'm sure there are tonnes of things I'll be able to do.
After I've cried a bit.
I've shed a tear, Felic.
To ease the "pain",ask your Mum about weekly ladies tennis groups. At least you can all cry on each others shoulders then.


Find full time, part time, casual and entry level jobs at Allphones today!
With over 170 locations across Australia Allphones is the largest independent telecommunications retailer consisting of company owned, licensed and franchised stores.
Allphones started trading as a single store in Mile End, South Australia in 1989. After moderate growth in the early 90's the business moved into franchising and the operation grew in South Australia to 15 stores. In 1999 the master franchise rights were purchased for Western Australia and the first store in W.A was opened in May 2000.
Late in 2000, the rights to the franchise system were purchased. During 2001, the group moved into the eastern states opening the first store in Hurstville, NSW. Since that time the group has continually grown and is now a truly national company, operating in WA, NSW, ACT, VIC, SA, QLD, NT and TAS.
In 2004 the group diversified into Allphones Business, partnering with a range of industry leaders to provide complete communications solutions for small to medium businesses.
Spotjobs specialises in helping YOU find jobs at the companies you want to work with! If you cannot find a suitable position at Allphones, check out all the other companies waiting for your resume!


Over time, Microsoft pushed out what used to be Windows 10 Mobile exclusives, including Edge and Cortana, over to the iOS and Android platforms. While the company isn't leaving the many proud iPhone users out of the equation given its releases of Edge and Cortana for that platform, it's clear Android users will be able to make themselves feel even more at home to Microsoft's services. This is because the company can virtually bake its services into those phones by installing a simple app: Microsoft Launcher.
Originally known as Arrow Launcher, the home screen app started as a Microsoft Garage project and has since been rebranded to become the central hub for users to use Bing, Cortana, and Microsoft News. Microsoft has taken features in Windows 10, such as Cortana, Timeline, more recently Sticky Notes, and brought them to Android thanks to this one app. Below are some of likely the most useful features you get with Microsoft Launcher over the stock version that likely comes with your phone.
Timeline first came to Windows 10 in the April 2018 Update as a way for users to easily jump from one PC to the next by syncing recently viewed activities. These include web pages in Edge as well as documents in Word, PowerPoint, and Excel, which are synced between devices in a single view. However, the feature became available to those on Android devices thanks to Microsoft Launcher's 5.0 update, giving users a chronological list of activities browsed on Edge for Android as well as Office documents.
In Microsoft Launcher, activities are listed in chronological list order, with the most recent being on top. Assuming your privacy settings allow this, the activities include Edge history from both your phone as well as what where you've been to on your PC.
I find this to be very useful because often, I close tabs unintentionally, and Timeline is a very easy way to re-access the web pages I was on before. As a writer, I also find it handy that I can access a source article on my phone as well, and then quickly access the same link on my PC when I begin writing.
While certainly an interesting feature, many users are likely skeptical about it given its nature on user privacy. For this to work, Microsoft must sync all of the user's activity of those supported apps and store them in the cloud, then redistribute the data onto other devices. It's not a big issue for me as I am not big on privacy myself, but I can understand where the concerned people come from.
Cortana is the assistant that comes on Windows 10 PCs and Xbox One consoles, although it was first released for the Windows Phone 8.1 platform to compete with the likes of Siri on iPhones. Microsoft Launcher includes integration with that same assistant, which can be accessed from the microphone icon either on the search bar or the Cortana card.
The Cortana card can display quick info, which she gathers from the system, including unread text messages, upcoming reminders, tracking info. She is especially useful because of her integration with Microsoft's services, including Outlook, To-Dos, Bing, and Translator. She's very basic if you use her through the Microsoft Launcher, however, there is a dedicated app on the Google Play Store, which can additionally play music, and manage devices such as the Xbox or the Surface Headphones we recently reviewed.
Most Android phones come with a left home screen with Google search and news. Apple devices show a customizable list of widgets, and even the OnePlus 6T lets you choose between a Google Search screen or a widgets list. Microsoft takes all this a step further by putting it all on a single glance screen, complete with info cards, widgets, news, and the Timeline history.
Cards are Launcher's built-in information widgets, useful for displaying many different things, such as sticky notes, recent messages and emails, calendar, tasks, screen time, contacts, and recently opened documents and apps, just to name a few. And of course, if the cards aren't enough, you can also add any Android widget to the list, which is fully customizable in height to suit the user's preference.
I am a big fan of the vertical list of widgets. It's how information should be sorted. Windows Phone and iOS got this right, with both platforms sorting tiles and widgets (respectively) in this order. On an Android phone, someone with a lot of widgets would have to use multiple home pages to sort all of this info, and resorting can also take extra time. Putting all of it in a vertical list makes it easier to access the info on one scrollable screen and saves me a lot of time rearranging the widgets if I want to remove one or add another.
I really do enjoy using Microsoft Launcher. But there are a few issues that cause me to scratch the back of my head. For one, the expandable dock at the bottom is buggy. Rearranging icons can cause icons to mistakenly duplicate and track over each other, adding to frustration when the intention is to swap one app for another.
I would also like to see Microsoft expand the gesture settings a little bit. Right now, I'm using my phone's home button to access the app drawer, reserving the upwards swipe for accessing the expanded dock. But I think it might be slightly more intuitive if I could set a slight swipe up to expand the dock, with a longer swipe opening the app drawer. Something similar is already incorporated into the Google Pixel's new navigation introduced in Android Pie, where a slight swipe up brings up the recent apps and the dock, while moving the finger all the way up opens the app drawer.
Other than that, Microsoft has done an excellent job at bringing its ecosystem to Android devices, giving users quick access to Cortana and the company's other services with just the one app. Adding the additional apps like the Edge browser, Outlook, OneNote, To-Do and the countless others makes for a terrific Windows Phone alternative.


The stories have been plastered all over the internet–adults so fed up with children's behavior that the youth are punished with extreme consequences. You may remember the father who shot up his daughter's laptop because of her Facebook post (see video below) or the boy who got suspended when he swore at his teacher. This week's story was about a mother who took to Facebook to apologize for her teen's behavior at the movies.
The epicenter of all these stories are kids behaving badly. Kids being kids. Sure, they said bad words, acted impolitely, earned bad grades, or badmouthed their loved ones, but these acts are not new! Children have behaved badly forever. So what are we getting all worked up about? And why are we glorifying the adult's bad behavior for publicly shaming the children in their charge?
In my moments of teenage angst, my father would punish me in a passive-aggressive manner. Instead of grounding me for slamming the door when I was angry, I just came home from school to a room sans door. The note taped to the frame was simple, "When you prove you respect our home, we'll gift you a door." My dad was wicked clever! Though this example is one of a multitude of my dad's inventive consequences, my parents were nothing if not respectful. They didn't take to the internet to share their "great" parenting schemes. They didn't publicize my wrongness by touting their genius in the church bulletin or to a room full of friends at a dinner party. My mistakes and my parents' collective genius was private. If I never shared the story–you'd never know.
With the internet open 24/7, privacy has become a thing of the past. We're so concerned about our children and our student's footprint and privacy that we're forgetting about our own behavior. Dr. Devorah Heitner's article entitled, Kids Don't Understand Privacy Anymore made me wonder– do ADULTS understand privacy anymore?
You may remember the 2014 story of the middle school teacher in Oklahoma who crafted a handwritten note (left) that went viral. The unfortunate truth about Miss Bour's message is that despite the fact that she has since deleted the photo from her own Facebook page–the picture and story live on! Her message may have taught her students a valuable lesson about privacy and their reputation, but what lesson(s) did she learn?
So why I am I bothered by any of this?
As an international educator, recruiting season is usually the most taxing period in our lives and since I'll be recruiting again in the next few years, I've been seriously considering MY footprint. After reading: The 10 Reasons Why I Ignored Your Resume and Job Hunting? Take a close look at your Facebook page I became a bit flustered. Though the articles are not a bible for why someone would or would not hire me, the articles gave me some things to consider.
My Facebook footprint (or, Faceprint, if you will) does not tell the story of any particular stereotype (baby worshiper, animal lover, gym god, partier, or foodie), it does, rather, tell a tale of my adventures around the globe, fun outings with friends, new hairstyles, and the Beers of Belgium. Because of my privacy settings, a future employer will not be able to dig deeply into my true presence. Hidden betwixt the "cheers" photos, sporting events, and beach trips are the posts that define me and make me a desirable employer: the posts about an inspiring read, shares of a poignant video about disadvantaged students, articles about educational reform, or shared tweets about excursions my students have gone on.
The truth is–my faceprint, footprint, and life are out there on the web. No matter how careful I am about sharing–I exist. I can't change what others post about me or how someone may chose to shame me in a public forum. But I can monitor myself. When I put my name and face out there, I need to ensure that I am doing so in the way in which I want to be remembered: polite, principled, and passionate. Now, can the rest of the adults please remember to do the same?
If poor Hannah Jordan's dad had just been a bit more like my own father, her footprint may look a tad more like mine. If her dad would have acted differently and not destroyed her laptop by gunshots and then uploaded it to YouTube, then when I Googled her nearly 4 years after the event, there would be no ugly memory. If her dad had just been a bit more polite, principled, and maybe a little less passionate, people may actually hire her.
Like you I found myself concerned about both adult's sets of actions. But for the same reasons, using public shaming to gain compliance. In the past, the audience for punishments would be quite small. Now they are global. For all the talk of kids behaving badly, I often think that adults are no better. I wonder if the internet will mature in terms of cyberbullying as the average increases? I've noticed these days that people are more likely to use their real names where as in the bad old days a username was almost mandatory.
Good point @traintheteacher. In the past, the internet has been far more vague and ambiguous, but more people are flaunting their thoughts more publicly now. I remember listening to an NPR Podcast by Ira Glass on "This American Life." It was about cyberbullying to the extreme–trolling ("If you Don't Have Anything Nice to Say, SAY IT IN ALL CAPS") Glass shared the experience of Lindy West's speaks to her own vehement troll. He talks about why he has come out of the shadows and the reasons at the crux of WHY some people hate on the net. Very interesting.


The shape consists of a number of points which it can either calculate the convex hull of or use as a polygon directly.
A shape is essentially a 2D shape however it can be rotated arbitrarily. When a matrix and a list of points is specified in the constructor the matrix decides what direction is the 'up' direction. When checking if a point is contained in the shape, the point will be projected down on a plane where the 'up' direction is the normal and then it will check if the shape contains the point.
World space bounding box of this shape.
If true, the convex hull of the points will be calculated.
local to world space matrix for the points. The matrix determines the up direction of the shape.
If the points would be in the XZ plane only, the shape would not have a height and then it might not include any points inside it (as testing for inclusion is done in 3D space when updating graphs). This ensures that the shape has at least the minimum height (in the up direction that the matrix specifies).
Sets if the convex hull of the points should be calculated.
Convex hulls are faster but non-convex hulls can be used to specify more complicated shapes.
Gets or sets the points of the polygon in the shape.


text:
Q: Query SQL Update from select How to update this column rank with a SQL query?
char_id|char_name|point|w_point|rank|
-------|---------|-----|-------|----|
 100000|Adminn   |   17|     17|   0|
 100008|admin3   |    2|      2|   0|

with select
SELECT
    char_id,
    char_name,
    `point`,
    `w_point`,
    RANK() OVER (ORDER BY `point` DESC) as `rank`
FROM
    glro_worlddrop;

The result I want in column rank update
char_id|char_name|point|w_point|rank|
-------|---------|-----|-------|----|
 100000|Adminn   |   17|     17|   1|
 100008|admin3   |    2|      2|   2|

Thanks

A: Assuming char_id is unique, use JOIN:
UPDATE glro_worlddrop w JOIN
       (SELECT w.*,
               RANK() OVER (ORDER BY `point` DESC) as new_rank
        FROM glro_worlddrop w
       ) ww
       USING (char_id)
    SET w.rank = ww.new_rank;

redpajama_set_name: RedPajamaStackExchange


text:
Q: Slide UIView Transitions I want to switch views in a viewcontroller with a transition slide. I found the following code online.
//  get  the  view  that's  currently  showing
UIView *currentView = self.view;
//  get  the  the  underlying  UIWindow,  or  the  view  containing  the  current  view  view
UIView *theWindow = [currentView superview];

//  remove  the  current  view  and  replace  with  myView1
[currentView removeFromSuperview];
[theWindow  addSubview:PlayingView];
PlayingView.frame = CGRectMake(0, 0, 320, 460);
//  set  up  an  animation  for  the  transition  between  the  views
CATransition *animation = [CATransition animation];
[animation setDuration:1];
[animation setType:kCATransitionPush];
[animation setSubtype:kCATransitionFromLeft];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];

[[theWindow layer] addAnimation:animation forKey:@"SwitchToView1"];

This code words great but there is a VERY annoying white strip on the bottom!  I found the code:
  PlayingView.frame = CGRectMake(0, 0, 320, 460);

which doesn't seem to work.
So, the link to the place I found http://www.iphonedevsdk.com/forum/iphone-sdk-development/13427-uiview-slide-transition.html

A: It needs to be 480 high, not 460, but you should instead use PlayingView.frame = theWindow.bounds instead of manually creating the CGRect.  It'll also work in a universal app or for landscape.

A: If you're not displaying the status bar then the height of the screen is 480 (the status bar is 20 pixels).  So try changing it to CGRectMake(0, 0, 320, 480).


text:
Exploding the Myth of Russia's Internet
Once again, data has confirmed that two-thirds of the people of Russia have absolutely no access to the Internet and never access it.
Those who do manage to access the Runet, moreover, use it for nothing more than socializing, and even that they do at a rate well below the European average.
What this means is really quite simple: Those who tell you that it doesn't matter that Russians have no real TV news, because all sources of it are owned and operated by the Kremlin, and no real newspapers, because the same situation prevails, because Russians have ready access to the Internet to make up for it, are lying to you.
There is no significant offset of the Kremlin's propaganda on TV and in the mainstream press to be found in the Internet. What's more, the obscure sources that do exist, serving a tiny fraction of the population, are under constant assault, and the Kremlin is aggressively seeking to co-opt or destroy them.
There is no hope to be found for Russia online.
tagged as Runet, Russia
3 responses to "Exploding the Myth of Russia's Internet"
jen ⋅
As a PR practitioner following Russian social media activity, it would help if you could cite sources for this information. Thank you, jen
OK – sorry I see the links to click on now. Duh.
Catherine A. Fitzpatrick ⋅
For most people, there's OBS (odna baba skazala). For only a very thin layer, there's ZhZh. They're easily coopted.
Talk back to La Russophobe Cancel reply
The People of Russia do not Deserve Respect
Glorious Russian Music Played as Putin booed Off Stage

redpajama_set_name: RedPajamaCommonCrawl


text:
Life Media Spectator sport
How will The Athletic's expansion change British sports journalism?
Sports journalism in Britain is being attacked by an American predator
Forty years ago the soccer transfer market went crazy: the British record was broken four times in 1979, more than in any other year before or since. A lot of this was down to Malcolm Allison at Manchester City, who shelled out a record amount for a teenager (£250,000 for Steve MacKenzie, an apprentice at Palace) and £1.45 million to bring Steve Daley from Wolves. That was later, unkindly but not inaccurately, described as 'the biggest waste of money in football history'. Allison continued to spend money like a drunk in a bar; something the club never recovered from until it became part of the sovereign wealth portfolio of one of the richest countries in the world.
Now could something similar be happening in the recondite and less lucrative world of sports journalism? Here the interloper is a hyper-aggressive American sports website called The Athletic which is opening in the UK under the leadership of well-regarded former Times executive Alex Kay-Jelski. In the time-honored way of ruthless American predators, they are on a hiring spree, raiding the sports departments of Britain's best newspapers and throwing money, stock options, signing-on fees and benefits at many of its leading journalists. This is in turn leading to rapidly inflating salaries and bidding wars for talent. No bad thing, you may say; but some of the salaries could soon become unaffordable, with parts of the UK's already beleaguered national and regional press having to pull horns in further, or even close.
The website, which promises to be free of adverts, has a subscription model (like Netflix and Spotify). It will concentrate on soccer, and not just the Premier League. Fans will be able to access granular reporting about every nook and cranny of their club. That seems to have worked in America. But in America you don't have the huge range of high-quality sports journalism that is already available every day in the UK national press.
Papers such as the Mail, the Guardian and the Telegraph offer exceptional coverage and have invested heavily in their print and online offerings. In the US, the complaint is often that sports journalism has been undernourished; I don't think anyone would say the same here. And the US doesn't have the BBC's excellent sports website. My friend Ben, a Swansea fan, can for example find out everything about his club from local press websites, the BBC, and independent fan sites. He already knows everything he needs to know.
Again in America, journalists' access to the locker room — for all US sports — is guaranteed. Here, access to players and managers is ferociously controlled by clubs and agents. It takes time to cultivate the relationships that yield informed journalism. The late great Hugh McIlvanney had a famously close relationship with Sir Alex Ferguson. But that took years to develop. In America sports writers can have high status — they're even the subject of acclaimed novels (take a bow, Richard Ford). Here it's not so easy to unlock the secrets of clubs and players' lives.
The men behind The Athletic take a pretty dismissive view of local press. Alex Mather, 37, one of the founders, talking about their US program, told the New York Times: 'We will wait every local paper out and let them continuously bleed until we are the last ones standing. We will suck them dry of their best talent at every moment. We will make business extremely difficult for them.' Hmmm: nice eh!
I am all for the rewards of journalism being more fairly shared out, but I have the highest regard for what we have in Britain and I feel that our Yankee friends — with their millions, their fashionable stubble, their groovy jeans and their brutal tactics — should show a tad more respect.
This article was originally published in The Spectator magazine.
The Athletic
What have you changed your mind on?The Spectator


text:
package com.cjburkey.claimchunk.config;

import com.cjburkey.claimchunk.Utils;
import com.cjburkey.claimchunk.config.access.Accesses;
import com.cjburkey.claimchunk.config.access.BlockAccess;
import com.cjburkey.claimchunk.config.access.EntityAccess;
import com.cjburkey.claimchunk.config.ccconfig.CCConfig;
import com.cjburkey.claimchunk.config.ccconfig.ICCConfigSerializable;
import com.cjburkey.claimchunk.config.spread.FullSpreadProfile;
import com.cjburkey.claimchunk.config.spread.SpreadProfile;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * A class that represents the permissions that players have in a given world.
 *
 * @since 0.0.23
 */
public class ClaimChunkWorldProfile {

    static final String DEFAULT = "__DEFAULT__";

    private static final String CLASS_STARTING_CHARS = "_.";
    private static final String ENTITY_CLASS_KEY = CLASS_STARTING_CHARS + "_@E_.";
    private static final String BLOCK_CLASS_KEY = CLASS_STARTING_CHARS + "_@B_.";

    private static final String KEY =
            "^ (claimedChunks | unclaimedChunks) \\. (entityAccesses | blockAccesses) \\."
                    + " (@? [a-zA-Z0-9\\-_]+) $";
    private static final Pattern KEY_PAT = Pattern.compile(KEY, Pattern.COMMENTS);

    /**
     * Whether ClaimChunk will be enabled in this world. If ClaimChunk is disabled for a world, no
     * one will be able to make any claims, including admins.
     */
    public boolean enabled;
    /** Whether players' claims should be protected when they are offline. */
    public boolean protectOffline = true;
    /** Whether players' claims should be protected when they are online. */
    public boolean protectOnline = true;
    /**
     * If this is true, non-owner or access players won't be able to use ender pearls within claimed
     * chunks.
     */
    public boolean preventPearlFromClaims = false;

    /** Mapping from entity config class names to a set of entities for that class. */
    public final HashMap<String, HashSet<EntityType>> entityClasses = new HashMap<>();
    /** Mapping from block config class names to a set of blocks (materials) for that class. */
    public final HashMap<String, HashSet<Material>> blockClasses = new HashMap<>();

    private static final String FIRE_SPREAD_KEY = "allow_spread.fire";
    private static final String WATER_SPREAD_KEY = "allow_spread.water";
    private static final String LAVA_SPREAD_KEY = "allow_spread.lava";
    private static final String PISTON_EXTEND_KEY = "allow_piston";

    /** The fire spread config protection profile. */
    public FullSpreadProfile fireSpread = new FullSpreadProfile();
    /** The water spread config protection profile. */
    public FullSpreadProfile waterSpread = new FullSpreadProfile();
    /** The lava spread config protection profile. */
    public FullSpreadProfile lavaSpread = new FullSpreadProfile();
    /** The piston extension config protection profile. */
    public SpreadProfile pistonExtend = new SpreadProfile();

    /** A set of blocks for which to deny neighboring (same) block placement. */
    public final HashSet<Material> preventAdjacent =
            new HashSet<>(Arrays.asList(Material.CHEST, Material.TRAPPED_CHEST));

    /** A set of commands that should be denied for un-owning players in claimed chunks. */
    public HashSet<String> blockedCmdsInDiffClaimed = new HashSet<>();
    /** A set of commands that should be denied for players in their own claimed chunks. */
    public HashSet<String> blockedCmdsInOwnClaimed = new HashSet<>();
    /** A set of commands that should be denied for players in unclaimed chunks. */
    public HashSet<String> blockedCmdsInUnclaimed = new HashSet<>();

    /** The access storage for claimed chunks. */
    public final Accesses claimedChunks;
    /** The access storage for unclaimed chunks. */
    public final Accesses unclaimedChunks;

    public ClaimChunkWorldProfile(
            boolean enabled, @Nullable Accesses claimedChunks, @Nullable Accesses unclaimedChunks) {
        this.enabled = enabled;

        // Make sure the access storage isn't null
        if (Objects.isNull(claimedChunks)) {
            claimedChunks =
                    new Accesses(
                            new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>());
        }
        if (Objects.isNull(unclaimedChunks)) {
            unclaimedChunks =
                    new Accesses(
                            new HashMap<>(), new HashMap<>(), new HashMap<>(), new HashMap<>());
        }

        this.claimedChunks = claimedChunks;
        this.unclaimedChunks = unclaimedChunks;
    }

    /**
     * Copies the provided profile to make a new one.
     *
     * @param old The old world profile.
     */
    public ClaimChunkWorldProfile(@NotNull ClaimChunkWorldProfile old) {
        // Copy basic settings
        this.enabled = old.enabled;
        this.protectOffline = old.protectOffline;
        this.protectOnline = old.protectOnline;
        this.preventPearlFromClaims = old.preventPearlFromClaims;

        // Copy entity/block classes
        old.entityClasses.forEach(
                (className, members) -> this.entityClasses.put(className, new HashSet<>(members)));
        old.blockClasses.forEach(
                (className, members) -> this.blockClasses.put(className, new HashSet<>(members)));

        // Copy spread profiles
        this.fireSpread = old.fireSpread;
        this.waterSpread = old.waterSpread;
        this.lavaSpread = old.lavaSpread;
        this.pistonExtend = old.pistonExtend;

        // Copy adjacent prevention
        this.preventAdjacent.addAll(old.preventAdjacent);

        // Copy blocked commands
        this.blockedCmdsInDiffClaimed.addAll(old.blockedCmdsInDiffClaimed);
        this.blockedCmdsInOwnClaimed.addAll(old.blockedCmdsInOwnClaimed);
        this.blockedCmdsInUnclaimed.addAll(old.blockedCmdsInUnclaimed);

        // Block access mappings
        this.claimedChunks = new Accesses(old.claimedChunks);
        this.unclaimedChunks = new Accesses(old.unclaimedChunks);
    }

    // Returns `true` if the player should be allowed to perform this action
    public boolean canAccessEntity(
            boolean isOwned,
            boolean isOwnerOrAccess,
            @NotNull Entity entity,
            @NotNull EntityAccess.EntityAccessType accessType) {
        // If the chunk is claimed and the player has access, they can just
        // edit and interact with it as if it were their own. Then check
        // for the entity access and determine if the player is allowed to
        // access it.
        return isOwnerOrAccess
                || checkEntityAccess(
                        isOwned, entity.getWorld().getName(), entity.getType(), accessType);
    }

    // Returns `true` if the player should be allowed to perform this action
    private boolean checkEntityAccess(
            boolean isClaimed,
            String worldName,
            @NotNull EntityType entityType,
            @NotNull EntityAccess.EntityAccessType accessType) {
        // Check for the type of access
        return accessType.getShouldAllow(getEntityAccess(isClaimed, worldName, entityType));
    }

    public @NotNull EntityAccess getEntityAccess(
            boolean isClaimed, String worldName, EntityType entityType) {
        // Get all of the entity access mappings
        HashMap<EntityType, EntityAccess> entityAccesses =
                (isClaimed ? claimedChunks : unclaimedChunks).liveEntityAccesses;

        // Get the access for this entity, if one is present
        EntityAccess access = entityAccesses.get(entityType);

        // If one is not present, get the default
        if (access == null) access = entityAccesses.get(EntityType.UNKNOWN);

        // If there is no default, then there should be a console error and assume a value of allow
        if (access == null) {
            Utils.err(
                    "Entity \"%s\" doesn't have a specific protection profile for world \"%s\" for"
                            + " %s chunks and a default could not be found!",
                    entityType, worldName, isClaimed ? "claimed" : "unclaimed");
            access = new EntityAccess(true, true, true);
        }

        return access;
    }

    // Returns `true` if the player should be allowed to perform this action
    public boolean canAccessBlock(
            boolean isOwned,
            boolean isOwnerOrAccess,
            @NotNull String worldName,
            @NotNull Material blockType,
            @NotNull BlockAccess.BlockAccessType accessType) {
        // If the chunk is claimed and the player has access, they can just
        // edit and interact with it as if it were their own. Then check
        // for the block access and determine if the player is allowed to
        // access it.
        return isOwnerOrAccess || checkBlockAccess(isOwned, worldName, blockType, accessType);
    }

    // Returns `true` if the player should be allowed to perform this action
    public boolean canAccessBlock(
            boolean isOwned,
            boolean isOwnerOrAccess,
            @NotNull World world,
            @NotNull Material blockType,
            @NotNull BlockAccess.BlockAccessType accessType) {
        // If the chunk is claimed and the player has access, they can just
        // edit and interact with it as if it were their own. Then check
        // for the block access and determine if the player is allowed to
        // access it.
        return canAccessBlock(isOwned, isOwnerOrAccess, world.getName(), blockType, accessType);
    }

    // Returns `true` if the player should be allowed to perform this action
    private boolean checkBlockAccess(
            boolean isClaimed,
            @NotNull String worldName,
            @NotNull Material blockType,
            @NotNull BlockAccess.BlockAccessType accessType) {
        // Check for the type of access
        return accessType.getShouldAllow(getBlockAccess(isClaimed, worldName, blockType));
    }

    public @NotNull BlockAccess getBlockAccess(
            boolean isClaimed, @NotNull String worldName, @NotNull Material blockType) {
        // Get all of the block access mappings
        HashMap<Material, BlockAccess> blockAccesses =
                (isClaimed ? claimedChunks : unclaimedChunks).liveBlockAccesses;

        // Get the access for this block, if one is present
        BlockAccess access = blockAccesses.getOrDefault(blockType, blockAccesses.get(Material.AIR));

        // If there is no default, then there should be a console error and assume a value of allow
        if (access == null) {
            Utils.err(
                    "Block \"%s\" doesn't have a specific protection profile for world \"%s\" for"
                            + " %s chunks and a default could not be found!",
                    blockType, worldName, isClaimed ? "claimed" : "unclaimed");
            access = new BlockAccess(true, true, true, true);
        }

        return access;
    }

    public String getEntityClass(final EntityType entityType) {
        // Find which entity class this entity belongs to (or return null if it doesn't belong to
        // any)
        for (Map.Entry<String, HashSet<EntityType>> e : entityClasses.entrySet()) {
            if (e.getValue().contains(entityType)) return e.getKey();
        }
        return null;
    }

    public String getBlockClass(final Material material) {
        // Find which block class this block belongs to (or return null if it doesn't belong to any)
        for (Map.Entry<String, HashSet<Material>> e : blockClasses.entrySet()) {
            if (e.getValue().contains(material)) return e.getKey();
        }
        return null;
    }

    // Generics make this method look a little more confusing than it has to,
    // I only did that so I didn't have to have two separate methods to handle
    // block accesses and entity classes.
    private @NotNull <Type extends Enum<Type>> HashMap<String, HashSet<Type>> loadClasses(
            @NotNull Class<Type> enumType,
            @NotNull CCConfig config,
            @NotNull String key,
            @NotNull String debugName) {
        HashMap<String, HashSet<Type>> classes = new HashMap<>();

        // I think the streams API is fairly readable, but I'll add comments
        // just in case anyone is curious.
        config.values().stream()
                // Only load config values that start with the given key
                .filter(val -> val.getKey().startsWith(key))
                .map(
                        kv -> {
                            HashSet<Type> finishedSet = new HashSet<>();

                            // Get the entities/blocks within this class
                            for (String listedType : config.getStrList(kv.getKey())) {
                                try {
                                    finishedSet.add(Type.valueOf(enumType, listedType));
                                } catch (Exception e) {
                                    Utils.err(
                                            "Failed to get %s by name \"%s\"",
                                            debugName, listedType);
                                }
                            }

                            // Map to a map entry that can be inserted into a map
                            return new AbstractMap.SimpleEntry<>(kv.getKey(), finishedSet);
                        })
                // Ignore empty classes
                .filter(kv -> !kv.getValue().isEmpty())
                // Move into the output map (minus starting 3 chars)
                .forEach(kv -> classes.put(kv.getKey().substring(key.length()), kv.getValue()));

        return classes;
    }

    private void loadPermissions(
            @NotNull Map.Entry<String, String> keyValue, @NotNull CCConfig config) {
        // Use regex to check which keys are for chunk permissions
        final Matcher matcher = KEY_PAT.matcher(keyValue.getKey());
        if (!matcher.matches() || matcher.groupCount() < 3) {
            return;
        }

        // Get the access depending on whether this is for
        // claimed/unclaimed chunks.
        Accesses accesses =
                matcher.group(1).equals("claimedChunks") ? claimedChunks : unclaimedChunks;

        // Get the name of the protection
        String strType = matcher.group(3);
        if (strType == null) {
            return;
        }

        // Load the permissions from this value
        if (matcher.group(2).equals("entityAccesses")) {
            // Entity
            addPermissionsFromValue(
                    strType,
                    keyValue.getKey(),
                    "entity",
                    () -> EntityType.UNKNOWN,
                    EntityType::valueOf,
                    accesses.entityAccesses,
                    accesses.liveEntityAccesses,
                    accesses.entityAccessClassMapping,
                    EntityAccess::new,
                    entityClasses,
                    config);
        } else {
            // Block
            addPermissionsFromValue(
                    strType,
                    keyValue.getKey(),
                    "block",
                    () -> Material.AIR,
                    Material::valueOf,
                    accesses.blockAccesses,
                    accesses.liveBlockAccesses,
                    accesses.blockAccessClassMapping,
                    BlockAccess::new,
                    blockClasses,
                    config);
        }
    }

    // THIS FUNCTION MUTATES. IT'S ANNOYINGLY COMPLICATED!
    // I'M SORRY!
    private <T, V extends ICCConfigSerializable> void addPermissionsFromValue(
            @NotNull String strType,
            @NotNull String key,
            String debugVal,
            Supplier<T> getDefaultType,
            Function<String, T> getByName,
            // These map will be mutated!
            HashMap<T, V> accessMap,
            HashMap<T, V> liveAccessMap,
            HashMap<String, V> accessClassMapping,
            Supplier<V> genNewAccess,
            HashMap<String, HashSet<T>> classMap,
            CCConfig config) {
        // Get the value of the access type, aka which protections to apply.
        V newAccess = genNewAccess.get();
        newAccess.fromCCConfig(config, key);

        // Get the type for this
        T actualType;
        if (strType.equals(DEFAULT)) {
            // The default entity/block is set to these values internally. I
            // hope this choice doesn't come back to bite me in the ass.
            actualType = getDefaultType.get();
        } else {
            try {
                // This will throw an exception if the entity/block isn't found.
                actualType = getByName.apply(strType);
            } catch (Exception ignored) {
                // Remove the '@'
                String className = strType.substring(1);

                // Get the members of this particular class
                HashSet<T> classMembers = classMap.get(className);

                // Check if the given value wasn't a valid class either
                if (classMembers == null) {
                    // This wasn't a particular entity/block or class
                    Utils.err(
                            "Invalid %s type or class: \"%s\" in world config from \"%s\"",
                            debugVal, strType, key);
                    return;
                }

                // Add the access for each member of the class
                classMembers.forEach(member -> liveAccessMap.put(member, newAccess));
                accessClassMapping.put(className, newAccess);
                return;
            }
        }

        // Add the new protection to the specified entity/block or the default
        // access
        accessMap.put(actualType, newAccess);
        liveAccessMap.put(actualType, newAccess);
    }

    // Loads all the commands and double checks with Spigot that they exist
    private static Set<PluginCommand> getCommands(Collection<String> commandNames) {
        return commandNames.stream()
                .map(
                        cmd -> {
                            PluginCommand pluginCmd = Bukkit.getPluginCommand(cmd);
                            if (pluginCmd == null) {
                                Utils.err(
                                        "Invalid command \"%s\" in ClaimChunk blocked commands",
                                        cmd);
                            }
                            return pluginCmd;
                        })
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());
    }

    public void toCCConfig(@NotNull CCConfig config) {
        // Write basic boolean config values
        config.set("_.enabled", enabled);
        config.set("_.protectOffline", protectOffline);
        config.set("_.protectOnline", protectOnline);
        config.set("_.preventPearlFromClaims", preventPearlFromClaims);

        // Write entity and block classes
        entityClasses.forEach(
                (name, entities) ->
                        config.setList(
                                ENTITY_CLASS_KEY + name,
                                entities.stream()
                                        .map(EntityType::name)
                                        .collect(Collectors.toSet())));
        blockClasses.forEach(
                (name, blocks) ->
                        config.setList(
                                BLOCK_CLASS_KEY + name,
                                blocks.stream().map(Material::name).collect(Collectors.toSet())));

        // Fire spread configs
        fireSpread.toCCConfig(config, FIRE_SPREAD_KEY);
        // Water spread configs
        waterSpread.toCCConfig(config, WATER_SPREAD_KEY);
        // Lava spread configs
        lavaSpread.toCCConfig(config, LAVA_SPREAD_KEY);
        // Piston protection configs
        pistonExtend.toCCConfig(config, PISTON_EXTEND_KEY);

        // Change types of adjacent blocks to check, empty this list to stop checking
        config.setList("_.preventAdjacent", preventAdjacent);

        // Command blocking configs
        config.setList("claimedChunks.other.blockedCmds", blockedCmdsInDiffClaimed);
        config.setList("claimedChunks.owned.blockedCmds", blockedCmdsInOwnClaimed);
        config.setList("unclaimedChunks.blockedCmds", blockedCmdsInUnclaimed);

        // Write entity accesses
        for (HashMap.Entry<EntityType, EntityAccess> entry :
                claimedChunks.entityAccesses.entrySet()) {
            entry.getValue()
                    .toCCConfig(
                            config,
                            "claimedChunks.entityAccesses."
                                    + (entry.getKey() == EntityType.UNKNOWN
                                            ? DEFAULT
                                            : entry.getKey()));
        }
        for (HashMap.Entry<EntityType, EntityAccess> entry :
                unclaimedChunks.entityAccesses.entrySet()) {
            entry.getValue()
                    .toCCConfig(
                            config,
                            "unclaimedChunks.entityAccesses."
                                    + (entry.getKey() == EntityType.UNKNOWN
                                            ? DEFAULT
                                            : entry.getKey()));
        }

        // Write entity accesses classes
        for (HashMap.Entry<String, EntityAccess> entry :
                claimedChunks.entityAccessClassMapping.entrySet()) {
            entry.getValue().toCCConfig(config, "claimedChunks.entityAccesses.@" + entry.getKey());
        }
        for (HashMap.Entry<String, EntityAccess> entry :
                unclaimedChunks.entityAccessClassMapping.entrySet()) {
            entry.getValue()
                    .toCCConfig(config, "unclaimedChunks.entityAccesses.@" + entry.getKey());
        }

        // Write block accesses
        for (HashMap.Entry<Material, BlockAccess> entry : claimedChunks.blockAccesses.entrySet()) {
            entry.getValue()
                    .toCCConfig(
                            config,
                            "claimedChunks.blockAccesses."
                                    + (entry.getKey() == Material.AIR ? DEFAULT : entry.getKey()));
        }
        for (HashMap.Entry<Material, BlockAccess> entry :
                unclaimedChunks.blockAccesses.entrySet()) {
            entry.getValue()
                    .toCCConfig(
                            config,
                            "unclaimedChunks.blockAccesses."
                                    + (entry.getKey() == Material.AIR ? DEFAULT : entry.getKey()));
        }

        // Write block accesses classes
        for (HashMap.Entry<String, BlockAccess> entry :
                claimedChunks.blockAccessClassMapping.entrySet()) {
            entry.getValue().toCCConfig(config, "claimedChunks.blockAccesses.@" + entry.getKey());
        }
        for (HashMap.Entry<String, BlockAccess> entry :
                unclaimedChunks.blockAccessClassMapping.entrySet()) {
            entry.getValue().toCCConfig(config, "unclaimedChunks.blockAccesses.@" + entry.getKey());
        }
    }

    public void fromCCConfig(@NotNull CCConfig config) {
        // Load basic boolean config options
        enabled = config.getBool("_.enabled", enabled);
        protectOffline = config.getBool("_.protectOffline", protectOffline);
        protectOnline = config.getBool("_.protectOnline", protectOnline);
        preventPearlFromClaims = config.getBool("_.preventPearlFromClaims", preventPearlFromClaims);

        // Load fire spread properties
        fireSpread.fromCCConfig(config, FIRE_SPREAD_KEY);
        // Load water spread properties
        waterSpread.fromCCConfig(config, WATER_SPREAD_KEY);
        // Load lava spread properties
        lavaSpread.fromCCConfig(config, LAVA_SPREAD_KEY);
        // Load piston protection properties
        pistonExtend.fromCCConfig(config, PISTON_EXTEND_KEY);

        // Load list of adjacent block types to check
        preventAdjacent.clear();
        config.getStrList("_.preventAdjacent").stream()
                .map(
                        blockType -> {
                            Material material = Material.getMaterial(blockType);
                            if (material == null) {
                                Utils.warn(
                                        "Material type \"%s\" not found when loading from"
                                                + " preventAdjacent, this one will be removed!",
                                        blockType);
                            }
                            return material;
                        })
                .filter(Objects::nonNull)
                .forEach(preventAdjacent::add);

        // Load blocked commands for unowned claimed chunks
        // (`getCommands()` will verify the commands actually exist)
        blockedCmdsInDiffClaimed.clear();
        getCommands(config.getStrList("claimedChunks.other.blockedCmds"))
                .forEach(cmd -> blockedCmdsInDiffClaimed.add(cmd.getName()));

        // Load blocked commands for owned claimed chunks
        // (getCommands()` will verify the commands actually exist)
        blockedCmdsInOwnClaimed.clear();
        getCommands(config.getStrList("claimedChunks.owned.blockedCmds"))
                .forEach(cmd -> blockedCmdsInOwnClaimed.add(cmd.getName()));

        // Load blocked commands for unclaimed chunks
        // (getCommands()` will verify the commands actually exist)
        blockedCmdsInUnclaimed.clear();
        getCommands(config.getStrList("unclaimedChunks.blockedCmds"))
                .forEach(cmd -> blockedCmdsInUnclaimed.add(cmd.getName()));

        // Load block and entity classes
        entityClasses.clear();
        entityClasses.putAll(loadClasses(EntityType.class, config, ENTITY_CLASS_KEY, "entity"));
        blockClasses.clear();
        blockClasses.putAll(loadClasses(Material.class, config, BLOCK_CLASS_KEY, "block"));

        // Load permissions
        config.values().stream()
                // Make sure these are protections. This should ideally be made
                // a little more elegant than this particular solution.
                .filter(
                        kv ->
                                kv.getKey().startsWith("claimedChunks")
                                        || kv.getKey().startsWith("unclaimedChunks"))
                // Load the permissions; permissions may be for classes, which
                // will return a new permission for each member of that class.
                .forEach(val -> this.loadPermissions(val, config));
    }
}

redpajama_set_name: RedPajamaGithub


Coordinates: 38°00′21″N 121°51′36″W / 38.0059, -121.86 Los Medanos College (LMC) is a two-year community college located in Pittsburg in Contra Costa County, California. LMC has an extension in Brentwood. The name, meaning "the dunes" in Spanish, refers to the sand dunes that characterize its location in eastern Contra Costa County. The college, opened in 1974, is one of three publicly supported two-year community colleges in the Contra Costa Community College District (along with Contra Costa College and Diablo Valley College). Current enrollment is 14,000 students.. The college's faciliites were expanded significantly with the completion of a new library and math building in the summer of 2007. Construction is continuing at the campus; a new science buildings is expected to open in time for the 2008 summer semester. LMC is a regional police academy for Contra Costa County. LMC has an Honors Transfer program and a highly demanded nursing program.
Question and Answer about "Los Medanos College"


If you're thinking of inviting your favorite rappers to a board game night, you can cross Snow tha Product's name off the guest list. As the Atlantic Records signee makes abundantly clear on her latest mixtape single, she "don't Play." Beatsmith DK's buzzing, whirring electronic grooves accompany the Golden State native as she emphasizes her un-f**k-wit-ability in rapid-fire verses. To ensure that her point gets across, she makes it in español as well as inglés, spitting, "Mira cabron, conmigo no te metas guey." Available now on iTunes, this aggressive jam can also be found on Snow's Good Nights & Bad Mornings 2: The Hangover mixtape, released to the 'net in mid-October.


text:
read next: Crown Royal Has the Answer to the Meaning of Life, the Universe, and Everything
The Curious Eleven With Luca Cinalli
By Team Flaviar
Luca Cinalli is a respected bartender who has consulted, mixed, and invented new drinks all over the world. He worked at London's prestigious Oriole for over three years, and then went on to set up on his own; designing menus and creating new cocktails for renowned drinkeries worldwide!
When did that Eureka moment happen when you realized your mission is to be a bartender?
I feel I am a waiter/bartender as I've spent so much time on the floor waiting. When I was working on the bar that was when I found out it was for me - I make it myself and serve it myself - doing both is what I really like. You can also see the table from where you are serving, which is great, you get to see the reactions firsthand. I don't want to deliver something I'm not involved in, so bringing food from the kitchen as a waiter, that I hadn't produced, that wasn't really up my street. Once I started working in bars about 17 years ago in London, I felt like I had found freedom.
I feel like I'm still a student and it's great to learn new things.
What are the TOP 5 skills every bartender should have?
The top five skills for me… those would be speed, efficiency, communication, understanding (psychological understanding) eg don't judge people, have some patience and understanding. If there is a misunderstanding I always try to work things out, it is a people's job through and through. Understanding is a must with customers. And then lastly, self-training. There's a lot of new people coming into the industry; I feel like I'm still a student and it's great to learn new things. You can put deadlines on yourself for daily, weekly, or yearly learning. That's how to progress too.
Which cocktail is the biggest pain in the ass to make, pardon our French?
Bloody Mary, because I think anyone can make his own, but to do a complicated Bloody Mary with stock reduction etc, sometimes they are just too over-complicated. There are some recipes where people use raw tomatoes, and I just don't think it's the best. As an Italian I always try to make it as simply as possible. Nowadays I have a signature one that I make: a Champagne Mary with a clean consommé, Brandy Vermouth, cacao butter, it's a yellow White Wine colour, and tastes great because it is so simple.
I don't even shake the Daiquiri, I just make it with crushed ice.
A post shared by ?? Volen Kai (@totalsky) on
Sep 9, 2016 at 10:33pm PDT
And which cocktail is served in your version of heaven?
A Daiquiri for me would be heaven, just perfect with lime sugar and Rum. The classic recipe. I call it like a sauce - the right balance of caster sugar and fresh lime juice that gives a fresh zingy texture. I don't even shake the Daiquiri, I just make it with crushed ice. Ideal! Using a milkshake blender is wonderful for this.
I really enjoy a Tom Collins.
Which drink or cocktail would you say is way underrated? (And a tricky followup: Which one is the most overrated?)
I really enjoy a Tom Collins. Everybody can make it, but you don't see it as much as you would think. If a customer asks me for it I adjust it slightly with a fino Sherry. That's definitely the one I would say. And then overrated perhaps… Maybe a Viuex Carre, it's okay but I wouldn't say it's outstanding.
A post shared by Hospitality Gourmet (@hospitality_gourmet) on
Jan 28, 2020 at 9:34am PST
You come home, slide into something comfortable, and throw yourself on the couch. What's in your glass?
Beer! A nice IPA… or if it was a Spirit then I would have a single malt Whisky.
What are the five essential ingredients every booze lover should have in their home bar?
There's an easy five for me - angostura bitter, Campari, sweet Vermouth, maraschino and chartreuse.
Don't judge people, have some patience and understanding.
Which booze is the most versatile?
That's Gin everytime.
Is there a favorite life hack you learned at your job?
Well it's not a life hack as such, but definitely important in this industry... controlling what you drink. I've never been a massive drinker, but I have definitely learnt control over the years; I'm all about training my palate. Another tip would be around planning your day, week or month and then sticking to that plan!
Jan 4, 2020 at 8:06am PST
What's the craziest anecdote you're willing to share with us?
Sincerely, there's nothing that comes to mind - perhaps I've always been a good boy behind the bar!
What are your passions outside the world of Spirits?
I absolutely love foraging. I have a really well planned calendar and have to harvest at the right moment. Spending time doing this, and going to the coast and gardening really relaxes me.
What would you be doing if you weren't a bartender?
I would be a policeman!
I absolutely love foraging.
Tell us what's your favorite tool of the trade and why.
You could do much worse than getting your hands on the V60 coffee filter, it makes a great cold drip extraction and I use it for a lot of my cocktails too.
Mar 9, 2020 at 11:07am PDT
Fast-forward five years. Where do you see yourself?
I would love to have a few bars in different spots around the world!
A Genie tells you to pick someone to fix a drink for; dead or alive, real or fictional. Who would it be?
Charles Schumann! He was one of the main bartenders around when I was younger, and one of the first books I bought was his Tropical Bar Book. I would make him a Sherry Collins.
Published Apr 23rd 2020
We're here to help people try more new things more often. Not only do we send out personalized samples & complimentary bottles, we give people access to rare and original spirits, invite them to great events, and keep them educated & entertained with booze-themed content. Join us.
Show all in interview
We'll send you the latest booze news, cool finds and great deals.
Uncapping Wild Turkey With the Legendary Eddie Russell
Uncovering the Secrets of Whiskey Grains with Colby & Ashley Frey
Crown Royal Has the Answer to the Meaning of Life, the Universe, and Everything
The Best Bottle For Each Zodiac Sign
Flaviar's Year in Rearview: Twenty-Twenty-Fun


"Great service and such great quality! I LOVE my lashes, I wouldn't go anywhere else!"
"I enjoyed my session from start to finish. Brittany has product knowledge and her quality of work is top-noch. It was a very positive and relaxing atmosphere."


text:
Winning Fantasy 5 ticket sold in Fort Pierce
The winning ticket was sold at the Quick Mart at 4101 Okeechobee Road.
Winning Fantasy 5 ticket sold in Fort Pierce The winning ticket was sold at the Quick Mart at 4101 Okeechobee Road. Check out this story on tcpalm.com: https://www.tcpalm.com/story/news/local/st-lucie-county/2019/02/21/winning-fantasy-5-ticket-sold-fort-pierce-1-4-winners/2936420002/
Enable Javascript to view this content, or open it in a new window.
Trouble viewing this embed? Open it in a new window.
Cheryl McCloud, Treasure Coast Newspapers Published 7:56 a.m. ET Feb. 21, 2019 | Updated 7:56 a.m. ET Feb. 21, 2019
Check those Fantasy 5 tickets.
After a dry spell of almost two weeks, a winning ticket sold in Fort Pierce was one of four winners in Wednesday night's drawing.
It was the fourth winning ticket sold on the Treasure Coast since the beginning of the year, and the third winning ticket sold in St. Lucie County.
More: Winning Fantasy 5 lottery ticket sold in Port St. Lucie worth $196,274
More: Fantasy 5 ticket sold in Vero Beach 1 of 4 winners
Top prize was $50,056.
Winning numbers were: 5-9-14-19-26.
Read or Share this story: https://www.tcpalm.com/story/news/local/st-lucie-county/2019/02/21/winning-fantasy-5-ticket-sold-fort-pierce-1-4-winners/2936420002/
Port St. Lucie man dead after motorcycle crash in Fort Pierce
8 remain in hospital following fatal crash
Walmart erred in NFL player's $80K layaway donation
Sunday vigil a citywide show of support for woman killed in crash


text:
package com.intellij.tasks.integration.live;

import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.tasks.CustomTaskState;
import com.intellij.tasks.trello.TrelloRepository;
import com.intellij.tasks.trello.TrelloRepositoryType;
import com.intellij.tasks.trello.TrelloTask;
import com.intellij.tasks.trello.model.*;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import static com.intellij.tasks.trello.model.TrelloLabel.LabelColor.*;

/**
 * @author Mikhail Golubev
 */
public class TrelloIntegrationTest extends LiveIntegrationTestCase<TrelloRepository> {

  // Basic functionality (searching, filtering, etc.)
  private static final String BASIC_FUNCTIONALITY_BOARD_NAME = "Basic Functionality";
  private static final String BASIC_FUNCTIONALITY_BOARD_ID = "53c416a8a6e5a78753562043";

  private static final String LIST_1_1_NAME = "List 1-1";
  private static final String LIST_1_1_ID = "53c416a8a6e5a78753562044";

  private static final String CARD_1_1_1_NAME = "Card 1-1-1";
  private static final String CARD_1_1_1_ID = "53c416d8b4bd36fb078446e5";
  private static final String CARD_1_1_1_NUMBER = "1";

  // Labels and colors
  private static final String LABELS_AND_COLORS_BOARD_NAME = "Labels and Colors";
  private static final String COLORED_CARD_ID = "548591e00f3d598512ced37b";

  // State updates
  private static final String STATE_UPDATES_BOARD_NAME = "State Updates";
  private static final String STATE_UPDATES_BOARD_ID = "54b3e0e3b4f415b3c9d03449";
  private static final String BACKLOG_LIST_ID = "54b3e0e849e831746351e063";
  private static final String IN_PROGRESS_LIST_ID = "54b3e0ebf5035aaddcbe15b4";
  private static final String FEATURE_CARD_ID = "54b3e0efed4db033b634cd39";

  @Override
  protected TrelloRepository createRepository() throws Exception {
    try {
      TrelloRepository repository = new TrelloRepository(new TrelloRepositoryType());
      String token = System.getProperty("tasks.tests.trello.token");
      assertTrue("Authorization token is not set", !StringUtil.isEmpty(token));
      repository.setPassword(token);
      TrelloUser user = repository.fetchUserByToken();
      assertNotNull(user);
      repository.setCurrentUser(user);
      return repository;
    }
    catch (AssertionError ae){
      tearDown();
      throw ae;
    }
  }

  // TODO Check closed tasks exclusion
  // TODO Check various cards visibility corner cases

  public void testFetchBoard() throws Exception {
    TrelloBoard board = myRepository.fetchBoardById(BASIC_FUNCTIONALITY_BOARD_ID);
    assertNotNull(board);
    assertEquals(BASIC_FUNCTIONALITY_BOARD_NAME, board.getName());
  }

  public void testFetchList() throws Exception {
    TrelloList list = myRepository.fetchListById(LIST_1_1_ID);
    assertNotNull(list);
    assertEquals(LIST_1_1_NAME, list.getName());
  }

  public void testFetchCard() throws Exception {
    TrelloCard card = myRepository.fetchCardById(CARD_1_1_1_ID);
    assertNotNull(card);
    assertEquals(CARD_1_1_1_NAME, card.getName());
  }

  public void testFetchBoardsOfUser() throws Exception {
    List<TrelloBoard> boards = myRepository.fetchUserBoards();
    assertEquals(3, boards.size());
    assertObjectsNamed("All boards of the user should be included", boards,
                       BASIC_FUNCTIONALITY_BOARD_NAME, LABELS_AND_COLORS_BOARD_NAME, STATE_UPDATES_BOARD_NAME);
  }

  public void testFetchListsOfBoard() throws Exception {
    TrelloBoard selectedBoard = myRepository.fetchBoardById(BASIC_FUNCTIONALITY_BOARD_ID);
    assertNotNull(selectedBoard);
    myRepository.setCurrentBoard(selectedBoard);
    List<TrelloList> lists = myRepository.fetchBoardLists();
    assertEquals(3, lists.size());
    assertObjectsNamed("All lists of the board should be included", lists, "List 1-1", "List 1-2", "List 1-3");
  }

  @NotNull
  private List<TrelloCard> fetchCards(@Nullable String boardId, @Nullable String listId, boolean withClosed) throws Exception {
    if (boardId != null) {
      TrelloBoard selectedBoard = myRepository.fetchBoardById(BASIC_FUNCTIONALITY_BOARD_ID);
      assertNotNull(selectedBoard);
      myRepository.setCurrentBoard(selectedBoard);
    }
    if (listId != null) {
      TrelloList selectedList = myRepository.fetchListById(LIST_1_1_ID);
      assertNotNull(selectedList);
      myRepository.setCurrentList(selectedList);
    }
    return myRepository.fetchCards(100, withClosed);
  }

  public void testFetchingCardsOfUser() throws Exception {
    myRepository.setIncludeAllCards(true);
    List<TrelloCard> cards = fetchCards(null, null, true);
    assertObjectsNamed("All cards assigned to user should be included", cards, "Card 1-1-1");
  }

  public void testFetchingCardsOfBoard() throws Exception {
    myRepository.setIncludeAllCards(true);
    List<TrelloCard> cards = fetchCards(BASIC_FUNCTIONALITY_BOARD_ID, null, true);
    assertObjectsNamed("All cards of the board should be included",
                       cards, "Card 1-1-1", "Card 1-1-2", "Card 1-2-1", "Card 1-3-1", "Archived Card");
  }

  public void testCardsFilteringByMembership() throws Exception {
    myRepository.setIncludeAllCards(true);
    List<TrelloCard> allCards = fetchCards(BASIC_FUNCTIONALITY_BOARD_ID, LIST_1_1_ID, true);
    assertObjectsNamed("All cards of the list should be included", allCards, "Card 1-1-1", "Card 1-1-2", "Archived Card");

    myRepository.setIncludeAllCards(false);
    List<TrelloCard> assignedCards = fetchCards(BASIC_FUNCTIONALITY_BOARD_ID, LIST_1_1_ID, true);
    assertObjectsNamed("Only cards of the list assigned to user should be included", assignedCards, "Card 1-1-1");
  }

  public void testCardsFilteringByStatus() throws Exception {
    myRepository.setIncludeAllCards(true);
    List<TrelloCard> allCards = fetchCards(BASIC_FUNCTIONALITY_BOARD_ID, LIST_1_1_NAME, true);
    assertObjectsNamed("All cards of the list should be included", allCards, "Card 1-1-1", "Card 1-1-2", "Archived Card");

    TrelloCard card = ContainerUtil.find(allCards, new Condition<TrelloCard>() {
      @Override
      public boolean value(TrelloCard card) {
        return card.getName().equals("Archived Card");
      }
    });
    assertNotNull(card);
    assertTrue(card.isClosed());
    assertFalse(card.isVisible());
  }

  public void testTestConnection() throws Exception {
    assertNull(myRepository.createCancellableConnection().call());

    myRepository.setPassword("illegal password");
    final Exception error = myRepository.createCancellableConnection().call();
    assertNotNull(error);
    assertTrue(error.getMessage().contains("Unauthorized"));
  }

  public void testLabelsAndColors() throws Exception {
    final TrelloCard card = myRepository.fetchCardById(COLORED_CARD_ID);
    assertNotNull(card);
    final List<TrelloLabel> labels = card.getLabels();

    assertEquals(6, labels.size());
    final Set<String> labelNames = ContainerUtil.map2Set(labels, new Function<TrelloLabel, String>() {
      @Override
      public String fun(TrelloLabel label) {
        return label.getName();
      }
    });
    assertEquals(ContainerUtil.newHashSet("Sky colored label", "Boring label", "Dull label", ""), labelNames);

    assertEquals(EnumSet.of(SKY, LIME, PINK, BLACK), card.getColors());
  }

  public void testStateUpdates() throws Exception {
    TrelloCard card = myRepository.fetchCardById(FEATURE_CARD_ID);
    assertNotNull(card);
    assertEquals(STATE_UPDATES_BOARD_ID, card.getIdBoard());
    assertEquals(BACKLOG_LIST_ID, card.getIdList());

    // Discover "In Progress" list
    TrelloTask task = new TrelloTask(card, myRepository);
    Set<CustomTaskState> states = myRepository.getAvailableTaskStates(task);
    assertEquals(1, states.size());
    final CustomTaskState inProgressState = states.iterator().next();
    assertEquals(IN_PROGRESS_LIST_ID, inProgressState.getId());
    assertEquals("In Progress", inProgressState.getPresentableName());

    // Backlog -> In Progress
    myRepository.setTaskState(task, inProgressState);
    card = myRepository.fetchCardById(FEATURE_CARD_ID);
    assertNotNull(card);
    assertEquals(STATE_UPDATES_BOARD_ID, card.getIdBoard());
    assertEquals(IN_PROGRESS_LIST_ID, card.getIdList());

    // Discover "Backlog" list
    task = new TrelloTask(card, myRepository);
    states = myRepository.getAvailableTaskStates(task);
    assertEquals(1, states.size());
    final CustomTaskState backlogState = states.iterator().next();
    assertEquals(BACKLOG_LIST_ID, backlogState.getId());
    assertEquals("Backlog", backlogState.getPresentableName());

    // In Progress -> Backlog
    myRepository.setTaskState(task, backlogState);
    card = myRepository.fetchCardById(FEATURE_CARD_ID);
    assertNotNull(card);
    assertEquals(STATE_UPDATES_BOARD_ID, card.getIdBoard());
    assertEquals(BACKLOG_LIST_ID, card.getIdList());
  }

  // IDEA-139903
  public void testCardBoardLocalNumber() throws Exception {
    final TrelloCard card = myRepository.fetchCardById(CARD_1_1_1_ID);
    assertNotNull(card);
    assertEquals(CARD_1_1_1_ID, card.getId());
    assertEquals(CARD_1_1_1_NUMBER, new TrelloTask(card, myRepository).getNumber());
  }

  static void assertObjectsNamed(@NotNull String message, @NotNull Collection<? extends TrelloModel> objects, @NotNull String... names) {
    assertEquals(message, ContainerUtil.newHashSet(names), ContainerUtil.map2Set(objects, new Function<TrelloModel, String>() {
      @Override
      public String fun(TrelloModel model) {
        return model.getName();
      }
    }));
  }
}


For more information about International Slavery Studies at University of Liverpool, please visit the webpage using the button above.
Why study International Slavery at Liverpool?
Our regular research seminars offer unparalleled opportunities to debate fresh approaches with a programme of renowned international speakers.
The unique partnership between the University and the International Slavery Museum offers students the opportunity to work with the curators of the Museum as they consider how to develop its galleries in the future.
Our library boasts a wide range of resources, many available online, with a particularly strong collection for the study of slavery, abolition and resistance.
This programme is a pioneering opportunity to choose your disciplinary skills training to suit your interests and aspirations, permitting you to pick from a wide variety of literary, historical and social science modules.