text:
Home / 4Q 2022 Recap & 1Q 2023 Outlook
Recapping A Challenging 2022
Markets faced several challenges in 2022, including high inflation, historic central bank policy, the war in Ukraine, and Covid lockdowns in China. Inflation was a major factor in the markets throughout the year, with the headline consumer price index reaching a 40-year high of 9.1% in June. High inflation prompted the Federal Reserve and its global central bank peers to aggressively raise interest rates, which caused stocks and bonds to trade lower. There was no place to hide as central banks rapidly tightened monetary policy. Figure 1 shows the S&P 500 returned -19.4% in 2022, its worst annual return since 2008, and Figure 5 shows the Bloomberg U.S. Bond Aggregate produced its worst total return since 1976. This letter reviews the fourth quarter, recaps a difficult 2022, and discusses what the market will be focused on in 2023.
Putting 2022's Interest Rate Hikes Into Perspective
The main story of 2022 was the reversal of monetary policy from extraordinarily accommodative levels during the Covid-19 pandemic. Figure 2 shows the speed and size of interest rate increases as central banks worked to bring inflation under control. The chart tracks the cumulative percentage of interest rate increases and decreases by global central banks during rolling three-month periods since 1995. For example, the 68% at the end of November 2022 indicates that central banks across the globe raised interest rates by a total of 68% from September to November. In contrast, the total amount of interest rate cuts during that same period was only 4%. As the data shows, 2022 was the quickest, largest, and most imbalanced global tightening cycle since the late 1990s.
The pace of interest rate increases is forecasted to slow during 2023. Central banks continue to hint that they are approaching the end of their interest rate hike cycle, citing concerns that further tightening could push the economy into recession. In addition, data suggests price pressures are easing. While the year-over-year headline consumer price index rose by 7.1% in November 2022, which is still high compared to historical levels, it was down from the 9.1% rate seen in June 2022. As inflation and central bank policy return to normal, a new uncertainty is emerging – the unknown effects of 2022's rate hikes.
Markets Wait for the Lagged Effect of Higher Interest Rates to Show Up in Economic Data
The Federal Reserve's interest rate hikes occurred in 2022, but the full impact of its restrictive measures has not yet been fully felt in the real economy. While the U.S. economy contracted during the first half of 2022, it expanded at a robust +3.2% annualized pace during the third quarter. Consumer spending remained strong throughout most of 2022 despite high inflation, and the U.S. labor market added more than 4 million jobs through the end of November. The data indicates the U.S. economy has withstood tightening thus far, but the real test will come in 2023 as the cumulative impact of higher interest rates becomes clearer.
While a recession is not a foregone conclusion, it is possible the economy could be tested in 2023. An index of leading economic indicators shows the U.S. economy is already starting to slow as the impact of higher interest rates takes hold. Figure 3 graphs the month-over-month change in The Conference Board's Leading Economic Index, which tracks ten economic components that tend to precede changes in the overall economy. Included in the components are the average weekly hours worked by manufacturing workers, new home building permits, and the volume of new orders for capital goods, such as equipment, vehicles, and machinery. The chart reveals that the Leading Economic Index has decreased every month since March 2022, an indication the economy is slowing after a period of strong growth during the pandemic recovery.
Equity Valuations Are More Attractive, But Corporate Earnings Are An Open Question
Whereas inflation and central bank policy were the primary drivers of markets in 2022, economic data and corporate fundamentals are expected to play a larger role in determining the market's direction in 2023. Figure 4 tracks two important S&P 500 metrics. The top chart tracks the next 12-month price-to-earnings ratio, which divides the S&P 500's projected next 12-month earnings by its current price. It shows valuation multiples expanded during the pandemic as interest rates were cut to near 0% before reversing lower during 2022 as rising interest rates weighed on company valuations.
While current valuations are at a more attractive starting point today than at the beginning of 2022, corporate earnings are an open question entering 2023 with the potential for an earnings reset as the economy slows. The bottom chart in Figure 4 tracks the S&P 500's trailing 12-month earnings growth, showing the jump in corporate earnings during the pandemic. Despite expectations for an economic slowdown, Wall Street analysts still forecast single-digit earnings growth for the S&P 500 in 2023. The positive earnings growth forecast is encouraging, but it creates a risk for the market. If actual earnings growth falls short of the forecast, stock prices could decline as markets price in lower actual earnings.
Equity Market Recap – Stocks Trade Higher in 4Q'22
Stocks traded lower during December but still ended the fourth quarter higher. The S&P 500 Index of large cap stocks returned +7.6% during the fourth quarter, outperforming the Russell 2000 Index's +6.2% return. The Dow Jones Index, which includes large companies such as Visa, Caterpillar, Nike, and Boeing, was the top performer, returning +15.9%, while the Nasdaq 100 Index of technology and other growth-style stocks produced a -0.1% return during the fourth quarter.
Energy was the top performing S&P 500 sector during the fourth quarter, followed by the cyclical sector trio of Industrials, Materials, and Financials. Defensive sectors, including Health Care, Consumer Staples, and Utilities, were middle of the pack performers. Growth-style sectors, including Technology, Communication Services, and Consumer Discretionary, and interest-rate sensitive Real Estate underperformed as higher interest rates continued to weigh on valuation multiples.
International stocks outperformed U.S. stocks during the fourth quarter. The MSCI EAFE Index of developed market stocks returned +17.7% during the fourth quarter, while the MSCI Emerging Market Index returned +10.3%. A weaker U.S. dollar boosted the returns of international stocks, with U.S. dollar weakness driven by a shrinking monetary policy gap as other central banks catch up with the Federal Reserve's aggressive policy. Separately, China's decision to relax its Covid-zero restrictions raised the prospect of stronger global growth as one of the world's biggest economies reopens.
Bond Market Recap – The Great 2022 Yield Reset
The bond market experienced a significant resetting of interest rates during 2022, with yields steadily rising as the Federal Reserve pushed through large interest rate hikes. Despite posting positive returns during the fourth quarter, bonds produced significant losses during 2022 as central banks raised interest rates at a rapid pace. The top chart in Figure 5 shows the Bloomberg U.S. Bond Aggregate produced a -13% total return during 2022, its biggest negative total return since tracking began in 1976. The bottom two charts in Figure 5 examine the current state of the credit market after 2022's rate hikes. The middle chart shows the 10-year Treasury yield sits at its highest level since 2007. Yields are now higher across most credit classes, and investors can earn a yield of around 4% to 5% on a portfolio of high-quality bonds, such as U.S. Treasury bonds and investment grade corporate bonds, without locking up capital for long periods of time. In the corporate credit market, the bottom chart shows the high-yield corporate bond spread, which is the extra yield investors demand to loan to lower quality borrowers, is in line with its median since 1999.
The starting point for bonds, both in terms of yield and credit spreads, is now more compelling than it has been in a long time. However, there is still the potential for continued volatility in the bond market. There is still significant uncertainty regarding how high the Fed will need to raise interest rates and how long it will need to keep interest rates at restrictive levels to bring inflation down to normal levels. There is a risk that inflation could remain above the Fed's 2% target, leading to an extended tightening cycle. At the same time, the economy is likely to start feeling the effects of 2022's rate hikes in 2023, which could make bonds more attractive. The crosscurrents of uncertain central bank policy and a volatile global economy could keep interest rate volatility elevated and test bond investors' nerves again during 2023.
2023 Outlook – Turning the Page on 2022's Historic Tightening Cycle
2023 brings the next phase of the tightening cycle where the lagged effects of tighter monetary policy will be felt. It has the potential to be a year of two halves. In the first half, the focus is likely to shift from the number of future interest rate hikes to how much those interest rate hikes will slow the economy. Some data, such as the housing market, indicate that tighter monetary policy is being transmitted into the economy at a rapid pace. Home sales are slowing, and homebuilder confidence weakened every month during 2022 and now sits at its lowest level since 2012. At the same time, consumers continue to spend, and employers continue to add jobs. There is still a wide range of possible outcomes, and the unique nature of the pandemic followed by rapid interest rate cuts and hikes makes the path forward less certain.
The second half has the potential to be different depending on how severe the slowdown is in early 2023. Markets are based on forward-looking decisions, and investors will be watching closely for signs that the economy has bottomed and is recovering. Plus, Figure 1 contains an encouraging historical trend. The chart shows there have only been two instances of consecutive negative S&P 500 return years since 1950, in 1973-1974 and 2000-2002. This does not necessarily mean the S&P 500 will produce a positive return in 2023 or trade higher in a straight line from here, because it may not. However, it does provide helpful historical context in a volatile environment.
Wishing you and your family happiness and health in the New Year! We look forward to serving you another year.
Important Notices & Disclaimer
The information and opinions expressed herein are solely those of PFG Private Wealth Management, LLC (PFG), are provided for informational purposes only and are not intended as recommendations to buy or sell a security, nor as an offer to buy or sell a security. Recipients of the information provided herein should consult with their financial advisor before purchasing or selling a security.
The information and opinions provided herein are provided as general market commentary only, and do not consider the specific investment objectives, financial situation or particular needs of any one client. The information in this report is not intended to be used as the primary basis of investment decisions, and because of individual client objectives, should not be construed as advice designed to meet the particular investment needs of any investor.
The comments may not be relied upon as recommendations, investment advice or an indication of trading intent. PFG is not soliciting any action based on this document. Investors should consult with their financial adviser before making any investment decisions. There is no guarantee that any future event discussed herein will come to pass. The data used in this publication may have been obtained from a variety of sources including U.S. Federal Reserve, FactSet, Bloomberg, Bank of America Merrill Lynch, iShares, Vanguard and State Street, which we believe to be reliable, but PFG cannot be held responsible for the accuracy of data used herein. Any use of graphs, text or other material from this report by the recipient must acknowledge MarketDesk Research as the source. Past performance does not guarantee or indicate future results. Investing involves risk, including the possible loss of principal and fluctuation of value. PFG disclaims responsibility for updating information. In addition, PFG disclaims responsibility for third-party content, including information accessed through hyperlinks.
No mention of a particular security, index, derivative or other instrument in the report constitutes a recommendation to buy, sell, or hold that or any other security, nor does it constitute an opinion on the suitability of any security, index, or derivative. The report is strictly an information publication and has been prepared without regard to the particular investments and circumstances of the recipient.
READERS SHOULD VERIFY ALL CLAIMS AND COMPLETE THEIR OWN RESEARCH AND CONSULT A REGISTERED FINANCIAL PROFESSIONAL BEFORE INVESTING IN ANY INVESTMENTS MENTIONED IN THE PUBLICATION. INVESTING IN SECURITIES AND DERIVATIVES IS SPECULATIVE AND CARRIES A HIGH DEGREE OF RISK, AND READERS MAY LOSE MONEY TRADING AND INVESTING IN SUCH INVESTMENTS.
PFG Private Wealth Management, LLC is a registered investment advisor.
Tags: Financial Advice, Financial Advisor, Financial Planning, Investment Management, investments, Retirement, Stock Market, Wealth Management
Previous Post Putting Context Around Recent Stock Market Volatility
Next Post Ep 54: Warning Signs: How To Spot Problems In Your Financial Life


THE opposition MDC led by Nelson Chamisa is likely to hold its congress in October after a national standing committee meeting held on Wednesday failed to come up with a date, NewsDay has learnt.
Sources who attended the meeting said there were heated exchanges during the meeting over the interpretation of the party's constitution.
But Chamisa told his lieutenants that he would have the final word.
Chamisa reportedly clashed with party secretary-general, Douglas Mwonzora after the latter recused himself from indicating which date he preferred congress to be held.
"It was a heated meeting. Chamisa asked everyone to give a date on which the congress should be held, but Mwonzora refused probably feeling he had been waylaid. Chamisa probably wanted to gauge his adversaries' preparedness and was angered by Mwonzora's response," a source said.
Chamisa controversially rose to power last February railroading the party's national council into endorsing him as successor after founding leader, Morgan Tsvangirai passed away in South Africa.
Tsvangirai's death triggered an internal power struggle that resulted in then co-vice-president Thokozani Khupe breaking away, while another vice-president, Elias Mudzuri and Mwonzora stayed on. They are reportedly plotting to challenge Chamisa at congress.
Another source, however, said Chamisa had given everyone a chance to give their interpretation of the constitutional provisions.
"Chamisa asked everyone to read the constitution and give their interpretation of when the congress should be held. Our constitution says congress must be held every five years, but a special congress can be held in the event of a vacancy in the office of the president before his or her term expires.
"While we all know that Chamisa was endorsed by the national council to take over as substantive leader, it is important to note that it would be unhygienic to hold an extra-ordinary congress in the same year as a congress proper," NewsDay heard.
Party spokesperson Jacob Mafume confirmed that the standing committee discussed the issue of political dialogue, congress and the situation in the country.
"It was an open meeting in which people were allowed to air their views regarding congress. While we do not have a specific date yet, most agreed that we will have it in October. What is left are logistics and, in any case, our structures will have to begin this process soon," Mafume said.
Mwonzora refused to comment on the claims of an altercation between him and Chamisa.
"The national standing committee is a private meeting whose discussions are the preserve of members of the party," he said.


Fuddruckers Saskatoon serves the World's Greatest Burgers handmade daily on freshly baked buns with a build your own produce bar and a sauce selection to die for! We also offer delicious salads, fries, milkshakes, & pies –our menu has something for everyone, including those with gluten intolerance. In addition, did you know that Fuddruckers has Saskatoon restaurant gift cards, Rucker's gift cards and that we have a gift card reward program?
We are contacted about Fuddruckers gift cards throughout the year, but enquiries really increase when we near the festive season. In our latest Fudds news, we answer the most frequently asked questions about Fudds Saskatoon restaurant gift cards and Ruckers / Family Fun Centre gift cards. In addition, we wanted to share the Fuddruckers 2019 gift card reward program!
Fuddruckers Saskatoon restaurant gift cards & Rucker's gift card FAQs.
Q: What denominations are available in the gift cards?
A: Our gift cards can be any amount you want.
Q: Are they paper copies, plastic cards or electronic gift cards?
We have 2 types of gift cards.
Our plastic, credit card style reloadable gift cards, which are only available for Fuddruckers Family Restaurant in Saskatoon.
Q: Where do we purchase the gift cards?
A: The plastic Fuddruckers Saskatoon restaurant gift cards are only available for purchase in the restaurant at the front till. The paper gift cards for Fudds, Rucker's and the Family Fun Center can be purchased in either of Rucker's two Saskatoon locations.
What is the Fuddruckers Gift Card Incentive program?
Please note: This reward can only be redeemed between Jan 01 – Feb 28, 2019 – and is only valid at Fuddruckers Saskatoon location.
Swing by and buy your gift cards today!
They are guaranteed to be appreciated stocking stuffers for friends and family as well as staff and client appreciation gifts!
Make the World a Burger Place!


Home Tech Handyman Services is a proud service provider for Dallas/Ft. Worth. We believe in our customers opinion and value every kind word and thoughtful feedback.
What is the difference between a contractor and a Handyman?
A contractor does the service you want, and a Home Tech Handyman gives you the service you need no "flatting pockets" gimmick's or unnecessary up-charges. We offer several options and figure out the best feasible way to get the job done at a reasonable and fair price.
What if I have a multitude of home improvement projects?
Home Tech Handyman Service provides an itemized estimate based on project. This way the customer is not obligated to the entire quote and can pick and choose a different project to be completed at their own convenience and expense.
Can I review and compare Quotes?
A quoted estimates is good for 90-days, there is no hassle or customer service representative calling you every day with pressure to start. At Home Tech Handyman Services we understand "budget & planning" and wanting a service at a fair and reasonable price.Take as much time you need. We will gladly price match or come back out after the 91-days and provide you with a new estimate at a small cost..


It must have been in late 2017 when Red Hat's VPN servers were rebooted for a kernel upgrade. A few days later I was contacted by someone who knew that I am working on Checkpoint/Restore in Userspace (CRIU) and asked if CRIU could be used to avoid terminated VPN connections due to a reboot of the VPN server. Always happy to hear about interesting use cases for CRIU I thought that this sounds like great idea to try out and answered that it should be theoretically possible.
For those not familiar with CRIU, the goal of CRIU is to "freeze" an application or process, then save the files and restore them later to run as they were when frozen. This is to enable things like migrating containers or application snapshots, or to avoid terminating VPN connections!
Now that we know that it actually works to update the kernel on an OpenVPN server without terminating the connections between clients and server I want to go into the details what I did to set this up.
I am using 'unshare -n' to run my command in a new network namespace. 'setsid' and the stdin and stdout redirection ('&> /dev/null < /dev/null') is used to make it easier for CRIU to dump the process.
Up to this point I have configured a regular OpenVPN based VPN tunnel with the only exception that the server part of the connection is running in a network namespace. Now that all this works I can finally checkpoint and restore my OpenVPN server process.
--ext-mount-map auto --enable-external-sharing --enable-external-masters - all those options are helping CRIU to correctly handle checkpointing a process in a network namespace. If using CRIU as part of a container runtime to checkpoint and restore a container, this would happen automatically.
CRIU will complain if something did not work, but if the checkpointing was successful it will write the checkpoint image to the specified directory. At this point the OpenVPN process will be gone and the ping command on the client side will stop receiving replies. The client side still thinks that the VPN tunnel is alive but the server process is gone.
--external veth[veth1]:veth0@br0 - this option tells CRIU how to wire the network interface in the network namespace to the host's network setup. This is basically the same as the manual setup of the network namespace when the VPN server process was initially started.
If CRIU succeeds to restore the process the OpenVPN server process will continue to run and the ping command on the client side should receive replies again.
Now the basic functionality, to checkpoint and restore the OpenVPN server process, is working. All that is left to do is combine the checkpointing and restoring with a reboot. I am using kexec to reboot as it should be faster which should reduce the downtime of the OpenVPN server process.
$ kexec -l /boot/vmlinuz-3.10.0-862.14.4.el7.x86_64 --initrd=/boot/initramfs-3.10.0-862.14.4.el7.x86_64.img --command-line="root=UUID=8c1540fa-e2b4-407d-bcd1-59848a73e463 ro console=tty0 console=ttyS0,115200n8 crashkernel=auto console=ttyS0,115200 LANG=en_US.UTF-8"
The version of the kernel and the ramdisk (initramfs) depends on which kernel is installed and the value for --command-line= is copied from /proc/cmdline.
With this proof of concept I am able to reboot the OpenVPN server into a new kernel with a downtime of fewer than 10 seconds and without losing the connection between client and server.
So my initial assumption that it should be theoretically possible turned out to be correct and with some manual configuration of a network namespace it actually was easy to get it running.
With this proof of concept I am able to reboot the OpenVPN server into a new kernel with a downtime of less than 10 seconds and without losing the connection between client and server.


text:
Archbishop Gomez Brings Accountability to the Catholic Church
By Timothy R. Busch, Founder of the Napa Institute
Originally posted in National Catholic Register
COMMENTARY: The election last month of the Los Angeles archbishop as president of the U.S. Conference of Catholic Bishops is the most recent sign of hope.
The Christmas season has been noticeably less joyous in the Catholic Church the past few years. Continued news about old abuse scandals, allegations of cover-ups, and egregious behavior by priests and bishops alike have pushed countless parishioners away during the happiest time of the year.
Yet now the faithful — and all who care about protecting children — have reason for renewed hope. The Church in the U.S. is taking greater steps toward accountability.
The election last month of Los Angeles Archbishop José Gomez as president of the U.S. Conference of Catholic Bishops is the most recent sign of hope. The U.S. bishops placed their trust in the first Latino to head the Church's governing body in America in part because he has a track record of caring for the neglected and downtrodden, including abuse victims.
During his eight years in Los Angeles, Archbishop Gomez has earned high marks for his transparency in the handling of abuse allegations and implementing child-safety protocols. Last year, the archdiocese released the names of priests who were "plausibly" accused of abuse, whereas other dioceses only acknowledge "credible" allegations.
Also important: Instead of handling everything in-house, Archbishop Gomezhas coordinated with professional lay Catholics — non-priests and non-Church employees — whom he calls his "co-workers."
As USCCB president, Archbishop Gomez will oversee the implementation of historic new accountability measures, the broad contours of which were passed by the USCCB in June. The final policies will fulfill Pope Francis' call for the bishops of every country to design a "public, stable, and easily accessible" system for people to submit allegations of abuse or cover-ups by Catholic priests and bishops.
The first big test of this system in America will come in early 2020, when the USCCB unveils a new toll-free hotline and dedicated websites through which anyone can report an abuse-related crime or complaint. The USCCB will heavily publicize these new tools, for good reason. They will allow every allegation to be aired and heard. Nothing will be swept under the rug.
The USCCB is also advancing unprecedented measures to hold bishops accountable. Historically, these senior leaders have avoided meaningful oversight, a cause of much scandal and a source of profound distrust for those of us in the pews. No longer. For the first time, every allegation involving a bishop will be reported to Church authorities as well as lay leaders.
Lay Catholics will be involved in the reporting system in two ways. First, each of the Church's 30-plus geographic areas in America will choose a lay leader to receive every complaint involving a bishop — with no exceptions. These individuals can release that information to the public, even if Church officials try to stop them. The USCCB is currently identifying the best people for these important jobs.
Second, the bishops in each region are identifying qualified lay leaders who will discern the credibility of allegations and recommend next steps. Crucially, the USCCB is taking steps to prevent conflicts of interest.
For example, a layperson appointed by a bishop cannot also participate in the investigation of that same bishop. Church authorities will be unable to stop the boards from fulfilling their duty.
Archbishop Gomez and his fellow bishops support this system because they've seen it work, albeit at a lower level.
In the wake of the Boston sex-abuse scandal in the early 2000s, the USCCB ordered every diocese to create local review boards, run primarily by lay Catholics, to investigate accusations against priests and create policies to prevent future abuse.
This system has contributed to the dramatic decline in priestly abuse of minors.
Last year, the local lay boards documented more than 860 credible allegations, yet only 5% occurred after the year 2000. Even one credible allegation is too many, and more lay oversight — especially for bishops — will continue to expose and expel the Church leaders who perpetrate such crimes and cover them up.
America's bishops, led by Archbishop Gomez, are now holding themselves to a higher standard. Their actions herald a new — and long overdue — era of accountability, transparency and protection for children in the U.S. Catholic Church. Catholic or not, that's something to celebrate this Christmas season.

redpajama_set_name: RedPajamaCommonCrawl


Forums Terms and Disclaimer - Newbies Assistance - Craxme.com - Powered by Discuz!
CraxMe Forum is a website created under the Forum model, which allows free association and registration of users with varied interests who wish to share knowledge through digital content (digital files of any known format and/or links).
CraxMe Forum is established and located in India and is subject to relevant legislation in that country.
CraxMe Forum reserves the right to prohibit (ban) and/or void any user account that violates the general and/or specific regulations of CraxMe and its sections.
1.1.1. About of CraxMe Forum use.
CraxMe Forum (hereinafter "CraxMe" or "CraxMe Forum") authorizes the user to post, view and download the materials on this website (prior registration and login) solely for their personal and non-commercial use, the illegal use of the materials that hosts and/or shared by users in CraxMe is not allowed. The user must indicate all the copyright and intellectual property notices contained in the original materials in any copy of said materials that the user shares in CraxMe Forum. The user will not be able to modify the materials in this site of any form for its commercialization.
For the purposes of these terms, any link, file of any kind, comment, opinion, emanating from the user on CraxMe, is entirely the responsibility (personal and legal) of the user, CraxMe is not responsible for the activities that contravene the rulers and CraxMe reserves the right to edit and/or delete any publication of users, which endangers the legal integrity of CraxMe.
1.1.2. The shared (upload) and the download of any content and/or material shared by users, is entirely the responsibility of whoever upload or downloads it. CraxMe is not responsible for the wrong or illegal use that users may make of the material shared and downloaded. CraxMe does not encourage or sponsor the commercialization or obtain economic or financial benefits from the material that users share or download.
1.1.3. About the links of other shared websites and/or textual information quoted from third parties or external sources to CraxMe.
CraxMe in its space allows to the users to share links that can lead to third party websites outside of CraxMe. In that sense, navigation outside the site CraxMe is the sole responsibility of users.
CraxMe is not responsible in any way for the content of third-party websites whose links are shared on CraxMe.
CraxMe reserves the right to edit and/or delete any shared links that violate the regulations established in its sections or at the discretion of its Administration and/or Team of Moderators.
Disclaimer: Links to third party Internet sites on this site are included solely for the convenience of users. If the user uses these links, user will stop being on this site. CraxMe has not reviewed such third party sites, and does not control or be responsible for them or their content. Therefore, CraxMe does not endorse or make any statements regarding such sites, nor with respect to the information, software or other products or materials contained therein, nor for any results that may be obtained from its use. If the user decides to access third-party websites whose links appear on this site, the user will do so at his sole risk.
2. Declaration of limitation of liability.
The files and/or links that are shared by users on this site are shared "as is", without any guarantee by CraxMe, including guarantees of fitness or permission to market, for a particular purpose or rights intellectual property rights of others.
CraxMe does not grant any permission to market any content or material in its name. Likewise, CraxMe does not guarantee the accuracy, state and level of conformity of files, links or materials shared by users. At any time and without notice, CraxMe could introduce changes or delete any content of the Forum without that action leading or provoking legal claim any of any user or third party.
The files and/or links shared by users in CraxMe Forum may not be up-to-date, and CraxMe does not undertake any obligation to update or provide any support or derivative service.
The information, files, shared links and published in CraxMe may not be accessible from some countries with their own legal restrictions, CraxMe assumes no responsibility derived from that situation.
Neither CraxMe Forum nor its Administrators or Moderators mentioned or not on this site will be liable under any circumstances for any type of damage caused by the information, files, links and/or materials/contents shared by its users (including, without limitation, resulting from situations of loss of profit, loss of data or interruption of activities) that arise as a result of the use, impossibility of use or consequences of the use of this site, any Internet site whose link is on this site or the materials, information or services contained in any such site, whether such damages are based on warranties, contractual liability, civil unlawful or any other legal theory, and whether or not there has been a warning about the possibility of such damages. If your use of such materials, information or services results in you incurring costs of maintenance, repair or correction of equipment or data, you will bear all costs.
Applicable law may not authorize the exclusion or limitation of incidental or consequential damages, so this limitation may not apply to you.
2.2. Procedure to file claims for copyright violations.
Any notification of copyright infringement should be sent to the point of origin of the Information, files, links and/or materials/content shared in CraxMe Forum (the point of origin of any information shared and contained in CraxMe Forum comes solely and exclusively from its users).
Any person (natural or juridical) may contact CraxMe and request modification and/or deletion of any content shared and posted by users at CraxMe Forum, only attaching the reasons that give your request a relevant legal basis. The acceptance of CraxMe about the modification and/or elimination of any content shared in CraxMe Forum, does not imply any recognition of economic and/or legal responsibility.
CraxMe only recognizes its ability and responsibility to modify and/or eliminate any content shared by its users and in order to safeguard the integrity of any economic or legal rights of claims of third parties that have been compromised.
CraxMe, its Administrators and Moderators are committed to respecting and protecting the privacy of its users. CraxMe Forum has been designed, structured and developed on the Internet so that, in general, you can browse CraxMe Forum and the contents shared by its users through a secure connection.
CraxMe undertakes not to disclose personal information to third parties under any reason other than strictly by legal and/or judicial mandate. If you choose to provide us with personally identifiable information (ie any information through which you can identify yourself), you can be sure that it will only be used within the framework of your CraxMe - User relationship, only to allow you access to the Forum.
CraxMe Forum makes public these statements of use, responsibility, privacy and other concepts, to inform any interested party about the scope of our internal policies, our practices and the options available to them on how all information is collected and used. In order for these statements to be easily accessible by any person or entity, they are public and do not need to be registered in the CraxMe Forum in order to download or read them.
CraxMe Forum will not sell or rent your personally identifiable information to others, unless the law requires it.


MCCC grant opens August 27, 2018. Curious about learning how to apply? Join us for an optional information session.
The Multnomah County Cultural Coalition (MCCC) works to foster a community that is rich in cultural offerings and increase the likelihood of cultural participation among the broadest spectrum of county residents. Multnomah County is home to over 100 heritage, humanities and arts non-profits and we strive to support them. MCCC is the re-granting board of the Oregon Cultural Trust in Multnomah County. Monies donated to the Cultural Trust come back to Multnomah County and are distributed as grants to cultural organizations. MCCC's maximum grant award is $2,000.
What can MCCC grants support?
MCCC grants support a wide variety of activities. Examples of possible grants include expenses for activities such as interactive art exhibits, reading and discussion groups, a neighborhood art fair, projects to preserve an aspect of the county's cultural history, performances, workshops, lectures, and other projects that clearly deepen cultural participation. Programs must be open to the public, and broadly advertised.
To be eligible for a MCCC grant, applicants must have a project that serves Multnomah County residents. Eligible organizations or groups are those whose primary purpose is to provide general benefit to the public. This includes registered neighborhood associations, groups of citizens with a declared common purpose that is consistent with the goals of MCCC and organizations with an 501(c)(3) status. However, IRS 501(c)(3) status is not required.
What are MCCC's grant goals?
The grant cycle typically opens August 27, 2018 and closes October 5, 2018. MCCC is available to answer your questions! Please contact us at info@multcoculturalcoalition.org All grant applications are due October 5, 2018, no exceptions. In December, MCCC sends out grant award notifications. Additional information on optional information sessions are included on the backside of this sheet.


text:
How Ruth Carter, Black Panther Costume Designer and Oscar Nominee, Put a "Wakandan Spin" on the Film
The three-time Oscar nominee opened up about her process for designing the intricate costumes in the film, 3-D printing, and researching traditional African art.
by Brooke Marine
Bennett Raglin/Getty Images
"Color follows me, I don't follow it," said Ruth E. Carter, the esteemed costume designer and three-time Oscar nominee who is known for her vibrant work on films such as Black Panther, Do the Right Thing, and Selma.
It's true—those familiar with the oeuvre of directors Spike Lee, Keenan Ivory Wayans, and Robert Townsend would be remiss if they did not acknowledge the immense body of work that Carter contributed to those groundbreaking films.
Her work spans decades. In the late 1980s, the designer was inspired by the bright pops of color that athletic brands like Nike were incorporating into their compression shorts and crop tops, which ultimately informed a "fun, young, and vibrant" palette for School Daze and Do the Right Thing, her first collaborations with Lee. Thirty years later, Carter's costumes featured in Black Panther are recognized not just for their use of color but also for the explicit celebration of traditional African designs and Afrofuturistic ideals embedded in the clothes worn by the warriors, royals, and superheroes onscreen. The story of a reluctant king of one of the most technologically advanced nations in the world is a fascinating concept on its own, but it would have been boring to watch the narrative play out if the costumes worn by the various tribes and characters were not so visually compelling and intricately designed.
"Costume design and fashion sometimes can't coexist because you can't make everybody a fashion plate. Some of that has to tell a story," Carter said about her process of designing looks for Black Panther. "Black people look great in color, and it's a very intricate balance to not overpower the scene or what the person is saying," the costume designer said, explaining the efforts she and her team took to both punch up and honor the Marvel comics upon which director Ryan Coogler based his film.
For a superhero blockbuster, Black Panther's narrative is innovative because of its deft merging of past traditions with Afrofuturistic imagery, and included in the film's costumes are a mix of these real-life traditional design elements, such as the Adinkra symbols painted on various outfits, with modern design elements, like the inclusion of chrome. The Isicholo (a South African woman's traditional marriage hat) worn by Angela Bassett's Queen Ramonda, and T'Challa's supersuit, which is infused with vibranium to protect him from physical attacks—these costumes somehow feel both familiar and fresh.
With roughly six months to prepare the costumes worn in Black Panther, Carter worked closely with the production designer and director to capture the resilient spirit of the film's narrative. They had put together what Carter calls a "Wakandan Bible," which outlined the tribes and people of Wakanda, as well as the real African tribes and cultures they were based on. "If you look at the Jabari tribe, they were influenced by the Dogon of Mali, if it was the Merchant tribe, they were influenced by the Turkana. It's a collaboration," Carter said. "I wanted to look at this and say, those neck rings that the Ndebele women wear in South Africa would be great in our piece," she continued, adding that in the past, people have defined African art as simply primitive, without celebrating it for its innovation. "Now, I think people will be able to contextualize and look at African art, and appreciate it so much differently. That's what we did: We appreciated it, we reimagined it, we took it to another level, another place, and there were inspirations everywhere!"
It was important for Carter to "put a Wakandan spin" on the costumes, rather than simply copying what has existed for centuries and haphazardly slapping together disparate designs together for the screen. For example, with T'Challa's superhero suit (worn by Chadwick Boseman), there wasn't a lot of time for dilly-dallying with trial and error. Marvel was very hands-on in providing initial sketches for the shape of the suit, but Carter's task was to push the story of T'Challa forward with his costume. "For me, it was in the surface texture," Carter said. "It was the texture that needed to connect him to Africa, so we came up with the little triangle in the pattern. The triangle represents the sacred geometry of Africa," she went on. "When we printed the suit fabric, we did this triangle all over it, and it really did make it have this richer, more storied look. So now he's not only a superhero, he's also an African king."
Chadwick Boseman as T'Challa in *Black Panther*.
Much like Princess Shuri, T'Challa's wise-cracking, tech-savvy sister, who designs his indestructible supersuit, Carter relied on 3-D printing technology to create a handful of the looks seen in the film. The Isicholo worn by Queen Ramonda in the scene where T'Challa returns to Wakanda was 3-D printed, as was her shoulder mantle. Just about everything else, according to Carter, was sewn in Africa. Antique pieces were also incorporated for the sake of authenticity.
Ayo (Florence Kasumba), Queen Ramonda (Angela Bassett), and Princess Shuri (Leititia Wright) in *Black Panther.*
The Warrior Falls scene, where the leaders of different tribes of Wakanda challenge T'Challa for the throne before his coronation ceremony, showcases the variety of colors and garments associated with each tribe. "[In that scene] a lot of people have turbans, a lot of people have striped pieces. They were not easy to get, and you cannot just go to Target or Macy's and find those," Carter said. "We built a lot of the beautiful ponchos that the women wear, and for the Miners, who wear orange, we made their work coveralls. We didn't just want to throw African culture up there." Wakandan garments exist on an aspirational yet attainable plane. "That meant we had to be fashion forward and think about different silhouettes, and think about not making it necessarily so familiar to the eye," she said.
Carter has designed film costumes for three decades, receiving three Oscar nominations (for her period-specific pieces in Malcolm X in 1992, and Amistad in 1997), and winning the 2019 Critics Choice Award for Best Costume Design. It only feels right, if not long overdue, for Carter to be honored by IMG and Harlem Fashion Row as a kickoff to New York Fashion Week. A curated installation of her work from Black Panther placed alongside reinterpretations of her costumes by Ib Kamara—whom Carter said was inspired by characters in Baby Boy and School Daze as well as costumes worn in Black Panther—were placed on display on February 6 as part of the "Next of Kin" event.
IMG and Harlem Fashion Row Host "Next Of Kin": An Evening Honoring Ruth E. Carter.
The designer appears to be humbled by her influence, and willing to give advice to any up-and-comers who ask for it. "I get designers calling me—not only black designers but also white designers, all kinds of young designers—they call me and ask for advice about situations they're in," Carter said. "They figure that I've been here a long time and I've probably had to deal with some of the common problems that occur. Sometimes when you're young, you don't know how to work it out. I do my best to just answer them, and I feel good about being a role model," she went on, before addressing the positive changes she has seen in the industry over the years. "I think in general there's always been a push for inclusiveness and for women to be in key positions, and we weren't talking about it enough, but now I feel like we're talking about it. We're pledging to create environments that help women instead of the unhealthy ones that have existed in this industry for so long," Carter said.
With the Academy Awards looming, the red-carpet looks worn by the actors in Black Panther will be the subject of intrigue. As for Carter's own red-carpet agenda for this year, she remains coy about whether or not she will pay homage to the film or the fictional Wakanda with her outfit for the evening. "I'm not saying, because I don't want to jinx it," she admitted with a laugh. "But I do have some plans."
Related: Black Panther Could Have an All-Female Sequel, According to Director Ryan Coogler


text:
New Zealand's PM Calls For Global Censorship Regime
September 29, 2022 September 29, 2022 5 min read John Galt
Only days after the American left was lamenting the fall of Italy to the alleged fascist Giorgia Meloni, New Zealand PM Jacinda Ardern told world leaders assembled at the United Nations that unfettered free expression was one of the greatest threats facing humanity. In her speech, cloaked in the same trendy euphemisms popular among American progressives — and probably familiar to the depots and theocrats in attendance — she warned that the internet had been corrupted and weaponized by bad actors who spread mis- and disinformation and hateful ideologies. And the only way we can stop this "weapon of war" is to come together and create a set of "rules and transparency."
As our president might say, no right is absolute. Or, as our former president might say, disinformation is killing people.
Ardern went on to argue even "light touches" in regulating speech can often be "misinterpreted" as attacks on free expression, which "we value so highly." Do you, though? Arden is under the impression that a concerted global regulatory speech code, some "light touch" censorship, is a liberal position. A person who lobbies world leaders to band together to dictate the contours of appropriate discourse is an authoritarian. And a person who maintains the state should be the "single source of truth," as Ardern had during the Covid lockdowns, is cartoonishly so. If you only value speech when it comports with your worldview and beliefs, you do not value it at all.
That's the principled point.
The practical point is that whatever good you think suppressing speech might achieve, sooner or later, every censor in history expands the definition of mis- or disinformation to attack political opponents. One of the ways they do this is by conflating genuine disinformation and hateful rhetoric — which exists in abundance and always will — with legitimate debate. A good example of how this works was on display when American media, big corporations, and the FBI worked together to shut down inconvenient stories about Hunter Biden and "the big guy" to help elect their preferred candidate.
Arden herself offers an example of how this soft illiberalism has been normalized in the left's thinking. Allowing unregulated discourse, the prime minister argues, destabilizes "the norms we all value." For example: "How do you tackle climate change if people don't believe it exists?"
You don't.
There should be absolutely zero expectation that your policy positions will be implemented without any debate. In truly free nations, "tackling" climate change is a policy decision that is sorted out in the democratic process. Or not. What level of climate change rhetoric will Ardern require us to believe? Some of us don't believe the moral and economic tradeoffs of tackling climate change are worth it. Some of us don't believe there's any "climate crisis" at all. I'm not sure there are enough internet speech regulations that will convince many of us otherwise. When that reality sets in, "light touch" regulation will evolve into something a little firmer, no doubt.
And, speaking of misinformation, what will the UN's Ministry of Truth do about the alarmist predictions of Malthusians, who have been unwaveringly wrong about nearly everything for the past 50 years? Nothing, of course.
As we've learned during the coronavirus pandemic, and long before, state officials are themselves quite adept at conveying misinformation. The government has no moral authority in dictating the veracity of speech. In this nation, it has a duty not to. And yet the Biden administration had regularly involved itself in what we talk about, using the same rationalizations as Arden. Take, for instance, the pressuring of rent-seeking Big Tech companies, which oversee huge swaths of our daily digital interactions. Not that long ago, the White House admitted it was "flagging problematic posts for Facebook that spread disinformation." Under what constitutional authority these actions were justified, it did not share. It has been argued that social media companies "should be held accountable" for the ideas people exchange on platforms. Joe Biden previously accused Facebook of "killing people." Department of Homeland Security Secretary Alejandro Mayorkas even tried creating a "Disinformation Governance Board" to combat "misinformation" — run by the right kind of conspiracy theorist. I assume this is what New Zealand's prime minister, a hero of the international left, had in mind.
"How do you ensure the human rights of others are upheld if they are subjected to hateful and dangerous rhetoric and ideology?" she asks. Easy. You treat all inalienable liberal "values" — including free expression — as neutral rights.
Sometimes, it's difficult to believe we have to debate these issues again. Rationalizing state censorship as a means of protecting people from dangerous "misinformation" has been the rationale of every tin-pot authoritarian regime in history. If you still think it's a good idea, you're one of the bad guys.
David Harsanyi is a senior editor at The Federalist. Harsanyi is a nationally syndicated columnist and author of five books—the most recent, Eurotrash: Why America Must Reject the Failed Ideas of a Dying Continent. His work has appeared in National Review, the Wall Street Journal, Washington Post, Reason, New York Post, and numerous other publications. Follow him on Twitter, @davidharsanyi.
Originally Posted on: https://thefederalist.com/2022/09/29/jacinda-ardern-makes-clear-at-the-un-she-wants-global-illebral-censorship/?utm_source=rss&utm_medium=rss&utm_campaign=jacinda-ardern-makes-clear-at-the-un-she-wants-global-illebral-censorship
[By: David Harsanyi
Antifa Berlin Chapter Fails Attempted Shutdown Of Sold-Out Jordan Peterson Event
States Sue to Stop Biden Loan 'Forgiveness' Program: 'Unwise,' 'Unfair,' and 'Unlawful'
The "legislative violence" of gun control – Bearing Arms
Recent Riots
Ohio criminal justice "reform" fails to address gun control law – Bearing Arms


text:
Sight Of Emptiness: Instincts
I'm not sure whether it is a good thing or a bad thing, but over the past few years I've had the opportunity to read many a press release for an album. However I must admit that a piece of PR blurb which proudly announces that a Melodic Death Metal act have the piano talents of Manuel Obregon; the Costa Rican Minister Of Culture featured on their latest album Instincts was enough to have me choking on my crunchy nut cornflakes!
Whether that guest spot is a gimmick or not, what the song he plays on illustrates is that Sight Of Emptiness, from the same country as Senior Obregon, do like to operate in left field some of the time. Oddly however when they are not adding political jazz piano to "Paradox", a song where some Latino rhythm and Opeth like guitar work and vocal expulsions rule, or dance/dub beats and electronica to "Sanctuary", what Sight Of Emptiness do can be seen as decidedly safe. "Essence" opens the album with the sort of ideals Fear Factory introduced many years ago and Scar Symmetry perpetuate, while "Obsession" treads a similar, scorched path of destruction. Both are good, with guitars blazing, drums blasting and vocals snarling, however on their own they make a well rehearsed statement that we've all heard over and over. However add some more unusual elements elsewhere such as keyboard stabs, less manic but equally jabbing guitar breaks and varying vocal attacks and things begin to become more interesting. The "hidden" bonus track "Transition" brings an even stronger dance element, shocking at first but actually making complete sense if you're willing to put any misconceptions aside.
Guests come and go, Scar Symmetry's Christian Alvestam turning in a fine performance, Megadeth's Glenn Drover also proving his worth. While the addition of Ugly Kid Joe's Whitfield Crane on clean vocals and Ole Halvard Sveen from Extol could be seen as slightly less obvious. All add to the line-up of Eduardo Chacon (vocals), Andres Castro (guitar), Esteban Monestel (bass), Rodrigo Chaverri (drums) and Gabriel Arias (keys, synth, samples) well, with Crane in particular finding a new side to his vocal delivery on "Essence"!
It would be a stretch to suggest that Sight Of Emptiness have reinvented the Melodic Death Metal wheel with Instincts � the band's third album. However it would also be unkind to give the impression that they aren't fully aware that moving out of their comfort zone is something they need to do if they want to make a mark in a genre which seems to throw up sixteen new pretenders to the throne every nine seconds. Instincts does just that and is all the better for it.
2. Instincts
3. Obsession
5. Paradox
6. Deception
9. Genetics
10. Sanctuary
11. Departure
12. Transition (Bonus Track)
Added: December 4th 2013
Reviewer: Steven Reid
Related Link: Sight Of Emptiness Online


text:
WKL NL0000395903
(WKL)
91.56 EUR -2.07%
01/13 Wolters Kluwer and Laerdal Medical Launch Virtual Simulation Solution to Support Higher Clinical Fidelity in Nursing Education
01/13 Wolters Kluwer starts the year with a 2022 BIG Innovation Award win for its CCH® Tagetik Predictive Intelligence global expert solution
01/13 WOLTERS KLUWER : N.V., - Share Buyback Transaction Details January 6 – 12, 2022
Wolters Kluwer : N.V., - Share Buyback Transaction Details November 18 – November 24, 2021
Share Buyback Transaction Details November 18 - November 24, 2021
November 25, 2021 - Wolters Kluwer today reports that it has repurchased 67,700 of its own ordinary shares in the period from November 18, 2021, up to and including November 24, 2021, for €6.7 million and at an average share price of €99.53.
These repurchases are part of the share buyback program announced on February 24, 2021, under which we intend to repurchase shares for up to €350 million during 2021.
The cumulative amounts repurchased to date under this program are as follows:
Share Buyback 2021
Cumulative shares
Total consideration
Average share price
repurchased in
(€ million)
For the period starting November 4, 2021, up to and including December 29, 2021, we have engaged a third party to execute €51 million of buybacks on our behalf, within the limits of relevant laws and regulations (in particular Regulation (EU) 596/2014) and the company's Articles of Association.
Repurchased shares are added to and held as treasury shares and will be used for capital reduction purposes or to meet obligations arising from share-based incentive plans.
Further information is available on our website:
Download the share buyback transactions excel sheetfor detailed individual transaction information.
Weekly reports on the progress of our share repurchases.
Overview of share buyback programs.
Wolters Kluwer (WKL) is a global leader in professional information, software solutions, and services for the healthcare; tax and accounting; governance, risk and compliance; and legal and regulatory sectors. We help our customers make critical decisions every day by providing expert solutions that combine deep domain knowledge with specialized technology and services.
Wolters Kluwer reported 2020 annual revenues of €4.6 billion. The group serves customers in over 180 countries, maintains operations in over 40 countries, and employs approximately 19,200 people worldwide. The company is headquartered in Alphen aan den Rijn, the Netherlands.
Wolters Kluwer shares are listed on Euronext Amsterdam (WKL) and are included in the AEX and Euronext 100 indices. Wolters Kluwer has a sponsored Level 1 American Depositary Receipt (ADR) program. The ADRs are traded on the over-the-counter market in the U.S. (WTKWY).
For more information, visit www.wolterskluwer.com, follow us on Twitter, Facebook, LinkedIn, and YouTube.
Investors/Analysts
Gerbert van Genderen Stort
Meg Geldens
g.van.genderen.stort@wolterskluwer.com
ir@wolterskluwer.com
Forward-looking Statements and Other Important Legal Information
This report contains forward-looking statements. These statements may be identified by words such as "expect", "should", "could", "shall" and similar expressions. Wolters Kluwer cautions that such forward-looking statements are qualified by certain risks and uncertainties that could cause actual results and events to differ materially from what is contemplated by the forward- looking statements. Factors which could cause actual results to differ from these forward- looking statements may include, without limitation, general economic conditions; conditions in the markets in which Wolters Kluwer is engaged; behavior of customers, suppliers, and competitors; technological developments; the implementation and execution of new ICT systems or outsourcing; and legal, tax, and regulatory rules affecting Wolters Kluwer's businesses, as well as risks related to mergers, acquisitions, and divestments. In addition, financial risks such as currency movements, interest rate fluctuations, liquidity, and credit risks could influence future results. The foregoing list of factors should not be construed as exhaustive. Wolters Kluwer disclaims any intention or obligation to publicly update or revise any forward-looking statements, whether as a result of new information, future events or otherwise.
This press release contains information which is to be made publicly available under Regulation (EU) 596/2014.
Original Document
Wolters Kluwer NV published this content on 25 November 2021 and is solely responsible for the information contained therein. Distributed by Public, unedited and unaltered, on 25 November 2021 16:09:05 UTC.
© Publicnow 2021
All news about WOLTERS KLUWER
01/13 Wolters Kluwer and Laerdal Medical Launch Virtual Simulation Solution to Support Higher..
01/13 Wolters Kluwer starts the year with a 2022 BIG Innovation Award win for its CCH® Tageti..
01/13 Share Buyback Transaction Details January 6 – 12, 2022
01/13 WOLTERS KLUWER : Share buyback
01/10 New Clinical Evidence Workflow Solution From Wolters Kluwer Accelerates Research Activi..
01/06 WOLTERS KLUWER : N.V., - Share Buyback Transaction Details January 3 – 5, 2022
01/06 MEDIA ALERT – Earnings from name, image, or likeness can help offset tuition cost..
01/06 Share Buyback Transaction Details January 3 – 5, 2022
Analyst Recommendations on WOLTERS KLUWER
2017 JP MORGAN CHASE MPANY : Springer Nature asks JP Morgan, Morgan Stanley to organise IPO - s..
2013 Thomson Reuters profit falls on severance costs
Sales 2021 4 744 M 5 371 M 5 371 M
Net income 2021 727 M 823 M 823 M
Net Debt 2021 2 131 M 2 413 M 2 413 M
P/E ratio 2021 33,1x
Capitalization 23 676 M 26 828 M 26 805 M
Chart WOLTERS KLUWER
Technical analysis trends WOLTERS KLUWER
Trends Bearish Neutral Bullish
Mean consensus HOLD
Last Close Price 93,50 €
Average target price 91,33 €
Spread / Average Target -2,33%
Nancy McKinstry Chairman-Executive Board & Chief Executive Officer
Kevin B. Entricken Chief Financial Officer
Frans J. G. M. Cremers Chairman-Supervisory Board
Jeanette Horan Independent Member-Supervisory Board
Ann Elizabeth Ziegler Independent Member-Supervisory Board
WOLTERS KLUWER -9.75% 27 581
S&P GLOBAL INC. -8.38% 104 145
RELX PLC -6.37% 59 236
THOMSON REUTERS CORPORATION -9.14% 53 496
MSCI INC. -14.03% 43 428
EQUIFAX INC. -14.79% 30 439


text:
require 'highline/import'
require 'net/ldap'
require 'yaml'
require 'set'
require 'logger'

# Runs a block in the context of an object. This is similar to the `with` keyword
# in Pascal or JavaScript. For example:
#
#     str = "Hello World"
#     with str do
#       puts reverse
#     end
#
# It also supports blocks with arity of 1:
#
#     str = "Hello World"
#     with str do |my_str|
#       puts my_str.reverse
#     end
#
# @param [Object, nil] obj The object that serves as the context for the block. If `nil` then
#                          the block won't be executed
# @yield A block of arity 0 or 1 that will be executed in the context of the given object
# @return [Object, nil] The return value of the block if any. If the block is not
#                       executed because the object is `nil`, then nothing will be
#                       returned
def with(obj, &block)
  if obj && block_given?
    if block.arity == 1
      yield obj
    else
      obj.instance_eval(&block)
    end
  end
end

# This is the same as `#with` except that it will only run the block in the context of the object
# if the object is not an instance of `Cosmic::HoneyPot`. In effect this means that you'd use
# this in cases where a plugin is not configured but used in a script and you don't want to
# run code using the plugin at all.
#
# @param [Object, nil] obj The object that serves as the context for the block. If `nil` or an
#                          instance of `Cosmic::HoneyPot` then the block won't be executed
# @yield A block of arity 0 or 1 that will be executed in the context of the given object
# @return [Object, nil] The return value of the block if any. If the block is not
#                       executed because the object is `nil`, then nothing will be
#                       returned
def with_available(obj, &block)
  if obj && !obj.is_a?(Cosmic::HoneyPot) && block_given?
    if block.arity == 1
      yield obj
    else
      obj.instance_eval(&block)
    end
  end
end

# Wraps the given object in an array unless it is already one. If passed `nil` then
# it will return an empty array.
#
# @param [Object] obj The object to arrayify
# @return [Array] The object if it is already an array, or an empty array if given `nil`.
#                 Otherwise an array with the object as the single element
def arrayify(obj)
  if obj
    if obj.is_a?(Array)
      obj
    else
      [obj]
    end
  else
    []
  end
end

# Helper method that runs a block peridically until the block returns
# a non `nil` value or a certain amount of time has passed
#
# @params [Integer] timeout The timeout to wait in seconds
# @params [Integer] sleep_time How long to wait between executions of the block
# @yield The block of arity 0 that will be executed
# @return The result of the block if any
def repeat_until_result(timeout = 60, sleep_time = 5)
  raise "No block given" unless block_given?
  start_time = Time.new.to_i
  while Time.new.to_i - start_time < timeout
    result = yield
    return result if result
    sleep sleep_time
  end
end

# A version of the `require` method that prints out an optional text telling the user
# how to fix the load problem.
#
# @param [String] what What to load
# @param [String] hint An optional hint to show if the thing could not be loaded
# @return [true,false] Whether the module was loaded (`true`) or it was already loaded
#                      before (`false`)
def require_with_hint(what, hint)
  begin
    require what
  rescue LoadError => e
    puts hint
    raise e
  end
end

def split_off!(arr)
  result_idx = nil
  arr.each_with_index do |item, idx|
    is_match = yield item
    if is_match
      result_idx = idx
      break
    end
  end
  if result_idx.nil?
    nil
  else
    arr.slice!(result_idx)
  end
end

def map_by(arr)
  arr.inject({}) do |result, item|
    key = yield item
    (result[key] ||= []).push(item)
    result
  end
end

# The main cosmic namespace.
module Cosmic
  # Represents the message passing facility in between the environment or plugins.
  # Each message on the bus has a set of tags. Interested parties register
  # themselves as listeners for messages that have specific tags. The bus then
  # guarantees that whenever a message is sent on the bus (via `notify`) then all
  # listeners that expressed interest in the one of tags of the message, will receive
  # the message. The bus will call the listener in order of registration, and all
  # calls happen sequentially in the thread that generates the message.
  class MessageBus
    # Creates a new message bus without any listeners.
    #
    # @return [Environment] The new instance
    def initialize
      @listeners = []
    end

    # Adds a listener for specific set of tags. Doesn't do anything if no listener
    # or no tags were specified.
    #
    # @param [Object] listener The listener. Must respond to the method
    #                          `on_message({:msg => message, :tags => tags})`
    # @param [Array<Symbol>, Symbol] tags The tags that the listener is interested in
    # @return [void]
    def add_listener(listener, tags)
      tag_set = Set.new(arrayify(tags))
      if listener && !tag_set.empty?
        @listeners.push({ :listener => listener, :tags => tag_set })
      end
    end

    # Removes a listener. Doesn't do anything if no listener was specified.
    #
    # @param [Object] listener The listener to remove
    # @return [void]
    def remove_listener(listener)
      if listener
        @listeners.delete_if { |registration| registration[:listener] == listener }
      end
    end

    # Notifies all listeners of a new message. Doesn't do anything if no listener
    # or no tags were specified.
    #
    # @param [Object] msg The message
    # @param [Array<Symbol>, Symbol] tags The tags for the message
    # @return [void]
    def notify(msg, tags)
      tag_set = Set.new(arrayify(tags))
      if msg && !tag_set.empty?
        @listeners.each do |listener_hash|
          if !(listener_hash[:tags] & tag_set).empty?
            listener_hash[:listener].on_message(:msg => msg, :tags => tags)
          end
        end
      end
    end

    # Shuts down this message bus by removing all listeners.
    def shutdown
      @listeners.clear
    end
  end

  # Helper class that responds to any method call with itself.
  class HoneyPot
    # Catches all method calls to the honey pot and returns itself.
    #
    # @param [Symbol] method_sym The method symbol to call
    # @param [Array<Object>] args The invocation arguments
    # @yield An optional block which however will never be executed
    # @return [HoneyPot] The honey pot itself
    def method_missing(method_sym, *args, &block)
      self
    end

    # Returns `true` for every passed method symbol indicating
    # that the object has that method.
    #
    # @param [Symbol] method_sym The method symbol to check
    # @param [true,false] include_private Whether to include private methods. Is ignored
    # @return [true] Always returns `true`
    def respond_to?(method_sym, include_private = false)
      true
    end
  end

  # Simple message listener that outputs messages to stdout.
  class StdoutListener
    # Called by the message bus on messages.
    #
    # @param [Hash] params The parameters
    # @option params [Object] :msg The message
    # @option params [Array<Symbol>] :tags The message's tags
    # @return [void]
    def on_message(params)
      msg = params[:msg]
      unless msg.nil?
        $stdout.puts("#{msg}\n")
      end
    end
  end

  # Simple message listener that outputs messages to stderr.
  class StderrListener
    # Called by the message bus on messages.
    #
    # @param [Hash] params The parameters
    # @option params [Object] :msg The message
    # @option params [Array<Symbol>] :tags The message's tags
    # @return [void]
    def on_message(params)
      $stderr.printf("#{params[:msg]}\n")
    end
  end

  # Custom logger for plugins that puts log messages onto the message bus.
  class CosmicLogger < Logger
    # Creates a new logger instance. The parameters are used to configure
    # the environment to log to, plus the tags for each log level. For
    # example:
    #
    #     CosmicLogger.new(:environment => @environment,
    #                      Logger::WARN => :warn,
    #                     Logger::ERROR => [:error,:fatal])
    #
    # Only messages with log levels that are mapped to tags will be put onto
    # the message bus, all others will be silently ignored.
    #
    # @param [Hash] params The parameters
    # @option params [Environment] :environment The environment
    # @option params [Array<Symbol>,Symbol] Logger::DEBUG The tags that debug messages should be mapped to
    # @option params [Array<Symbol>,Symbol] Logger::INFO The tags that info messages should be mapped to
    # @option params [Array<Symbol>,Symbol] Logger::WARN The tags that warn messages should be mapped to
    # @option params [Array<Symbol>,Symbol] Logger::ERROR The tags that error messages should be mapped to
    # @option params [Array<Symbol>,Symbol] Logger::FATAL The tags that fatal messages should be mapped to
    # @option params [Array<Symbol>,Symbol] Logger::UNKNOWN The tags that messages with unknown severity should be mapped to
    # @return [CosmicLogger] The new logger instance
    def initialize(params)
      @environment = params[:environment]
      @level_map = {}
      @level_map['DEBUG'] = arrayify(params[Logger::DEBUG])
      @level_map['INFO'] = arrayify(params[Logger::INFO])
      @level_map['WARN'] = arrayify(params[Logger::WARN])
      @level_map['ERROR'] = arrayify(params[Logger::ERROR])
      @level_map['FATAL'] = arrayify(params[Logger::FATAL])
      @level_map['UNKNOWN'] = arrayify(params[Logger::UNKNOWN])
      @level_map['ANY'] = arrayify(params[Logger::UNKNOWN])
    end

    # Base logger method responsible for dealing with a specific message.
    #
    # @param [String] severity The severity of the message
    # @param [Time] timestamp The time of the message, ignored
    # @param [String] progname The name of the logging program, ignored
    # @param [String] msg The message
    def format_message(severity, timestamp, progname, msg)
      tags = @level_map[severity]
      if tags
        @environment.notify(:msg => msg, :tags => tags)
      end
    end
  end

  # Represents the environment in which plugins are run.
  class Environment
    # The complete configuration
    attr_reader :config
    # Whether dry run mode is turned on (off by default)
    attr_reader :in_dry_run_mode

    # Creates a new environment instance from the configuration in a file. The
    # passed-in parameters hash is merged on top of the file configuration
    # thus allowing to modify configuration settings before the environment is
    # created. If no file was specified, then it will try to load `.cosmicrc` in
    # the current folder first, and if that fails, then `.cosmicrc` in the home
    # folder of the current user. If these don't exist either, then it will return
    # an environment which is configured using only the passed in parameters.
    #
    # @param [Hash] params The parameters, may contain config overrides
    # @option params [String,nil] :config_file The path to the configuration file
    # @return [Environment] The new environment instance
    def self.from_config_file(params = {})
      config = read_rc(params[:config_file])
      config = {} unless config && config.is_a?(Hash)
      Environment.new(config.merge(params))
    end

    # Creates a new environment instance from the given configuration settings.
    # See the configuration documentation for details.
    #
    # @param [Hash] config_hash The configuration
    # @return [Environment] The new instance
    def initialize(config_hash = {})
      @config = unify_keys(config_hash)
      @in_dry_run_mode = @config[:dry_run_mode] || false # we don't allow changing after the environment object is created
      @cached_plugins = {}
      @message_bus = MessageBus.new
      if @config[:verbose] === true
        @message_bus.add_listener(StdoutListener.new, [:dryrun, :warn, :info, :trace])
      else
        @message_bus.add_listener(StdoutListener.new, [:dryrun, :warn, :info])
      end
      @message_bus.add_listener(StderrListener.new, :error)
      authenticate
    end

    # Returns the configuration section for the indicated plugin.
    #
    # @param [Hash] params The parameters
    # @option params [Symbol] :name The plugin's name
    # @return [Hash] The plugin's config or an empty hash if not found or no name given
    def get_plugin_config(params)
      if @config[:plugins] && params[:name]
        @config[:plugins][params[:name].to_sym] || {}
      else
        {}
      end
    end

    # Helper method for plugins to resolve authentication tokens from the
    # environment. The environment understands several different authentication
    # schemes which are explained in detail in the configuration documentation.
    # When successful, then it will update `params[:config][:auth][:username]`
    # and `params[:config][:auth][:password]` with the resolved credentials,
    # or `params[:config][:auth][:key_data]` with the key data read from the
    # environment (e.g. for ssh private keys).
    #
    # @param [Hash] params The parameters
    # @option params [Symbol] :service_name The service name, e.g. `:irc`
    # @option params [Hash] :config The service's configuration
    # @option params [Hash] :force Force resolving. Different authentication types
    #                              have a different meaning of this. E.g. the
    #                              `credentials` type will ask for username and
    #                              passwords regardless of whether they are
    #                              already credentials in the config. `false` by
    #                              default
    # @return [void]
    def resolve_service_auth(params)
      return unless params[:service_name] && params[:config]
      service_name = params[:service_name].to_sym
      service_config = params[:config]
      service_config[:auth] ||= {}
      auth_config = service_config[:auth]
      force = params.has_key?(:force) ? params[:force] : false

      if service_config[:credentials]
        username = service_config[:credentials][:username]
        password = service_config[:credentials][:password]
      end
      case service_config[:auth_type]
        when /^credentials_from_env$/
          username, password = get_service_credentials_from_env(service_name, service_config)
        when /^ldap_credentials$/
          if service_config[:ldap] && service_config[:ldap][:auth]
            username = service_config[:ldap][:auth][:username]
            password = service_config[:ldap][:auth][:password]
          elsif @config[:ldap] && @config[:ldap][:auth]
            username = @config[:ldap][:auth][:username]
            password = @config[:ldap][:auth][:password]
          end
        when /^credentials$/
          if force || (username.nil? && password.nil?)
            username = ask("Username for #{service_name.to_s}?\n") if username.nil?
            password = ask("Password for user #{username} for #{service_name.to_s}?\n") { |q| q.echo = false }
          end
        when /^keys$/
          auth_config[:keys] = arrayify(service_config[:keys])
        when /^keys_from_env$/
          if service_config[:ldap]
            path = service_config[:ldap][:key_path] || ldapify_username(@config[:ldap][:auth][:username])
            attrs = arrayify(service_config[:ldap][:key_attrs])
            if path && attrs.length > 0
              key_entry = first_or_nil(get_from_ldap(:path => path))
              if key_entry
                key_data = []
                attrs.each do |attr_name|
                  attr_value = first_or_nil(key_entry[attr_name])
                  key_data << attr_value if attr_value
                end
                auth_config[:key_data] = key_data if key_data.length > 0
              end
            end
          end
      end
      auth_config[:username] = username
      auth_config[:password] = password
    end

    # If Cosmic is connected to an LDAP server, then this method
    # will return the entry referenced by the given path.
    #
    # @param [Hash] params The parameters
    # @option params [String] :path The LDAP path to the desired entry
    # @return [Net::LDAP::Entry,nil] The entry or nil if the path doesn't exist
    def get_from_ldap(params)
      case @config[:auth_type]
        when /^ldap$/
          return @ldap.search(:base => params[:path] || '', :return_result => true)
      end
      nil
    end

    # Connects a listener with the message bus. Doesn't do anything if
    # no listener or tags are given.
    #
    # @param [Hash] params The parameters
    # @option params [Object] :listener The listener
    # @option params [Array<Symbol>, Symbol] :tags The tags that the listener is interested in
    # @return [void]
    def connect_message_listener(params)
      @message_bus.add_listener(params[:listener], params[:tags])
    end

    # Disconnects a listener from the message bus. Doesn't do anything if
    # no listener was given.
    #
    # @param [Hash] params The parameters
    # @option params [Object] :listener The listener
    # @return [void]
    def disconnect_message_listener(params)
      @message_bus.remove_listener(params[:listener])
    end

    # Sends a message to the message bus. Doesn't do anything if no message or tags
    # are given.
    #
    # @param [Hash] params The parameters
    # @option params [Object] :msg The message
    # @option params [Array<Symbol>, Symbol] :tags The tags of the message
    # @return [void]
    def notify(params)
      @message_bus.notify(params[:msg], params[:tags])
    end

    # Catches calls to undefined methods and tries to map them to plugins. It tries
    # to look for a plugin configuration section under that name, and if it finds
    # one, check if the section has a `plugin_class` attribute. If so, then it will
    # try to instantiate the class and return the instance. Otherwise, it will
    # check if there is a class of the following form:
    #
    # * `Cosmic::<name>`
    # * `Cosmic::<name in all uppercase>`
    # * `Cosmic::<name in camel case>`
    # * `::<name>`
    # * `::<name in all uppercase>`
    # * `::<name in camel case>`
    #
    # E.g. for `irc`, it would look for `Cosmic::irc`, `Cosmic::IRC`, `Cosmic::Irc`,
    # `::irc`, `::IRC`, `::Irc`. If it finds one, it will instantiate it and return
    # it.
    # The environment also caches the instantiated plugins so that the second call
    # for the same case-insensitive name returns the same plugin instance. So for
    # example calls like
    #
    #     environment.irc
    #     environment.Irc
    #
    # will first check if the environment knows about a plugin `irc` and if yes,
    # then will return the instance right away. If not then it will instantiate the
    # plugin as explained above.
    #
    # @param [Symbol] method_sym The method symbol to call
    # @param [Array<Object>] args The invocation arguments
    # @yield An optional block which is ignored
    # @return [Plugin,nil] The plugin instance if found, otherwise `nil`
    def method_missing(method_sym, *args, &block)
      name = method_sym.to_s
      required = true
      if name =~ /^(.+)\?$/
        required = false
        name = $1
      end

      # First we check if we already know it
      instance = @cached_plugins[name.downcase]
      return instance if instance

      # Now let's check if there is a plugin configured for that name, or if
      # there is a class of that name in namespace Cosmic
      clazz = find_plugin_class(name)
      begin
        if clazz
          instance = clazz.new(self, name.to_sym)
          @cached_plugins[name.downcase] = instance
          instance
        else
          super
        end
      rescue Exception => e
        if required
          raise "No such plugin instance configured or configuration is invalid for '#{name}': #{e}"
        else
          HoneyPot.new
        end
      end
    end

    # Checks if the environment instance could handle the call to `method_sym`.
    # In effect, this checks if the environment knows about a plugin of that name
    # or could instantiate one of that name. See #method_missing for details on
    # the rules.
    #
    # @param [Symbol] method_sym The method symbol to check
    # @param [true,false] include_private Whether to include private methods. Is ignored
    # @return [true,false] `true` if the environment could handle the call
    def respond_to?(method_sym, include_private = false)
      name = method_sym.to_s
      if name =~ /^(.+)\?$/
        name = $1
      end

      return @cached_plugins[name.downcase] || find_plugin_class(name)
    end

    # Shuts down this environment. This method will basically shut down all registered
    # plugins and the message bus.
    def shutdown
      @cached_plugins.values.each do |plugin|
        plugin.shutdown
      end
      @message_bus.shutdown
    end

    private

    def self.read_rc(config_file)
      if config_file
        YAML.load_file(config_file)
      else
        if File.exist?(".cosmicrc")
          YAML.load_file(".cosmicrc")
        elsif File.exists?("#{ENV['HOME']}/.cosmicrc")
          YAML.load_file("#{ENV['HOME']}/.cosmicrc")
        end
      end
    end

    def unify_keys(obj)
      if obj && obj.is_a?(Hash)
        obj.inject({}){ |memo,(k,v)| memo[k.to_sym] = unify_keys(v); memo }
      else
        obj
      end
    end

    def first_or_nil(values)
      if values && values.length && values.length > 0
        values[0]
      else
        nil
      end
    end

    def find_plugin_class(name)
      if @config[:plugins] && @config[:plugins][name.to_sym]
        plugin_class = @config[:plugins][name.to_sym][:plugin_class]
        if plugin_class
          clazz = load_class(plugin_class)
          return clazz if clazz
        end
      end
      camel_case_name = name.gsub(/^[a-z]/) { |a| a.upcase }
      clazz_names = ["Cosmic::#{name}",
                     "Cosmic::#{name.upcase}",
                     "Cosmic::#{camel_case_name}",
                     "Module::#{name}",
                     "Module::#{name.upcase}",
                     "Module::#{camel_case_name}"]
      clazz_names.each do |clazz_name|
        clazz = load_class(clazz_name)
        return clazz if clazz
      end
      nil
    end

    def load_class(name)
      if name
        # we're using eval here instead of const_get since it works for all classes
        begin
          clazz = eval(name)
          return clazz if clazz && clazz.is_a?(Class)
        rescue Exception => e
          # ignored
        end
      end
      nil
    end

    def authenticate
      case @config[:auth_type]
        when /^ldap$/
          authenticate_with_ldap
        when /^credentials$/
          authenticate_with_credentials
      end
    end

    def ldapify_username(username)
      if username.nil? || username =~ /cn=.*/
        username
      else
        "cn=#{username},ou=users,#{@config[:ldap][:base]}"
      end
    end

    def authenticate_with_ldap
      ldap_config = @config[:ldap]
      return unless ldap_config

      # net/ldap doesn't handle strings instead of symbols, so let's convert them as necessary
      ldap_config[:encryption] = ldap_config[:encryption].to_sym if ldap_config[:encryption]

      if ldap_config[:auth]
        ldap_config[:auth][:method] = ldap_config[:auth][:method].to_sym if ldap_config[:auth][:method]

        case ldap_config[:auth][:method]
          when /^simple$/
            if !ldap_config[:auth][:username]
              ldap_config[:auth][:username] = ldapify_username(ask("LDAP user ?\n"))
              ldap_config[:auth][:password] = ask("LDAP password ?\n") { |q| q.echo = false }
            end
        end
      end
      begin
        @ldap = Net::LDAP.new(ldap_config)
        if !@ldap.bind
          error = @ldap.get_operation_result
          @ldap = nil
          notify(:msg => "Cannot connect to LDAP: Error #{error.code} #{error.message}", :tags => :error)
        end
      rescue Net::LDAP::LdapError => e
        notify(:msg => "Cannot connect to LDAP: #{e.message}", :tags => :error)
      end
    end

    def authenticate_with_credentials
      cred_config = @config[:credentials]
      return unless cred_config

      if !cred_config[:username]
        cred_config[:username] = ask("Username ?\n")
        cred_config[:password] = ask("Password ?\n") { |q| q.echo = false }
      end
    end

    def get_service_credentials_from_env(service_name, service_config)
      username = nil
      password = nil
      case @config[:auth_type]
        when /^ldap$/
          service_ldap_config = service_config[:ldap] || @config[:ldap]
          if service_ldap_config && @ldap
            @ldap.search(:base => service_ldap_config[:path] || '', :return_result => true) do |entry|
              if service_ldap_config[:username_attr]
                username = first_or_nil(entry[service_ldap_config[:username_attr]])
              end
              if service_ldap_config[:password_attr]
                password = first_or_nil(entry[service_ldap_config[:password_attr]])
              end
            end
          end
      end
      [username, password]
    end

  end
end

redpajama_set_name: RedPajamaGithub


text:
Amy Jo Martin
SOCIAL MEDIA PIONEER; NEW YORK TIMES BEST-SELLING AUTHOR; PODCAST HOST OF WHY NOT NOW
Why Not Now?
You know that thing you've been thinking about doing? Why Not Now? Amy Jo has had more than 100 vulnerable conversations with wildly successful and fascinating people from Tony Robbins to Mark Cuban to Simon Sinek and beyond. She's helped them dissect the critical moments that have changed their lives. The day, hour or minute when they navigated over the bridge from dreaming to doing. She calls these Why Not Now? moments. Amy Jo has spotted consistent themes and patterns that has led to a formula for tackling your own Why Not Now? Through storytelling and providing literal, tactical step-by-step examples, Amy Jo guides the audience through the process.
Future of Technology is the Future of Humanity
We are only bound by the speed of technology. There are no geographic barriers and the gatekeepers have been removed. The world of technology has created an equal opportunity space. However, with more and more people communicating virtually, via technology instead of face-to-face, we have a deficit of serotonin exchange – especially when some generations are learning to use technology before they learn to talk. Positive and negative energy (content) can move equally as fast. As a pioneer of social communication, the second verified person ever on Twitter with a million+ person following, Amy Jo originally fell in love with social communication channels because of the positive potential they offered. She will share her current clinical research on the impact technology is having on human behavior – including the emerging world of Artificial Intelligence.
Humanize Your Brand
Humans connect with humans, not logos. Consumers now expect to connect and engage with brands online, yet there is a hesitancy for many people to truly open up and humanize their personal brands. Who are the faces behind your logo? From the CEO to the accounting manager, everyone in your company is living the brand they represent. Amy Jo talks through the tangible ways you can humanize your brand, and shares personal stories of working with everyone from high-profile leaders to front line employees.
There's No Finish Line to Innovation
Any time we innovate, adversity follows. Everyone suffers from Innovation Allergies, the excuses that pop up in meetings such as "That's not the way we've always done it" or "What if it doesn't work?" Amy Jo shares stories and tips on how to evolve your value to your customer and your culture so it doesn't become extinct. Whether you are an intrepreneur, an entrepreneur living inside corporate walls, or looking to start your own business, Amy Jo talks through ways to get comfortable with being uncomfortable so you can innovate and thrive.
Women Will Impact Your Bottom Line
Work, Family, Self – choose two, you can't have all three." That's what Amy Jo's female supervisor once told her. That was also the very moment Amy Jo decided to kick open the entrepreneurial door and start her own business. Amy Jo talks about two tangible solutions for increasing the process of women breaking through in business. 1. Get more men involved. As mentors and supporters. 2. Address the unconscious gender bias. This is not just a gender equality issue; it is also about businesses reaching their full potential. Amy Jo shares the data on how having more woman in leadership positions does impact the bottom line and how women can support one another to reach these leadership positions.
Where Purpose, Passion and Skill Collide, Bliss Resides
At various moments in her career, Amy Jo has diagnosed herself with a purpose problem. She has suffered from a deficit in purpose, which has suffocated her ability to innovate. After learning the hard way that where purpose, passion and skill collide, bliss resides, Amy Jo has made it a priority to help other people navigate finding their own intersection of bliss. This collision point is a moving target for everyone as their passions evolve and purpose shifts. This process can be a slight change to an existing situation or a large shift in direction. Amy Jo shares stories of people, including herself, who have learned to reinvent themselves after many times of falling in and out of bliss.
Why Book Amy Jo?
An established social media pioneer, this New York Times best-selling author and Why Not Now? podcaster shares her passion for digital media, positive disruption, effective branding and reaching your full potential.
Amy Jo Martin is the author of New York Times best-seller Renegades Write the Rules, and host of the Why Not Now? podcast. She founded Digital Royalty (one of the first ever social media agencies) in 2009 to help corporations, celebrities and sports entities humanize their brands online through social communication channels. Amy Jo has worked closely with world-renowned brands such as Hilton Worldwide, Dwayne "The Rock" Johnson and Shaquille O'Neal to successfully humanize their presence. Her motto: humans connect with humans, not logos. After a successful 7-year run, Amy Jo exited Digital Royalty in 2016.
Amy Jo herself has a social media following of more than a 1 million people and was named the third most powerful woman on Twitter by Forbes. Amy Jo believes the future of technology is the future of humanity. She has spoken to live audiences as large as 10,000 people.
In 2012 Tony Hsieh, CEO of Zappos.com, and Baron Davis, NBA player, invested in Amy Jo and her company. After a successful seven-year run as the Founder & CEO of Digital Royalty and growing the business globally into ten different countries, Amy Jo recently exited the company in 2016.
Prior to becoming an entrepreneur, Amy Jo began working for the NBA's Phoenix Suns during their 2005-06 season. These were the wild wild west days of social media and there were no rules or regulations in place.
As a young female building her career in male-centric industries, Amy Jo has developed a passion for helping women thrive in business leadership. Most recently she launched the Renegade Brand Bootcamp; an intensive three month training program destined to help female founders and entrepreneurs reach their full potential in life and business.
Amy Jo is also a contributor to news outlets including the Harvard Business Review and Sports Business Journal. She has been featured in top-tier media outlets including Vanity Fair, TIME, Forbes, The New York Times, Fast Company, ESPN SportsCenter, USA Today, MSNBC and Newsweek.
Client portfolio includes: Hilton Worldwide, Shaquille O'Neal, Motorola, FOX Sports, The X-Factor, Chicago White Sox, UFC and Dana White, Dwayne "The Rock" Johnson, Los Angeles Kings, Jabbawockeeez, Doubletree by Hilton, Tony Hsieh CEO of Zappos.com, Monte Carlo Resort & Casino, KC Royals and Hard Rock Hotel & Casino.
Renegades Write the Rules
"Amy Jo has changed the game of how business' and brands approach communication. She's a masterful strategist, true trailblazer and will continue to be an innovative presence."
--Dwayne "The Rock" Johnson, Actor
"She crushed!"
--Damon Goude, Director of Speaker Relations for Dave Ramsey's Business Solutions
"Here are the female speakers you should know: Brené Brown, Amy Jo Martin, Chelsea Clinton, Martha Stewart."
--Talent Booker for INBOUND Main Stage
"Amy Jo Martin is handing us the GPS needed to navigate this new world."
--Rob Palleschi, Global Head of Hilton Worldwide
"Incredible. She made me think about personal branding in a way I had never considered."
--CES CEO Summit Attendee
Social Media & Online Marketing
Branding & Advertising
Innovation & Creativity
Artificial Intelligence (AI) and Robotics


text:
#include "src/allocators/buffers_allocator.h"
#include <fstream>  // NOLINT(*)
#include <functional>
#include <map>
#include <set>

namespace sound_feature_extraction {
namespace memory_allocation {

void Node::Dump(const std::string& dotFileName) const {
  std::ofstream fw;
  fw.exceptions(std::ifstream::failbit | std::ifstream::badbit);
  fw.open(dotFileName);
  fw << "digraph BuffersAllocator {" << std::endl;
  int index = 1;
  std::map<const Node*, int> indices;
  std::function<int(const Node&)> write_node;
  write_node = [&](const Node& node) {
    int myindex = index++;
    indices[&node] = myindex;
    fw << "\t" << std::to_string(myindex) << " [";
    if (node.Children.size() == 0) {
      fw << "style=\"filled\", fillcolor=\"green\", ";
    }
    fw << "label=<[" <<
        std::to_string(node.Address) << ", " <<
        std::to_string(node.Address + node.Size) << "]>]" << std::endl;
    std::vector<int> myChildrenIndices;
    for (size_t i = 0; i < node.Children.size(); i++) {
      myChildrenIndices.push_back(write_node(node.Children[i]));
    }
    if (!myChildrenIndices.empty()) {
      fw << "\t" << std::to_string(myindex) << " -> {";
      for (auto i : myChildrenIndices) {
        fw << std::to_string(i) << "; ";
      }
      fw.seekp(-2, std::ios::cur);
      fw << "}" << std::endl;
    }
    return myindex;
  };
  write_node(*this);
  fw << std::endl;
  auto node = this;
  auto next = this->Next;
  while (next != nullptr) {
    fw << "\t" << std::to_string(indices[node]) << " -> " <<
        std::to_string(indices[next]) << " [color=\"red\"]" << std::endl;
    node = next;
    next = next->Next;
  }
  fw << "}" << std::endl;
}

BuffersAllocator::BuffersAllocator()
    : Logger("Allocator", EINA_COLOR_LIGHTRED) {
}

bool BuffersAllocator::Validate(const Node& root) const {
  const Node* node = &root;
  std::vector<const Node*> leaves;
  std::set<const void*> items;
  std::set<const Node*> visitedNodes;
  while (node != nullptr) {
    if (visitedNodes.find(node) != visitedNodes.end()) {
      ERR("Duplicate node");
      return false;
    }
    if (node->Item == nullptr) {
      ERR("Attached Item is null.");
      return false;
    }
    if (items.find(node->Item) != items.end()) {
      ERR("Duplicate item.");
      return false;
    }
    items.insert(node->Item);
    if (node->Address == Node::UNINITIALIZED_ADDRESS) {
      ERR("Address is not initialized.");
      return false;
    }
    const Node* parent = node->Parent;
    if (parent != nullptr) {
      if (NodesOverlap(*node, *parent)) {
        ERR("Memory regions overlap on dependent nodes.");
        return false;
      }
      const Node* archParent = parent->Parent;
      while (archParent != nullptr) {
        if (NodesOverlap(*node, *archParent)) {
          size_t visitedChildrenCount = 0;
          for (size_t i = 0; i < archParent->Children.size(); i++) {
            if (visitedNodes.find(&archParent->Children[i]) !=
                visitedNodes.end()) {
              visitedChildrenCount++;
            }
          }
          if (visitedChildrenCount < archParent->Children.size() - 1) {
            ERR("Memory regions overlap on dependent nodes.");
            return false;
          }
        }
        archParent = archParent->Parent;
      }
    }
    for (auto leaf : leaves) {
      if (NodesOverlap(*node, *leaf)) {
        ERR("Memory regions overlap with leaves.");
        return false;
      }
    }
    if (node->Children.size() == 0) {
      leaves.push_back(node);
    }
    visitedNodes.insert(node);
    node = node->Next;
  }
  if (visitedNodes.size() < NodesCount(root)) {
    ERR("Not all nodes are linked.");
    return false;
  }
  return true;
}

size_t BuffersAllocator::NodesCount(const Node& root) const noexcept {
  size_t sum = 1;
  for (auto child : root.Children) {
    sum += NodesCount(child);
  }
  return sum;
}

bool BuffersAllocator::NodesOverlap(const Node& n1, const Node& n2) noexcept {
  if (n1.Size * n2.Size == 0) {
    return false;
  }
  return SegmentsOverlap(n1.Address, n1.Address + n1.Size,
                         n2.Address, n2.Address + n2.Size);
}

bool BuffersAllocator::SegmentsOverlap(size_t a1, size_t a2,
                                       size_t b1, size_t b2) noexcept {
  return (a1 > b1 && a1 < b2) || (a2 > b1 && a2 < b2) || (a1 <= b1 && a2 >= b2);
}

}  // namespace sound_feature_extraction
}  // namespace memory_allocation