A software toolkit developed at the Department of Energy's Lawrence Berkeley National Laboratory (Berkeley Lab) to better understand supercomputer performance is now being used to boost application performance for researchers running codes at the National Energy Research Scientific Computing Center (NERSC) and other supercomputing facilities.
This work, spearheaded by computer scientists in Berkeley Lab's Computational Research Division (CRD), is helping to address the growing gap between processor performance and memory performance—the "memory wall"—that can limit how well many scientific applications perform. Even with the fastest processors, if data gets bogged down moving in and out of memory, the processors end up waiting for data to process, which slows overall performance.
With the popularity of manycore processors—such as the Intel Knights Landing processors in Cori, NERSC's new 30-petaflop system—and the diversity of computing architectures, supercomputers are increasingly complex, making it difficult for users to achieve sustained application performance across different architectures. But understanding memory bandwidth limits can help explain the gap between theoretical and observed performance. Thus performance models and tools that aid users' understanding of bandwidth limits for a particular application are crucial.
Toward this end, in 2005 Sam Williams—then a Ph.D. student at the University of California, Berkeley and now a staff scientist in CRD's Performance Algorithms Research Group —began sketching out a model that could estimate performance on a variety of kernels common to high performance computing.
"As the HPC community transitioned from single-core to multicore architectures, it became clear we needed some means of visualizing the performance potential of various HPC kernels on the zoo of emerging manycore architectures," Williams said, "At the time there was a great deal of buzz around IBM's forthcoming Cell processor and interest in quantifying its performance on HPC codes. Unfortunately, as neither hardware nor simulators were yet available, we could not directly run benchmarks on the platform."
Williams' initial model, which used bound and bottleneck analysis, was applied to the Cell processor, and in 2006 the performance results were published in a UC Berkeley Tech Report and in a well-received Computing Frontiers paper. He then began working to visualize the performance bottlenecks. After several iterations, the resulting model—dubbed "Roofline" by David Patterson, William's thesis advisor at UC Berkeley—was published in Communications of the ACM in 2009.
The Roofline Model is designed to enable users to assess the quality of attained performance of an application by combining data locality (how much data needs to move in and out of the processor), bandwidth (the speed at which that data can be moved) and different parallelization paradigms into a single performance figure, yielding a two-dimensional graph that clearly plots the bandwidth bottlenecks that must be eliminated to speed up the application.
"The idea of Roofline is two-fold," said Lenny Oliker, a computer senior scientist in CRD's Performance Algorithms Research Group who has worked closely with Williams to refine and expand Roofline's capabilities. "First, we need to understand the underlying hardware architecture (of the supercomputer), its capabilities and the performance of real codes running on it. Then we want to characterize actual applications and graph them onto the Roofline chart."
In practice, the Roofline model is a graph with an x and a y axis where the x axis is the arithmetic intensity—a measure of flops per byte, explained Jack Deslippe, acting group lead for NERSC's Application Performance Group who is working with Williams and other Berkeley Lab colleagues to extend the model and its applications. "In computer code what this means is how many floating point operations (FLOPs) do you do for every byte of data that you have to bring in from memory," Deslippe said. "What the Roofline curve tells you is what performance you can expect from the system given the characteristics of your application or a subroutine of the application."
Since its initial development, what is now known as the Empirical Roofline Toolkit (ERT) has benefitted from contributions by several Berkeley Lab staff. In 2013, CRD's Terry Ligocki developed a benchmark that could automatically characterize CPU and GPU architectures; this became the ERT. And in 2015 NERSC's Matt Cordery created the toolkit's initial instrumentation technology. Along the way, HPC users who write scientific applications for manycore systems have been able to apply the toolkit to their applications and see how changing parameters of their code can improve performance.
While the Roofline model has been used for a number of years to characterize supercomputing systems and architectures, over the past year it has been expanded to both visualize and guide application optimization, and new tools have been developed to support this, according to Deslippe. As part of this effort, NERSC's Doug Doerfler has extended and applied the technology to the Knights Landing processors in the Cori KNL system.
"We are using this model to frame the conversation with users about where their application stands," Deslippe said. "It's a good way to communicate with users about what they need to work on with a given application or subroutine. It takes a little of the mystery out of code optimization."
In addition, through a collaboration with Intel, the Roofline team has been working to incorporate Roofline into Intel's Vector Advisor, a vectorization optimization and shared memory threading assistance tool. The resulting Intel Advisor Roofline Tool allows users to collect Roofline performance data, including accurate FLOPs counts that correctly consider different vector registers and masks using Intel's PIN tool, as well as accurate data traffic from various levels of the cache memory hierarchy. By determining the total number of FLOPs that will be performed and the amount of data that will be moved, plus the amount of time it will take to complete the job, users can plot the performance of their code on the Roofline graph. They can then use this plot to see how adjustments to how the code is set up can increase the performance.
"In the past we were using Roofline to characterize the HPC systems themselves," said Deslippe. "In the last year, we have gone to using Roofline not just for this but as a way to guide the optimization process for applications. There are all these new, novel parts of the Intel Knights Landing (KNL) hardware—very fast memory right on the chip, bigger vector units, manycores…—and they all sound impressive to the user, but how do they know which one is important for their application? This is where Roofline comes in."
Over the past year, the Roofline team has been introducing NERSC users, including those involved in the NERSC Exascale Science Applications Program (NESAP), to the Roofline model to help them gauge performance improvements. For example, Tuomas Koskela, a NERSC postdoc who joined the center in 2016 to work on XGC1 (a fusion particle-in-cell code) as part of a NESAP project, has been using Roofline to improve the code's performance on Cori.
"We started talking about using Roofline last spring," Koskela said. "It was interesting to me because I had a problem with my code that we didn't understand why it wasn't getting very good performance." After using Roofline via Intel Advisor to optimize the performance of kernels of the XGC1 code for the KNL architecture, Koskela was able to dramatically improve the code's performance on Cori.
"This demonstrates an effective optimization strategy that has enabled this science application to achieve up to 4.6x speed-up and prepare it for future exascale architectures," Koskela said. "The Roofline model is a powerful tool for analyzing the performance of applications with respect to the theoretical peak achievable on a given computer architecture."
With the increased flexibility of multiple cores with 3 level caches and CUDA accelerators available- we now need roofline-aware-compilers to make dynamic code to adapt and optimise itself. Especially as the 'Performance Counter Monitor' element in every modern CPU tells in real time how well balanced or badly roofline/bottleneck limited a CPU is.
This will only get more important as parallel vector processing for speech/image recognition, AI, and media transcoding dominates applications.


This 2 days trip starts with crossing the channel and spending the night in Arras where you will receive a full briefing in preparation for the next day's tour. You will visit battlefields, trenches, war memorials and museums. The battlefields have been well preserved so visitors can fully appreciate the conditions faced by the soldiers and the hundreds of cemeteries show the devastating loss of life involved.


text:
I PAALU SOLAR PLANT
Under the program Colciencias Ideas for change, provision of safe water was proposed to the Kamusuchiwo community located in the area of Crescent, Alta Guajira, given the desert conditions water scarcity is permanent, the only contribution drinking water is Cerrejon company that supplies the resource by tank car, however this water supply is not sufficient and does not reach the vital minimum recommended by the wHO: 50 lt / person / day. The initiative also had the support of the University of Wuppertal, Germany, donating two solar refrigerators and entire solar photovoltaic system for the operation of the solar plant planta.La water has the name I PAALU has a booth plot in which 6 solar panels that provide electricity plant to operate the hydraulic system, lighting system and the automation system were installed. About ten meters from the sea, a deep well of 4 m depth from which water is extracted to lead to elevated tank located in solar house was built. About 5 meters from the well pump room is with a solar panel that powers the hydraulic pump.
The main component of the plant is 12 distillers who are converting seawater into drinking water through evaporation and condensation, the water produced is fed to a 500-liter tank where the water is ready and available for drinking. The plant is in its start-up phase, is being tracked for two months to observe the operation and the volume of water produced.
Another component are the two coolers 160 liters each, in which the community makes ice for use in the conservation of fish and to cool drinks. These coolers are operated by solar energy, the plant has 4 solar panels for this purpose, four batteries and two charge controllers, all these teams are part of the solar photovoltaic system. Steca brand refrigerators are only powered by solar energy and reaches temperatures of up to -14 ° C in freezer mode. The project was developed over a year in three specific phases: a phase of sociocultural characterization, an implementation phase of the technical proposal and finally a phase of monitoring and control of plant solar distillation and cooling system with panels solar.
Solar water plant has the name I PAALU, has a solar house in which 6 solar panels that provide electricity plant to operate the hydraulic system, lighting system and the automation system installed
The hydraulic system of the plant consists of a deep well that stores seawater, this well is located ten meters from the sea so the sands and gravels that are on this path function as a filter and retain solids and algae, then a 150 W solar pump sucks water from the well and drives 90 meters to the solar tank shed. The storage tank saltwater has a capacity of 2000 liters and is raised to 2 meters and medium terrain. Once the salt water in the tank, the distillers is distributed by an automation system which lights every 24 hours, by means of sensors located in the trays trays are filled to the brim, preventing water sea to overflow into distillers.
Once the salt water in the tank, the distillers is distributed by an automation system which lights every 24 hours, by means of sensors located in the trays trays are filled to the brim, preventing water sea to overflow into distillers. In the next picture we see the distillers operating at noon.
Fundamntal as part of the solar plant, training sessions were conducted for the community to take care of the plant and thus this is sustainable over time for this, reponsables people from both the accounting management and system maintenance were appointed. Mr. Armando Gonzales was appointed plant manager and one of its tasks is to keep an accounting record of water and ice sold to the community.
Likewise reponsables for maintenance of the plant, a group of women d were designated ela community are responsible for cleaning the trays d elos destiladoress and a group of men is responsible for removing the domes and perform the d elos cleaning solar panels both of the house and the pumphouse

redpajama_set_name: RedPajamaCommonCrawl


text:
namespace ADO.ReadExcel
{
    using System;
    using System.Data.OleDb;

    /// <summary>
    /// 6. Create an Excel file with 2 columns: name and score:
    /// Write a program that reads your MS Excel file through the OLE DB data provider and displays the name and score
    /// row by row.
    /// </summary>
    public class ReadFromExcel
    {
        public static void Main()
        {
            string connectionString = @"Provider=Microsoft.ACE.OLEDB.12.0;" +
            @"Data Source=../../Scores.xlsx;Extended Properties=""Excel 12.0 XML;HDR=Yes""";

            OleDbConnection excelConn = new OleDbConnection(connectionString);

            excelConn.Open();

            using (excelConn)
            {
                string querySelect = "Select * FROM [Sheet1$]";
                OleDbCommand cmd = new OleDbCommand(querySelect, excelConn);

                OleDbDataReader reader = cmd.ExecuteReader();
                using (reader)
                {
                    while (reader.Read())
                    {
                        string name = (string)reader["Name"];
                        double score = (double)reader["Score"];
                        Console.WriteLine("{0}: {1}", name, score);
                    }
                }
            }

            excelConn.Close();
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
Best Ways to Give
Pillars of the Force
Home / Meet Our Donors / Page 39
VESH, Lois
WACHOWICZ, the late Rita & Tony
WADE, John
WADE, Steven
WAKE, Malcolm
WAKE, Malcolm & the late Grace
WAKE, Malcolm and Grace
WAKELY, Garry L.
Walter Achtymichuk
WARD, R.D.S. (Deceased)
WARNKE, Bob & Becky
WARREN, Philip J.
WATT, A. Doug
WATT, C. D.
WEBER, Doug
WEEKS, Frank B. (Deceased)
WEINER, Jeffrey
WEINER, Jeffrey S.
WEISS, Wilfred
WERBOWSKI, Shirley, Stable Manager, Horse Program
DONOR LEGEND
Donor Categories
Individual(597)
President's Circle, Platinum ($60,000 to $69,999)(0)
President's Circle, Gold ($50,000 to $59,999)(0)
President's Circle, Silver ($40,000 to $49,999)(0)
President's Circle, Bronze ($30,000 to $39,999)(0)
President's Circle ($20,000 to $29,999)(3)
Patron ($10,000 to $19,000)(7)
Benefactor ($5,000 to $9,999)(8)
Life Sponsor ($3,000 to $4,999)(13)
Life Member ($1,200 to $2,999)(242)
Friend ($500 to $1,199)(325)
In Memoriam(193)
Troop(14)
Friends' Certificate of Appreciation(5)
Honourary Life Member(8)
Sort Results By Name (Descending) Name (Ascending)
Friends of the Mounted Police Heritage Centre All rights reserved.


text:
Лебедя́нский райо́н — административно-территориальная единица в Липецкой области России. В границах района образован одноимённый муниципальный район.

Административный центр — город Лебедянь.

География
Площадь 1420 км². Район граничит с Тульской областью, а также с Липецким, Данковским, Лев-Толстовским, Добровским, Краснинским и Задонским районами Липецкой области.

Основные реки — Дон, Красивая меча.

История
Лебедянский уезд был образован в 1779 году в составе Тамбовского наместничества (с 1796 года — Тамбовской губернии). В 1924 году уезд был упразднен, его территория вошла в состав Липецкого уезда.

После того, как Пётр I своим указом от 18 (29) декабря 1708 года разделил Россию на 8 губерний, Лебедянь и большая часть современного Лебедянского района была приписана к Азовской губернии (переименованной 22 апреля (3 мая) 1725 года в Воронежскую). Новый указ императора от 29 мая (9 июня) 1719 года ввёл деление губерний на провинции, и Лебедянь вошла в состав Елецкой провинции данной губернии.

В 1826 году тут был открыт первый в России ипподром и основано Лебедянское скаковое общество, членами которого стали видные коннозаводчики со всей России. В 1847 году было учреждено Лебедянское общество сельского хозяйства, оставившее глубокий след в истории агрономической науки страны и ставшее колыбелью основных проектов реформы 1861 года.

30 июля 1928 года в связи с упразднением деления  на губернии и уезды в составе Центрально-Чернозёмной области (ЦЧО) был образован Лебедянский район. Изначально он входил в Елецкий округ, упразднённый по постановлению от 23 июля 1930 года. После разделения ЦЧО 31 декабря 1934 года вошёл в состав Воронежской, а 26 сентября 1937 года — во вновь образованную Рязанскую область. После образования 6 января 1954 года Липецкой области включён в её состав.

Население

 Урбанизация
В городских условиях (город Лебедянь) проживают  % населения района.

Административно-муниципальное устройство
Лебедянский район, в рамках административно-территориального устройства области, включает 16 административно-территориальных единиц, в том числе 1 город районного значения и 15 сельсоветов.

Лебедянский район включает одно городское и 15 сельских поселений:

1 октября 2017 года Павловский сельсовет был включён в Куйманский сельсовет.

Населённые пункты

В Лебедянском районе 89 населённых пунктов.

Официальные символы района
Герб Лебедянского района утверждён решением Лебедянского районного Совета депутатов № 238 от 25 ноября 2003 года.

Флаг Лебедянского района утверждён решением Лебедянского районного Совета депутатов № 239 от 25 ноября 2003 года.

Экономика
На территории района действуют:
 7 крупных промышленных предприятий;
 12 предприятий агропромышленного комплекса;
 около 1700 субъектов малого бизнеса;
 6 банков.

Потребительский рынок включает 252 магазинов, 51 павильона и киоска, 65 предприятий общественного питания, 1 универсальный рынок, 2 ярмарки, 60 объектов бытового обслуживания.

Транспорт
По состоянию на 7 декабря 2016 года действует 20 внутрирайонных регулярных автобусных маршрутов.

Примечания

Литература
  (обл.)
  (обл.)
  (обл.)

Ссылки
 Сведения на сайте областной администрации

Лебедянский район

redpajama_set_name: RedPajamaWikipedia


One of my favorite parts of playing slots is getting a bonus round. The payout has been so disappointing recently - sometimes not even a single bet's worth....is that a mistake? Takes away the anticipation!
It's very disappointing, the $100 bonus doesn't make it worth playing.. I also noticed in the daily bonus I am now getting 1 free spin. Perhaps the developers are pushing for people to buy more coins. Would the developers like to chime in here to let us know why you are punishing long time players who support your games?
I'm still getting 300 but when it updated I got a "daily" piggy choice for extra $ or free spins. This only appeared 3 days when I logged in and haven't seen in days....anyone know what that is/was?
I have slots (both same version) on my Ipad and on my Ipod. The Ipad slots (level 41)game gives me a daily bonus of $100 (used to be $300) yet the Ipod slots game (level 26) gives adaily $300??????? wasn't that way before. Weird.
I'm just wondering why the daily bonus free spins knock my betting from $7500 to $450. I bet $7500 every other time, but you can't allow that for the daily prize thing? Bit unfair, you know.
I haven't received the daily free spins for months. But now in the past few days, I'm unable to collect the bonus dollars. The icon show Max Bonus of $300, but when I click the icn, it adds the dollars to my account but one second later it subtracts the money and the Max Bonus icon still shows the money is available.
It was bad enough to lose the dily bonus spins, but losing the small bonus dollar payout is ready to make me quit this game for good.
Any slot players that play daily & want to friend me?
Any budy know how to get more Coins any sugestion??


text:
Q: How can $k$ and $k'$ be vectors of different directions on Griffiths chapter on scattering? The last chapter of the Griffiths book on quantum mechanics is about scattering. When dealing with the Born approximation, he says that the scattering wave has a direction $\mathbf k'$, different from the incident wave, with direction $\mathbf k$. And that $\mathbf k' = k\hat z$, that means it has $z$ direction and the same magnitude of $\mathbf k$.
But the incident wave is $\psi(\mathbf r) = e^{ikz}$. I understand this equation as: $\psi(\mathbf r) = e^{i\mathbf{k.r}}$, where $\mathbf k = (0,0,k)$ and $\mathbf r = (x,y,z)$. So the incident wave has also $z$ direction.
What am I missing?

A: . . . . .  he says that the scattering wave has a direction $k′$, different from the incident wave, with direction $k$ . . . .
Griffiths writes In case you have lost track of the definitions of ${\bf k}[= k\hat r]$ and ${\bf k'}[=k\hat z]$, they both have magnitude $k$, but the former points in the direction of the incident beam, while the latter points towards the detector - see Figure 11.10.

A: As I said in a comment, I found an errata in the web saying that $\mathbf k$ and $\mathbf k'$ are mistakenly identified as incident wave and scattering wave respectively in the first edition.
In reality, $\mathbf k$ is previously defined as $\mathbf k = k\hat r$, where $\hat r$ is the unit vector that defines the orientation of the wave.
$\mathbf k'$ is defined as $\mathbf k' = k\hat z$, where $\hat z$ is the unit vector in the z-direction, which was by hypothesis the incident wave.
So, the correct information is: $\mathbf k'$ refers to the incident wave and $\mathbf k$ to the scattered wave.
That definitions are used in the Born approximation, that supposes that the incident wave is not much modified by the potencial $V(\mathbf {r_0})$ around $\mathbf {r_0} = 0$, where the target particule is located.

redpajama_set_name: RedPajamaStackExchange


You may send this item to up to five recipients. Cleis Press 5 January Language: Joel Tan Find more information about: Please create a new list with a new name; move some items to a new or existing list; or delete some items. Citations are based on reference standards.
However the play seems to ignore that gay rights in Cuba come with a hidden clause that you must support the dictatorship of the Castro family.
I'd like to read this book on Kindle Don't have a Kindle? Would you like to tell us about a lower price? Interesting play and excellent review by Mr. Citations are based on reference standards. See all free Kindle reading apps.


How can I synchronize my OX-Data to my Mobile?
All mobile devices connected to the Mac, like iPhones, iPods and cell phones from other manufacturers, as well as software from third-party ISVs that support iSync can access Open-Xchange data.
Even without a connection to the Internet, users can continue to work without interruption.
Which Requirements are to be fulfilled by the Open-Xchange Server?
- Open-Xchange Server 6 SP4 Update 1 or higher.
- The Update 1 is available for all customers with a Open-Xchange Hosting Edition or Open-Xchange Server Edition Maintenance.
Which Requirements are to be fulfilled by my Mac OS X System?
What is the default time for synchronization?
If the user changes any data on their Mac OS X, the synchronization will be started after a 10 seconds waiting time via "Trickle-Sync".
Which components will be synchronized?
What is with the Open-Xchange InfoStore Objects?
Via the configuration dialog, it is possible to enable the synchronization of the InfoStore files via access as Network Volume.


text:
10 Top Things to Do in South Africa's Lake District
Lake Chrissiemeer | © Mariette du Buson / Chrissiemeer Tourism
Gill Lange
The Chrissiesmeer Lake District in Mpumalanga is a treasure for roving travelers seeking solitude and natural grandeur, featuring over 270 scenic lakes and pans centred around the charming little hamlet of Chrissiesmeer. Here are some delightful things to do in the area.
Hear the noisy chatter of birds
Chrissiesmeer is awash with spectacular birdlife and huge flocks of flamingos are a common sight, adorning the wetlands in all their white and pink glory. Also vying for attention around the marshes and lakes are all three species of southern African crane and vocal flocks of southern red bishops, among many other species. The ideal time for twitchers to visit is between September and March, when migrant birds arrive for the summer. Detailed birding maps are easy to come by and can be picked up at most of the local guesthouses.
Flamingos on Lake Chrissiesmeer | © Mariette du Buson / Chrissiesmeer Tourism
See the land of frogs
With so much water around, it's only natural that one would find frogs. This lake area is also referred to as Matotoland, Swazi for "land of frogs," and frog-catching expeditions armed with a headlamp and plastic bag are popular evening events. The kids will love it, and it's a fantastic way to learn more about this amazing natural environment as well as the breeding ecology of all 13 frog species found around the lakes. Contact Florence Guest Farm for more information and bookings.
Well-disguised common river frog | © Bernard DUPONT / Flickr
Discover fascinating rock formations
Goliath's Footprint, a large impression in a granite rock face resembling a giant left foot, is shrouded in mystery and intrigue. To some it's holy, to others, part of a larger conspiracy theory. However, no matter which camp you choose to side with, the giant "footprint" is quite astounding. Another natural anomaly in the area is a 29-yard (27-meter) natural stone bridge that crosses the Vaal River and was used by the early Voortrekkers when the river was in flood.
Stock up on bedding
While this may sound strange, Chrissiesmeer is home to a one-of-a-kind pillow and duvet shop that sells 100% wool-filled bedding with cotton casings. Said to be hypoallergenic and wonderfully snuggly, the bedding is also well priced and worth a browse. McCloud's is located in a beautifully quaint and historic sandstone building in the town's main drag, and you can grab a bite to eat there too.
McCloud's, 78 Parkwood St, Chrissiesmeer, 2332, +27828014158
McCloud's duvet and pillow shop | © Chrissiesmeer Tourism
Skip through the flowers
The flora around the Chrissiesmeer Lake District is simply stunning, especially from August to February, when spring and summer bring a riot of color to the surrounding landscape. The area is also well known for its 12 species of wild orchids, and guided flower tours can be booked in advance.
Colourful vygies are common | © Jolette Roodt / Flickr
Check out some vintage tractors
Farmer Jan Randell's Ranch Museum has one of the largest collections of vintage tractors in Africa, all immaculately restored and in full running order. There is a constantly updated collection of machines to admire, with the oldest dating back to the 1920s, as well as a collection of vintage cars, trucks, and motorbikes, old engines and church organs, and even a 1948 Beechcraft Bonanza 35 plane. The collection is private, so a viewing appointment must be made in advance. Serious browsers will be pleased to know that there is also a selection of vintage pieces for sale.
For bookings call +27828075515 or mail Jan at jansnr@randellsranch.co.za.
Tractor display at Randall's Ranch | © Chrissiesmeer Tourism
Explore the Scottish heritage
Many, many years ago a Scottish settler named Alexander McCorkindale fell in love with this amazing lake area that reminded him of his homeland. He purchased 200 farms from the South African government and gave them beautiful Scottish names such as Lochiel, Dundonald, and Bonnie Brae. Many of these farms still retain their Scottish titles, while the town is awash with beautifully restored sandstone buildings, a further reminder of Scotland. Worth a visit are the Ou Sending Pastorie (Old Mission Parsonage), the old Methodist Church, the old Barclays Bank, and the Old Mill.
Whispers of Scotland in Chrissiesmeer's winter landscape | © Chrissiesmeer Tourism
Hop on your bike
The undulating landscape of the Lake District's grasslands and wetlands lend themselves to cycling while you enjoy gorgeous views and fresh, clean air. Most of the local farmers have no problem with cyclists using their gravel roads. From short mountain bike rides to longer, more strenuous cycles that may require hopping over a fence or two, there's something for every biker to enjoy.
A group of cyclists enjoying Chrissiesmeer's pastoral scenes | © Chrissiesmeer Tourism
Stay on a working farm
The fertile lands of the Lake District are dotted with picturesque working farms where visitors can be woken by the cries of cockerels and watch tractors and cattle passing by. A whole host of accommodation options are available with most offering homely comforts such as wholesome farmhouse breakfasts and cozy fire places that beckon you to curl up and snooze. Family-run Florence Guest Farm is one such option, providing genuine, friendly old-style hospitality. It is also a popular wedding venue, and what could be more romantic than tying the knot surrounded by old sandstone buildings and misty wooded lakes?
Florence Guest Farm, R17, Chrissiesmeer, 2332, +27828041771
Newlywed couple at Florence Guest Farm | © Florence Guest Farm
Admire the rock art
Numerous rock art sites and fascinating stories about ancient tribesmen are plentiful in and around Chrissiesmeer. Rock paintings that depict cattle, buck, giraffe, and other wild animals that once frequented the verdant wetlands are woven with tales such as those of the Tlou-tle tribe. Folklore has it that they lived on reed rafts in the middle of the lakes. These eventually took root and grew into islands, while the tribesmen hid underwater for hours on end, breathing though reeds, to avoid the dangers posed by aggressors.


text:
A Snapshot From Lois Sakany
EL, ULTA
By Lois Sakany
New York congresswoman Alexandria Ocasio-Cortez's views on skincare, makeup and diet reflect her generation's dynamic views on appearance, which emphasize an integrated approach rooted in transparency and simplicity.
New York Rep. Alexandria Ocasio-Cortez may be best known among her detractors for her thoughts on tax rates for the wealthy, but among her followers, she's admired not just for her progressive politics but also her lifestyle views. Since she was elected, she's both celebrated and been outspoken about the need for female politicians to wear makeup. When social media followers wondered what lipstick color she was wearing on a TV appearance shortly after her primary election, she responded on Twitter Inc., "I have been getting many inquiries about my debate lip color in the last two days. I GOT YOU. It's Stila [Corp.] Stay All Day Liquid in Beso."
Earlier this week, she received global media coverage for her Facebook Inc.'s Instagram Stories musings on skincare, makeup and diet. Not just the voice of a generation, Ocasio-Cortez's thoughts on beauty can be viewed as prescient in that their emphasis is on caring for skin rather than covering it with makeup. As much as it makes sense that a phone-screen-obsessed generation would embrace makeup, it follows that as the trend matures and the customer ages, they will be more focused on the potential to slow signs of aging, which will likely include backing away from a war paint, full-coverage approach.
While Ocasio-Cortez's views aren't going to cause any neck-breaking inflections in demand (though her shade of Stila lipstick did sell out after she announced it), they reflect what might be a shifting tide favoring companies and retailers with the elasticity to authentically adjust their product assortments and service offering. The change may also provide fertile grounds for companies rooted in skincare products emphasizing transparency in ingredients. A natural skin care supplier to Ulta Beauty Inc. said she believes Ocasio-Cortez's comments "100%" have the potential to influence beauty enthusiasts' purchases. "I think she's amazing. I would love to work with her," she said, having recently rolled out a serum with vitamin C and other ingredients Ocasio-Cortez espouses.
And indeed, during the past few months, companies including Huda Beauty LLC have announced plans to expand into skincare, and last fall, rumors emerged around a Kylie Cosmetics LLC skincare line. At the same time, it was viewed as a big coup for LVMH Moët Hennessy Louis Vuitton SE's Sephora that it won back The Estée Lauder Cos. Inc. Deciem Inc.'s The Ordinary brand, a line of low-cost serums celebrated for their minimalist ingredients. Sephora lost distribution of the brand last year, and after it was pulled, it was rumored Ulta would begin carrying the brand, which never came to fruition.
Reflecting her generation's obsession with ingredients, Ocasio-Cortez wrote on Instagram Stories, "Skincare is straight up a hobby of mine. I'm a science nerd and I truly enjoy the science of it, reading about compounds and studies," and went on to detail a three-step process that included a Korean skincare approach known as "double cleansing," along with "toner and actives" and "moisturizer and sunscreen." The 29-year-old repeatedly stressed the importance of removing makeup before going to bed. She wrote, "When it comes to makeup, don't use more than you need! If it's a hobby or creative outlet for you, then definitely incorporate double cleansing and use a face brush or makeup towel to totally clean your face as soon as you can in your day. Let your skin BREATHE."
While Ocasio-Cortez didn't provide brands, she advocated for alcohol-free toner, a position that makes us think she's a reader on Reddit's wildly popular "SkincareAddiction" forum, where most posters hold the same view on alcohol as a toner ingredient to avoid, a view also pushed by Paula's Choice LLC with a full-page explainer on its website on why it's wrong.
On makeup, Ocasio-Cortez reflects Ulta's mass/prestige approach, but at the same time proudly states she sometimes doesn't wear makeup at all. "I've used both nice makeup and drugstore makeup. I also straight up don't wear makeup some days and everyone just has to deal with it," she said on Instagram Stories.
When Ocasio-Cortez was asked about the impact of diet on skincare, like a lot of her peers, she again reflected her generation's focus on an integrated approach to wellness and provided an answer that would lead makers of oat and cashew milk to cheer. "I'm very into oat milk right now, which [in my opinion] is the best of all the milks after cashew milk. I know I sound [very] bougie right now so almost any nondairy milk sounds bougie so here we are. My heart wants me to eat less meat and go more vegetarian, and some days I cannot for logistical reasons or I'm just gonna pass out if I don't scarf down whatever is in front of me. But I do find that I consume way less meat and dairy than I once did. I feel better when I don't eat it as much, too," she said on her Instagram Stories.
Contributors: Donna Crothers
What is an OTR Snapshot?
OTR Snapshots are direct feeds from our editors expressing their views on key issues and events in their industries, within and beyond our core coverage. Snapshots feature industry insights, source commentary, and general observations.
Newsroom ››
Snapshots ››
Contact OTR Global
The industry's most respected provider of marketplace and channel intelligence.
Download a Sample Report
Featuring industry insights, source commentary and general observations.


Living without a full set of teeth in your upper or lower jaw can greatly impact your life, health, and overall happiness. Wearing dentures may be a viable option for some patients, but for others, the sliding and shifting around that occurs when they simply speak or eat can be quite unbearable.
At Triad Cosmetic Dentistry, we offer numerous dental implant options that eliminate the hassles of wearing dentures and provide patients with a fully restored smile that looks and feel just like their natural teeth.
All-on-4 is used to replace an entire set of teeth in either jaw. You won't need an implant placed for every single missing tooth because All-on-4 only uses four dental implants for each jaw. Additionally, the All-on-4 procedure can be completed in just one day, so you'll be able to shine your beautiful new smile the same day as when the implants are placed.
When you visit Triad Cosmetic Dentistry for your implant consultation, one of our experienced implant dentists will examine the condition of your mouth and check to see if your oral health is substantial enough to support a dental implant.
After your oral exam, we will be able to inform you of all our restorative treatment options that we believe are the best choice for you and your smile. Once we've determined you're a good candidate for one of our procedures, we'll be able to begin treatment and deliver you the smile you've been waiting for.


text:
package vstreamer

import (
	"fmt"
	"regexp"
	"strconv"
	"strings"

	"vitess.io/vitess/go/vt/vtgate/evalengine"

	vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
	"vitess.io/vitess/go/vt/vterrors"

	"vitess.io/vitess/go/vt/log"

	"vitess.io/vitess/go/mysql"
	"vitess.io/vitess/go/sqltypes"
	"vitess.io/vitess/go/vt/key"
	"vitess.io/vitess/go/vt/sqlparser"
	"vitess.io/vitess/go/vt/vtgate/vindexes"

	binlogdatapb "vitess.io/vitess/go/vt/proto/binlogdata"
	querypb "vitess.io/vitess/go/vt/proto/query"
	topodatapb "vitess.io/vitess/go/vt/proto/topodata"
)

// Plan represents the plan for a table.
type Plan struct {
	Table *Table

	// ColExprs is the list of column expressions to be sent
	// in the stream.
	ColExprs []ColExpr

	convertUsingUTF8Columns map[string]bool

	// Filters is the list of filters to be applied to the columns
	// of the table.
	Filters []Filter
}

// Opcode enumerates the operators supported in a where clause
type Opcode int

const (
	// Equal is used to filter a comparable column on a specific value
	Equal = Opcode(iota)
	// VindexMatch is used for an in_keyrange() construct
	VindexMatch
	// LessThan is used to filter a comparable column if < specific value
	LessThan
	// LessThanEqual is used to filter a comparable column if <= specific value
	LessThanEqual
	// GreaterThan is used to filter a comparable column if > specific value
	GreaterThan
	// GreaterThanEqual is used to filter a comparable column if >= specific value
	GreaterThanEqual
	// NotEqual is used to filter a comparable column if != specific value
	NotEqual
)

// Filter contains opcodes for filtering.
type Filter struct {
	Opcode Opcode
	ColNum int
	Value  sqltypes.Value

	// Parameters for VindexMatch.
	// Vindex, VindexColumns and KeyRange, if set, will be used
	// to filter the row.
	// VindexColumns contains the column numbers of the table,
	// and not the column numbers of the stream to be sent.
	Vindex        vindexes.Vindex
	VindexColumns []int
	KeyRange      *topodatapb.KeyRange
}

// ColExpr represents a column expression.
type ColExpr struct {
	// ColNum specifies the source column value.
	ColNum int

	// Vindex and VindexColumns, if set, will be used to generate
	// a keyspace_id. If so, ColNum is ignored.
	// VindexColumns contains the column numbers of the table,
	// and not the column numbers of the stream to be sent.
	Vindex        vindexes.Vindex
	VindexColumns []int

	Field *querypb.Field

	FixedValue sqltypes.Value
}

// Table contains the metadata for a table.
type Table struct {
	Name   string
	Fields []*querypb.Field
}

// fields returns the fields for the plan.
func (plan *Plan) fields() []*querypb.Field {
	fields := make([]*querypb.Field, len(plan.ColExprs))
	for i, ce := range plan.ColExprs {
		fields[i] = ce.Field
	}
	return fields
}

// getOpcode returns the equivalent planbuilder opcode for operators that are supported in Filters
func getOpcode(comparison *sqlparser.ComparisonExpr) (Opcode, error) {
	var opcode Opcode
	switch comparison.Operator {
	case sqlparser.EqualOp:
		opcode = Equal
	case sqlparser.LessThanOp:
		opcode = LessThan
	case sqlparser.LessEqualOp:
		opcode = LessThanEqual
	case sqlparser.GreaterThanOp:
		opcode = GreaterThan
	case sqlparser.GreaterEqualOp:
		opcode = GreaterThanEqual
	case sqlparser.NotEqualOp:
		opcode = NotEqual
	default:
		return -1, fmt.Errorf("comparison operator %s not supported", comparison.Operator.ToString())
	}
	return opcode, nil
}

// compare returns true after applying the comparison specified in the Filter to the actual data in the column
func compare(comparison Opcode, columnValue, filterValue sqltypes.Value) (bool, error) {
	// use null semantics: return false if either value is null
	if columnValue.IsNull() || filterValue.IsNull() {
		return false, nil
	}
	// at this point neither values can be null
	// NullsafeCompare returns 0 if values match, -1 if columnValue < filterValue, 1 if columnValue > filterValue
	result, err := evalengine.NullsafeCompare(columnValue, filterValue)
	if err != nil {
		return false, err
	}

	switch comparison {
	case Equal:
		if result == 0 {
			return true, nil
		}
	case NotEqual:
		if result != 0 {
			return true, nil
		}
	case LessThan:
		if result == -1 {
			return true, nil
		}
	case LessThanEqual:
		if result <= 0 {
			return true, nil
		}
	case GreaterThan:
		if result == 1 {
			return true, nil
		}
	case GreaterThanEqual:
		if result >= 0 {
			return true, nil
		}
	default:
		return false, fmt.Errorf("comparison operator %d not supported", comparison)
	}
	return false, nil
}

// filter filters the row against the plan. It returns false if the row did not match.
// The output of the filtering operation is stored in the 'result' argument because
// filtering cannot be performed in-place. The result argument must be a slice of
// length equal to ColExprs
func (plan *Plan) filter(values, result []sqltypes.Value) (bool, error) {
	if len(result) != len(plan.ColExprs) {
		return false, fmt.Errorf("expected %d values in result slice", len(plan.ColExprs))
	}
	for _, filter := range plan.Filters {
		switch filter.Opcode {
		case VindexMatch:
			ksid, err := getKeyspaceID(values, filter.Vindex, filter.VindexColumns, plan.Table.Fields)
			if err != nil {
				return false, err
			}
			if !key.KeyRangeContains(filter.KeyRange, ksid) {
				return false, nil
			}
		default:
			match, err := compare(filter.Opcode, values[filter.ColNum], filter.Value)
			if err != nil {
				return false, err
			}
			if !match {
				return false, nil
			}
		}
	}
	for i, colExpr := range plan.ColExprs {
		if colExpr.ColNum == -1 {
			result[i] = colExpr.FixedValue
			continue
		}
		if colExpr.ColNum >= len(values) {
			return false, fmt.Errorf("index out of range, colExpr.ColNum: %d, len(values): %d", colExpr.ColNum, len(values))
		}
		if colExpr.Vindex == nil {
			result[i] = values[colExpr.ColNum]
		} else {
			ksid, err := getKeyspaceID(values, colExpr.Vindex, colExpr.VindexColumns, plan.Table.Fields)
			if err != nil {
				return false, err
			}
			result[i] = sqltypes.MakeTrusted(sqltypes.VarBinary, []byte(ksid))
		}
	}
	return true, nil
}

func getKeyspaceID(values []sqltypes.Value, vindex vindexes.Vindex, vindexColumns []int, fields []*querypb.Field) (key.DestinationKeyspaceID, error) {
	vindexValues := make([]sqltypes.Value, 0, len(vindexColumns))
	for _, col := range vindexColumns {
		vindexValues = append(vindexValues, values[col])
	}
	destinations, err := vindexes.Map(vindex, nil, [][]sqltypes.Value{vindexValues})
	if err != nil {
		return nil, err
	}
	if len(destinations) != 1 {
		return nil, fmt.Errorf("mapping row to keyspace id returned an invalid array of destinations: %v", key.DestinationsString(destinations))
	}
	ksid, ok := destinations[0].(key.DestinationKeyspaceID)
	if !ok || len(ksid) == 0 {
		return nil, fmt.Errorf("could not map %v to a keyspace id, got destination %v", vindexValues, destinations[0])
	}
	return ksid, nil
}

func mustSendStmt(query mysql.Query, dbname string) bool {
	if query.Database != "" && query.Database != dbname {
		return false
	}
	return true
}

func mustSendDDL(query mysql.Query, dbname string, filter *binlogdatapb.Filter) bool {
	if query.Database != "" && query.Database != dbname {
		return false
	}
	ast, err := sqlparser.Parse(query.SQL)
	// If there was a parsing error, we send it through. Hopefully,
	// recipient can handle it.
	if err != nil {
		return true
	}
	switch stmt := ast.(type) {
	case sqlparser.DBDDLStatement:
		return false
	case sqlparser.DDLStatement:
		if !stmt.GetTable().IsEmpty() {
			return tableMatches(stmt.GetTable(), dbname, filter)
		}
		for _, table := range stmt.GetFromTables() {
			if tableMatches(table, dbname, filter) {
				return true
			}
		}
		for _, table := range stmt.GetToTables() {
			if tableMatches(table, dbname, filter) {
				return true
			}
		}
		return false
	}
	return true
}

func ruleMatches(tableName string, filter *binlogdatapb.Filter) bool {
	for _, rule := range filter.Rules {
		switch {
		case strings.HasPrefix(rule.Match, "/"):
			expr := strings.Trim(rule.Match, "/")
			result, err := regexp.MatchString(expr, tableName)
			if err != nil {
				return false
			}
			if !result {
				continue
			}
			return true
		case tableName == rule.Match:
			return true
		}
	}
	return false
}

// tableMatches is similar to buildPlan below and MatchTable in vreplication/table_plan_builder.go.
func tableMatches(table sqlparser.TableName, dbname string, filter *binlogdatapb.Filter) bool {
	if !table.Qualifier.IsEmpty() && table.Qualifier.String() != dbname {
		return false
	}
	return ruleMatches(table.Name.String(), filter)
}

func buildPlan(ti *Table, vschema *localVSchema, filter *binlogdatapb.Filter) (*Plan, error) {
	for _, rule := range filter.Rules {
		switch {
		case strings.HasPrefix(rule.Match, "/"):
			expr := strings.Trim(rule.Match, "/")
			result, err := regexp.MatchString(expr, ti.Name)
			if err != nil {
				return nil, err
			}
			if !result {
				continue
			}
			return buildREPlan(ti, vschema, rule.Filter)
		case rule.Match == ti.Name:
			return buildTablePlan(ti, vschema, rule.Filter)
		}
	}
	return nil, nil
}

// buildREPlan handles cases where Match has a regular expression.
// If so, the Filter can be an empty string or a keyrange, like "-80".
func buildREPlan(ti *Table, vschema *localVSchema, filter string) (*Plan, error) {
	plan := &Plan{
		Table: ti,
	}
	plan.ColExprs = make([]ColExpr, len(ti.Fields))
	for i, col := range ti.Fields {
		plan.ColExprs[i].ColNum = i
		plan.ColExprs[i].Field = col
	}
	if filter == "" {
		return plan, nil
	}

	// We need to additionally set VindexColumn, Vindex and KeyRange
	// based on the Primary Vindex of the table.
	cv, err := vschema.FindColVindex(ti.Name)
	if err != nil {
		return nil, err
	}
	whereFilter := Filter{
		Opcode: VindexMatch,
		Vindex: cv.Vindex,
	}
	whereFilter.VindexColumns, err = buildVindexColumns(plan.Table, cv.Columns)
	if err != nil {
		return nil, err
	}

	// Parse keyrange.
	keyranges, err := key.ParseShardingSpec(filter)
	if err != nil {
		return nil, err
	}
	if len(keyranges) != 1 {
		return nil, fmt.Errorf("error parsing keyrange: %v", filter)
	}
	whereFilter.KeyRange = keyranges[0]
	plan.Filters = append(plan.Filters, whereFilter)
	return plan, nil
}

// BuildTablePlan handles cases where a specific table name is specified.
// The filter must be a select statement.
func buildTablePlan(ti *Table, vschema *localVSchema, query string) (*Plan, error) {
	sel, fromTable, err := analyzeSelect(query)
	if err != nil {
		log.Errorf("%s", err.Error())
		return nil, err
	}
	if fromTable.String() != ti.Name {
		log.Errorf("unsupported: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), ti.Name)
		return nil, fmt.Errorf("unsupported: select expression table %v does not match the table entry name %s", sqlparser.String(fromTable), ti.Name)
	}

	plan := &Plan{
		Table: ti,
	}
	if err := plan.analyzeWhere(vschema, sel.Where); err != nil {
		log.Errorf("%s", err.Error())
		return nil, err
	}
	if err := plan.analyzeExprs(vschema, sel.SelectExprs); err != nil {
		log.Errorf("%s", err.Error())
		return nil, err
	}

	if sel.Where == nil {
		return plan, nil
	}

	return plan, nil
}

func analyzeSelect(query string) (sel *sqlparser.Select, fromTable sqlparser.TableIdent, err error) {
	statement, err := sqlparser.Parse(query)
	if err != nil {
		return nil, fromTable, err
	}
	sel, ok := statement.(*sqlparser.Select)
	if !ok {
		return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(statement))
	}
	if len(sel.From) > 1 {
		return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
	}
	node, ok := sel.From[0].(*sqlparser.AliasedTableExpr)
	if !ok {
		return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
	}
	fromTable = sqlparser.GetTableName(node.Expr)
	if fromTable.IsEmpty() {
		return nil, fromTable, fmt.Errorf("unsupported: %v", sqlparser.String(sel))
	}
	return sel, fromTable, nil
}

// isConvertColumnUsingUTF8 returns 'true' when given column needs to be converted as UTF8
// while read from source table
func (plan *Plan) isConvertColumnUsingUTF8(columnName string) bool {
	if plan.convertUsingUTF8Columns == nil {
		return false
	}
	return plan.convertUsingUTF8Columns[columnName]
}

// setConvertColumnUsingUTF8 marks given column as needs to be converted as UTF8
// while read from source table
func (plan *Plan) setConvertColumnUsingUTF8(columnName string) {
	if plan.convertUsingUTF8Columns == nil {
		plan.convertUsingUTF8Columns = map[string]bool{}
	}
	plan.convertUsingUTF8Columns[columnName] = true
}

func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error {
	if where == nil {
		return nil
	}
	exprs := splitAndExpression(nil, where.Expr)
	for _, expr := range exprs {
		switch expr := expr.(type) {
		case *sqlparser.ComparisonExpr:
			opcode, err := getOpcode(expr)
			if err != nil {
				return err
			}
			qualifiedName, ok := expr.Left.(*sqlparser.ColName)
			if !ok {
				return fmt.Errorf("unexpected: %v", sqlparser.String(expr))
			}
			if !qualifiedName.Qualifier.IsEmpty() {
				return fmt.Errorf("unsupported qualifier for column: %v", sqlparser.String(qualifiedName))
			}
			colnum, err := findColumn(plan.Table, qualifiedName.Name)
			if err != nil {
				return err
			}
			val, ok := expr.Right.(*sqlparser.Literal)
			if !ok {
				return fmt.Errorf("unexpected: %v", sqlparser.String(expr))
			}
			//StrVal is varbinary, we do not support varchar since we would have to implement all collation types
			if val.Type != sqlparser.IntVal && val.Type != sqlparser.StrVal {
				return fmt.Errorf("unexpected: %v", sqlparser.String(expr))
			}
			pv, err := sqlparser.NewPlanValue(val)
			if err != nil {
				return err
			}
			resolved, err := pv.ResolveValue(nil)
			if err != nil {
				return err
			}
			plan.Filters = append(plan.Filters, Filter{
				Opcode: opcode,
				ColNum: colnum,
				Value:  resolved,
			})
		case *sqlparser.FuncExpr:
			if !expr.Name.EqualString("in_keyrange") {
				return fmt.Errorf("unsupported constraint: %v", sqlparser.String(expr))
			}
			if err := plan.analyzeInKeyRange(vschema, expr.Exprs); err != nil {
				return err
			}
		default:
			return fmt.Errorf("unsupported constraint: %v", sqlparser.String(expr))
		}
	}
	return nil
}

// splitAndExpression breaks up the Expr into AND-separated conditions
// and appends them to filters, which can be shuffled and recombined
// as needed.
func splitAndExpression(filters []sqlparser.Expr, node sqlparser.Expr) []sqlparser.Expr {
	if node == nil {
		return filters
	}
	switch node := node.(type) {
	case *sqlparser.AndExpr:
		filters = splitAndExpression(filters, node.Left)
		return splitAndExpression(filters, node.Right)
	}
	return append(filters, node)
}

func (plan *Plan) analyzeExprs(vschema *localVSchema, selExprs sqlparser.SelectExprs) error {
	if _, ok := selExprs[0].(*sqlparser.StarExpr); !ok {
		for _, expr := range selExprs {
			cExpr, err := plan.analyzeExpr(vschema, expr)
			if err != nil {
				return err
			}
			plan.ColExprs = append(plan.ColExprs, cExpr)
		}
	} else {
		if len(selExprs) != 1 {
			return fmt.Errorf("unsupported: %v", sqlparser.String(selExprs))
		}
		plan.ColExprs = make([]ColExpr, len(plan.Table.Fields))
		for i, col := range plan.Table.Fields {
			plan.ColExprs[i].ColNum = i
			plan.ColExprs[i].Field = col
		}
	}
	return nil
}

func (plan *Plan) analyzeExpr(vschema *localVSchema, selExpr sqlparser.SelectExpr) (cExpr ColExpr, err error) {
	aliased, ok := selExpr.(*sqlparser.AliasedExpr)
	if !ok {
		return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(selExpr))
	}
	switch inner := aliased.Expr.(type) {
	case *sqlparser.ColName:
		if !inner.Qualifier.IsEmpty() {
			return ColExpr{}, fmt.Errorf("unsupported qualifier for column: %v", sqlparser.String(inner))
		}
		colnum, err := findColumn(plan.Table, inner.Name)
		if err != nil {
			return ColExpr{}, err
		}
		as := aliased.As
		if as.IsEmpty() {
			as = sqlparser.NewColIdent(sqlparser.String(aliased.Expr))
		}
		return ColExpr{
			ColNum: colnum,
			Field:  plan.Table.Fields[colnum],
		}, nil
	case *sqlparser.FuncExpr:
		if inner.Name.Lowered() != "keyspace_id" {
			return ColExpr{}, fmt.Errorf("unsupported function: %v", sqlparser.String(inner))
		}
		if len(inner.Exprs) != 0 {
			return ColExpr{}, fmt.Errorf("unexpected: %v", sqlparser.String(inner))
		}
		cv, err := vschema.FindColVindex(plan.Table.Name)
		if err != nil {
			return ColExpr{}, err
		}
		vindexColumns, err := buildVindexColumns(plan.Table, cv.Columns)
		if err != nil {
			return ColExpr{}, err
		}
		return ColExpr{
			Field: &querypb.Field{
				Name: "keyspace_id",
				Type: sqltypes.VarBinary,
			},
			Vindex:        cv.Vindex,
			VindexColumns: vindexColumns,
		}, nil
	case *sqlparser.Literal:
		//allow only intval 1
		if inner.Type != sqlparser.IntVal {
			return ColExpr{}, fmt.Errorf("only integer literals are supported")
		}
		num, err := strconv.ParseInt(string(inner.Val), 0, 64)
		if err != nil {
			return ColExpr{}, err
		}
		if num != 1 {
			return ColExpr{}, fmt.Errorf("only the integer literal 1 is supported")
		}
		return ColExpr{
			Field: &querypb.Field{
				Name: "1",
				Type: querypb.Type_INT64,
			},
			ColNum:     -1,
			FixedValue: sqltypes.NewInt64(num),
		}, nil
	case *sqlparser.ConvertUsingExpr:
		colnum, err := findColumn(plan.Table, aliased.As)
		if err != nil {
			return ColExpr{}, err
		}
		field := plan.Table.Fields[colnum]
		plan.setConvertColumnUsingUTF8(field.Name)
		return ColExpr{
			ColNum: colnum,
			Field:  field,
		}, nil
	default:
		log.Infof("Unsupported expression: %v", inner)
		return ColExpr{}, fmt.Errorf("unsupported: %v", sqlparser.String(aliased.Expr))
	}
}

// analyzeInKeyRange allows the following constructs: "in_keyrange('-80')",
// "in_keyrange(col, 'hash', '-80')", "in_keyrange(col, 'local_vindex', '-80')", or
// "in_keyrange(col, 'ks.external_vindex', '-80')".
func (plan *Plan) analyzeInKeyRange(vschema *localVSchema, exprs sqlparser.SelectExprs) error {
	var colnames []sqlparser.ColIdent
	var krExpr sqlparser.SelectExpr
	whereFilter := Filter{
		Opcode: VindexMatch,
	}
	switch {
	case len(exprs) == 1:
		cv, err := vschema.FindColVindex(plan.Table.Name)
		if err != nil {
			return err
		}
		colnames = cv.Columns
		whereFilter.Vindex = cv.Vindex
		krExpr = exprs[0]
	case len(exprs) >= 3:
		for _, expr := range exprs[:len(exprs)-2] {
			aexpr, ok := expr.(*sqlparser.AliasedExpr)
			if !ok {
				return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected: %T %s", expr, sqlparser.String(expr))
			}
			qualifiedName, ok := aexpr.Expr.(*sqlparser.ColName)
			if !ok {
				return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected: %T %s", aexpr.Expr, sqlparser.String(aexpr.Expr))
			}
			if !qualifiedName.Qualifier.IsEmpty() {
				return vterrors.Errorf(vtrpcpb.Code_UNIMPLEMENTED, "unsupported qualifier for column: %v", sqlparser.String(qualifiedName))
			}
			colnames = append(colnames, qualifiedName.Name)
		}

		vtype, err := selString(exprs[len(exprs)-2])
		if err != nil {
			return err
		}
		whereFilter.Vindex, err = vschema.FindOrCreateVindex(vtype)
		if err != nil {
			return err
		}
		if !whereFilter.Vindex.IsUnique() {
			return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "vindex must be Unique to be used for VReplication: %s", vtype)
		}

		krExpr = exprs[len(exprs)-1]
	default:
		return vterrors.Errorf(vtrpcpb.Code_INTERNAL, "[BUG] unexpected in_keyrange parameters: %v", sqlparser.String(exprs))
	}
	var err error
	whereFilter.VindexColumns, err = buildVindexColumns(plan.Table, colnames)
	if err != nil {
		return err
	}
	kr, err := selString(krExpr)
	if err != nil {
		return err
	}
	keyranges, err := key.ParseShardingSpec(kr)
	if err != nil {
		return err
	}
	if len(keyranges) != 1 {
		return fmt.Errorf("unexpected in_keyrange parameter: %v", sqlparser.String(krExpr))
	}
	whereFilter.KeyRange = keyranges[0]
	plan.Filters = append(plan.Filters, whereFilter)
	return nil
}

func selString(expr sqlparser.SelectExpr) (string, error) {
	aexpr, ok := expr.(*sqlparser.AliasedExpr)
	if !ok {
		return "", fmt.Errorf("unsupported: %v", sqlparser.String(expr))
	}
	val, ok := aexpr.Expr.(*sqlparser.Literal)
	if !ok {
		return "", fmt.Errorf("unsupported: %v", sqlparser.String(expr))
	}
	return string(val.Val), nil
}

// buildVindexColumns builds the list of column numbers of the table
// that will be the input to the vindex function.
func buildVindexColumns(ti *Table, colnames []sqlparser.ColIdent) ([]int, error) {
	vindexColumns := make([]int, 0, len(colnames))
	for _, colname := range colnames {
		colnum, err := findColumn(ti, colname)
		if err != nil {
			return nil, err
		}
		vindexColumns = append(vindexColumns, colnum)
	}
	return vindexColumns, nil
}

func findColumn(ti *Table, name sqlparser.ColIdent) (int, error) {
	for i, col := range ti.Fields {
		if name.EqualString(col.Name) {
			return i, nil
		}
	}
	return 0, fmt.Errorf("column %s not found in table %s", sqlparser.String(name), ti.Name)
}


The purpose of these projects is to gather different forms of data, and come up with own way of visually representing the data.
all different aspects of information together into a single piece. Gathering all the data process was the most challenging for me.
Details / Colors, lyrics and information about the artist has been visualized under the same concept with the music video.
Details / On the top right of this infographic are legend indicate the elements, such as sound effects and hidden meanings of the lyrics.


With new state-of-the-art workshops and prototyping labs, the Emera IDEA Building dramatically expands the Faculty's capacity for research & development.
The Richard Murray Design Building provides a wealth of new student spaces, including meeting rooms, a new design commons, and the Sexton Campus' largest classroom.
The Chemical Engineering and A.E. Cameron building have had their exteriors refurbished and their interiors entirely rebuilt to provide cutting edge facilities for the applied sciences and process engineering.
The Advanced Manufacturing Hub houses infrastructure that supports our world-leading researchers in the development of sustainable industrial processes for manufacturing advanced materials.
Innovation enhances our lives, makes us safer, and makes our society more sustainable, all while fueling economic growth. New technologies, fresh ideas, and design-driven ingenuity are the resources that keep our country an international economic leader. That's why the demand for highly skilled, professional, innovation workers continues to increase every year.
Dalhousie's Faculties of Engineering and Architecture have a key role to play in fostering innovation in Halifax and in driving economic growth nationally and internationally. The IDEA Project is an acknowledgement of that role and the responsibility it entails.
The IDEA Project is the largest capital investment in the Sexton Campus since the 1970s: a $64-million investment to contruct new buildings, revitalize existing infrastructure, and provide our students and faculty with the classrooms, labs, workshops, and meeting spaces they need to collaborate and innovate.
Sexton Campus has been the home of engineering training and excellence in Nova Scotia since its inception in 1907 and in architecture since 1961: a legacy bolstered by IDEA Project's renewal. The revitalization of our downtown campus promises to inspire the next generation of highly skilled, innovative young professionals at a time of growing demand for design-driven ingenuity.
The centrepiece of the IDEA Project is two new academic buildings on the Sexton Campus: the Emera IDEA Building, which houses state-of-the-art workshops, prototyping labs, and innovation studios, and the Richard Murray Design Building, which includes a 450-seat auditorium, a design commons and meeting rooms where students can collaborate, and studio space for the Faculty of Architecture and Planning.
The Emera IDEA Building is also home to the Emera ideaHUB, an advanced engineering incubator/accelerator space to enhance students' educational experience and foster connections between our engineering community and Halifax's entrepreneurs. Made possible by a $10-million gift from Emera, the Emera ideaHUB will play a key role in transforming Halifax into a hub of innovation in Atlantic Canada.
the Chemical Engineering (F) Building has had its exterior renovated and its interior entirely rebuilt, while the A. E. Cameron Building has been extensively refurbished. These revitalized spaces will be the new home for our Applied Science and Process Engineering programs.
the Electrical Engineering (C) Building, along with the H. Theakston (C1) building, has received substantial upgrades to its research spaces. These new research spaces will form the cores of the Advanced Manufacturing Hub and the Ocean Engineering Hub.
the D building has undergone significant renovation to enhance its sustainability, particularly with regards to the energy efficiency of the building exterior.
a green corridor has been added to the exterior infrastructure of the Sexton Campus, connecting Spring Garden Road to Morris Street and encouraging active transportation.
The design of the IDEA Project represents a demonstration of the Faculty of Engineering's commitment to the ideals of sustainability and diversity.
Many of the new workspaces IDEA provides will be used to develop sustainable technologies, but the IDEA Project's contributions to sustainability begin with the buildings themselves. Designed with sustainability in mind, Sexton's new buildings and renovated spaces improve efficiency, reduce greenhouse-gas emissions and support student and faculty learning and research.
Renovated space on the Secton Campus is reserved for outreach programming for young people to explore engineering and science and encourage them to consider careers in these fields. This initiative is also a reflection of the Faculty's broader commitment to diversity. Imothep's Legacy Academy is a significant user of this space, and their outreach programming for young people of African descent is a leading example of this approach.


text:
Tomsk-400 wins Russian Team Cup
They did it in 2007 and this year they did it again: Tomsk-400, the team lead by Jakovenko and Timofeev, won the Premier League of the Russian Team Cup with 11 match points and 23.5 game points out of 7 matches. Spartak won the Women's League while Polytechnik came first in the second-level "Higher League".
The Russian Team Cup took place in Dagomys April 4-10, 2009. This year only 7 rounds were played in the Premier League, after the economic situation caused a couple of teams to withdraw. The Women's League was also 8 teams; the league below the Premier, interestingly called Higher League, consisted of 10 teams, and started two days earlier.
Moscow 64 was leading the pack, one point ahead of Tomsk-400 and two points ahead of St. Petersburg and Economist. The team from Russia's capital drew with Economist in round 6; Najer lost to European Champ Tomashevsky but Caruana defeated another strong player, Ni Hua, to level the score. The 16-year-old Italian scored 5.0/6 in Dagomys; a fantastic 2896 performance!
The Tomsk team joined Moscow in the lead thanks to an excellent 2.5-3.5 victory over St. Petersburg where the only decisive games was Tkachiev's win over Zvjaginsev.
Moscow then lost their final round match against St. Petersburg 2.5-3.5, and so Tomsk, beating Eurasia-Logistic with the same score, eventually took the cup. Amonatov was the man of the match, scoring the only win, against Rychagov.
[TABLE=691] [TABLE=688]
Games selection rounds 6-7
Polytechnik, a team led by relatively unknown GMs Kokarev and Maletin, won the Higher League while Spartak, with Stefanova, the Kosintseva sisters, Lahno and Ovod, won the Women's - only by one board point, though.
Europe-Echecs videos


Lets say you are a small average investor and you have $300, looking to buy bitcoin on this black friday sale. Buy $100 now then wait a day or two and see if there is any price action. Whether up or down, buy again with the next $100. Learn about the unit of Satoshi's within a bitcoin.