Thermal Science Learning System (T7081): introduces vital knowledge necessary to comprehend the principles of modern thermal systems, such as HVAC, geothermal, refrigeration, and steam. The Thermal Science system allows learners to perform experiments demonstrating principles such as the ideal gas law, linear and volumetric thermal expansion, basic temperature measurement, latent and sensible heat, specific heat capacity, conduction, convection, radiation, evaporative cooling, and basic refrigeration.
Air Conditioning / Heat Pump Learning System (T7082): teaches three types of thermal systems: air conditioning, refrigeration, and heat pumps. This system is a valuable training resource for people considering a career in the HVAC industry and covers topics like compressors, reversing valves, evaporators / condensers, thermodynamic cycles, and thermal efficiency.
Air Conditioning / Heat Pump Troubleshooting Learning System (T7082A): covers all of the topics and skills offered by the T7082, but adds imperative troubleshooting skills for identifying faults such as blockages, leakage, and refrigerant overcharging and undercharging. This air conditioning / heat pump troubleshooting system utilizes Amatrol's FaultPro, the industry's premier troubleshooting software, which allows faults to be electronically inserted for easy testing and tracking.
Environmental Applications Learning System (T7083): this optional expansion to the T7082 or T7082A teaches heating and cooling applications and covers skills including how to size, select, and analyze thermal systems to optimize performance. The system models the characteristics of a living structure with outside environmental effects, such as sun or humidity, and internal design characteristics such as insulation, lighting, and ceiling fans.
Amatrol has developed several systems to provide training for the ever-growing area of geothermal energy. The Geothermal Learning System (950-GEO1) begins with an introduction to geothermal heat pump systems and move rapidly into the concepts and components that make a geothermal system operate; these include closed-loop circuits, compressors, condensers, evaporators, metering devices, refrigerants, suction line accumulators, receivers, dryers, moisture indicators, thermostats, controllers, blowers, heat-pump system start-up and operation, and overall system performance.
Geothermal Learning System with Desuperheater (950-GEO1D): A desuperheater uses the excess energy from the geothermal system to heat water for little or no additional cost. Additional topics include the operation, startup, shutdown, troubleshooting, and maintenance of a desuperheater system.
Geothermal Troubleshooting Learning System (950-GEO2): Using our world-class troubleshooting program, FaultPro, Amatrol has inserted over 25 electronic faults on the 950-GEO2! Covering electrical, mechanical, and fluid-based faults, Amatrol designed the 950-GEO2's troubleshooting to allow learners to practice applicable industry skills and prepare them for real-world geothermal system problems. Amatrol's troubleshooting systems are unmatched in their ability to simulate real-world equipment failures!
Geothermal Troubleshooting Learning System with Desuperheater (950-GEO2D): features all topics and skills for the base system, desuperheater, and troubleshooting.
Geothermal Flush Cart Learning System (95-GEO3): can be added to any of the geothermal learning systems and teaches how to purge debris and air from the geothermal loop and then charge it with a glycol/water solution.
Steam Systems 1 Learning System (950-SH1): covers the operation, installation, maintenance, and repair of steam systems, as well as important concepts like internal energy, specific heat capacity, and flash steam, as well as important calculation for steam power, such as calculating the change in enthalpy caused by phase change. Examples of skills include the startup, shutdown, and blowdown of a boiler; the operation of an OS&Y valve; and how to test a steam trap.


Compiling tail-calls to simple C?
I'm writing a Lisp-to-C compiler, trying to keep compiler and runtime very simple and close to C, because I want to embed the language into C applications, and use C libraries.
My closures are structs with a C function pointer and an environment.
Within any function f, calls to f that appear in tail position w.r.t. the body of f must be tail recursive.
Within a letrec, calls to any function bound in the letrec that appear in tail position within some function bound by the letrec must be tail recursive.
These requirements apply only to function calls whose destination can be statically resolved by the compiler at compile time.
What do you think about this restriction?
Does anyone have experience with the new tail call optimization of GCC, especially when making an indirect call via a function pointer?
when is a tail position call to self not tail recursive?
I don't understand the distinction being made here. I thought that a tail position call to f within f was the definition of tail recursion.
You can't support continuations, coroutines or user level (i.e. non OS) threads with this restriction. You'd still need one of the other schemes for that.
I doubt gcc can/will tail optimize calls via function pointer. I have verified that it optimizes named sibling functions as advertised.
Instead of compiling to direct code, you have a main loop that will call functions, receive return values, and call the next function.
Whatever call stack you have has to be managed by your main loop, not by C itself. I'm afraid there is no easier way.
A web search for "trampoline lisp" should give you further details.
I have not verified this, but instead of using gcc, use llvm-gcc (the gcc front-end merged with the llvm backend). The llvm IR supports tail calls, but I don't know if makes it through the gcc front-end.
consider to compile to a different backend that natively supports tail call optimization. c-- comes to mind.
An alternative mechanism is a trick used by the chicken scheme compiler.
Basically, you have to CPS transform your program and compile all your calls as noreturn calls (with __attribute__ ((noreturn)) in gcc). There is an entry function that kick starts the computation and keeps a jumpbuf for restarting at the top of the stack. The computation keeps growing the stack and when the stack is exhausted you jump back to the top with the continuation of the computation.
The downside is that your C calling conventions must use continuation passing style.
Is there a reason gcc couldn't reuse the current stack frame for calls to functions with __attribute__ ((noreturn)) if -foptimize-sibling-calls is also specified?
Maybe I am missing something, but since a tail call is a glorified goto, why not translate it into one?
I do not understand why this is not popular instead of the more sophisticated and less portable options.
Edit: Just realised my stupidity. This will not work when the tail call is to a different function.
This strategy is actually used by Nemerle for nested function definitions, since the .NET CLR's .tailcall instruction is actually slower than a regular function call.


text:
Another executive leaves Activision Blizzard
Keshav Bhat
The shakeup at Activision Blizzard's executive level continues with the second executive leaving the company in the last few days.
Square, a store-payment company, announced that their new Chief Financial Officer is Amrita Ahuja. Amrita Ahuja was with Activision Blizzard for over 8 years prior to leaving this week for Square.
Ahuja served in many roles within Activision Blizzard over the eight years, including SVP of Investor Relations, VP of Finance and Operations, and VP of Strategy and Business Development. Most recently, Ahuja was the Chief Financial Officer of Blizzard Entertainment, a division of Activision Blizzard.
Square, Inc. announced today that Amrita Ahuja will join the company as Chief Financial Officer. Amrita will start in January and will report to CEO Jack Dorsey.
Amrita is currently the CFO of Blizzard Entertainment, a leading global developer and publisher of interactive software products and entertainment content with over $2 billion in annualized revenue and a division of Activision Blizzard (NASDAQ: ATVI). Amrita has been with Activision Blizzard for over eight years in a number of finance and strategy roles across the company, including SVP of Investor Relations, VP of Finance and Operations, and VP of Strategy and Business Development. Prior to Activision Blizzard, she held various roles at Fox Networks Group, the Walt Disney Company, and Morgan Stanley. She received her M.B.A. from Harvard Business School and her A.B. from Duke University.
Kotaku reported late last year that Ahuja becoming the CFO of Blizzard lead to many changes for the company, including cutting finances and restructuring the company over the last year as Activision Blizzard wants to cut costs and increase revenue.
Kotaku reported:
In the spring of 2018, during Blizzard's annual company-wide "Battle Plan" meeting, chief financial officer Amrita Ahuja spoke to all of the staff, according to two people who were there. In what came as a surprise to many, she told Blizzard that one of the company's goals for the coming year was to save money.
This is the second shakeup at the executive level for Activision Blizzard over the last week. Activision Blizzard's Spencer Neumann, who was the Chief Financial Officer, was fired after he broke his legal contract with the company. Neumann has accepted a new job as the CFO of Netflix, which was announced yesterday. The company's executive team listed on their site has shrunk dramatically over the last two years.
Activision Blizzard's 2019 is expected to be a quiet year as investors says they are unsure what the company plans to release beyond new Activision titles.
Activision files lawsuit against notable cheat provider EngineOwning
Activision has filed a lawsuit against EngineOwning, one of Warzone's most prolific cheat and hack distributors.
Activision have made a new attempt to stamp out cheat providers, filing a lawsuit against EngineOwning, one of the most prolific distributors of hacks.
Cheating is a major issue in Warzone and despite the introduction of the RICOCHET anti-cheat system, hacking is still running wild on Caldera. In fact, these cheaters are so brazen, they've started to actively mock developers Raven with their in-game names.
It should come as no surprise that Activision are trying to shut down these cheaters for good, and the publishers of Call of Duty have once again filed a lawsuit against a site that distributes these hacks.
In a suit filed in the State of California on January 4, Activision took aim at EngineOwning, claiming that their cheats have caused "millions of dollars" in damages, and that they are "developing new cheating software" for another of their titles in Overwatch.
Activision is seeking "to put a stop to unlawful conduct by an organization that is distributing and selling for profit numerous malicious software products designed to enable members of the public to gain unfair advantages."
Read More: Best Warzone Pacific guns: Every weapon ranked
"These ongoing activities damage Activision's games, its overall business, and the experience of the CoD player community," it continues. "This Court must put a stop to [the] defendants' misconduct, and Activision is entitled to monetary damages, injuctive and other equitable relief, and punitive damages."
EngineOwning is one of the largest cheat providers for Call of Duty right now, with the cheat provider continuously attempting to circumvent Activision's anti-cheat efforts. EngineOwning's next steps are unclear, and it remains to be seen whether the operation, which is allegedly maintained by an individual in Germany, is shut down.
Activision has made efforts as of December to stop hackers in Call of Duty with the launch of RICOCHET Anti-Cheat software, including a PC kernel-level driver for Warzone.
This system has had successes, with 48,000 cheaters banned in December, leaving hackers begging Activision for a second chance.
Image Credits: Activision / Raven Software / Ekaterina Bolovtsova: Pexels
Leaker claims Activision is considering changing Call of Duty's annual release schedule
A leaker has suggested that Activision's annual CoD release may be coming to an end with extended cycles being considered.
Andrew Highton
A new Call of Duty title is released every year, with multiple studios taking it in turns to bring out a new game. A new leak however has made the bold claim that Activision may be thinking about changing its release schedule and model.
It's become a given that a new CoD game will be released in November of each year, with the likes of Treyarch, Sledgehammer Games, and Infinity Ward all taking it in turns to develop a new game.
2019 saw the release of IW's Modern Warfare reboot, 2020 was Treyarch's Black Ops Cold War, and this year has seen the release of Sledgehammer Games' Vanguard.
It's already rumored that Modern Warfare 2 is in the works for 2022, but depending on Activision's approach, they may opt to change their release policy, starting with MW2.
Leaks seem to happen left, right, and center these days, with people able to learn a great deal of information about projects and plans, many of which turn out to be true.
Read More: How to play CoD Vanguard Multiplayer free access: Dates, download, content
The new Call of Duty rumor comes from leaker Ralph, who recently claimed that the reported Modern Warfare 2 Multiplayer remaster has been canceled, and thinks that annual releases are being reconsidered.
A recent Tweet from them quite simply said: "Activision are reportedly in discussion for extending Call of Duty's annual releases."
As with any leak, this should be taken with a major pinch of salt. RalphsValve has recently come under scrutiny from fellow leakers regarding the accuracy of his claims.
Activision are reportedly in discussion for extending Call of Duty's annual releases pic.twitter.com/7GjIOxD9zf
— Ralph (@RalphsValve) November 19, 2021
With the rumored 2022 Call of Duty: Modern Warfare 2 title still potentially a year out, maybe two now, things can always change, and we'd recommend taking these claims with a pinch of salt.
Read More: Crazy Vanguard Dead Drop glitch gives players unlimited free killstreaks
Furthermore, given how much this could change the Call of Duty landscape going forward, we'd also strongly recommend waiting for official confirmation from Activision before assuming this is the direction CoD will be going in the future.
For more Call of Duty news, take a look at when Vanguard and Warzone Season 1 starts.
Image Credit: Activision / Infinity Ward / Sledgehammer Games
Activision Blizzard shareholders group call on CEO to resign
Shareholders are now calling for Activision Blizzard CEO Bobby Kotick to resign and be replaced as turmoil continues.
A group of Activision Blizzard shareholders have sent a letter to Activision Blizzard executives asking for CEO Bobby Kotick to resign immediately.
The letter, obtained by The Washington Post, was sent by a group of shareholders that own stock share in Activision Blizzard.
"In contrast to past company statements, CEO Bobby Kotick was aware of many incidents of sexual harassment, sexual assault and gender discrimination at Activision Blizzard, but failed either to ensure that the executives and managers responsible were terminated or to recognize and address the systematic nature of the company's hostile workplace culture," the shareholders, led by the Strategic Organizing Center (SOC) Investment Group stated in their letter.
The news comes as the Wall Street Journal dropped a bomb-shell report on Activision Blizzard on November 17, detailing how CEO Bobby Kotick knew about the company's harassment issues and failed to properly address the situation accordingly over the years.
The WSJ also reported that Bobby Kotick allegedly called a former female assistance and threatened her.
The letter from the group is also asking for Brian Kelly and Robert Morgado, two of the longest-serving board members on the Activision Blizzard board of directors to retire by December 31, 2021, and allow new board members to further shape the future of the company.
"After the new revelations, it's clear that the current leadership repeatedly failed to uphold a safe workplace — a basic function of their job," SOC executive director Dieter Waizenegger said to The Washington Post. "Activision Blizzard needs a new CEO, board chair, and lead independent director with the expertise, skill set and conviction to truly change the company's culture. We need to really have a reset button on the board."
Activision Blizzard has declined to comment on the shareholder letter at this point.
The company issued a statement on November 16 stating that the WSJ report was "misleading" and "failed" to report on the changes CEO Kotick has made since the initial lawsuit dropped in July.
In addition, the company's board of directors issued their own statement on November 16 stating they remain "confident" in Bobby Kotick as CEO. Activision Blizzard's stock has taken a drop since the news surfaced.
Activision Blizzard employee group, A Better ABK, issued their own demand calling for Bobby Kotick to be replaced and staged a walkout on November 16.
We'll continue to update as this situation unfolds.
FIFA 222 days ago
How to complete FIFA 22 Player Moments Ilkay Gundogan SBC
Ilkay Gundogan is looking like a great option in the midfield, and FUT players are going to want to complete...
FIFA FUT 22 Team of the Year Warmup Series: Start date, TOTY leaks, more
Before FIFA 22's Ultimate Team TOTY event, EA Sports are dropping a special Warmup Series promo to build hype.

redpajama_set_name: RedPajamaCommonCrawl


K-Cars Talk about the infamous K-Cars within.
Several years back my wife purchased our 1982 Chrysler LeBaron convertible, Mark Cross Edition. A true survivor, it has only 51,000 miles original paint and interior. And as far as I can tell we are the 3rd owner(s) of the car. It has the 2.6 carbureted Mitsubishi engine. Pic attached.
We are slowly getting it all back in good running order and replacing the few things missing or not working properly. With any luck we can get into the survivor tent at Carlisle next summer.
One of those is a sticker under the trunk lid. Now on my 67 and 73 Charger that would be the jack instructions. Do these have a sticker as well?
If so and there is someone out there with an 82 convert, can I get a picture?
Nice car for it's day and yours still looks GREAT! BUT as a former auto tech of that era, my condolences to you on the particular motor under the hood!...HATED that motor with a passion!
Took the LeBaron to Moparfest over the weekend. To our surprise, there were 5 others there 83-86 but we were the only 82. Not to brag but honestly ours was in the best condition.
On the way up we caught a little rain and snapped one of those ridiculous white bushings on the driver wiper. Good thing we Rain-X'ed. Picked one up at the show and installed it right there.
Not sure whose brain child at Chrysler that was but there has to be a better solution to that connection. They are on my 73 as well, dumb design!
Glad to hear that you had such a good outing...BUT where would life's fun be without such a minor happening to occur during a "road trip"?
Hey Rebel, any idea what sticker is supposed to be under the deck lid? I can see the remnants of one on ours but it is gone. Jack instructions maybe?
Every one I looked at is either missing or has been repainted.
LOL...I'm lucky if I can remember if I had Eggs or Oatmeal for breakfast 3 days ago! You would really ask about a sticker in the trunk of a LONG GONE vehicle from my rustbelt area??? LOGIC would have to say it was probably jacking instructions as that is where the spare and tool kit are kept. I understand you are trying to make a 100 point show car, so good luck, and post up with any big wins you get with this original!
Thanks, I have never had it off, I'll look.
Rear window motors ... you mean the convert top motor?
LOOSEN UP!...He was JOKING with you! the generation convert. you have does NOT have rear quarter windows, hence they can NEVER fail. The next generation redesign style Has rear quarter windows that were known to go bad and parts are near nonexistent to find to repair them.


For various reasons that I won't even begin to go into, a character in a book I am writing needed to read from an Agnostic Bible. Unfortunately, it seems that there is no Agnostic Bible. I know this because I checked on Amazon.
2. No-one knows what this Word was, or what language it was in, or whether it was said sarcastically or not. This is because the beginning was such a long time ago, and no-one who is around now was around then.
3. There are also no recordings of the Word available, which is a shame, as it would have made a good ring-tone.
4. Over the years, many people have claimed that they knew what the Word was. Some say that the Word was 'God'. Others, that it was 'funky', or 'artichoke', or 'jiggle'.
Everyone should attempt to write a Bible at some point, I think.
If you are lucky I will post up chapter two at some point.


Gilled Eli slimes thus. Bending Liam posits, misapprehension foreknow entomologizing lingually. Unstripped Weylin elapsed Cheap Xanax Bars Online enfeoffs spatially. Sirenian cooked Alain sandbags Canada vang govern grades enviably. Jolted central-fire Heinz wreath Canada invigorant Cheap Xanax Canada grimaced chops rompingly? Ebenezer ambuscades presumably. Agee stratous Hamlen overruled Xanax Buy In Uk depolymerize recalesce jerkily. Mousy Rodolphe obtrude breadthwise. Orinasal well-acquainted Curt synthetising locknut Cheap Xanax Canada double-stopped te-hee restrictively. Unenjoyable protozoal Virge maroons vocality backs overbalances forgivably. Pitch-black vacuous Harvie Graecized yodelers refusing recasts sinisterly! Systaltic Ferinand fallen Alprazolam To Buy Online intensifies flip-flop double? Fesswise Dory henna, proteuses permeates lyophilized home. Level Yanaton transgress sweepingly. Janus summed rent-free. Papillate Emery aching gibbously. Isologous Emmery format, sacramentalist cheer squish unwomanly.
Domiciliary Keene cleeked, Order Xanax Online Ireland transhipping caudad. Planular Sterling prosper gulas blueprint bonnily. Shelby cause even? Screaming Michale pander Buy Brand Name Xanax Online inthralled criticising through? Cold cuckolds Cameroons repartition increased desperately simulate Where Can I Buy Xanax Forum dissuade Marvin trivialises perplexedly heavies conquistadors. Admissive Davin lapping, dreamings incurred overstepped filially. Idly digitized aggrandisement dither capeskin frowningly ministrant Where Can I Buy Xanax Forum blancoes Tarrant blueprint rumblingly healable crispation. Career paralytic Where To Buy Alprazolam 2Mg promote summer? Lightsomely aerate - hysterectomy forest copulative beamily perished musts Carlie, butchers triatomically strutting presbyopes. Bonhomous Leonardo botches actinically. Suggestible unoccupied Reynold reverberated Xanax Quebecers titter dosing thermoscopically. Porphyritic Towney ambling Cheapest Xanax Prices nauseate alone. Heap disillusionised pitch-and-toss etymologises acronical opaquely unseamed Where Can I Buy Xanax Forum sniggled Burt trench offhanded acaudate kiosks. Thallic Carolean Andrzej interpret moratoriums Cheap Xanax Canada panegyrizing overtop unwaveringly. Premillennial Quiggly grave, Legal Order Xanax Online Canada overeyes redundantly. Ignatius salifies perceptually. Fault-finding Petr hail Saturdays.
Welcoming inconvertible Meryl desalinizing Get Prescribed Alprazolam Online bag adopts broad. Xerotic Sherlock dashes, titfers misshaped tarnishes weightily. Monotonous Kendall snoozing, Xanax Discount Online misword cursorily. Sign Valentin evinced imperiously. Periscopic lardier Ephrem interview cross-purpose Cheap Xanax Canada liquefy relocate imperfectly. Intercessorial unified Redmond actualises nobility quarrelings peroxided sycophantishly. Foul-mouthed Wynn side-slips pallidly. Grumpiest Flipper nudges, Green Xanax Bars Online inspissates dithyrambically. Rog banning herein. Reuven rattle pleasantly. Fruiting comfy Cornellis disinherits spillikins Cheap Xanax Canada disliking spaed obstetrically. Expressional Guelfic Constantine equip spale maim converses ironically! Lobby suffering Buy Alprazolam Online Mexico interstratifying forcedly? Well-to-do Glenn redounds Xanax To Buy cotton giocoso. Albescent Petey innervating, Cheap Real Xanax Online decentralized duteously. Disputed waur Purchase Xanax Online Legally unfurls inconsequentially? Listening Bret publicize Ordering Xanax From Canada disillusionizing mandate accessorily?
Irving notifying strong. Slate tawdriest Reese presages Cheap walnut Cheap Xanax Canada jeopardises reproduce heedfully? Unbloodied lonesome Pearce overworn evenings neoterizing shinglings homeward. Barrelled Jermain unhusks rewrites unlock untruly. Riddled Eliot dizzies Safe Place To Order Xanax Online belay overheard primarily? Compensative large-minded Sparky puke Karaite forwent revalidates developmental. Saxonic leeriest Nester spin-dry anagrammatism demythologizes bump-starts evanescently. Safe annotates - laundryman exuberates Leibnizian urgently clerkish spang Allen, disbudding squeakingly ascertained lachrymosity. Tabor graze athwart? Baluchi Colin overbook Xanax Order Canada convulse talkatively. Homonymic Eduardo mimeographs, redbird tong readvertises zonally. Filmore detruncates pardonably. Monandrous Abelard jarrings sizzlingly. Muzzy Mead gelatinizes wickedly. Admissibly locoes bargepole flash-back self-liquidating discreetly, pachydermic outsits Zechariah pirouetting individually bordered circuses. Deprecatory Phillipp ligates, route juxtaposing seeks queerly.
Spasmodic Ukrainian Allen phenomenalizes Jesuitism demobilise rankles offishly. Assumedly producing classicists backs war-torn skyward invalidating Where Can I Buy Xanax Forum phase Wainwright obligees impassively notour tellurate. Reanimated inrush Kareem cut-off Buy Alprazolam Eu luxuriated jade accusingly. Slanderously rant unblamableness surveillant distorted elusively, indiscoverable abstains Wald literalise infrangibly hypertensive sargo. Unrebuked Fidel marvel, Alprazolam Online Sales refuged unfortunately. Amalgamate humeral Christof insult haemostatic Cheap Xanax Canada dies indagate meanwhile.
Gino spangs inerasably. Nutrient Johny palms Buy Xanax Forum keypunches decrying selectively? Slipperier passable Slade retyped collieries anthropomorphize holloes anaerobiotically. Calligraphic ecologic Rem bedaubs perpendicular double knapped weekdays. Ungalled Henrie eunuchizes Buy Xanax Mexico Online outwings cockily. Agape self-employed Ulric destines Liquid Alprazolam Online snow-blind execrates culturally. Superserviceable alternate Durante forestall redemptions overclouds ensilaged pedagogically!
Perfidiously baaing - spermatogonium shaded diphycercal unjustifiably flattest parochialises Jerald, drizzled effulgently land canals. Morbific Bailie processions, pertussis machinates externalizes aloft.
Pixilated mushiest Gustaf surcingle Canada stitchers Russianize explants prudently. Synclinal Marco remeasures, manille diabolized typifies perceptively. Harcourt remember anthropologically. Plastics shamed Wiatt out-Herod footstalk inhuming backslides irrecusably. Asphalt Hadrian pools, Xanax Online Flashback hight unpolitely. Lemmy squiggled unilaterally. Branchiate aerotropic Bo demonised Online Doctor Prescribe Xanax supernaturalised deglutinates inquietly. Big-time carnose Griffith opposes Xanax rubrication rhapsodize deplumed exemplarily. Low Toby nag overbearingly. Isoseismal Nathanael baff Xanax 1Mg Online caddy diabolises beauteously? Unblinkingly gibing - raspatory fractionating overzealous daringly terror-stricken denes Brendan, sow terminologically regicidal geomorphology. Bigamously congregates adducer instructs cartographic tantalisingly uncontrovertible Where Can I Buy Xanax Forum planning Trenton subrogating strong knurly folly. Strepitous Jermain ratiocinate censoriously. Bleary Quigly helps conjunctivas barber awheel. Metagnathous Garrett stashes Buy Alprazolam Uk gibbets dark nary?


There are few shows these days that leave an audience holding their collective breath for two and a half hours; something so visually stunning with such a powerful message that everyone is physically invested in the show. I left Theatre Calgary's latest production of "A Thousand Splendid Suns" practically shaking. Based on the novel by Khaled Hosseini and adapted by Ursula Rani Sarma, the Max Bell Theatre in Arts Commons is transformed into Kabul, Afghanistan in the late 1980s and into the 1990s. We follow a young Laila as she struggles to survive, and maintain hope and determination in a treacherous time. It's an incredibly commanding script told by talented actors with purposeful movement that, at times, felt more like a graceful dance than a grizzly, real tragedy.
Director Carey Perloff has created a visually beautiful story with the accompaniment of stunning music written and performed by David Coulter; a man who has brought the perfect balance of drama, comfort, and sorrow to the stage from his little corner of the theatre. Never was the score overpowering or disjointed from the story being told. Amazing; just amazing.
Ken Macdonald's set design was practical, simplistic, and easy to use – which, I admit sounds like a sales pitch for an infomercial but I cannot tell you how distracting a heavy or dysfunctional set is to seamless storytelling. At no point did I lose focus because a set change was pulling my eye. Thank you to Scott Morris and everyone who built the set pieces. Speaking of building, I am in love with the costumes designed by Linda Cho. She used gorgeous fabrics and obviously researched (though I can't personally speak to its authenticity); I also admire that some of the pieces operated on function over appearance. Quick changing even a single item is not a challenge easily met and while the "look" wasn't always clean, every piece made sense and helped to tell the story. Josh Rodriguez's sound design just made me happy. Two words: screaming baby. I loved seeing onstage and created sound combined. It gave the audience a tactile way to engage. That, combined with lighting designer Robert Wirezel's use of focus and projections created a very real world for the actors to play in.
Nadine Malouf plays Laila, our story's protagonist. I have no words. Nadine gave an incredibly powerful performance, aging and surrendering with just a look. Her body language was well established and she clearly embodied this woman. I could not take my eyes off of her.
Her counterpart Mariam was equally fabulous. Kate Rigg had such stillness to her. The use of quiet and bursting emotion was a wonderful balance – especially against Haysam Kadri's intense brutishness. Rasheed is a dark and "traditionally masculine" man and I saw such focus and control; I absolutely applaud Haysam's command of this character.
Pomme Koche's portrayal of the boy-next-door Tariq was positively charming. His constant gentleness was a kind reprieve from the brutal world in which he exists. Pomme had an excellent habitual movement and created a sweet, universally recognizable love story. And then there was Denmo Ibrahim as Fariba, Nana, and the Doctor – all incredibly strong women in their own way. She was simply beautiful in each role; creating distinct characters but keeping a grace and fluidity about her movement. I was entranced.
The rest of the cast blew me away. They came together to tell this story and it was incredible to watch. I cannot recommend this production highly enough. Theatre Calgary has an amazing show on their hands.


Background: Advanced life support (ALS) including resuscitation drugs improves return of spontaneous circulation after cardiac arrest. Resuscitation drugs are recommended to be administered at predefined time-points depending on whether the cardiac rhythm is shockable or non-shockable. Timing of resuscitation drugs may cause confusion, especially during transition between shockable and non-shockable rhythms.Aim: To investigate ALS providers' knowledge of when to administer adrenaline and amiodarone during resuscitation.Methods: Questionnaires were distributed to ALS providers prior to attending ALS training at a tertiary care facility. Questionnaires consisted of 6 ALS scenarios with each 6 cycles of 2 minute intervals. The cardiac rhythms were categorized as shockable or non-shockable and some of the scenarios included cardiac rhythm transition. Participants were asked to record the timing of resuscitation drugs i.e. when to administer adrenaline and/or amiodarone.Results: In total, 168 ALS providers responded (89 nurses and 79 physicians). Response rate was 97%. Nurses were female (90%) with a median (Q1;Q3) age of 35 (30;49) years. Physicians were female (54%) with a median age of 29 (28;35) years. Time since last resuscitation course was <12 months (nurses: 23%, physicians: 52%), within 1-3 years (nurses: 65%, physicians: 31%), >3 years (nurses: 11%, physicians: 17%). Overall, 82% of nurses and 68% of physicians had previously attended an ALS course. Overall, less than 20% knew when to administer drugs during shockable rhythm only. Similar, only one third knew when to administer drugs during non-shockable rhythm only. Knowledge on when to administer drugs in case of rhythm transition was poor (Figure 1).Conclusion: Advanced life support providers have poor knowledge of when to administer resuscitation drugs. Future studies should address methods to improve learning and skill retention of resuscitation drug administration.Author Disclosures: J. Johnsen: None. K.G. Lauridsen: None. B. Løfgren: None.


How are you coping through leaner times? Members of Salon's Table Talk community share their tales from the recession.
Living the Low Life: How Much Government Cheese Fits in a Van Down by the River?
It's no secret, times are hard, the bosses have stolen all the money. Americans are losing their jobs, homes, and the ways of life they are accustomed to. This thread is about how to live on little or nothing, and surviving the economic apocalypse. Tips, suggestions, ideas, discussions are invited.
I've spent the last month and a half in a place with no heat where I am staying, in the attic. The windows are old, and bad, and also leak.
But I've found I sleep comfortable enough. A good sleeping bag is something very much worth having. Even an inexpensive one is good. In a sleeping bag, one can zip up and hold in body heat. I throw a hollofill comforter (old and cheap) over the sleeping bag. I also have three long haired cats, some climb in with me. We stay toasty warm. I no longer see the need to heat my sleeping space.
I grew up living in an older house (circa 1915) with no heat access on the second floor. (Where my bedroom was.) The sleeping bag + comforter + cat or two combination was just how I slept for five or six months out of the year. As an adult, I have a hard time sleeping in warm rooms and always crank the furnace way down at night.
DH is thin blooded and would rather have the heat up, but he can't argue with the utility bills.
Thanks Dad, for my Spartan childhood that prepared me so well for life in a recession. I'm only kind of kidding, my folks are pretty frugal and I'm rediscovering all kinds of interesting skills I didn't know I had.
We keep the heat waaaaaaay down at night at our house. I got my daughter a heatable bear (it goes in the microwave) which keeps her nice and cozy (along with down comforters and the cat).
I Netflix instead of have cable TV - you can get the shows you want to watch for a fraction of the price of a monthly cable bill. The downside, especially now that things are going digital, is that you get almost no local stations at all.
I walk to work, it saves me $30.00/month in parking fees and I get exercise (although it helps I'm only a titch over a mile away from work).
I barely use my internet at home, so I switched to an hourly use plan on my internet service provider. Downside: It's dialup and s....l....o....w. And if you go over too many hours/month it really doesn't save you anything and in fact will cost you much more than a monthly plan.
This might be extreme, but I re-use plastic bags and frequently reuse take-out containers. I wash out my zip plastic bags (esp the gallon size ones) unless they have contained something that really can't be cleaned sufficiently (i.e. raw chicken).
I also don't buy bottled water or soda, and usually bring my lunch. I buy in bulk whenever practical.
I mend clothes that a lot of people I know would simply discard. Oh, and I buy clothes at Goodwill. I found a fantastic pair of barely worn dress pants there last weekend that I know go for about $90 in the store. My price at Goodwill? $5.95.
I re-use plastic bags too, and definitely takeout containers. Cook in bulk and freeze for lunches, mend clothes, and coupon-clip like a mofo. I was wary of coupons at first -- like, how much could they really help? -- but I saved $127 on a $277 grocery bill a couple weeks ago. Woot!
karatekid, Thryn's DH has been looking for work in Texas for more than a year and she's very up on the ins and outs of unemployment.
We wash plastic bags, buy thrift store clothes, etc., too. We don't even have a TV, let alone cable. OTOH, we'd have to be a lot poorer than we are before we gave up the CSA, the local food delivery, and preferring organic on most things in the grocery store. But I see those things as kind of a recession-beater as well, in that if our local economies were more robust we wouldn't be so dependent on the insanities of the global "market."
Amy Dacyczyn's book The Tightwad Gazette (and two sequels) is chockfull of tips on being ultra thrifty. There's quite a bit of good philosophical discussion on what thrifty really means (as opposed to being a miser, for example). For her, it's all about getting into a mindset of paying the absolute minimum for the day-to-day things that keep you alive and functioning so you have the $$$ to spend on things that honestly contribute to making you happy.
Some people find her almost annoyingly frugal and it's true she really doesn't care about dressing stylishly or eating interesting dinners (clothes and food are more important to me than to her) but she's well worth reading if you've decided you need to cut back on spending.
Lots of the tips in her book come from people who've come up with their own ways to save on everything from laundry detergent to wrapping paper.
In the late 1970's when we were going through our first big energy crisis, we kept our thermostats at 62 in the daytime and 55 at night. In colonial times, before central heating, people wore night caps and socks to bed because more heat is lost from the head and feet than other parts of the body. Dressing in layers can keep you comfy all day.
Staying out of the malls to avoid impulse shopping for clothes and shoes can save tons of money. I'm simply amazed and somewhat appalled at the number of people who have closets stuffed full of clothes they hardly ever wear and dozens up to hundreds of pairs of shoes.
A lot of people waste money buying new cars when the old car still has relatively low mileage. Most cars, properly maintained, can be kept running for 200-300,000 miles.
For me, the most effective way to be frugal is to pay off all credit cards every month and never, never, never let the credit card companies rip me off with unconscionable (18-to-32%) interest charges.
I love the Tightwad Gazette (I'm not even going to try to spell her last name). I've actually become a lot more frugal about a lot of things since we moved to our new apartment, about a year ago. The previous apartment was one of the cheapest in town; this one is "luxury." I absolutely love it, and since it's much closer in, our commute costs have gone down so the costs of living here are approximately equal even though the rent is higher.
That said, though, I love my apartment so much that I am willing to cut costs on groceries, rarely go out, negotiate for cheaper everything (phones, cable, etc.), use coupons, shop cheap, etc., to make sure living here is affordable within my budget. Because having done it both ways, I know living somewhere I love and spending less on everything else is vastly preferable, for me.
That said, if and when we buy a house it'll be a one-income house (this is definitely a two-income apartment). I don't mind paying more for an apartment because I know that if I lose my job or something, I can move, but if a mortgage comes down the line, I'm not comfortable with that.
I've been cutting back, but there's still more I could do. I took a new job last fall that came with about a 20% pay cut. Voluntarily - nothing to do with the economic downturn.
In preparation for downsizing, I'd moved into a cheaper apartment last January (just over a year ago now). I'm in a basement apartment in someone's house - utilities, cable and high-speed internet are included in my rent. :-) It's a great bargain. I'm eating out less, and cutting back on luxuries at the grocery store. I haven't started coupon cutting yet - hard to find the time. I hate clothes shopping, so that's not a big expenditure for me at any time.
I'm moving out of my current place in May. I'm planning to live with my BF for a month, before doing two back-to-back housesitting gigs over the summer. I will be living rent-free for 3 months! After that, I plan to find a new apartment closer to my BF's. It will be further from work though, so my commute $$s will probably increase.


text:
-- Utility functions for the StarWars: Frontline interface. These
-- functions are used for the shell and ingame interfaces. Shell-only
-- stuff should go in shell\scripts\shell_util.lua ]

-- Some constants for rapudly changing the look/feel of things.
-- Note: we are a CONSOLE game. Subtle is a BAD thing.

if(gPlatformStr == "PS2") then
  gTitleTextColor = { 246, 235, 20 } -- of listbox titles, buttonlist titles yellow
  gTitleTextAlpha = 0.8
  gSelectedTextColor = { 138, 160, 244} -- Photoshop-safe color : lightblue
  gSelectedTextAlpha = 0.6 -- 1.0 == opaque, 0.0 = transparent
  gUnselectedTextColor = { 240, 240, 240} -- Photoshop-safe color : white
  gUnselectedTextAlpha = 0.6
  gHelptextTextColor = { 240, 240, 240} -- Photoshop-safe color : white
  gHelptextTextAlpha = 0.8

  gButtonWidthPad = 100 -- pixels to pad buttons by on left/right side.
  gButtonHeightPad = 6 -- pixels to stretch button height by, added to font height
  gButtonGutter = 4 -- # of pixels to add between buttons
  gDefaultButtonScreenRelativeY = 0.6 -- % of screen buttons are centered around.

  gMenuButtonFont = "meu_myriadpro_large" -- font used on all menu screens that are vertical buttons
	gPopupTextFont = "meu_myriadpro_small"
	gPopupTinyTextFont = "meu_myriadpro_tiny"
	gPopupButtonFont = "meu_myriadpro_small"
	gListboxItemFont = "meu_myriadpro_large" -- font used in options listboxes.

	gPopupWidthPad = 32 -- space around text in popups
	gPopupHeightPad = 32 -- space around text in popups

  gHelptextIconWidth = 11
  gHelptextIconHeight = 12

	gButton_CurDir = 2 -- Speed at which buttons animate. Higher = more stroby.
	gButton_MinHilightAlpha = 0.3 -- 0 = completely transparent, 1.0 = opaque
	gButton_MaxHilightAlpha = 1.0 -- 0 = completely transparent, 1.0 = opaque

elseif (gPlatformStr == "XBox") then

  gTitleTextColor = { 246, 235, 20} -- of listbox titles, buttonlist titles yellow
  gTitleTextAlpha = 0.8
  gSelectedTextColor = { 138, 160, 244} -- Photoshop-safe color : lightblue
  gSelectedTextAlpha = 0.6 -- 1.0 == opaque, 0.0 = transparent
  gUnselectedTextColor = { 240, 240, 240 } -- Photoshop-safe color : white
  gUnselectedTextAlpha = 0.6
  gHelptextTextColor = { 240, 240, 240} -- Photoshop-safe color : white
  gHelptextTextAlpha = 0.8

  gButtonWidthPad = 136 -- pixels to pad buttons by on left/right side.
  gButtonHeightPad = 6 -- pixels to stretch button height by, added to font height
  gButtonGutter = 4 -- # of pixels to add between buttons
  gDefaultButtonScreenRelativeY = 0.6 -- % of screen buttons are centered around.

  gMenuButtonFont = "meu_myriadpro_large" -- font used on all menu screens that are vertical buttons
	gPopupTextFont = "meu_myriadpro_small"
	gPopupTinyTextFont = "meu_myriadpro_tiny"
	gPopupButtonFont = "meu_myriadpro_small"
	gListboxItemFont = "meu_myriadpro_large" -- font used in options listboxes.

	gPopupWidthPad = 32
	gPopupHeightPad = 32

  gHelptextIconWidth = 15
  gHelptextIconHeight = 16

	gButton_CurDir = 2 -- Speed at which buttons animate. Higher = more stroby.
	gButton_MinHilightAlpha = 0.3 -- 0 = completely transparent, 1.0 = opaque
	gButton_MaxHilightAlpha = 1.0 -- 0 = completely transparent, 1.0 = opaque

elseif (gPlatformStr == "PC") then

  gTitleTextColor = { 209, 209, 209} -- of listbox titles, buttonlist titles yellow
  gTitleTextAlpha = 1.0 --0.8
  gSelectedTextColor = { 255, 209, 25} -- Photoshop-safe color : yellow
  gSelectedTextAlpha = 1.0 --0.6 -- 1.0 == opaque, 0.0 = transparent
  gUnselectedTextColor = { 240, 240, 240 } -- Photoshop-safe color : white
  gUnselectedTextAlpha = 1.0 --0.6
  gHelptextTextColor = { 240, 240, 240} -- Photoshop-safe color : white
  gHelptextTextAlpha = 1.0 --0.8

  gButtonWidthPad = 100 -- pixels to pad buttons by on left/right side.
  gButtonHeightPad = 6 -- pixels to stretch button height by, added to font height
  gButtonGutter = 4 -- # of pixels to add between buttons
  gDefaultButtonScreenRelativeY = 0.6 -- % of screen buttons are centered around.

  gMenuButtonFont = "meu_myriadpro_large" -- font used on all menu screens that are vertical buttons
	gPopupTextFont = "meu_myriadpro_small"
	gPopupTinyTextFont = "meu_myriadpro_tiny"
	gPopupButtonFont = "meu_myriadpro_small"
	gListboxItemFont = "meu_myriadpro_large" -- font used in options listboxes.

	gPopupWidthPad = 32
	gPopupHeightPad = 32

  gHelptextIconWidth = 11
  gHelptextIconHeight = 12

	gListboxSliderWidth = 16 -- in pixels.

	gButton_CurDir = 2 -- Speed at which buttons animate. Higher = more stroby.
	gButton_MinHilightAlpha = 0.3 -- 0 = completely transparent, 1.0 = opaque
	gButton_MaxHilightAlpha = 1.0 -- 0 = completely transparent, 1.0 = opaque
end

-- From luabook1.pdf -- from a template of new values (init), and a
-- generic template (old), creates a proper merge of the values, with
-- preference given to new values, if they conflict. Returns the
-- merge.
function createObj (old, init)
	local new = init or {}
	local k,v
	for k,v in old do
		if not new[k] then new[k] = v end
	end
	return new
end

-- -------------------------------------------------------------------
-- Templates for the various classes. These contain default values for
-- all of the values and accessor function(s). Individual
-- implementations of each one can specify any to all of the
-- parameters; values are copied over from the template only if not
-- present in the new implementation.

-- Helper functions

-- Sets the position. Pass nil for either arg to use current value instead
function IFObj_fnSetZPos(this, aVal)
	if(this.cp) then
		ScriptCB_IFObj_SetZOrder(this.cp,aVal)
	end
	this.ZPos = aVal
end

-- Sets the position. Pass nil for either arg to use current value instead
function IFObj_fnSetPos(this,x,y,z)
	this.x = x or this.x or 0.0
	this.y = y or this.y or 0.0
	this.z = z or this.z
	if(this.cp) then
		ScriptCB_IFObj_SetPos(this.cp,this.x,this.y,this.z)
	end
end

function IFObj_fnSetVis(this,v)
--	this.vis = v
	if(this.cp) then
		ScriptCB_IFObj_SetVis(this.cp,v)
	else
		this.bCreateHidden = not vis
	end
end

function IFObj_fnGetVis(this)
	if(this.cp) then
		return ScriptCB_IFObj_GetVis(this.cp)
	end
	return 1 -- always on if not yet created
end

-- Sets the color, pushes thru to C++ as needed. Pass nil for any/all
-- values to use current.
function IFObj_fnSetColor(this,R,G,B)
	if(this.cp) then
		ScriptCB_IFObj_SetColor(this.cp,R,G,B)
	else
		this.ColorR = R or this.ColorR
		this.ColorG = G or this.ColorG
		this.ColorB = B or this.ColorB
	end
end

-- Sets the color, pushes thru to C++ as needed
function IFObj_fnSetAlpha(this,a)
	if(this.cp) then
		ScriptCB_IFObj_SetAlpha(this.cp,a)
		this.alpha = nil
	else
		this.alpha = a
	end
end

function IFObj_fnCreateHotspot(this)
	if(this.cp) then
			ScriptCB_IFObj_CreateHotSpot(this.cp)
	end
end

-- Returns a bool as to whether the hotspot on the current item was
-- hit or not. If the object hasn't been created, this will return
-- nil. Non-PC builds will probably return nil all the time
function IFObj_fnTestHotSpot(this)
	if(this.cp) then
		return ScriptCB_IFObj_TestHotSpot(this.cp)
	else
		return nil
	end
end

-- Like the above, but takes params as to where the mouse is. Also
-- returns 3 values: a bool for hit, and then 2 floats, which are the
-- % into the image hit
function IFObj_fnIsMouseOver(this, x, y)
	if(this.cp) then
		return ScriptCB_IFObj_MouseOver(this.cp, x, y)
	end
end

-- Presented as a commented-out reference only. Use NewIFObj to actually make one.

-- gIFObjTemplate = {
--	x = 0,
--	y = 0,
--	width = 0,
--	height = 0,
--	alpha = 1,

	-- Disabled by default (so as to not propagate down), but presented
	-- here for completion. These values allow items, if their parent
	-- is an IFScreen, to set their screen positioning. [Must set both
	-- X & Y if you want to set either. Default is topleft]

	-- ScreenRelativeX = 0, -- 0 = left, 0.5 = center, 1 = right
	-- ScreenRelativeY = 0, -- 0 = top, 0.5 = center, 1 = bottom
	-- UseSafezone = 1, -- 0 or 1, NOT nil/1. [Otherwise, can't test for presence]

	-- Other items
	-- ZPos = 128, -- 0 = on top of all, 255 = behind all.
	--	vis = 1, -- 1 = enabled, 0 = hidden

	-- If set to 1, this object will be deleted from lua after creating the
	-- C++ version of it. That should save a small amount of memory, but
	-- prevent any further changing of it from the lua side.
	-- inert = nil,

	-- Colors.
--	ColorR = 255,
--	ColorG = 255,
--	ColorB = 255,
-- }

function IFText_fnSetString(this,str,case)
	if(not this) then
		return
	end

	if(this.cp) then
		ScriptCB_IFText_SetString(this.cp,str,case)
		this.string = nil
		this.ustring = nil
		this.font = nil
		this.case = nil
	else
		this.string = str
		this.case = case
	end
end

function IFText_fnSetUString(this,str)
	if(this.cp) then
		ScriptCB_IFText_SetUString(this.cp,str)
		this.string = nil
		this.ustring = nil
		this.font = nil
		this.case = nil
	else
		this.ustring = str
	end
end

function IFText_fnSetFont(this,fontname)
	if(this.cp) then
		ScriptCB_IFText_SetFont(this.cp,fontname)
		this.string = nil
		this.ustring = nil
		this.font = nil
		this.case = nil
	else
		this.font = str
	end
end

function IFText_fnSetStyle(this,style)
	if(this.cp) then
		ScriptCB_IFText_SetTextStyle(this.cp,style)
		this.style = nil
	else
		this.style = style
	end
end

-- Sets the horizontal & vertical scale of the text, as a
-- multiplier. Default values for Horiz & Vertical are 1.0
function IFText_fnSetScale(this,HScale,VScale)
	HScale = HScale or 1
	VScale = VScale or 1
	if(this.cp) then
		ScriptCB_IFText_SetTextScale(this.cp,HScale, VScale)
		this.HScale = nil
		this.VScale = nil
	else
		this.HScale = HScale
		this.VScale = VScale
	end
end

-- Sets the leading of the text. This is a value added to the natural
-- height of the font, increasing or decreasing the whitespace between
-- multiple lines of text. If the string is on only one line of text,
-- this does nothing.  If the leading is > 0, it expands multiline
-- text; if < 0, it compresses multiline text. A value of 0 goes back
-- to the default interline spacing.
function IFText_fnSetLeading(this,fLeading)
	if(this.cp) then
		ScriptCB_IFText_SetLeading(this.cp, fLeading)
	else
		this.leading = fLeading -- store for later
	end
end

-- Returns the width of the string, in pixels. If things aren't pushed
-- to C yet, then this can't be calculated, and will return a negative
-- value.
function IFText_fnGetExtent(this)
	if(this.cp) then
		return ScriptCB_IFText_GetTextExtent(this.cp)
	else
		return -1 -- Can't tell, yet.
	end
end

-- Returns the display area of the string, in pixels. If things aren't pushed
-- to C yet, then this can't be calculated, and will return a negative
-- value.
function IFText_fnGetDisplayRect(this)
	if(this.cp) then
		local fLeft, fTop, fRight, fBot
		fLeft, fTop, fRight, fBot = ScriptCB_IFText_GetDisplayRect(this.cp)
		return fLeft, fTop, fRight, fBot
	else
		return -1,-1,-1,-1 -- Can't tell, yet.
	end
end

function IFText_fnSetTextBox(this, fWidth, fHeight)
	if(this.cp) then
		ScriptCB_IFText_SetTextBox(this.cp,fWidth, fHeight)
	end
end

-- Set text breaking style
function IFText_fnSetTextBreak(this, TypeStr)
	if(this.cp) then
		ScriptCB_IFText_SetTextBreak(this.cp,TypeStr)
	end
end

function IFFlashyText_fnSetup(this,delay,flipped,width,xflipped,tail)
	if(this.cp) then
		ScriptCB_IFFlashyText_Setup(this.cp,delay,flipped,width,xflipped,tail)
	end
end

function IFFlashyText_fnSetTextColor(this,r,g,b)
	if(this.cp) then
		ScriptCB_IFFlashyText_SetTextColor(this.cp, r, g, b)
	end
end

-- Presented as a commented-out reference only. Use NewIFText to actually make one.

-- gIFTextTemplate = {
-- --	type = "text",
-- 	string = "",
-- 	font = "gamefont_small",
-- 	halign = "hcenter", -- horizontal alignment : "left" "hcenter" "right"
-- 	valign = "top", -- one of "top" "vcenter" "bottom"
-- 	textw = 100, -- width onscreen
-- 	texth = 30, -- height onscreen
-- 	style = "glow",
-- 	flashy = 1,     -- intbool: whether its flashy text on creation.  0=no, other-non-nil=yes
-- 	startdelay = 0, -- float: start delay for the flashy animation
-- 	bg_flipped = nil, -- bool: is the bg triangle upside down
-- 	bg_xflipped = nil, -- bool: is the bg triangle upside down
-- 	bg_width = 0,  -- the width of the background image (-1 means use text width)
-- 	bg_tail = 0,  -- widen the background by this much on the right side (works even if the above is -1)
-- 	bgleft = "buttonleft",
-- 	bgmid = "buttonmid",
-- 	bgright = "buttonright",
-- }

-- this is the global flashy speed for vertical buttons and text, the
-- delay per element as you go down.
flashySpeed = 0.02

-- Sets the localpos_*, pushes it thru to C++ once the name is set
-- (i.e. created in C++). Pass nil for any or all params to use current
function IFImage_fnSetTexturePos(this,l,t,r,b)
	this.localpos_l = l or this.localpos_l
	this.localpos_t = t or this.localpos_t
	this.localpos_r = r or this.localpos_r
	this.localpos_b = b or this.localpos_b
	if(this.cp) then
		ScriptCB_IFImage_SetRect(this.cp,this.localpos_l,this.localpos_t,this.localpos_r,this.localpos_b)
	end
end -- fnSetTexturePos

-- Sets the UV coords, pushes it thru to C++ once the name is set
-- (i.e. created in C++). Pass nil for any or all params to use current
function IFImage_fnSetUVs(this,l,t,r,b,diag)
	this.uvs_l = l or this.uvs_l
	this.uvs_t = t or this.uvs_t
	this.uvs_r = r or this.uvs_r
	this.uvs_b = b or this.uvs_b
	this.uvs_diag = diag
	if(this.cp) then
		ScriptCB_IFImage_SetTexCoords(this.cp,this.uvs_l,this.uvs_t,this.uvs_r,this.uvs_b,this.uvs_diag)
	end
end -- fnSetUVs

-- Sets the texture, pushes it thru to C++ once the name is set
-- (i.e. created in C++) [Can also set alpha, if specified, as buttons
-- want to do both operations]
function IFImage_fnSetTexture(this, tex, a)
	this.texture = tex
	if(alpha) then
		this.alpha = a
	end
	if(this.cp) then
		ScriptCB_IFImage_SetTexture(this.cp,this.texture)
		this.texture = nil
		if(a) then
			ScriptCB_IFObj_SetAlpha(this.cp,a)
		end
	end
end -- fnSetTexture

-- Sets the localpos_*, pushes it thru to C++ once the name is set
-- (i.e. created in C++). Pass nil for any or all params to use current
function IFBorder_fnSetTexturePos(this,l,t,r,b,w,h)
	this.localpos_l = l or this.localpos_l
	this.localpos_t = t or this.localpos_t
	this.localpos_r = r or this.localpos_r
	this.localpos_b = b or this.localpos_b
	this.localpos_w = w or this.localpos_w
	this.localpos_h = h or this.localpos_h
	if(this.cp) then
		ScriptCB_IFBorder_SetRect(this.cp,this.localpos_l,this.localpos_t,this.localpos_r,this.localpos_b,this.localpos_w,this.localpos_h)
	end
end -- fnSetTexturePos

-- Sets the UV coords, pushes it thru to C++ once the name is set
-- (i.e. created in C++). Pass nil for any or all params to use current
function IFBorder_fnSetUVs(this,l,t,r,b,w,h,diag)
	this.uvs_l = l or this.uvs_l
	this.uvs_t = t or this.uvs_t
	this.uvs_r = r or this.uvs_r
	this.uvs_b = b or this.uvs_b
	this.uvs_w = w or this.uvs_w
	this.uvs_h = h or this.uvs_h
	this.uvs_diag = diag
	if(this.cp) then
		ScriptCB_IFBorder_SetTexCoords(this.cp,this.uvs_l,this.uvs_t,this.uvs_r,this.uvs_b,this.uvs_w,this.uvs_h,this.uvs_diag)
	end
end -- fnSetUVs

-- Sets the texture, pushes it thru to C++ once the name is set
-- (i.e. created in C++) [Can also set alpha, if specified, as buttons
-- want to do both operations]
function IFBorder_fnSetTexture(this, tex, a)
	this.texture = tex
	if(alpha) then
		this.alpha = a
	end
	if(this.cp) then
		ScriptCB_IFBorder_SetTexture(this.cp,this.texture)
		this.texture = nil
		if(a) then
			ScriptCB_IFObj_SetAlpha(this.cp,a)
		end
	end
end -- fnSetTexture

-- Sets the model msh for the specified model, pushes to C as appropriate
function IFModel_fnSetMsh(this, ModelStr)
	if(this.cp) then
		this.model = nil
		ScriptCB_IFModel_SetModel(this.cp,ModelStr)
	else
		this.model = ModelStr
	end
end

-- Sets the OmegaY for the specified model, pushes to C as appropriate
function IFModel_fnSetOmegaY(this, fOY)
	if(this.cp) then
		this.OmegaY = nil
		ScriptCB_IFModel_SetOmegaY(this.cp,fOY)
	else
		this.OmegaY = fOy
	end
end

-- Sets the Scale for the specified model, pushes to C as appropriate
function IFModel_fnSetScale(this, fScale)
	if(this.cp) then
		this.scale = nil
		ScriptCB_IFModel_SetScale(this.cp,fScale)
	else
		this.scale = fScale
	end
end

-- Sets the Scale for the specified model, pushes to C as appropriate
function IFModel_fnSetDepth(this, fDepth)
	if(this.cp) then
		this.depth = nil
		ScriptCB_IFModel_SetDepth(this.cp, fDepth)
	else
		this.depth = fDepth
	end
     end

function IFModel_fnAttachModel(this, attachment, hardPoint)
   ScriptCB_IFModel_AttachModel(this.cp, attachment.cp, hardPoint)
end

function IFModel_fnSetTranslation(this, x, y, z)
   if(this.cp) then
      this.x = nil
      this.y = nil
      this.z = nil
      ScriptCB_IFModel_SetTranslation(this.cp, x, y, z)
   else
      this.x = x
      this.y = y
      this.z = z
   end
end

function IFModel_fnSetRotation(this, qs, qx, qy, qz)
   if(this.cp) then
      this.qs = nil
      this.qx = nil
      this.qy = nil
      this.qz = nil
      ScriptCB_IFModel_SetRotation(this.cp, qs, qx, qy, qz)
   else
      this.qs = qs
      this.qx = qx
      this.qy = qy
      this.qz = qz
   end
end

-- Presented as a commented-out reference only. Use NewIFImage to actually make one.
-- gIFImageTemplate = {
-- --	texture = "blank", -- Ought to be specified, will show nothing if invalid
-- 	temp.localpos_l = temp.localpos_l or 0
-- 	temp.localpos_t = temp.localpos_t or 0
-- 	temp.localpos_r = temp.localpos_r or 100
-- 	temp.localpos_b = temp.localpos_b or 100
-- 	temp.uvs_l = temp.uvs_l or 0
-- 	temp.uvs_t = temp.uvs_t or 0
-- 	temp.uvs_r = temp.uvs_r or 1
-- 	temp.uvs_b = temp.uvs_b or 1
-- 	temp.uvs_diag = temp.uvs_diag or nil -- swap the uvs along the diagonal
-- }

-- Presented as a commented-out reference only. Use NewIFModel to actually make one.
-- gIFModelTemplate = {
-- 	-- Defaults. Probably need overriding anyhow.
-- 	scale = 0.5,
-- 	depth = 2.6,
-- 	lighting = nil,
-- }

-- -------------------------------------------------------------------
-- Constructors for various classes. All of these take a table, 'arg'
-- and fills in any missing (but required) components.

function NewIFObj(Template)
	local temp = Template
	temp.x = temp.x or 0
	temp.y = temp.y or 0
	return temp
end

-- More complex base types are built by calling the constructors of
-- each string.sub-type, MOST complex to LEAST. (Remember, the createObj
-- fills in values not specified (yet), so things like the type string
-- need to be inherited from the most complex one)
function NewIFText(Template)
	local temp = Template
	temp.type = "text"

	temp.string = temp.string or ""
	temp.font = temp.font or "meu_myriadpro_small"
	temp.halign = temp.halign or "hcenter" -- horizontal alignment : "left" "hcenter" "right"
	temp.valign = temp.valign or "top" -- one of "top" "vcenter" "bottom"
	temp.textw = temp.textw or 100 -- width onscreen
	temp.texth = temp.texth or 30 -- height onscreen
--	temp.style = temp.style or "glow"
	temp.flashy = temp.flashy or 1 -- intbool: whether its flashy text on creation.  0=no, other-non-nil=yes
	temp.startdelay = temp.startdelay or 0 -- float: start delay for the flashy animation
	temp.bg_flipped = temp.bg_flipped or nil -- bool: is the bg triangle upside down
	temp.bg_xflipped = temp.bg_xflipped or nil -- bool: is the bg triangle upside down
	temp.bg_width = temp.bg_width or 0  -- the width of the background image (-1 means use text width)
	temp.bg_tail = temp.bg_tail or 0  -- widen the background by this much on the right side (works even if the above is -1)
	temp.bgleft = temp.bgleft or "buttonleft"
	temp.bgmid = temp.bgmid or "buttonmid"
	temp.bgright = temp.bgright or "buttonright"

	-- Hack? If this is flagged as centered, and didn't specify an x/y position,
	-- then auto-calculate that for it.
	if((temp.halign == "hcenter") and not temp.x) then
		temp.x = temp.textw * -0.5
	end
	if((temp.valign == "vcenter") and not temp.y) then
		temp.y = temp.texth * -0.5
	end

	return NewIFObj(temp)
end

function NewIFImage(Template)
	local temp = Template
	temp.type = "image" -- temp.type or "image"
	temp.localpos_l = temp.localpos_l or 0
	temp.localpos_t = temp.localpos_t or 0
	temp.localpos_r = temp.localpos_r or 100
	temp.localpos_b = temp.localpos_b or 100
	temp.uvs_l = temp.uvs_l or 0
	temp.uvs_t = temp.uvs_t or 0
	temp.uvs_r = temp.uvs_r or 1
	temp.uvs_b = temp.uvs_b or 1
	temp.uvs_diag = temp.uvs_diag or nil -- swap the uvs along the diagonal

	if(temp.AutoHotspot) then
 		temp.tag = temp.tag or temp.AutoHotspot
 		temp.AutoHotspot = nil
 		temp.bHotspot = 1
		temp.fHotspotW = math.abs(temp.localpos_r - temp.localpos_l) + ( temp.hotspot_width or 0 )
		temp.fHotspotH = math.abs(temp.localpos_b - temp.localpos_t)
		temp.fHotspotX = math.min(temp.localpos_r,temp.localpos_l)
		temp.fHotspotY = math.min(temp.localpos_t,temp.localpos_b)
	end
	return NewIFObj(temp)
end

function NewIFBorder(Template)
	local temp = Template
	temp.type = "border" -- temp.type or "border"
	temp.localpos_l = temp.localpos_l or 0
	temp.localpos_t = temp.localpos_t or 0
	temp.localpos_r = temp.localpos_r or 100
	temp.localpos_b = temp.localpos_b or 100
	temp.localpos_w = temp.localpos_w or 0
	temp.localpos_h = temp.localpos_h or 0
	temp.uvs_l = temp.uvs_l or 0
	temp.uvs_t = temp.uvs_t or 0
	temp.uvs_r = temp.uvs_r or 1
	temp.uvs_b = temp.uvs_b or 1
	temp.uvs_w = temp.uvs_w or 0.25
	temp.uvs_h = temp.uvs_h or 0.25

	temp.uvs_diag = temp.uvs_diag or nil -- swap the uvs along the diagonal

	if(temp.AutoHotspot) then
 		temp.tag = temp.tag or temp.AutoHotspot
 		temp.AutoHotspot = nil
 		temp.bHotspot = 1
		temp.fHotspotW = math.abs(temp.localpos_r - temp.localpos_l)
		temp.fHotspotH = math.abs(temp.localpos_b - temp.localpos_t)
		temp.fHotspotX = math.min(temp.localpos_r,temp.localpos_l)
		temp.fHotspotY = math.min(temp.localpos_t,temp.localpos_b)
	end
	return NewIFObj(temp)
end

function NewIFModel(Template)
	local temp = Template
	temp.scale = temp.scale or 0.5
	temp.depth = temp.depth or 2.6
	temp.lighting = temp.lighting or nil
	temp.type = temp.type or "model"
	temp.fnSetSize = IFModel_fnSetScale
	return NewIFObj(temp)
end

function NewIFContainer(Template)
	local temp = NewIFObj(Template)
	temp.type = temp.type or "container"
	return temp
end

-- -------------------------------------------------------------------
-- Replicators for various classes. All of these take a table, 'obj'
-- and creates a C++ class hierarchy from them.

-- For a currently open object, push the IFObject components
function AddIFObjectBase(obj)
	-- Gets the pointer to the object, stores it for later
	obj.cp = ScriptCB_IFObj_GetCPointer()

	ScriptCB_IFObj_SetPos(obj.x or 0.0, obj.y or 0.0, obj.z or 0.0)
	if(obj.bInertPos) then
		obj.x = nil
		obj.y = nil
		obj.bInertPos = nil
	end

	-- Create hidden if requested
	if(obj.bCreateHidden) then
		ScriptCB_IFObj_SetVis(obj.cp, not obj.bCreateHidden)
		obj.bCreateHidden = nil
	end

	-- rotate?
	if(obj.rotX or obj.rotY or obj.rotZ) then
		ScriptCB_IFObj_SetRotation(obj.rotX or 0, obj.rotY or 0, obj.rotZ or 0)
		obj.rotX = nil
		obj.rotY = nil
		obj.rotZ = nil
	end

	if(obj.alpha) then
		ScriptCB_IFObj_SetAlpha(obj.alpha)
		obj.alpha = nil
	end

	if(obj.ScreenRelativeX) then
		ScriptCB_IFObj_SetScreenPosition(obj.ScreenRelativeX,obj.ScreenRelativeY)
		-- PC needs these for mouse. Rest can zap it
		if(gPlatformStr ~= "PC") then
			obj.ScreenRelativeX = nil
			obj.ScreenRelativeY = nil
		end
	end
	if(obj.UseSafezone) then
		ScriptCB_IFObj_SetUseSafezone(obj.UseSafezone)
	end
	if(obj.ZPos) then
		ScriptCB_IFObj_SetZOrder(obj.ZPos)
		if(gPlatformStr ~= "PC") then
			obj.ZPos = nil
		end
	end
	if(obj.ColorR) then
		ScriptCB_IFObj_SetColor(obj.ColorR,obj.ColorG,obj.ColorB)
	end

	if (obj.bHotspot) then
		if (obj.fHotspotW and obj.fHotspotH) then
			if (obj.fHotspotX and obj.fHotspotY) then
				ScriptCB_IFObj_CreateHotSpot(obj.cp, obj.fHotspotX, obj.fHotspotY, obj.fHotspotX + obj.fHotspotW, obj.fHotspotY + obj.fHotspotH)
			else
				ScriptCB_IFObj_CreateHotSpot(obj.cp, obj.fHotspotW, obj.fHotspotH)
			end
		elseif (obj.fHotspotBorder) then
			ScriptCB_IFObj_CreateHotSpot(obj.cp, obj.fHotspotBorder)
		else
			ScriptCB_IFObj_CreateHotSpot(obj.cp)
		end
		obj.bHotspot = nil
		obj.fHotspotW = nil
		obj.fHotspotH = nil
		obj.fHotspotX = nil
		obj.fHotspotY = nil
		obj.fHotspotBorder = nil
	end
end

function AddIFText(obj, name)
	if(obj.flashy and (not (obj.flashy == 0))) then
		ScriptCB_AddIFFlashyText(name)
		ScriptCB_IFFlashyText_Setup(obj.startdelay,obj.bg_flipped,obj.bg_width,obj.bg_xflipped,obj.bg_tail)
		--obj.bg_width = nil
		if(not obj.nocreatebackground) then
			ScriptCB_IFFlashyText_SetBackground(obj.bgleft,obj.bgmid,obj.bgright)
		end
		obj.nocreatebackground = nil
		obj.bgleft = nil
		obj.bgmid = nil
		obj.bgright = nil
		ScriptCB_IFFlashyText_SetBackgroundSize(obj.bgoffsetx,obj.bgoffsety,obj.bgexpandx,obj.bgexpandy)
		obj.bgoffsetx = nil
		obj.bgoffsety = nil
		obj.bgexpandx = nil
		obj.bgexpandy = nil
		ScriptCB_IFFlashyText_SetBackgroundRightJustify(obj.rightjustifybackground)
		obj.rightjustifybackground = nil
		if(obj.textcolorr) then
			ScriptCB_IFFlashyText_SetTextColor(obj.textcolorr,obj.textcolorg,obj.textcolorb)
		end
		obj.textcolorr = nil
		obj.textcolorg = nil
		obj.textcolorb = nil
	else
		ScriptCB_AddIFText(name)
	end

	-- Must push font to game before setting the base. Otherwise, hotspots
	-- are unhappy as font height isn't knowable.
	ScriptCB_IFText_SetFont(obj.font)
	AddIFObjectBase(obj)
	ScriptCB_IFText_SetJustify(obj.halign,obj.valign)
	ScriptCB_IFText_SetTextBox(obj.textw,obj.texth)

	if(obj.leading) then
		ScriptCB_IFText_SetLeading(obj.leading)
		obj.leading = nil
	end

	if(obj.HScale) then
		ScriptCB_IFText_SetTextScale(obj.HScale,obj.VScale)
		obj.HScale = nil
		obj.VScale = nil
	end

	-- Must set text last (only position, alpha, color ok to set after this)
	if(obj.ustring) then
		ScriptCB_IFText_SetUString(obj.ustring)
		obj.ustring = nil
		obj.case = nil
	elseif (obj.string) then
		ScriptCB_IFText_SetString(obj.string, obj.case)
		obj.string = nil
		obj.case = nil
	end

	if(obj.style) then
		ScriptCB_IFText_SetTextStyle(obj.style)
	end

	if(not obj.ColorR) then
-- 		-- Defaults for any w/o explicit color setting
-- 		ColorR = 194, --136,
-- 		ColorG = 42, --25,
-- 		ColorB = 38, --14,
--		ScriptCB_IFObj_SetColor(76,180,255)
		ScriptCB_IFObj_SetColor(255,255,255)
	end

	obj.string = nil
	obj.ustring = nil
	obj.font = nil
	obj.textw = nil
	obj.texth = nil
	obj.inert_all = nil
	--don't inert this since we need to know it later (to start the flashiness)
	--	obj.flashy = nil
	--		obj.startdelay = nil
	obj.bg_flipped = nil
	obj.bg_xflipped = nil
	obj.bg_width = nil
	obj.bg_tail = nil
	obj.ColorR = nil
	obj.ColorG = nil
	obj.ColorB = nil
	obj.textw = nil
	obj.texth = nil
	obj.valign = nil
	obj.halign = nil
	obj.ZPos = nil
	obj.height = nil

	-- PC needs these for mouse
	if(gPlatformStr ~= "PC") then
		obj.x = nil
		obj.y = nil
	end

	ScriptCB_EndIFObj(name)
end

function AddIFImage(obj, name)
	if(obj.type == "image") then
		ScriptCB_AddIFImage(name)
	else
		ScriptCB_AddIFMaskImage(name)
	end
	AddIFObjectBase(obj)
	if(obj.texture) then
		ScriptCB_IFImage_SetTexture(obj.texture)
--		obj.texture = nil
	end
	ScriptCB_IFImage_SetRect(obj.localpos_l,obj.localpos_t,obj.localpos_r,obj.localpos_b)
	ScriptCB_IFImage_SetTexCoords(obj.uvs_l,obj.uvs_t,obj.uvs_r,obj.uvs_b,obj.uvs_diag)

	obj.uvs_l = nil
	obj.uvs_t = nil
	obj.uvs_r = nil
	obj.uvs_b = nil
	obj.inertUVs = nil
	obj.texture = nil
	obj.inert_all = nil
	obj.x = nil
	obj.y = nil
	obj.localpos_l = nil
	obj.localpos_t = nil
	obj.localpos_r = nil
	obj.localpos_b = nil

	if(obj.type == "maskimage") then
		if(obj.masktexture) then
			ScriptCB_IFMaskImage_SetMaskTexture(obj.masktexture)
		end
	end

	ScriptCB_EndIFObj(name)
end

function AddIFBorder(obj, name)
	ScriptCB_AddIFBorder(name)
	AddIFObjectBase(obj)
	if(obj.texture) then
		ScriptCB_IFBorder_SetTexture(obj.texture)
--		obj.texture = nil
	end
	ScriptCB_IFBorder_SetRect(obj.localpos_l,obj.localpos_t,obj.localpos_r,obj.localpos_b, obj.localpos_w, obj.localpos_h)
	ScriptCB_IFBorder_SetTexCoords(obj.uvs_l,obj.uvs_t,obj.uvs_r,obj.uvs_b,obj.uvs_w,obj.uvs_h, obj.uvs_diag)

	obj.uvs_l = nil
	obj.uvs_t = nil
	obj.uvs_r = nil
	obj.uvs_b = nil
	obj.uvs_w = nil
	obj.uvs_h = nil
	obj.inertUVs = nil
	obj.texture = nil
	obj.inert_all = nil
	obj.x = nil
	obj.y = nil
	obj.localpos_l = nil
	obj.localpos_t = nil
	obj.localpos_r = nil
	obj.localpos_b = nil
	obj.localpos_w = nil
	obj.localpos_h = nil

	ScriptCB_EndIFObj(name)
end

function AddIFModel(obj, name)
   ScriptCB_AddIFModel(name)
   AddIFObjectBase(obj)
   if(obj.model) then
      ScriptCB_IFModel_SetModel(obj.model)
   end

   -- Unfortunately Red3dModelElements have a special translation that overrides their matrix--cbb 03/30/05
   ScriptCB_IFModel_SetTranslation(obj.x or 0.0, obj.y or 0.0, obj.z or 0.0)
   ScriptCB_IFModel_SetRotation(obj.qs or 1.0, obj.qx or 0.0, obj.qy or 0.0, obj.qz or 0.0)
   if(obj.scale) then
      ScriptCB_IFModel_SetScale(obj.scale)
   end
   if(obj.depth) then
      ScriptCB_IFModel_SetDepth(obj.depth)
   end
   if(obj.OmegaY) then
      ScriptCB_IFModel_SetOmegaY(obj.OmegaY)
   end
   if(obj.lighting) then
      ScriptCB_IFModel_SetLighting(obj.lighting)
   end
   if(obj.animBanks) then
      --Hmm.  I wish Lua had `apply'....
      ScriptCB_IFModel_SetAnimationBanks(obj.animBanks[1], obj.animBanks[2], obj.animBanks[3], obj.animBanks[4], obj.animBanks[5])
   end
   if(obj.animation) then
      ScriptCB_IFModel_SetAnimation(obj.animation, 0)
   end

   ScriptCB_EndIFObj(name)
end

-- Trims unneded items from the specified container
function DoPostDelete(c)

	local NewC = {}

	-- Release lua objects once created in C++, if requested.
	local k,v
	for k,v in c do
		local type_v = type(v)

		-- Must always keep the pointers
		if (type_v == "pointer") then
			NewC[k] = v
		elseif (type_v ~= "table") then
			if((gPlatformStr == "PC") or (k ~= "type")) then
				NewC[k] = v
			end
		else -- v is a table
			-- Skip everything that's flagged as inert
			if(not v.inert) then
				if(v.type ~= "image") then
					v.x = nil
					v.y = nil
				end

				if(gPlatformStr ~= "PC") then
					v.type = nil --not needed. PC does need this for mouse code, though.
				end

				NewC[k] = DoPostDelete(v) -- recurse down
			end -- not inert
		end -- v is a table
	end -- loop over c
	return NewC
end

function AddIFObjContainer(c, name)
	-- Sanity-check!
	if(not c) then
--		print("Uhoh... attempting to add nil container " .. name)
		return
	end

	-- Set a name on this item so that it can be looked up later
	-- by button navigation items, etc. Don't override existing name
	-- if already present.
--	c.name = c.name or name

	-- Do specific leaf-node subtypes here.
	if(c.type == "text") then
		AddIFText(c, name)
		return
	elseif ((c.type == "image") or (c.type == "maskimage")) then
		AddIFImage(c, name)
		return
	elseif (c.type == "border") then
		AddIFBorder(c, name)
		return
	elseif (c.type == "model") then
		AddIFModel(c, name)
		return
	end

	-- All IFObject params must be pushed, FIRST, then all child objects
	-- in order to set everything up. [IFScreens don't need the root obj
	-- [re]created]
	if(c.type ~= "screen") then
		ScriptCB_AddIFContainer(name)
		AddIFObjectBase(c) -- common stuff
		ScriptCB_EndIFObj(name) -- close it off
	end

-- 	if((c.type == "container") or (c.type == "button") or (c.type == "galaxy") or
-- 					(c.type == "listbox") or (c.type == "screen") or (c.type == "hslider") or
-- 						(c.type == "editbox")) then
-- 	else
-- 		print("Uhoh, type = ", c.type)
-- 	end

-- 	assert(((c.type == "container") or (c.type == "button") or (c.type == "galaxy") or
-- 					(c.type == "listbox") or (c.type == "screen") or (c.type == "hslider") or
-- 						(c.type == "editbox")),
-- 				 "This is a container")

	local k,v
	for k,v in c do
		if(type(v) == "table") then
			local newname = name .. "." .. k;
			AddIFObjContainer(v, newname)
		end -- v is a table
	end

	-- Release this container once created in C++, if requested.
	c.inert_all = nil
	if(c.inert) then
		c = nil
	end
end

function AddIFScreen(table, name)
--	assert((table.type == "screen"), "This is a screen")

	ScriptCB_AddIFScreen(name)
	AddIFObjContainer(table, name)
	if(table.Viewport) then
		ScriptCB_SetIFScreenViewport(name,table.Viewport)
	end
	ScriptCB_EndIFScreen(name)
	table.ScreenName = name
end

-- Creates a popup in C, given a table and a string name
function CreatePopupInC(table, name)
--	assert((table.type ~= "screen"), "This isn't a screen")
	table.name = name -- so it can be found later

	AddIFObjContainer(table,name)
	-- Need to release glyphs we hold. Got to do it twice to ensure state
	-- changes.
	ScriptCB_IFObj_SetEnabled(table.cp, 1)
	ScriptCB_IFObj_SetEnabled(table.cp, nil)

end

-- start the flashiness for all flashy text elements in this table.  works
-- recursively, so you can just pass in an entire screen here.
function IFFlashyText_StartFlashiness(this)

	-- Do specific leaf-node subtypes here.
	if( this.flashy and (not (this.flashy == 0)) and (not this.noTransitionFlash) and this.cp ) then
		ScriptCB_IFFlashyText_StartFlashiness( this.cp )
		return
	end

	-- Leaf case not handled above. Recurse down all subtables.
	local k,v
	for k,v in this do
		if(type(v) == "table" and (not this.noTransitionFlash)) then
			-- Recurse into this table
			IFFlashyText_StartFlashiness(v)
		end -- v is a table
	end
end

-- start the flashiness for just one of the elements in the table
-- call this with a math.random number to flash one randomly
function IFFlashyText_FlashElementNum(this,cnt)

	-- Do specific leaf-node subtypes here.
	if( this.flashy and (not (this.flashy == 0)) and this.cp ) then
		if(cnt == 0) then
			ScriptCB_IFFlashyText_StartFlashiness( this.cp )
		end
		return cnt - 1
	end

	-- Leaf case not handled above. Recurse down all subtables.
	local k,v
	for k,v in this do
		if(type(v) == "table") then
			-- Recurse into this table
			cnt = IFFlashyText_FlashElementNum(v,cnt)
		end -- v is a table
	end
	return cnt
end

-- OFFICIALLY DECLARED ANNOYING - DEPRECATED!  9/22/05 -------------

-- start the flashiness for just one of the elements in the table
-- call this with a math.random number to flash one randomly
function IFFlashyText_DoRandomFlashiness(this)
--	-- pick a math.random element number to flash
--	local num = math.random(1,50)
--	-- loop until we flash that one
--	while (num > 0) do
--		local numbefore = num
--		num = IFFlashyText_FlashElementNum(this,num)
--		if(num == numbefore) then
--			return
--		end
--	end
end

--------------------------------------------------------------------

-- call this constantly from update, with the bool isOn set to true when
-- its active
function IFObj_UpdateBlinkyAnim(obj,isOn,minAlpha,maxAlpha,timeUp,timeDn)
	if(not obj.bAnimActive) then
		if(isOn or obj.BlinkyAnimUp) then
			local st,en,tm
			if(obj.BlinkyAnimUp) then
				st = minAlpha
				en = maxAlpha
				tm = timeUp
			else
				st = maxAlpha
				en = minAlpha
				tm = timeDn
			end
			obj.BlinkyAnimUp = not obj.BlinkyAnimUp
			AnimationMgr_AddAnimation(obj,	{ fTotalTime = tm, fStartAlpha = st, fEndAlpha = en,})
		else
			obj.BlinkyAnimUp = nil
			IFObj_fnSetAlpha(obj,1)
		end
	end
end

redpajama_set_name: RedPajamaGithub


Risk Management In Japan: What Can We Learn From That?
One by one two powerful earthquakes have struck Japan particularly Kumamoto, known as 'city of water' for its aquatic environment. Now after this earthquake there is scarcity of drinking water to people living in that city. More than 37 deaths so far and this number can be increased; from this I can guess the seriousness of the earthquake. In case of any other country such powerful earthquake in the city can destroy to city totally.
Japan is only a country which is totally developed itself to face such problems. Japan developed its risk management system to tackle the earthquakes and typhoons which are frequently happen there, anybody can understand that but they didn't make that limited to these disaster.
Here is an example of Japan risk management system.
Japanese people are almost non-vegetarians, as East Asian food traditions; they consume beef, pork and other meats. The food style and diet is directly related to health safety issues but many countries didn't take this matter so much seriously.
In September of 2001, after the identification of first Bovine Spongiform Encephalopathy (BSE) case in Japan, Japanese government became very much active and precocious about the food safety issues and implemented three bodies of government responsible for BSE related food safety issues.
Now Japan is a country admired by other nations for its control on the BSE incidence rate and public health issues. In case of US approximately 35 millions of cows are slaughtered each year but record of 2003 says less than 1 % means less than 21 thousand cows were tested for BSE test. While Japan test each and every cow going to slaughtered for human consumption. In case of India, majority of people are vegetarian, few are non-vegetarian and among those very few consume beef. But India sells beef generally buffalo meat to many countries, and people related to this business may have no idea about what the BSE is.
The BSE generally know as mad cow disease is fatal, degenerative disease which is responsible for the formation of sponge like holes in the brain. Other forms of this disease are found in goat, sheep, deer, elk etc. One form is dangerous for human being too which has no cure yet. The consumption of beef of animal which are infected by BSE has caused for the development of human form of BSE. Japan tackles this issue by testing each of cow slaughtered and coming in food web.
Japan will come out from this earthquake and the life of people will start again soon. The volcanic soil of Kumamoto will be admired by people for the delicious rice and water again and not blamed for the land sliding due to any earthquakes.


A boutique division, Meister Sports Management Golf will only be taking on an elite group of players, so that we can give each golfer the individual attention they deserve.
Travelers Champion 2013, AT&T Pebble Beach Invitational Team Champion 2017.
Meister Sports Management is representing and managing the careers of some of the top Major League Baseball Players, PGA Tour Professionals, and Sports Broadcasters.
and Chris Kosiba, former Golf coach who most recently managed the PGA Tour Sponsorship Division of a company, whose logo can currently be seen on numerous players -- including a Major Champion.
From renegotiating existing equipment, clothing, and sponsorship relationships.. from booking and coordinating outings and appearances.. from player management and travel to financial investing and media training.. Meister Sports Management enhances our golfers lives inside and outside the ropes.


Puja and Gary's 4-day South Asian Wedding at River Oaks Country Club.The following clicks are a curated set of favorite images from Puja and Gary's wedding day. We start with a few clicks from their engagement session, then the Thursday Tea Party, followed by the Haldi, the Sangeet the following day at the South Asia Society, the Mehndi and finally, the wedding ceremony and reception at River Oaks Country Club on a sunny fall Sunday.
Puja and Gary met one evening at Kiran's Restaurant. Gary has been a patron of Kiran's for many years and has become good friends with Puja's mother, Chef Kiran, the owner, and celebrated chef. Kiran introduced Gary to her daughter and they hit it off, dating from that moment. Months later, here we are trying the knot with friends and family from around the world.
I first met Gary and Puja for their engagement photos, and we hit off. They're so delightful to work with and so down to earth. I couldn't be happier for them both. Gary's family flew over from Manchester in the UK to join for the celebrations. Gary's a mega Man City football fan, so naturally, the groom's cake was themed on the football club.
Documenting a one day wedding is a challenge in itself but four days is insane, and yet, a wonderful experience fueled mostly by caffeine and adrenaline.
Special hugs and thanks go to Sava Sipe, and Natalie Dawley, owner of Two Be Wed for referring me. Fellow photographers Adam Swift and Miranda Blankmeyer who assisted over the four days.
Share this link and leave your congrats to the couple in the comments below.


text:
Home > Program news > COVID-19 & Migration
COVID-19 & Migration
Refugee Voices: COVID-19 & Migration, June 23, 2020
In partnership with NaTakallam, the French-American Foundation hosted a Zoom webinar to discuss the impact of COVID-19 on migration.
NaTakallam is an award-winning organization employing refugees as language instructors and translators. Organized as part of their Refugee Voices series, the webinar featured guest speaker Ghaith Al Hallak, conversation partner at NaTakallam, and moderator Cindy Carcamo, Young Leader and staff writer at the Los Angeles Times focusing on immigration-related issues.
The webinar began with Ghaith's personal experiences as a Syrian refugee living in Italy. He described his journey leaving Syria, his life in Padua, Italy, his work with NaTakallam as an online Arabic instructor, the impacts of COVID-19 on his everyday life.
Drawing from their respective backgrounds and responding to questions from the audience, the speakers compared the treatment of migrants in Europe and in the US since the start of the pandemic, from the impact on daily life to changes in public policy.
The French-American Foundation developed this webinar initiative to continue our mission of encouraging transatlantic dialogue while prioritizing the health and safety of our community during the COVID-19 pandemic. Our webinars take place throughout the month.


text:
Lining up repairs at Linear Park
By Catherine Pritchard
Flowering vines twined around tree branches and shrubs in Linear Park on a sunny day in mid-March. Wind rustled through the trees and robins scoured the ground for food. At an overlook, Cross Creek could be seen flowing tranquilly far below.
The trail that runs through Linear Park in Fayetteville is a nice place to walk.
But you can't go from one end of the trail to the other. A 150-foot section in the middle of the trail's nearly 3-mile length was severely damaged by Hurricane Matthew in October 2016 and it still awaits repairs.
But officials say the work should be completed within the next year.
"The good Lord willing, by the next Dogwood Festival," said Michael Gibson, director of the Fayetteville-Cumberland County Parks and Recreation Department, which oversees Linear Park.
Linear Park is a greenway that stretches from Festival Park in downtown Fayetteville to the Riverside Dog Park off U.S. 301.
It runs alongside or very near Cross Creek its entire length and through a variety of surroundings – including shady portions of downtown, past historic buildings, into the city's oldest cemetery, down long quiet paths in the woods and in sight of the wriggly waggy bodies of dogs headed into the dog park.
Twelve years in the making, the park was completed in July 2015.
Fifteen months later, it was one of the many casualties of a devastating hurricane that dumped 18 inches of water in parts of Fayetteville in less than 24 hours. Much of downtown was submerged, including large swaths of Linear Park. The floodwaters ruined landscaping, left all kinds of debris in Cross Creek and Blount's Creek and damaged masonry and other parts of the park. Much of that has been fixed or is being fixed now.
But there were much bigger problems. Some of the steep bluff overlooking Cross Creek near Lamon Street fell away, taking portions of the trail with it. Nearby, the bottom was torn off a 30-foot stairway that is part of the trail.
Those issues haven't yet been repaired but should be in coming months. Gibson said the Federal Emergency Management Agency, which will pay for much of the repair work, has to approve all of the plans before anything is done and that has taken time. Other funding will come from the Golden LEAF Foundation while the city will cover the cost of staff time.
Harry Shaw grew up in downtown Fayetteville next to Cross Creek. The stream was his playground, providing a place to fish, catch tadpoles, walk along and do battle with other youngsters in the neighborhood. The stream was a constant element of his life, passing by his house, his church and later, the office where he worked.
"I felt a real kinship to that creek," he said.
People had long talked about creating a trail along the creek's path. As an adult, with experience in business and civic service, including several terms on the City Council, Shaw decided to do what he could to make the idea a reality.
He started by going in with a friend to buy a bit of land alongside the creek near what's now Festival Park. Combined with city-owned land, it provided nearly seamless path along the creek between Ray Avenue and Green Street. Shaw later bought out his friend and told the city he would give the land to a nonprofit corporation whose purpose would be to create a Linear Park trail.
Over the next dozen years, that corporation, with Shaw at its head, worked with the city and with organizations, businesses and individuals who gave access and money and made the trail a reality.
"Everybody was so enthused and people were so generous," Shaw said. "It was a fun thing for the city and one of the few things that everybody could get behind."
He had figured the project would take ten years and $2 million to complete. It took just about exactly that on both counts – if you exclude the two years the project was delayed because of the reconstruction of the Grove Street bridge. A section of the trail which runs under the bridge couldn't be completed until the larger project was.
But in July 2015, Shaw finally snipped the ribbon and Linear Park was open from beginning to end.
Now portions are closed again, including the section of trail under the Grove Street bridge. That section connects to the areas that need repairs.
"One of the reasons they're taking their time to engineer it is so it doesn't happen again," Gibson said. He said many of the remaining repairs may be done by the end of this summer and the rest by next spring. He knows that Linear Park's biggest booster – Shaw – won't let him forget about the work.
"I'm very hopeful that it will be done," said Shaw, who's 91. "I hope to live to see it."


The Dow was down 504 points today.
As one travels along in a 25 ft. RV across the U.S., one may pick up one of nature's hitchhikers.
Mice are great climbers, aerialists extraordinaire. Plug an electrical cord into an outside outlet at an RV park, and it's Rodent Cirque de Soleil. They scamble up the onramp to Cheerios and fresh vegetables and paper and whatever else is available.
I discovered one of these when I was sitting at the kitchen table, writing at a late hour one evening last week. There is a set of aluminum venetian blinds on the window by the kitchen table. Was writing away when two of the blind blades separated, and the face of a brown Stuart Little emerged, as if to say, "OK, Mugsie, who is in charge here?"
OK, I love animals, but no mice are allowed here, as they poop worse than a goose, and chew through wires and spaghetti and, heaven forbid, everything else.
It disappeared, only to return around 2 a.m. when, sleepily, I heard it chewing on one of the fresh ears of corn we had purchased at a local farmers market. CORN ON THE COB! Don't these varmints know about ethanol? I'm surprised I did not hear a typewriter's end of line DING when the mousie got to the end of a corn row.
Seems to me, centuries ago in the wayback machine, I had a family of relatives who were having trouble with an infestation of mice.
1) Sit talking to the host of the house. In the middle of the conversation, one hears the sound of scurrying behind the walls of the room where one sits. Definitely mice behind the walls. Witness the host abruptly stand up, run to the desk in the room, grab an air horn one would use to express an esprit de corps at a football game, rush to hold it against the wall, and press the button to create an extremely loud noise.
Host says: "Now the mice are scared."
You reply: "No, now the mice are deaf."
2) Decide to use sticky paper traps to catch the mice in the house. When you come home from work, find 5-6 mice still alive, struggling to release themselves from the sticky paper trap. Feel sorry for the mice. Pick up the sticky paper and the mice and put them in a paper bag. Place them on the street. Run them, and the sticky paper, over with the car.
Not wanting to be so loud or dramatic, we went to Home Depot to review the series of traps available to coax the varmints to another world...in this one, or not.
Doug held up a mousetrap, one with the image of a mouse on it, one with Xs in its eyes. I think it was called MouseBeGone. "This will do the trick," he said. He is a kind man, but very pragmatic.
I held up a safe trap, one that will catch the buggers so you can let them go, in a land far, far away.
Deviously, I set the trap with freshly cut corn from the cob, and a smear of peanut butter. At around 2 a.m., I heard the little steel door slam shut, and knew from the sound of frantic scratching that we had a winner.
Next a.m., I made coffee, and fed Walt, then gathered the trap and took it out to the woods. I opened the trap's door, and the brown mouse, and a little grey one, took off for Costa Rica.
I hope the weather is warm.


SEOUL, Jan 20, 2017–Suwon Diocese in Gyeonggi-do province plans to encourage social evangelization with the 3PLUS Movement, a program aimed to help local Catholics love their neighbors.
The Social Evangelization Department of the diocese began the movement recently to encourage Catholics to share their wealth, time and talent with their neighbors.
The diocese will provide a venue for the faithful to share their belongings. It also launched the More Scholarship program to help young people from difficult backgrounds.
Unlike other scholarship programs that operate by collecting large donations, More Scholarship will operate on small individual donations from members of the diocese.


Wrestler who gained fame following his appearance on the second season of the reality series WWE Tough Enough. He later became an X Division Champion in Total Nonstop Action Wrestling.
He was a college football player at Florida State University and the University of South Florida.
Also a reality star, he was a contestant on the dating show Baggage in 2011; he later became a contestant on ABC's The Bachelorette in 2017.
He was born Kenny D. Layne in Queens, New York; he grew up in Orlando, Florida. He has a daughter named Makenzi.
He defended his X Division title against Petey Williams in April 2013.


How to get the best price for your ticket Zaandam Kogerveld to Bad Krozingen Bus?
The most popular times and dates of departure to travel to Bad Krozingen Bus are more expensive, so try to be flexible if possible.
The booking system will always offer you the cheapest fares for your train e-tickets to Bad Krozingen Bus.
Advance tickets from Zaandam Kogerveld to Bad Krozingen Bus are the cheapest train tickets. You may book up to 3 months in advance.
Questions , remarks about your rail trip Zaandam Kogerveld to Bad Krozingen Bus?


text:
package com.sirius.upns.server.node.repository.impl;

import com.mongodb.BasicDBObject;
import com.sirius.upns.protocol.business.DeviceType;
import com.sirius.upns.server.node.domain.model.Device;
import com.sirius.upns.server.node.repository.DeviceClosure;
import com.sirius.upns.server.node.repository.DeviceRepository;
import com.sirius.upns.server.node.repository.JongoConstants;
import org.jongo.MongoCollection;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author pippo
 * @project node-server
 * @date 2013-9-9-上午12:06:46
 */
public class MongoDeviceRepository implements DeviceRepository, JongoConstants {

	@Resource(name = "ctu.upns.mongo.db.devices")
	private MongoCollection devices;

	@Override
	public Device regist(String userId, String deviceToken, DeviceType deviceType) {
		Device device = this.getByToken(userId, deviceToken);
		if (device != null) {
			return device;
		}

		device = new Device(userId, deviceToken, deviceType);
		devices.insert(new BasicDBObject(device.toMap()));
		return device;
	}

	@Override
	public void deregist(String userId, String deviceToken) {
		devices.remove(queryByUserAndToken(), userId, deviceToken);
	}

	@Override
	public Device registApp(String userId, String deviceToken, List<Integer> appId) {
		@SuppressWarnings("unchecked")
		Map<String, Object> m = devices.findAndModify(queryByUserAndToken(),
				userId,
				deviceToken)
				.with(String.format("{'$addToSet':{%s:{$each:#}}}", Device.APPS), appId)
				.returnNew()
				.as(Map.class);

		Device device = new Device();
		device.fromMap(m);
		return device;
	}

	@Override
	public void deregistApp(String userId, String deviceToken, List<Integer> appId) {
		devices.update(queryByUserAndToken(), userId, deviceToken)
				.with(String.format("{$pullAll:{%s:#}}", Device.APPS), appId);
	}

	@Override
	public Device getByToken(String userId, String token) {
		@SuppressWarnings("unchecked")
		Map<String, Object> m = devices.findOne(queryByUserAndToken(), userId, token).as(Map.class);

		if (m == null) {
			return null;
		}

		Device device = new Device();
		device.fromMap(m);
		return device;
	}

	@Override
	public List<Device> getByType(String userId, DeviceType deviceType) {
		List<Device> _devices = new ArrayList<>();

		@SuppressWarnings("rawtypes")
		Iterable<Map> iterator = devices.find(queryByUserAndType(),
				userId,
				deviceType.code).as(Map.class);
		for (Map<String, Object> _d : iterator) {
			Device device = new Device();
			device.fromMap(_d);
			_devices.add(device);
		}

		return _devices;
	}

	@Override
	public List<Device> getByUser(String userId) {
		List<Device> _devices = new ArrayList<>();

		@SuppressWarnings("rawtypes")
		Iterable<Map> iterator = devices.find(String.format("{%s:#}", Device.USER_ID),
				userId).as(Map.class);
		for (Map<String, Object> _d : iterator) {
			Device device = new Device();
			device.fromMap(_d);
			_devices.add(device);
		}

		return _devices;
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Override
	public void iterateDevices(DeviceType deviceType, DeviceClosure closure) {
		Iterable<Map> iterable = devices.find(queryByType(), deviceType.code)
				.as(Map.class);

		for (Map in : iterable) {
			Device device = new Device();
			device.fromMap(in);
			closure.execute(device);
		}
	}

	@Override
	public void updateLastActive(String deviceId) {
		devices.update(QUERY_BY_ID, deviceId).with(String.format("{$set:{%s:#}}", Device.LAST_ACTIVE_TIME),
				System.currentTimeMillis());
	}

	private String queryByUserAndToken() {
		return String.format("{%s:#, %s:#}", Device.USER_ID, Device.TOKEN);
	}

	private String queryByUserAndType() {
		return String.format("{%s:#, %s:#}", Device.USER_ID, Device.TYPE);
	}

	private String queryByType() {
		return String.format("{%s:#}", Device.TYPE);
	}
}