Sean Connery

**Sir Sean Connery** (born **Thomas Connery**; 25 August 1930 – 31 October 2020) was a Scottish actor. He was the first actor to portray fictional British secret agent James Bond on film, starring in seven Bond films between 1962 and 1983. Originating the role in *Dr. No*, Connery played Bond in six of Eon Productions' entries and made his final appearance in *Never Say Never Again*.

Connery began acting in smaller theatre and television productions until his breakout role as Bond. Although he did not enjoy the off-screen attention the role gave him, the success of the Bond films brought Connery offers from notable directors such as Alfred Hitchcock, Sidney Lumet and John Huston. Their films in which Connery appeared included *Marnie* (1964), *The Hill* (1965), *Murder on the Orient Express* (1974), and *The Man Who Would Be King* (1975). He also appeared in *A Bridge Too Far* (1977), *Highlander* (1986), *The Name of the Rose* (1986), *The Untouchables* (1987), *Indiana Jones and the Last Crusade* (1989), *The Hunt for Red October* (1990), *Dragonheart* (1996), *The Rock* (1996), and *Finding Forrester* (2000). Connery officially retired from acting in 2006, although he briefly returned for voice-over roles in 2012.

His achievements in film were recognised with an Academy Award, two BAFTA Awards (including the BAFTA Fellowship), and three Golden Globes, including the Cecil B. DeMille Award and a Henrietta Award. In 1987, he was made a Commander of the Order of Arts and Letters in France, and he received the US Kennedy Center Honors lifetime achievement award in 1999. Connery was knighted in the 2000 New Year Honours for services to film drama.

## Early life

 File:Sean Connery plaque, Fountainbridge Edinburgh.jpg
 File:Connery birth certificate.jpg
Thomas Connery was born at the Royal Maternity Hospital in Edinburgh, Scotland on 25 August 1930; he was named after his paternal grandfather. He was brought up at No. 176 Fountainbridge, a block which has since been demolished. His mother, Euphemia McBain "Effie" McLean, was a cleaning woman. She was born the daughter of Neil McLean and Helen Forbes Ross, and named after her father's mother, Euphemia McBain, wife of John McLean and daughter of William McBain from Ceres in Fife. Connery's father, Joseph Connery, was a factory worker and lorry driver.

Two of his paternal great-grandparents emigrated to Scotland from Wexford, Ireland in the mid-19th century,**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** with his great-grandfather James Connery being an Irish Traveller. The remainder of his family was of Scottish descent, and his maternal great-grandparents were native Scottish Gaelic speakers from Fife and Uig on Skye. His father was a Roman Catholic, and his mother was a Protestant. Connery had a younger brother Neil and was generally referred to in his youth as "Tommy".**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Although he was small in primary school, he grew rapidly around the age of 12, reaching his full adult height of Template:Cvt at 18.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Connery was known during his teen years as "Big Tam", and he said that he lost his virginity to an adult woman in an ATS uniform at the age of 14.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).****Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** He had an Irish childhood friend named Séamus; when the two were together, those who knew them both called Connery by his middle name Sean, emphasizing the assonance of his personal and surnames. Since then Connery preferred to use his middle name.

Connery's first job was as a milkman in Edinburgh with St. Cuthbert's Co-operative Society. In 2009, Connery recalled a conversation in a taxi:
Template:Blockquote

In 1946, at the age of 16, Connery joined the Royal Navy, during which time he acquired two tattoos. Connery's official website says "unlike many tattoos, his were not frivolous — his tattoos reflect two of his lifelong commitments: his family and Scotland. ... One tattoo is a tribute to his parents and reads 'Mum and Dad', and the other is self-explanatory, 'Scotland Forever'". He trained in Portsmouth at the naval gunnery school and in an anti-aircraft crew. He was later assigned as an Able Seaman on HMS *Formidable*. Connery was discharged from the navy at the age of 19 on medical grounds because of a duodenal ulcer, a condition that affected most of the males in previous generations of his family.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Afterwards, he returned to the co-op and worked as a lorry driver, a lifeguard at Portobello swimming baths, a labourer, an artist's model for the Edinburgh College of Art, and after a suggestion by former Mr. Scotland Archie Brennan,**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** as a coffin polisher, among other jobs. The modelling earned him 15 shillings an hour.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Artist Richard Demarco, at the time a student who painted several early pictures of Connery, described him as "very straight, slightly shy, too, too beautiful for words, a virtual Adonis".**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Connery began bodybuilding at the age of 18, and from 1951 trained heavily with Ellington, a former gym instructor in the British Army.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** While his official website states he was third in the 1950 Mr. Universe contest, most sources place him in the 1953 competition, either third in the Junior class or failing to place in the Tall Man classification. Connery said he was soon deterred from bodybuilding when he found that Americans frequently beat him in competitions because of sheer muscle size and, unlike Connery, refused to participate in athletic activity which could make them lose muscle mass.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Connery was a keen footballer, having played for Bonnyrigg Rose in his younger days. He was offered a trial with East Fife. While on tour with *South Pacific*, Connery played in a football match against a local team that Matt Busby, manager of Manchester United, happened to be scouting. According to reports, Busby was impressed with his physical prowess and offered Connery a contract worth £25 a week (Template:Inflation) immediately after the game. Connery said he was tempted to accept, but he recalls, "I realised that a top-class footballer could be over the hill by the age of 30, and I was already 23. I decided to become an actor and it turned out to be one of my more intelligent moves".

### Early career

Seeking to supplement his income, Connery helped out backstage at the King's Theatre in late 1951. During a bodybuilding competition held in London in 1953, one of the competitors mentioned that auditions were being held for a production of *South Pacific*, and Connery landed a small part as one of the Seabees chorus boys. By the time the production reached Edinburgh, he had been given the part of Marine Cpl. Hamilton Steeves and was understudying two of the juvenile leads, and his salary was raised from £12 to £14–10s a week.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** The production returned the following year, out of popular demand, and Connery was promoted to the featured role of Lieutenant Buzz Adams, which Larry Hagman had portrayed in the West End.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

While in Edinburgh, Connery was targeted by the Valdor gang, one of the most violent in the city. He was first approached by them in a billiard hall where he prevented them from stealing his jacket and was later followed by six gang members to a 15-foot-high (4.6 m) balcony at the Palais de Danse.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** There, Connery singlehandedly launched an attack against the gang members, grabbing one by the throat and another by a biceps and cracked their heads together. From then on, he was treated with great respect by the gang and gained a reputation as a "hard man".**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Connery first met Michael Caine at a party during the production of *South Pacific* in 1954, and the two later became close friends.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** During this production at the Opera House, Manchester over the Christmas period of 1954, Connery developed a serious interest in the theatre through American actor Robert Henderson who lent him copies of the Ibsen works *Hedda Gabler*, *The Wild Duck*, and *When We Dead Awaken*, and later listed works by the likes of Proust, Tolstoy, Turgenev, Bernard Shaw, Joyce, and Shakespeare for him to digest.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Henderson urged him to take elocution lessons and got him parts at the Maida Vale Theatre in London. He had already begun a film career, having been an extra in Herbert Wilcox's 1954 musical *Lilacs in the Spring* alongside Anna Neagle.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Although Connery had secured several roles as extras, he was struggling to make ends meet, and was forced to accept a part-time job as a babysitter for journalist Peter Noble and his actress wife Marianne, which earned him 10 shillings a night.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** He met Hollywood actress Shelley Winters one night at Noble's house, who described Connery as "one of the tallest and most charming and masculine Scotsmen" she'd ever seen, and later spent many evenings with the Connery brothers drinking beer.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Around this time, Connery was residing at TV presenter Llew Gardner's house. Henderson landed Connery a role in a £6 a week Q Theatre production of Agatha Christie's *Witness for the Prosecution*, during which he met and became friends with fellow-Scot Ian Bannen.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** This role was followed by *Point of Departure* and *A Witch in Time* at Kew, a role as Pentheus opposite Yvonne Mitchell in *The Bacchae* at the Oxford Playhouse, and a role opposite Jill Bennett in Eugene O'Neill's play *Anna Christie*.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

During his time at the Oxford Theatre, Connery won a brief part as a boxer in the TV series *The Square Ring*, before being spotted by Canadian director Alvin Rakoff, who gave him multiple roles in *The Condemned*, shot on location in Dover in Kent. In 1956, Connery appeared in the theatrical production of *Epitaph*, and played a minor role as a hoodlum in the "Ladies of the Manor" episode of the BBC Television police series *Dixon of Dock Green*.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** This was followed by small television parts in *Sailor of Fortune* and *The Jack Benny Program* (on a special episode filmed in Europe).**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

 File:Lana Turner and Sean Connery — Another Time, Another Place.jpg
In early 1957, Connery hired agent Richard Hatton who got him his first film role, as Spike, a minor gangster with a speech impediment in Montgomery Tully's *No Road Back* alongside Skip Homeier, Paul Carpenter, Patricia Dainton, and Norman Wooland.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** In April 1957, RakoffTemplate:Sndafter being disappointed by Jack PalanceTemplate:Snddecided to give the young actor his first chance in a leading role, and cast Connery as Mountain McLintock in BBC Television's production of *Requiem for a Heavyweight*, which also starred Warren Mitchell and Jacqueline Hill. He then played a rogue lorry driver, Johnny Yates, in Cy Endfield's *Hell Drivers* (1957) alongside Stanley Baker, Herbert Lom, Peggy Cummins, and Patrick McGoohan.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Later in 1957, Connery appeared in Terence Young's poorly received MGM action picture *Action of the Tiger* opposite Van Johnson, Martine Carol, Herbert Lom, and Gustavo Rojo; the film was shot on location in southern Spain. He also had a minor role in Gerald Thomas's thriller *Time Lock* (1957) as a welder, appearing alongside Robert Beatty, Lee Patterson, Betty McDowall, and Vincent Winter; this commenced filming on 1 December 1956 at Beaconsfield Studios.

Connery had a major role in the melodrama *Another Time, Another Place* (1958) as a British reporter named Mark Trevor, caught in a love affair opposite Lana Turner and Barry Sullivan. During filming, Turner's possessive gangster boyfriend, Johnny Stompanato, who was visiting from Los Angeles, believed she was having an affair with Connery. Connery and Turner had attended West End shows and London restaurants together. Stompanato stormed onto the film set and pointed a gun at Connery, only to have Connery disarm him and knock him flat on his back. Stompanato was banned from the set. Two Scotland Yard detectives advised Stompanato to leave and escorted him to the airport, where he boarded a plane back to the United States. Connery later recounted that he had to lay low for a while after receiving threats from men linked to Stompanato's boss, Mickey Cohen.

In 1959, Connery landed a leading role in director Robert Stevenson's Walt Disney Productions film *Darby O'Gill and the Little People* (1959) alongside Albert Sharpe, Janet Munro, and Jimmy O'Dea. The film is a tale about a wily Irishman and his battle of wits with leprechauns. Upon the film's initial release, A. H. Weiler of *The New York Times* praised the cast (save Connery whom he described as "merely tall, dark, and handsome") and thought the film an "overpoweringly charming concoction of standard Gaelic tall stories, fantasy and romance". He also had prominent television roles in Rudolph Cartier's 1961 productions of *Adventure Story* and *Anna Karenina* for BBC Television, the latter of which he co-starred with Claire Bloom. Also in 1961 he portrayed the title role in a CBC television film adaptation of Shakespeare's *Macbeth* with Australian actress Zoe Caldwell cast as Lady Macbeth.

### James Bond: 1962–1971, 1983

 File:ETH-BIB Goldfinger 1964 – Com C13-035-007.jpg
Connery's breakthrough came in the role of British secret agent James Bond. He was reluctant to commit to a film series, but understood that if the films succeeded, his career would greatly benefit. Between 1962 and 1967, Connery played 007 in *Dr. No*, *From Russia with Love*, *Goldfinger*, *Thunderball*, and *You Only Live Twice*, the first five Bond films produced by Eon Productions. After departing from the role, Connery returned for the seventh film, *Diamonds Are Forever*, in 1971. Connery made his final appearance as Bond in *Never Say Never Again*, a 1983 remake of *Thunderball* produced by Jack Schwartzman's Taliafilm. All seven films were commercially successful. James Bond, as portrayed by Connery, was selected as the third-greatest hero in cinema history by the American Film Institute.

Connery's selection for the role of James Bond owed a lot to Dana Broccoli, wife of producer Albert "Cubby" Broccoli, who is reputed to have been instrumental in persuading her husband that Connery was the right man. James Bond's creator, Ian Fleming, originally doubted Connery's casting, saying, "He's not what I envisioned of James Bond looks," and "I'm looking for Commander Bond and not an overgrown stunt-man", adding that Connery (muscular, 6'Template:Nbs2", and a Scot) was unrefined. Fleming's girlfriend Blanche Blackwell told him Connery had the requisite sexual charisma, and Fleming changed his mind after the successful *Dr. No* première. He was so impressed, he wrote Connery's heritage into the character. In his 1964 novel *You Only Live Twice*, Fleming wrote that Bond's father was Scottish and from Glencoe in the Scottish Highlands.

 File:Sean Connery as James Bond (1971).jpg
Connery's portrayal of Bond owes much to stylistic tutelage from director Terence Young, who helped polish him while using his physical grace and presence for the action. Lois Maxwell, who played Miss Moneypenny, related that "Terence took Sean under his wing. He took him to dinner, showed him how to walk, how to talk, even how to eat". The tutoring was successful; Connery received thousands of fan letters a week after *Dr. No's* opening, and he became a major sex symbol in film.

Following the release of the film *Dr. No* in 1962, the line "Bond ... James Bond", became a catch phrase in the lexicon of Western popular culture.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** Film critic Peter Bradshaw writes, "It is the most famous self-introduction from any character in movie history. Three cool monosyllables, surname first, a little curtly, as befits a former naval commander. And then, as if in afterthought, the first name, followed by the surname again. Connery carried it off with icily disdainful style, in full evening dress with a cigarette hanging from his lips. The introduction was a kind of challenge, or seduction, invariably addressed to an enemy. In the early 60s, Connery's James Bond was about as dangerous and sexy as it got on screen".

During the filming of *Thunderball* in 1965, Connery's life was in danger in the sequence with the sharks in Emilio Largo's pool. He had been concerned about this threat when he read the script. Connery insisted that Ken Adam build a special Plexiglas partition inside the pool, but this was not a fixed structure, and one of the sharks managed to pass through it. He had to abandon the pool immediately.

### Beyond Bond

 File:Sean Connery 1964.png
Although Bond had made him a star, Connery grew tired of the role and the pressure the franchise put on him, saying "[I am] fed up to here with the whole Bond bit" and "I have always hated that damned James Bond. I'd like to kill him". Michael Caine said of the situation, "If you were his friend in these early days you didn't raise the subject of Bond. He was, and is, a much better actor than just playing James Bond, but he became synonymous with Bond. He'd be walking down the street and people would say, 'Look, there's James Bond'. That was particularly upsetting to him".**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

While making the Bond films, Connery also starred in other films such as Alfred Hitchcock's *Marnie* (1964) and Sidney Lumet's *The Hill* (1965), which film critic Peter Bradshaw regards as his two great non-Bond pictures from the 1960s. In *Marnie*, Connery starred opposite Tippi Hedren. Connery had said he wanted to work with Hitchcock, which Eon arranged through their contacts. Connery also shocked many people at the time by asking to see a script, something he did because he was worried about being typecast as a spy and he did not want to do a variation of *North by Northwest* or *Notorious*. When told by Hitchcock's agent that Cary Grant had not asked to see even one of Hitchcock's scripts, Connery replied: "I'm not Cary Grant". Hitchcock and Connery got on well during filming, and Connery said he was happy with the film "with certain reservations". In *The Hill*, Connery wanted to act in something that wasn't Bond related, and he used his leverage as a star to feature in it. While the film wasn't a financial success it was a critical one, debuting at the Cannes Film Festival winning Best Screenplay. The first of five films he made with Lumet, Connery considered him to be one of his favourite directors. The respect was mutual, with Lumet saying of Connery's performance in *The Hill*, ”The thing that was apparent to me — and to most directors — was how much talent and ability it takes to play that kind of character who is based on charm and magnetism. It’s the equivalent of high comedy and he did it brilliantly.”

In the mid 1960s, Connery played golf with Scottish industrialist Iain Maxwell Stewart, a connection which led to Connery directing and presenting the documentary film *The Bowler and the Bunnet* in 1967. The film described the Fairfield Experiment, a new approach to industrial relations carried out at the Fairfield Shipbuilding and Engineering Company, Glasgow during the 1960s, initiated by Stewart, and supported by George Brown, the First Secretary in Harold Wilson's cabinet, in 1966. The company was facing closure, and Brown agreed to provide £1 million to enable trade unions, the management and the shareholders to try out new ways of industrial management.

 File:Hepburn Connery Robin and Marian Still 1976.jpg
Having played Bond six times, Connery's global popularity was such that he shared a Golden Globe Henrietta Award with Charles Bronson for "World Film FavoriteTemplate:SndMale" in 1972. He appeared in John Huston's *The Man Who Would Be King* (1975) opposite Michael Caine. Playing two former British soldiers who set themselves up as kings in Kafiristan, both actors regarded it as their favourite film. The same year, he appeared in *The Wind and the Lion* opposite Candice Bergen who played Eden Pedecaris (based on the real-life Perdicaris incident), and in 1976 played Robin Hood in *Robin and Marian* opposite Audrey Hepburn, who played Maid Marian. Film critic Roger Ebert, who had praised the double act of Connery and Caine in *The Man Who Would Be King*, praised Connery's chemistry with Hepburn, writing: "Connery and Hepburn seem to have arrived at a tacit understanding between themselves about their characters. They glow. They really do seem in love".

During the 1970s Connery was part of ensemble casts in films such as *Murder on the Orient Express* (1974) with Vanessa Redgrave and John Gielgud, and played a British Army general in Richard Attenborough's war film *A Bridge Too Far* (1977), co-starring Dirk Bogarde and Laurence Olivier. In 1974, he starred in John Boorman's sci-fi thriller *Zardoz*. Often called one of the "weirdest and worst movies ever made" it featured Connery in a scarlet mankiniTemplate:Snda revealing costume which generated much controversy for its unBond-like appearance. Despite being panned by critics at the time, the film has developed a cult following since its release. In the audio commentary to the film, Boorman relates how Connery would write poetry in his free time, describing him as "a man of great depth and intelligence" and possessing the "most extraordinary memory". In 1981, Connery appeared in the film *Time Bandits* as Agamemnon. The casting choice derives from a joke Michael Palin included in the script, which describes the character's removing his mask and being "Sean ConneryTemplate:Sndor someone of equal but cheaper stature". When shown the script, Connery was happy to play the supporting role. In 1981 he portrayed Marshal William T. O'Niel in the science fiction thriller *Outland*. In 1982, Connery narrated *G'olé!*, the official film of the 1982 FIFA World Cup. That same year, he was offered the role of Daddy Warbucks in *Annie*, going as far as taking voice lessons for the John Huston musical before turning down the part.

 File:SeanConnery88.jpg
Connery agreed to reprise Bond as an ageing agent 007 in *Never Say Never Again*, released in October 1983. The title, contributed by his wife, refers to his earlier statement that he would "never again" return to the role. Although the film performed well at the box office, it was plagued with production problems: strife between the director and producer, financial problems, the Fleming estate trustees' attempts to halt the film, and Connery's wrist being broken by fight choreographer, Steven Seagal. As a result of his negative experiences during filming, Connery became unhappy with the major studios and did not make any films for two years. Following the successful European production *The Name of the Rose* (1986), for which he won a BAFTA Award for Best Actor, Connery's interest in more commercial material was revived. That same year, a supporting role in *Highlander* showcased his ability to play older mentors to younger leads, which became a recurring role in many of his later films.

In 1987, Connery starred in Brian De Palma's *The Untouchables*, where he played a hard-nosed Irish-American cop alongside Kevin Costner's Eliot Ness. The film also starred Charles Martin Smith, Patricia Clarkson, Andy Garcia, and Robert De Niro as Al Capone. The film was a critical and box office success. Many critics praised Connery for his performance including Roger Ebert who wrote "The best performance in the movie is ConneryTemplate:Nbs... [he] brings a human element to his character; he seems to have had an existence apart from the legend of the Untouchables, and when he's onscreen we can believe, briefly, that the Prohibition Era was inhabited by people, not caricatures". For his performance Connery received the Academy Award for Best Supporting Actor.

 File:Sean Connery 1999.jpg
Connery starred in Steven Spielberg's *Indiana Jones and the Last Crusade* (1989), playing Henry Jones, Sr., the title character's father, and received BAFTA and Golden Globe Award nominations. Harrison Ford said Connery's contributions at the writing stage enhanced the film. "It was amazing for me in how far he got into the script and went after exploiting opportunities for character. His suggestions to George [Lucas] at the writing stage really gave the character and the picture a lot more complexity and value than it had in the original screenplay". His subsequent box-office hits included *The Hunt for Red October* (1990), *The Russia House* (1990), *The Rock* (1996), and *Entrapment* (1999). In 1996, he voiced the role of Draco the dragon in the film *Dragonheart*. He also appeared in a brief cameo as King Richard the Lionheart at the end of *Robin Hood: Prince of Thieves* (1991). In 1998, Connery received the BAFTA Fellowship, a lifetime achievement award from the British Academy of Film and Television Arts.

Connery's later films included several box office and critical disappointments such as *First Knight* (1995), *Just Cause* (1995), *The Avengers* (1998), and *The League of Extraordinary Gentlemen* (2003); however, he received positive reviews for his performance in *Finding Forrester* (2000). He also received a Crystal Globe for outstanding artistic contribution to world cinema. In a 2003 UK poll conducted by Channel 4, Connery was ranked eighth on their list of the 100 Greatest Movie Stars. The failure of *The League of Extraordinary Gentlemen* was especially frustrating for Connery. He sensed during shooting that the production was "going off the rails", and announced that the director, Stephen Norrington should be "locked up for insanity". Connery spent considerable effort in trying to salvage the film through the editing process, ultimately deciding to retire from acting rather than go through such stress ever again.

Connery turned down the role of Gandalf in *The Lord of the Rings* films, saying he did not understand the script. He was reportedly offered US$30 million along with 15% of the worldwide box office receipts, which would have earned him US$450 million. He also turned down the opportunity to appear as Albus Dumbledore in the *Harry Potter* series and the Architect in *The Matrix* trilogy. In 2005, he recorded voiceovers for the *From Russia with Love* video game with recording producer Terry Manning in The Bahamas, and provided his likeness. Connery said he was happy the producers, Electronic Arts, had approached him to voice Bond.

### Retirement

 File:SeanConneryJune08.jpg
When Connery received the American Film Institute's Lifetime Achievement Award on 8 June 2006, he confirmed his retirement from acting. Connery's disillusionment with the "idiots now making films in Hollywood" was cited as a reason for his decision to retire. On 7 June 2007, he denied rumours that he would appear in the fourth *Indiana Jones* film, saying "retirement is just too much damned fun". In 2010, a bronze bust sculpture of Connery was placed in Tallinn, Estonia, outside The Scottish Club, whose membership includes Estonian Scotophiles and a handful of expatriate Scots. In 2012, Connery briefly came out of retirement to voice the title character in the Scottish animated film *Sir Billi the Vet*. Connery served as executive producer for an expanded 80-minute version.

## Personal life

 File:Diane Cilento, 1954.jpg
During the production of *South Pacific* in the mid-1950s, Connery dated a Jewish "dark-haired beauty with a ballerina's figure", Carol Sopel, but was warned off by her family.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** He then dated Julie Hamilton, daughter of documentary filmmaker and feminist Jill Craigie. Given Connery's rugged appearance and rough charm, Hamilton initially thought he was an appalling person and was not attracted to him until she saw him in a kilt, declaring him to be the most beautiful thing she had ever seen in her life.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).** He also shared a mutual attraction with jazz singer Maxine Daniels, whom he met at the Empire Theatre. He made a pass at her, but she told him she was already happily married with a daughter.**Lua error in Module:Footnotes at line 53: attempt to index local 'anchor\_id\_list' (a nil value).**

Connery was married to actress Diane Cilento from 1962 to 1973, though they separated in 1971. They had a son, actor Jason Joseph. While they were separated, Connery dated Jill St. John, Lana Wood, Carole Mallory, and Magda Konopka. In her 2006 autobiography, Cilento alleged that he had abused her mentally and physically during their relationship. Connery cancelled an appearance at the Scottish Parliament in 2006 because of controversy over his alleged support of abuse of women. He denied claims he told *Playboy* magazine in 1965, "I don't think there is anything particularly wrong in hitting a woman, though I don't recommend you do it in the same way you hit a man", and was also reported to have stated to *Vanity Fair* in 1993, "There are women who take it to the wire. That's what they are looking for, the ultimate confrontation. They want a smack". In 2006, Connery told *The Times* of London, "I don't believe that any level of abuse of women is ever justified under any circumstances. Full stop".

 File:ConneryKilt.jpg
Connery was married to French-Moroccan painter Micheline Roquebrune (born 4 April 1929) from 1975 until his death. The marriage survived a well-documented affair Connery had in the late 1980s with the singer and songwriter Lynsey de Paul, which she later bitterly regretted due to his views concerning domestic violence.

Connery owned the Domaine de Terre Blanche in the South of France from 1979. He sold it to German billionaire Dietmar Hopp in 1999. He was awarded an honorary rank of *Shodan* (1st dan) in Kyokushin karate. Connery relocated to The Bahamas in the 1990s; he owned a mansion in Lyford Cay on New Providence.

Connery was knighted by the Queen at an investiture ceremony at Holyrood Palace in Edinburgh on 5 July 2000. He had been nominated for a knighthood in 1997 and 1998, but these nominations were reportedly vetoed by Donald Dewar owing to Connery's political views.Template:R Connery had a villa in Kranidi, Greece. His neighbour was King Willem-Alexander of the Netherlands, with whom he shared a helicopter platform. Michael Caine (who co-starred with Connery in *The Man Who Would Be King* in 1975) was among Connery's closest friends.

Connery was granted armorial bearings including heraldic supporters in 2018 by the Lord Lyon King of Arms, the head of Scotland's heraldic authority. The armorial bearings included golf clubs and an Oscar statuette, with the painting subtly containing "007" in the compartment. Supporters are normally only granted to clan chiefs, peers, and members of the senior ranks of orders of chivalry.

Growing up Connery supported the Scottish football club Celtic F.C., having been introduced to the club by his father who was a lifelong fan of the team. Later in life, Connery switch his loyalty to Celtic's bitter rival, Rangers F.C., after he became close friends with the team's chairman, David Murray. He was a keen golfer, introduced to the game by his friend Iain Stewart. English professional golfer Peter Alliss gave Connery golf lessons before the filming of the 1964 James Bond film *Goldfinger*, which involved a scene where Connery, as Bond, played golf against gold magnate Auric Goldfinger at Stoke Park Golf Club in Buckinghamshire. The golf scene saw him wear a Slazenger v-neck sweater, a brand which Connery became associated with while playing golf in his free time, with a light grey marl being a favoured colour. Record major championship winner and golf course designer Jack Nicklaus said, "He loved the game of golfTemplate:SndSean was a pretty darn good golfer!Template:Sndand we played together several times. In May 1993, Sean and legendary driver Jackie Stewart helped me open our design of the PGA Centenary Course at Gleneagles in Scotland".

### Political views

Connery's Scottish roots and his experiences in filming in Glasgow's shipyards in 1966 inspired him to become a member of the centre-left Scottish National Party (SNP), which supports Scottish independence from the United Kingdom (in 2011, Connery said "*The Bowler and the Bunnet* was just the beginning of a journey that would lead to my long association with the Scottish National Party"). Connery supported the party both financially and through personal appearances. In 1967, he wrote to George Leslie, the SNP candidate in the 1967 Glasgow Pollok by-election, saying, "I am convinced that with our resources and skills we are more than capable of building a prosperous, vigorous and modern self-governing Scotland in which we can all take pride and which will deserve the respect of other nations." His funding of the SNP ceased in 2001, when the Parliament of the United Kingdom passed legislation prohibiting overseas funding of political activities in the United Kingdom.

### Tax status

In response to accusations that he was a tax exile, Connery released documents in 2003 showing he had paid £3.7 million in UK taxes between 1997 and 1998 and between 2002 and 2003; critics pointed out that had he been continuously residing in the UK for tax purposes, his tax rate would have been far higher. In the run-up to the 2014 Scottish independence referendum, Connery's brother Neil said Connery would not come to Scotland to rally independence supporters, since his tax exile status greatly limited the number of days he could spend in the country.

After Connery sold his Marbella villa in 1999, Spanish authorities launched a tax evasion investigation, alleging that the Spanish treasury had been defrauded of £5.5 million. Connery was subsequently cleared by officials, but his wife and 16 others were charged with attempting to defraud the Spanish treasury.

## Death and legacy

Connery died in his sleep on 31 October 2020, aged 90, at his home in the Lyford Cay community of Nassau in The Bahamas. His death was announced by his family and Eon Productions; although they did not disclose the cause of death, his son Jason said he had been unwell for some time. A day later, Roquebrune revealed he had dementia in his final years. Connery's death certificate was obtained by TMZ a month after his death, showing the cause of death was pneumonia and cardiopulmonary failure, and the time of death was listed as 1:30 a.m. He was cremated after his death, and his ashes will be scattered in Scotland at a date yet to be determined.

Following the announcement of his death, many co-stars and figures from the entertainment industry paid tribute to Connery, including Sam Neill, Nicolas Cage, Robert De Niro, Michael Bay, Tippi Hedren, Alec Baldwin, Hugh Jackman, George Lucas, Shirley Bassey, Kevin Costner, Catherine Zeta-Jones, Barbra Streisand, John Cleese, Jane Seymour and Harrison Ford, as well as former Bond stars George Lazenby, Timothy Dalton and Pierce Brosnan, the family of late former Bond actor Roger Moore and then-current 007 Daniel Craig. Connery's longtime friend Michael Caine called him a "great star, brilliant actor and a wonderful friend". James Bond producers Michael G. Wilson and Barbara Broccoli released a statement saying Connery had "revolutionized the world with his gritty and witty portrayal of the sexy and charismatic secret agent. He is undoubtedly largely responsible for the success of the film series and we shall be forever grateful to him".

In 2004, a poll in the UK *Sunday Herald* recognized Connery as "The Greatest Living Scot" and a 2011 EuroMillions survey named him "Scotland's Greatest Living National Treasure". He was voted by *People* magazine as the "Sexiest Man Alive" in 1989 and the "Sexiest Man of the Century" in 1999.

## Awards and honours

**Honours**

* 1987: Commander of the Order of Arts and Letters from France
* 1998: British Academy Film Fellowship
* 1999: Kennedy Center Honors
* 2000: Received Knighthood from Queen Elizabeth II
* 2005: European Film Awards Lifetime Achievement Award
* 2006: AFI Life Achievement Award

## References

1. ↑ 1.0 1.1 Harmetz, Aljean. "Sean Connery, Who Embodied James Bond and More, Dies at 90", 31 October 2020.
2. ↑ 2.0 2.1 Shapiro, T. Rees. "Sean Connery, first James Bond of film, dies at 90", 31 October 2020.
3. ↑ "Profile: Sean Connery", *BBC News*, 12 March 2006.
4. ↑ "Sir Sean's pride at knighthood", BBC.
5. ↑ Pendreigh, Brian. "Obituary: The Sean Connery I knew", *The Scotsman*, 1 November 2020.
6. ↑ Template:Who's Who Template:Subscription required
7. ↑ Sir Sean visits site of his childhood Edinburgh home. BBC (17 June 2010).
8. ↑ Scottish Roots People - Sean Connery.
9. ↑ Family tree of Euphemia McBain (en).
10. ↑ Familyrelatives.com | Case Study 1 - Sean Connery - James Bond.
11. ↑ Sean Connery Biography. Advameg, Inc..
12. ↑ Case Study 1 – Sean Connery – James Bond. Treequest Limited.
13. ↑ 13.0 13.1 13.2 13.3 Harry Brent (18 August 2021). Five things you never knew about Sean Connery's Irish roots.
14. ↑  (2009) *Being a Scot*. Phoenix Illustrated.
15. ↑ Scottish Genealogy Scottish Ancestry Family Tree Scottish Genealogists.
16. ↑ From the Co-op with love ... the days Sir Sean earned £1 a week (21 November 2005).
17. ↑ The Official Website of Sir Sean Connery – Biography. Seanconnery.com.
18. ↑ Catch up on all the Belly Buzz ... – Celebrity Veterans – Sean Connery, British Royal Navy 1946–1949.
19. ↑ Davidson, Lynn. "Even as an unknown, Sean was still a draw", 22 August 2003.
20. ↑ 20.0 20.1 20.2 Wills, Dominic. Sean Connery – Biography. Tiscali.
21. ↑ 1953 Mr. Universe – NABBA.
22. ↑ Crawford, Kenny (7 December 2016). Bonnyrigg Rose: Four things you might not know about the Rosey Posey. *BBC Scotland*.
23. ↑ Christopher Bray (2010) "Sean Connery: The measure of a man" p. 27. Faber & Faber
24. ↑ Scottish Junior Football Association > Mud & Glory > Sean Connery. Mud & Glory (April 2005).
25. ↑ Baldwin, Louis (1999). *Turning Points: Pivotal Moments in the Careers of 83 Famous Figures*. McFarland, page 53. ISBN 978-0-7864-0626-5.
26. ↑ Callan, Michael Feeney (2002). *Sean Connery*. Virgin, page 75. ISBN 978-1-85227-992-9.
27. ↑  (1997) *The films of Sean Connery*. Carol Pub. Group. ISBN 978-0-8065-1837-4.
28. ↑ Morella, Joe; Epstein, Edward Z. (1971) *Lana: The Public and Private Lives of Miss Turner* pp. 177–182 New York: Citadel Press
29. ↑ 29.0 29.1 "Sean Connery: How he seduced a movie legend and faced the wrath of the Mafia", *Evening Standard*.
30. ↑ Kohn, George C. (2001) *The New Encyclopedia of American Scandal. Facts on File: Library of American History* (Revised ed.) p. 388. New York: Infobase Publishing
31. ↑ Turner, Lana (1982) Lana: The Lady, the Legend, the Truth (1st ed.) p. 170. New York: Dutton
32. ↑ Weiler, A. H.. "Darby O'Gill and the Little People", 1 July 1959.
33. ↑ Wake, Oliver. Cartier, Rudolph (1904–1994). Screenonline.
34. ↑ Van Wagner, Danielle (2004). Macbeth. University of Guelph.
35. ↑  (2012) *Angelina Jolie – The Lightning Star*. London: Lulu, page 288. ISBN 978-1-4710-8935-0.
36. ↑ "AFI's 100 Years... 100 Heroes and Villains" --[[ ----------------------------------

Lua module implementing the Template loop detected: Template:Webarchive template.

A merger of the functionality of three templates: Template:Wayback, Template:Webcite and Template:Cite archives

]]

--[[--------------------------< D E P E N D E N C I E S >------------------------------------------------------
]]

require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;

--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]

local categories = {}; -- category names
local config = {}; -- global configuration settings
local digits = {}; -- for i18n; table that translates local-wiki digits to western digits
local err\_warn\_msgs = {}; -- error and warning messages
local excepted\_pages = {};
local month\_num = {}; -- for i18n; table that translates local-wiki month names to western digits
local prefixes = {}; -- service provider tail string prefixes
local services = {}; -- archive service provider data from
local s\_text = {}; -- table of static text strings used to build final rendering
local uncategorized\_namespaces = {}; -- list of namespaces that we should not categorize
local uncategorized\_subpages = {}; -- list of subpages that should not be categorized

--[[--------------------------< P A G E S C O P E I D E N T I F I E R S >----------------------------------
]]

local non\_western\_digits; -- boolean flag set true when data.digits.enable is true
local this\_page = mw.title.getCurrentTitle();

local track = {}; -- Associative array to hold tracking categories
local ulx = {}; -- Associative array to hold template data

--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------

Populates numbered arguments in a message string using an argument table.

]]

local function substitute (msg, args)
 return args and mw.message.newRawMessage (msg, args):plain() or msg;
end

--[[--------------------------< tableLength >-----------------------

Given a 1-D table, return number of elements

]]

local function tableLength(T)
 local count = 0
 for \_ in pairs(T) do count = count + 1 end
 return count
end

--[=[-------------------------< M A K E \_ W I K I L I N K >----------------------------------------------------

Makes a wikilink; when both link and display text is provided, returns a wikilink in the form D; if only
link is provided, returns a wikilink in the form L; if neither are provided or link is omitted, returns an
empty string.

]=]

local function make\_wikilink (link, display, no\_link)
 if nil == no\_link then
 if link and ( *~= link) then*
 if display and ( *~= display) then*
 return table.concat ({'', display, ''});
 else
 return table.concat ({'', link, ''});
 end
 end
 return display or *; -- link not set so return the display text*

 else -- no\_link
 if display and ( *~= display) then -- if there is display text*
 return display; -- return that
 else
 return link or *; -- return the target article name or empty string*
 end
 end
end

--[[--------------------------< createTracking >-----------------------

Return data in track[] ie. tracking categories

]]

local function createTracking()
 if not excepted\_pages[this\_page.fullText] then -- namespace:title/fragment is allowed to be categorized (typically this module's / template's testcases page(s))
 if uncategorized\_namespaces[this\_page.nsText] then
 return *; -- this page not to be categorized so return empty string*
 end
 for \_,v in ipairs (uncategorized\_subpages) do -- cycle through page name patterns
 if this\_page.text:match (v) then -- test page name against each pattern
 return *; -- this subpage type not to be categorized so return empty string*
 end
 end
 end

 local out = {};
 if tableLength(track) > 0 then
 for key, \_ in pairs(track) do -- loop through table
 table.insert (out, make\_wikilink (key)); -- and convert category names to links
 end
 end
 return table.concat (out); -- concat into one big string; empty string if table is empty

end

--[[--------------------------< inlineError >-----------------------

Critical error. Render output completely in red. Add to tracking category.

This function called as the last thing before abandoning this module

]]

local function inlineError (msg, args)
 track[categories.error] = 1
 return table.concat ({
 'Error in ', -- open the error message span
 config.tname, -- insert the local language template name
 ' template: ',
 substitute (msg, args), -- insert the formatted error message
 '.', -- close the span
 createTracking() -- add the category
 })
end

--[[--------------------------< inlineRed >-----------------------

Render a text fragment in red, such as a warning as part of the final output.
Add tracking category.

 ]]

local function inlineRed(msg, trackmsg)
 if trackmsg == "warning" then
 track[categories.warning] = 1;
 elseif trackmsg == "error" then
 track[categories.error] = 1;
 end

 return '' .. msg .. ''
end

--[[--------------------------< base62 >-----------------------

Convert base-62 to base-10
Credit: https://de.wikipedia.org/wiki/Modul:Expr

]]

local function base62( value )
 local r = 1 -- default return value is input value is malformed

 if value:match ('%W') then -- value must only be in the set [0-9a-zA-Z]
 return; -- nil return when value contains extraneous characters
 end

 local n = #value -- number of characters in value
 local k = 1
 local c
 r = 0
 for i = n, 1, -1 do -- loop through all characters in value from ls digit to ms digit
 c = value:byte( i, i )
 if c >= 48 and c <= 57 then -- character is digit 0-9
 c = c - 48
 elseif c >= 65 and c <= 90 then -- character is ascii a-z
 c = c - 55
 else -- must be ascii A-Z
 c = c - 61
 end
 r = r + c \* k -- accumulate this base62 character's value
 k = k \* 62 -- bump for next
 end -- for i

 return r
end

--[[--------------------------< D E C O D E \_ D A T E >--------------------------------------------------------

Given a date string, return it in iso format along with an indicator of the date's format. Except that month names
must be recognizable as legitimate month names with proper capitalization, and that the date string must match one
of the recognized date formats, no error checking is done here; return nil else

]]

local function decode\_date (date\_str)
 local patterns = {
 ['dmy'] = {'^(%d%d?) +([^%s%d]+) +(%d%d%d%d)$', 'd', 'm', 'y'}, -- %a does not recognize unicode combining characters used by some languages
 ['mdy'] = {'^([^%s%d]+) (%d%d?), +(%d%d%d%d)$', 'm', 'd', 'y'},
 ['ymd'] = {'^(%d%d%d%d) +([^%s%d]+) (%d%d?)$', 'y', 'm', 'd'}, -- not mos compliant at en.wiki but may be acceptible at other wikis
 };

 local t = {};

 if non\_western\_digits then -- this wiki uses non-western digits?
 date\_str = mw.ustring.gsub (date\_str, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 if date\_str:match ('^%d%d%d%d%-%d%d%-%d%d$') then -- already an iso format date, return western digits form
 return date\_str, 'iso';
 end

 for k, v in pairs (patterns) do
 local c1, c2, c3 = mw.ustring.match (date\_str, patterns[k][1]); -- c1 .. c3 are captured but we don't know what they hold

 if c1 then -- set on match
 t = { -- translate unspecified captures to y, m, and d
 [patterns[k][2]] = c1, -- fill the table of captures with the captures
 [patterns[k][3]] = c2, -- take index names from src\_pattern table and assign sequential captures
 [patterns[k][4]] = c3,
 };
 if month\_num[t.m] then -- when month not already a number
 t.m = month\_num[t.m]; -- replace valid month name with a number
 else
 return nil, 'iso'; -- not a valid date form because month not valid
 end

 return mw.ustring.format ('%.4d-%.2d-%.2d', t.y, t.m, t.d), k; -- return date in iso format
 end
 end
 return nil, 'iso'; -- date could not be decoded; return nil and default iso date
end

--[[--------------------------< makeDate >-----------------------

Given year, month, day numbers, (zero-padded or not) return a full date in df format
where df may be one of:
 mdy, dmy, iso, ymd

on entry, year, month, day are presumed to be correct for the date that they represent; all are required

in this module, makeDate() is sometimes given an iso-format date in year:
 makeDate (2018-09-20, nil, nil, df)
this works because table.concat() sees only one table member

]]

local function makeDate (year, month, day, df)
 local format = {
 ['dmy'] = 'j F Y',
 ['mdy'] = 'F j, Y',
 ['ymd'] = 'Y F j',
 ['iso'] = 'Y-m-d',
 };

 local date = table.concat ({year, month, day}, '-'); -- assemble year-initial numeric-format date (zero padding not required here)

 if non\_western\_digits then -- this wiki uses non-western digits?
 date = mw.ustring.gsub (date, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return mw.getContentLanguage():formatDate (format[df], date);
end

--[[--------------------------< I S \_ V A L I D \_ D A T E >----------------------------------------------------

Returns true if date is after 31 December 1899 (why is 1900 the min year? shouldn't the internet's date-of-birth
be min year?), not after today's date, and represents a valid date (29 February 2017 is not a valid date). Applies
Gregorian leapyear rules.

all arguments are required

]]

local function is\_valid\_date (year, month, day)
 local days\_in\_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 local month\_length;
 local y, m, d;
 local today = os.date ('\*t'); -- fetch a table of current date parts

 if not year or  *== year or not month or*  == month or not day or  *== day then*
 return false; -- something missing
 end

 y = tonumber (year);
 m = tonumber (month);
 d = tonumber (day);

 if 1900 > y or today.year < y or 1 > m or 12 < m then -- year and month are within bounds TODO: 1900?
 return false;
 end

 if (2==m) then -- if February
 month\_length = 28; -- then 28 days unless
 if (0==(y%4) and (0~=(y%100) or 0==(y%400))) then -- is a leap year?
 month\_length = 29; -- if leap year then 29 days in February
 end
 else
 month\_length=days\_in\_month[m];
 end

 if 1 > d or month\_length < d then -- day is within bounds
 return false;
 end
 -- here when date parts represent a valid date
 return os.time({['year']=y, ['month']=m, ['day']=d, ['hour']=0}) <= os.time(); -- date at midnight must be less than or equal to current date/time
end

--[[--------------------------< decodeWebciteDate >-----------------------

Given a URI-path to Webcite (eg. /67xHmVFWP) return the encoded date in df format

returns date string in df format - webcite date is a unix timestamp encoded as bae62
or the string 'query'

]]

local function decodeWebciteDate(path, df)

 local dt = {};
 local decode;

 dt = mw.text.split(path, "/")

 -- valid URL formats that are not base62

 -- http://www.webcitation.org/query?id=1138911916587475
 -- http://www.webcitation.org/query?url=http..&date=2012-06-01+21:40:03
 -- http://www.webcitation.org/1138911916587475
 -- http://www.webcitation.org/cache/73e53dd1f16cf8c5da298418d2a6e452870cf50e
 -- http://www.webcitation.org/getfile.php?fileid=1c46e791d68e89e12d0c2532cc3cf629b8bc8c8e

 if dt[2]:find ('query', 1, true) or
 dt[2]:find ('cache', 1, true) or
 dt[2]:find ('getfile', 1, true) or
 tonumber(dt[2]) then
 return 'query';
 end

 decode = base62(dt[2]); -- base62 string -> exponential number
 if not decode then
 return nil; -- nil return when dt[2] contains characters not in %w
 end
 dt = os.date('\*t', string.format("%d", decode):sub(1,10)) -- exponential number -> text -> first 10 characters (a unix timestamp) -> a table of date parts

 decode = makeDate (dt.year, dt.month, dt.day, 'iso'); -- date comparisons are all done in iso format with western digits
 if non\_western\_digits then -- this wiki uses non-western digits?
 decode = mw.ustring.gsub (decode, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return decode;
end

--[[--------------------------< decodeWaybackDate >-----------------------

Given a URI-path to Wayback (eg. /web/20160901010101/http://example.com )
or Library of Congress Web Archives (eg. /all/20160901010101/http://example.com)
or UK Government Web Archive (eg. /ukgwa/20160901010101/http://example.com or /tna/20160901010101/http://example.com)

return the formatted date eg. "September 1, 2016" in df format
Handle non-digits in snapshot ID such as "re\_" and "-" and "\*"

 valid date string in df format - wayback date is valid (including the text string 'index' when date is '/\*/')
 empty string - wayback date is malformed (less than 8 digits, not a valid date)
 nil - wayback date is '/save/' or otherwise not a number

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeWaybackDate(path, df)

 local msg, snapdate;

 snapdate = path:gsub ('^/web/', *):gsub ('^/all/',* ):gsub ('^/ukgwa/', *):gsub ('^/tna/',* ):gsub ('^/', *); -- remove leading /web/, /all/, /ukgwa/, /tna/, or /*
 snapdate = snapdate:match ('^[^/]+'); -- get timestamp
 if snapdate == "\*" then -- eg. /web/\*/http.., etc.
 return 'index'; -- return indicator that this url has an index date
 end

 snapdate = snapdate:gsub ('%a%a\_%d?$', *):gsub ('%-',* ); -- from date, remove any trailing "re\_", dashes

 msg = *;*
 if snapdate:match ('%\*$') then -- a trailing '\*' causes calendar display at archive .org
 snapdate = snapdate:gsub ('%\*$', *); -- remove so not part of length calc later*
 msg = inlineRed (err\_warn\_msgs.ts\_cal, 'warning'); -- make a message
 end

 if not tonumber(snapdate) then
 return nil, 'ts\_nan'; -- return nil (fatal error flag) and message selector
 end

 local dlen = snapdate:len();
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate, msg; -- return date with message if any
 else
 return snapdate, msg .. inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message(s)
 end
end

--[[--------------------------< decodeArchiveisDate >-----------------------

Given an Archive.is "long link" URI-path (e.g. /2016.08.28-144552/http://example.com)
return the date in df format (e.g. if df = dmy, return 28 August 2016)
Handles "." and "-" in snapshot date, so 2016.08.28-144552 is same as 20160828144552

 valid date string in df format - archive.is date is valid (including the text string 'short link' when url is the short form)
 empty string - wayback date is malformed (not a number, less than 8 digits, not a valid date)
 nil - wayback date is '/save/'

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeArchiveisDate(path, df)
 local snapdate

 if path:match ('^/%w+$') then -- short form url path is '/' followed by some number of base 62 digits and nothing else
 return "short link" -- e.g. http://archive.is/hD1qz
 end

 snapdate = mw.text.split (path, '/')[2]:gsub('[%.%-]', *); -- get snapshot date, e.g. 2016.08.28-144552; remove periods and hyphens*

 local dlen = string.len(snapdate)
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate; -- return date
 else
 return snapdate, inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message
 end
 end

--[[--------------------------< serviceName >-----------------------

Given a domain extracted by mw.uri.new() (eg. web.archive.org) set tail string and service ID

]]

local function serviceName(host, no\_link)
 local tracking;
 local index;

 host = host:lower():gsub ('^web%.(.+)', '%1'):gsub ('^www%.(.+)', '%1'); -- lowercase, remove web. and www. subdomains

 if services[host] then
 index = host;
 else
 for k, \_ in pairs (services) do
 if host:find ('%f[%a]'..k:gsub ('([%.%-])', '%%%1')) then
 index = k;
 break;
 end
 end
 end

 if index then
 local out = {*}; -- empty string in [1] so that concatenated result has leading single space*
 ulx.url1.service = services[index][4] or 'other';
 tracking = services[index][5] or categories.other;
 -- build tail string
 if false == services[index][1] then -- select prefix
 table.insert (out, prefixes.at);
 elseif true == services[index][1] then
 table.insert (out, prefixes.atthe);
 else
 table.insert (out, services[index][1]);
 end

 table.insert (out, make\_wikilink (services[index][2], services[index][3], no\_link)); -- add article wikilink
 if services[index][6] then -- add tail postfix if it exists
 table.insert (out, services[index][6]);
 end

 ulx.url1.tail = table.concat (out, ' '); -- put it all together; result has leading space character

 else -- here when unknown archive
 ulx.url1.service = 'other';
 tracking = categories.unknown;
 ulx.url1.tail = table.concat ({*, prefixes.at, host, inlineRed (err\_warn\_msgs.unknown\_url, error)}, ' ');*
 end

 track[tracking] = 1
end

--[[--------------------------< parseExtraArgs >-----------------------

Parse numbered arguments starting at 2, such as url2..url10, date2..date10, title2..title10
 For example: Template loop detected: Template:Webarchive
 Three url arguments not in numeric sequence (1..4..7).
 Function only processes arguments numbered 2 or greater (in this case 4 and 7)
 It creates numeric sequenced table entries like:
 urlx.url2.url = <argument value for url4>
 urlx.url3.url = <argument value for url7>
 Returns the number of URL arguments found numbered 2 or greater (in this case returns "2")

 ]]

local function parseExtraArgs(args)

 local i, j, argurl, argurl2, argdate, argtitle

 j = 2
 for i = 2, config.maxurls do
 argurl = "url" .. i
 if args[argurl] then
 argurl2 = "url" .. j
 ulx[argurl2] = {}
 ulx[argurl2]["url"] = args[argurl]
 argdate = "date" .. i
 if args[argdate] then
 ulx[argurl2]["date"] = args[argdate]
 else
 ulx[argurl2]["date"] = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end

 argtitle = "title" .. i
 if args[argtitle] then
 ulx[argurl2]["title"] = args[argtitle]
 else
 ulx[argurl2]["title"] = nil
 end
 j = j + 1
 end
 end

 if j == 2 then
 return 0
 else
 return j - 2
 end
end

--[[--------------------------< comma >-----------------------

Given a date string, return "," if it's MDY

]]

local function comma(date)
 return (date and date:match ('%a+ +%d%d?(,) +%d%d%d%d')) or *;*
end

--[[--------------------------< createRendering >-----------------------

Return a rendering of the data in ulx[][]

]]

local function createRendering()

 local displayfield
 local out = {};

 local index\_date, msg = ulx.url1.date:match ('(index)(.\*)'); -- when ulx.url1.date extract 'index' text and message text (if there is a message)
 ulx.url1.date = ulx.url1.date:gsub ('index.\*', 'index'); -- remove message

 if 'none' == ulx.url1.format then -- For Template:Wayback, Template:Webcite
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx.url1.url); -- add url

 if ulx.url1.title then
 table.insert (out, ' ') -- the required space
 table.insert (out, ulx.url1.title) -- the title
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, ulx.url1.tail); -- tail text
 if ulx.url1.date then
 table.insert (out, ' ('); -- open date text; TODO: why the html entity? replace with regular space?
 table.insert (out, 'index' == ulx.url1.date and s\_text.archive or s\_text.archived); -- add text
 table.insert (out, ' '); -- insert a space
 table.insert (out, ulx.url1.date); -- add date
 table.insert (out, ')'); -- close date text
 end
 else -- no title
 if index\_date then -- when url date is 'index'
 table.insert (out, table.concat ({' ', s\_text.Archive\_index, ']'})); -- add the index link label
 table.insert (out, msg or *); -- add date mismatch message when url date is /\*/ and |date= has valid date*
 else
 table.insert (out, table.concat ({' ', s\_text.Archived, '] '})); -- add link label for url has timestamp date (will include mismatch message if there is one)
 end
 if ulx.url1.date then
 if 'index' ~= ulx.url1.date then
 table.insert (out, ulx.url1.date); -- add date when data is not 'index'
 end
 table.insert (out, comma(ulx.url1.date)); -- add ',' if date format is mdy
 table.insert (out, ulx.url1.tail); -- add tail text
 else -- no date
 table.insert (out, ulx.url1.tail); -- add tail text
 end
 end

 if 0 < ulx.url1.extraurls then -- For multiple archive URLs
 local tot = ulx.url1.extraurls + 1
 table.insert (out, '.') -- terminate first url
 table.insert (out, table.concat ({' ', s\_text.addlarchives, ': '})); -- add header text

 for i=2, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 displayfield = ulx[index]['title'] and 'title' or 'date'; -- choose display text
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add the url
 table.insert (out, ' '); -- the required space
 table.insert (out, ulx[index][displayfield]); -- add the label
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, i==tot and '.' or ', '); -- add terminator
 end
 end
 return table.concat (out); -- make a big string and done

 else -- For Template:Cite archives
 if 'addlarchives' == ulx.url1.format then -- Multiple archive services
 table.insert (out, table.concat ({s\_text.addlarchives, ': '})); -- add header text
 else -- Multiple pages from the same archive
 table.insert (out, table.concat ({s\_text.addlpages, ' '})); -- add header text
 table.insert (out, ulx.url1.date); -- add date to header text
 table.insert (out, ': '); -- close header text
 end

 local tot = ulx.url1.extraurls + 1;
 for i=1, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add url
 table.insert (out, ' '); -- add required space

 displayfield = ulx[index]['title'];
 if 'addlarchives' == ulx.url1.format then
 if not displayfield then
 displayfield = ulx[index]['date']
 end
 else -- must be addlpages
 if not displayfield then
 displayfield = table.concat ({s\_text.Page, ' ', i});
 end
 end
 table.insert (out, displayfield); -- add title, date, page label text
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, (i==tot and '.' or ', ')); -- add terminator
 end
 return table.concat (out); -- make a big string and done
 end
end

--[[--------------------------< P A R A M E T E R \_ N A M E \_ X L A T E >--------------------------------------

for internaltionalization, translate local-language parameter names to their English equivalents

TODO: return error message if multiple aliases of the same canonical parameter name are found?

returns two tables:
 new\_args - holds canonical form parameters and their values either from translation or because the parameter was already in canonical form
 origin - maps canonical-form parameter names to their untranslated (local language) form for error messaging in the local language

unrecognized parameters are ignored

]]

local function parameter\_name\_xlate (args, params, enum\_params)
 local name; -- holds modifiable name of the parameter name during evaluation
 local enum; -- for enumerated parameters, holds the enumerator during evaluation
 local found = false; -- flag used to break out of nested for loops
 local new\_args = {}; -- a table that holds canonical and translated parameter k/v pairs
 local origin = {}; -- a table that maps original (local language) parameter names to their canonical name for local language error messaging
 local unnamed\_params; -- set true when unsupported positional parameters are detected

 for k, v in pairs (args) do -- loop through all of the arguments in the args table
 name = k; -- copy of original parameter name

 if 'string' == type (k) then
 if non\_western\_digits then -- true when non-western digits supported at this wiki
 name = mw.ustring.gsub (name, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 enum = name:match ('%d+$'); -- get parameter enumerator if it exists; nil else

 if not enum then -- no enumerator so looking for non-enumnerated parameters
 -- TODO: insert shortcut here? if params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (params) do -- loop through each parameter the params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 else -- enumerated parameters
 name = name:gsub ('%d$', '#'); -- replace enumeration digits with place holder for table search
 -- TODO: insert shortcut here? if num\_params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (enum\_params) do -- loop through each parameter the num\_params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 pname = pname:gsub ('#$', enum); -- replace the '#' place holder with the actual enumerator
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 end
 else
 unnamed\_params = true; -- flag for unsupported positional parameters
 end
 end -- for k, v
 return new\_args, origin, unnamed\_params;
end

--[[--------------------------< W E B A R C H I V E >----------------------------------------------------------

template entry point

]]

local function webarchive(frame)
 local args = getArgs (frame);

 local data = mw.loadData (table.concat ({ -- make a data module name; sandbox or live
 'Module:Webarchive/data',
 frame:getTitle():find('sandbox', 1, true) and '/sandbox' or  *-- this instance is ./sandbox then append /sandbox*
 }));
 categories = data.categories; -- fill in the forward declarations
 config = data.config;
 if data.digits.enable then
 digits = data.digits; -- for i18n; table of digits in the local wiki's language
 non\_western\_digits = true; -- use\_non\_western\_digits
 end
 err\_warn\_msgs = data.err\_warn\_msgs;
 excepted\_pages = data.excepted\_pages;
 month\_num = data.month\_num; -- for i18n; table of month names in the local wiki's language
 prefixes = data.prefixes;
 services = data.services;
 s\_text = data.s\_text;
 uncategorized\_namespaces = data.uncategorized\_namespaces;
 uncategorized\_subpages = data.uncategorized\_subpages;

 local origin = {}; -- holds a map of English to local language parameter names used in the current template; not currently used
 local unnamed\_params; -- boolean set to true when template call has unnamed parameters
 args, origin, unnamed\_params = parameter\_name\_xlate (args, data.params, data.enum\_params); -- translate parameter names in args to English

 local date, format, msg, udate, uri, url;
 local ldf = 'iso'; -- when there is no |date= parameter, render url dates in iso format

 if args.url and args.url1 then -- URL argument (first)
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.url, origin.url1});
 end

 url = args.url or args.url1;

 if not url then
 return inlineError (data.crit\_err\_msgs.empty);
 end
 -- these iabot bugs perportedly fixed; removing these causes lua script error
--[[ -- at Template:Webarchive/testcases/Production; resolve that before deleting these tests
 if mw.ustring.find( url, "https://web.http", 1, true ) then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot1);
 end
 if url == "https://web.archive.org/http:/" then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot2);
 end
]]

 if not (url:lower():find ('^http') or url:find ('^//')) then
 return inlineError (data.crit\_err\_msgs.invalid\_url );
 end

 ulx.url1 = {}
 ulx.url1.url = url

 ulx.url1.extraurls = parseExtraArgs(args)

 local good = false;
 good, uri = pcall (mw.uri.new, ulx.url1.url); -- get a table of uri parts from this url; protected mode to prevent lua error when ulx.url1.url is malformed

 if not good or nil == uri.host then -- abandon when ulx.url1.url is malformed
 return inlineError (data.crit\_err\_msgs.invalid\_url);
 end

 serviceName(uri.host, args.nolink)

 if args.date and args.date1 then -- Date argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.date, origin.date1});
 end

 date = args.date or args.date1;
 date = date and date:gsub (' +', ' '); -- replace multiple spaces with a single space

 if date and config.verifydates then
 if '\*' == date then
 date = 'index';
 ldf = 'iso'; -- set to default format
 elseif 'mdy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'mdy'; -- then |date=mdy overrides iso
 elseif 'dmy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'dmy'; -- then |date=dmy overrides iso
 elseif 'ymd' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'ymd'; -- then |date=ymd overrides iso
 else
 date, ldf = decode\_date (date); -- get an iso format date from date and get date's original format
 end
 end

 if 'wayback' == ulx.url1.service or 'locwebarchives' == ulx.url1.service or 'ukgwa' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeWaybackDate (uri.path); -- get the url date in iso format and format of date in |date=; 'index' when wayback url date is \*
 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 else -- no |date=
 udate, msg = decodeWaybackDate (uri.path);

 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 elseif 'webcite' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate = decodeWebciteDate (uri.path); -- get the url date in iso format
 if 'query' ~= udate then -- skip if query
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'),
 });
 end
 end
 end
 end
 else
 date = decodeWebciteDate( uri.path, "iso" )
 if date == "query" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif not date then -- invalid base62 string
 date = inlineRed (err\_warn\_msgs.date1, 'error');
 end
 end

 elseif 'archiveis' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeArchiveisDate (uri.path) -- get the url date in iso format
 if 'short link' ~= udate then -- skip if short link
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 end
 else -- no |date=
 udate, msg = decodeArchiveisDate( uri.path, "iso" )
 if udate == "short link" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 else -- some other service
 if not date then
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end
 end

 if 'index' == date then
 ulx.url1.date = date .. (msg or *); -- create index + message (if there is one)*
 elseif date then
 ulx.url1.date = makeDate (date, nil, nil, ldf) .. (msg or *); -- create a date in the wiki's local language + message (if there is one)*
 else
 ulx.url1.date = msg;
 end

 format = args.format; -- Format argument

 if not format then
 format = "none"
 else
 for k, v in pairs (data.format\_vals) do -- |format= accepts two specific values loop through a table of those values
 local found; -- declare a nil flag
 for \_, p in ipairs (v) do -- loop through local language variants
 if format == p then -- when |format= value matches
 format = k; -- use name from table key
 found = true; -- declare found so that we can break out of outer for loop
 break; -- break out of inner for loop
 end
 end

 if found then
 break;
 end
 end

 if format == "addlpages" then
 if not ulx.url1.date then
 format = "none"
 end
 elseif format == "addlarchives" then
 format = "addlarchives"
 else
 format = "none"
 end
 end
 ulx.url1.format = format

 if args.title and args.title1 then -- Title argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.title, origin.title1});
 end

 ulx.url1.title = args.title or args.title1;

 local rend = createRendering()
 if not rend then
 return inlineError (data.crit\_err\_msgs.unknown);
 end

 return rend .. ((unnamed\_params and inlineRed (err\_warn\_msgs.unnamed\_params, 'warning')) or *) .. createTracking();*

end

--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]

return {webarchive = webarchive}; AFI Retrieved 20 December 2013
37. ↑ Bray, Christopher. "Sean Connery: The Measure Of A Man", 3 March 2004.
38. ↑ 38.0 38.1 "8 Things You Didn't Know About James Bond".
39. ↑  (2009) *For Your Eyes Only : Ian Fleming and James Bond*. London: Bloomsbury, page 187. ISBN 978-0-7475-9866-4.
40. ↑ Playboy Interview: Sean Connery 1965.
41. ↑ 41.0 41.1 Bradshaw, Peter. "Sean Connery: a dangerously seductive icon of masculinity", 25 August 2020.
42. ↑  (2016) *Collection Editions James Bond*. CreateSpace Independent. ISBN 978-1-5305-7325-7.
43. ↑ Berman, Eliza (25 August 2015). Happy Birthday, Sean Connery: See Him as James Bond on the Cover of Life.
44. ↑ Ferguson, Euan (2 October 2004). Scotch myth.
45. ↑ Template:Harvnb
46. ↑ Template:Cite magazine
47. ↑ Playboy Interview: Sean Connery (November 1965).
48. ↑ Festival de Cannes: The Hill. *festival-cannes.com*.
49. ↑ Sidney Lumet (en).
50. ↑ "Sir Sean Connery 34th AFI Life Achievement Award Honoree".
51. ↑  (2020) *On the Road: Adventures from Nixon to Trump*. Simon and Schuster. ISBN 9781471177439.
52. ↑ 52.0 52.1 52.2 "Sir Sean Connery exclusive: The Clyde yard that shaped my politics ... and its Tory boss who introduced me to golf.", *Herald on Sunday*, 27 February 2011.
53. ↑ "Sean Connery: An enduring myth", *Scottish Review*, 4 November 2020.
54. ↑ Bowler and the Bunnet, The (1967) (en). BFI Screenonline. Retrieved on March 2, 2018.
55. ↑ Whatever Happened at Fairfields?, by Sydney Paulden and Bill Hawkins, published by Gower Press, 1969.
56. ↑  (2010) *Ships & Shipbuilders: Pioneers of Design and Construction*. Pen and Sword. ISBN 9781783830404.
57. ↑  (2012) *Our Glasgow: Memories of Life in Disappearing Britain* (in en). Headline. ISBN 9780755364466. Retrieved on 14 March 2018.
58. ↑ 58.0 58.1 Winners & Nominees Henrietta Award (World Film Favorites).
59. ↑ Sean Connery still has special Bond with movie fans (en-US) (17 June 2015).
60. ↑ Michael Caine: "People forget I know a few gangsters" --[[ ----------------------------------

Lua module implementing the Template loop detected: Template:Webarchive template.

A merger of the functionality of three templates: Template:Wayback, Template:Webcite and Template:Cite archives

]]

--[[--------------------------< D E P E N D E N C I E S >------------------------------------------------------
]]

require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;

--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]

local categories = {}; -- category names
local config = {}; -- global configuration settings
local digits = {}; -- for i18n; table that translates local-wiki digits to western digits
local err\_warn\_msgs = {}; -- error and warning messages
local excepted\_pages = {};
local month\_num = {}; -- for i18n; table that translates local-wiki month names to western digits
local prefixes = {}; -- service provider tail string prefixes
local services = {}; -- archive service provider data from
local s\_text = {}; -- table of static text strings used to build final rendering
local uncategorized\_namespaces = {}; -- list of namespaces that we should not categorize
local uncategorized\_subpages = {}; -- list of subpages that should not be categorized

--[[--------------------------< P A G E S C O P E I D E N T I F I E R S >----------------------------------
]]

local non\_western\_digits; -- boolean flag set true when data.digits.enable is true
local this\_page = mw.title.getCurrentTitle();

local track = {}; -- Associative array to hold tracking categories
local ulx = {}; -- Associative array to hold template data

--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------

Populates numbered arguments in a message string using an argument table.

]]

local function substitute (msg, args)
 return args and mw.message.newRawMessage (msg, args):plain() or msg;
end

--[[--------------------------< tableLength >-----------------------

Given a 1-D table, return number of elements

]]

local function tableLength(T)
 local count = 0
 for \_ in pairs(T) do count = count + 1 end
 return count
end

--[=[-------------------------< M A K E \_ W I K I L I N K >----------------------------------------------------

Makes a wikilink; when both link and display text is provided, returns a wikilink in the form D; if only
link is provided, returns a wikilink in the form L; if neither are provided or link is omitted, returns an
empty string.

]=]

local function make\_wikilink (link, display, no\_link)
 if nil == no\_link then
 if link and ( *~= link) then*
 if display and ( *~= display) then*
 return table.concat ({'', display, ''});
 else
 return table.concat ({'', link, ''});
 end
 end
 return display or *; -- link not set so return the display text*

 else -- no\_link
 if display and ( *~= display) then -- if there is display text*
 return display; -- return that
 else
 return link or *; -- return the target article name or empty string*
 end
 end
end

--[[--------------------------< createTracking >-----------------------

Return data in track[] ie. tracking categories

]]

local function createTracking()
 if not excepted\_pages[this\_page.fullText] then -- namespace:title/fragment is allowed to be categorized (typically this module's / template's testcases page(s))
 if uncategorized\_namespaces[this\_page.nsText] then
 return *; -- this page not to be categorized so return empty string*
 end
 for \_,v in ipairs (uncategorized\_subpages) do -- cycle through page name patterns
 if this\_page.text:match (v) then -- test page name against each pattern
 return *; -- this subpage type not to be categorized so return empty string*
 end
 end
 end

 local out = {};
 if tableLength(track) > 0 then
 for key, \_ in pairs(track) do -- loop through table
 table.insert (out, make\_wikilink (key)); -- and convert category names to links
 end
 end
 return table.concat (out); -- concat into one big string; empty string if table is empty

end

--[[--------------------------< inlineError >-----------------------

Critical error. Render output completely in red. Add to tracking category.

This function called as the last thing before abandoning this module

]]

local function inlineError (msg, args)
 track[categories.error] = 1
 return table.concat ({
 'Error in ', -- open the error message span
 config.tname, -- insert the local language template name
 ' template: ',
 substitute (msg, args), -- insert the formatted error message
 '.', -- close the span
 createTracking() -- add the category
 })
end

--[[--------------------------< inlineRed >-----------------------

Render a text fragment in red, such as a warning as part of the final output.
Add tracking category.

 ]]

local function inlineRed(msg, trackmsg)
 if trackmsg == "warning" then
 track[categories.warning] = 1;
 elseif trackmsg == "error" then
 track[categories.error] = 1;
 end

 return '' .. msg .. ''
end

--[[--------------------------< base62 >-----------------------

Convert base-62 to base-10
Credit: https://de.wikipedia.org/wiki/Modul:Expr

]]

local function base62( value )
 local r = 1 -- default return value is input value is malformed

 if value:match ('%W') then -- value must only be in the set [0-9a-zA-Z]
 return; -- nil return when value contains extraneous characters
 end

 local n = #value -- number of characters in value
 local k = 1
 local c
 r = 0
 for i = n, 1, -1 do -- loop through all characters in value from ls digit to ms digit
 c = value:byte( i, i )
 if c >= 48 and c <= 57 then -- character is digit 0-9
 c = c - 48
 elseif c >= 65 and c <= 90 then -- character is ascii a-z
 c = c - 55
 else -- must be ascii A-Z
 c = c - 61
 end
 r = r + c \* k -- accumulate this base62 character's value
 k = k \* 62 -- bump for next
 end -- for i

 return r
end

--[[--------------------------< D E C O D E \_ D A T E >--------------------------------------------------------

Given a date string, return it in iso format along with an indicator of the date's format. Except that month names
must be recognizable as legitimate month names with proper capitalization, and that the date string must match one
of the recognized date formats, no error checking is done here; return nil else

]]

local function decode\_date (date\_str)
 local patterns = {
 ['dmy'] = {'^(%d%d?) +([^%s%d]+) +(%d%d%d%d)$', 'd', 'm', 'y'}, -- %a does not recognize unicode combining characters used by some languages
 ['mdy'] = {'^([^%s%d]+) (%d%d?), +(%d%d%d%d)$', 'm', 'd', 'y'},
 ['ymd'] = {'^(%d%d%d%d) +([^%s%d]+) (%d%d?)$', 'y', 'm', 'd'}, -- not mos compliant at en.wiki but may be acceptible at other wikis
 };

 local t = {};

 if non\_western\_digits then -- this wiki uses non-western digits?
 date\_str = mw.ustring.gsub (date\_str, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 if date\_str:match ('^%d%d%d%d%-%d%d%-%d%d$') then -- already an iso format date, return western digits form
 return date\_str, 'iso';
 end

 for k, v in pairs (patterns) do
 local c1, c2, c3 = mw.ustring.match (date\_str, patterns[k][1]); -- c1 .. c3 are captured but we don't know what they hold

 if c1 then -- set on match
 t = { -- translate unspecified captures to y, m, and d
 [patterns[k][2]] = c1, -- fill the table of captures with the captures
 [patterns[k][3]] = c2, -- take index names from src\_pattern table and assign sequential captures
 [patterns[k][4]] = c3,
 };
 if month\_num[t.m] then -- when month not already a number
 t.m = month\_num[t.m]; -- replace valid month name with a number
 else
 return nil, 'iso'; -- not a valid date form because month not valid
 end

 return mw.ustring.format ('%.4d-%.2d-%.2d', t.y, t.m, t.d), k; -- return date in iso format
 end
 end
 return nil, 'iso'; -- date could not be decoded; return nil and default iso date
end

--[[--------------------------< makeDate >-----------------------

Given year, month, day numbers, (zero-padded or not) return a full date in df format
where df may be one of:
 mdy, dmy, iso, ymd

on entry, year, month, day are presumed to be correct for the date that they represent; all are required

in this module, makeDate() is sometimes given an iso-format date in year:
 makeDate (2018-09-20, nil, nil, df)
this works because table.concat() sees only one table member

]]

local function makeDate (year, month, day, df)
 local format = {
 ['dmy'] = 'j F Y',
 ['mdy'] = 'F j, Y',
 ['ymd'] = 'Y F j',
 ['iso'] = 'Y-m-d',
 };

 local date = table.concat ({year, month, day}, '-'); -- assemble year-initial numeric-format date (zero padding not required here)

 if non\_western\_digits then -- this wiki uses non-western digits?
 date = mw.ustring.gsub (date, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return mw.getContentLanguage():formatDate (format[df], date);
end

--[[--------------------------< I S \_ V A L I D \_ D A T E >----------------------------------------------------

Returns true if date is after 31 December 1899 (why is 1900 the min year? shouldn't the internet's date-of-birth
be min year?), not after today's date, and represents a valid date (29 February 2017 is not a valid date). Applies
Gregorian leapyear rules.

all arguments are required

]]

local function is\_valid\_date (year, month, day)
 local days\_in\_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 local month\_length;
 local y, m, d;
 local today = os.date ('\*t'); -- fetch a table of current date parts

 if not year or  *== year or not month or*  == month or not day or  *== day then*
 return false; -- something missing
 end

 y = tonumber (year);
 m = tonumber (month);
 d = tonumber (day);

 if 1900 > y or today.year < y or 1 > m or 12 < m then -- year and month are within bounds TODO: 1900?
 return false;
 end

 if (2==m) then -- if February
 month\_length = 28; -- then 28 days unless
 if (0==(y%4) and (0~=(y%100) or 0==(y%400))) then -- is a leap year?
 month\_length = 29; -- if leap year then 29 days in February
 end
 else
 month\_length=days\_in\_month[m];
 end

 if 1 > d or month\_length < d then -- day is within bounds
 return false;
 end
 -- here when date parts represent a valid date
 return os.time({['year']=y, ['month']=m, ['day']=d, ['hour']=0}) <= os.time(); -- date at midnight must be less than or equal to current date/time
end

--[[--------------------------< decodeWebciteDate >-----------------------

Given a URI-path to Webcite (eg. /67xHmVFWP) return the encoded date in df format

returns date string in df format - webcite date is a unix timestamp encoded as bae62
or the string 'query'

]]

local function decodeWebciteDate(path, df)

 local dt = {};
 local decode;

 dt = mw.text.split(path, "/")

 -- valid URL formats that are not base62

 -- http://www.webcitation.org/query?id=1138911916587475
 -- http://www.webcitation.org/query?url=http..&date=2012-06-01+21:40:03
 -- http://www.webcitation.org/1138911916587475
 -- http://www.webcitation.org/cache/73e53dd1f16cf8c5da298418d2a6e452870cf50e
 -- http://www.webcitation.org/getfile.php?fileid=1c46e791d68e89e12d0c2532cc3cf629b8bc8c8e

 if dt[2]:find ('query', 1, true) or
 dt[2]:find ('cache', 1, true) or
 dt[2]:find ('getfile', 1, true) or
 tonumber(dt[2]) then
 return 'query';
 end

 decode = base62(dt[2]); -- base62 string -> exponential number
 if not decode then
 return nil; -- nil return when dt[2] contains characters not in %w
 end
 dt = os.date('\*t', string.format("%d", decode):sub(1,10)) -- exponential number -> text -> first 10 characters (a unix timestamp) -> a table of date parts

 decode = makeDate (dt.year, dt.month, dt.day, 'iso'); -- date comparisons are all done in iso format with western digits
 if non\_western\_digits then -- this wiki uses non-western digits?
 decode = mw.ustring.gsub (decode, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return decode;
end

--[[--------------------------< decodeWaybackDate >-----------------------

Given a URI-path to Wayback (eg. /web/20160901010101/http://example.com )
or Library of Congress Web Archives (eg. /all/20160901010101/http://example.com)
or UK Government Web Archive (eg. /ukgwa/20160901010101/http://example.com or /tna/20160901010101/http://example.com)

return the formatted date eg. "September 1, 2016" in df format
Handle non-digits in snapshot ID such as "re\_" and "-" and "\*"

 valid date string in df format - wayback date is valid (including the text string 'index' when date is '/\*/')
 empty string - wayback date is malformed (less than 8 digits, not a valid date)
 nil - wayback date is '/save/' or otherwise not a number

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeWaybackDate(path, df)

 local msg, snapdate;

 snapdate = path:gsub ('^/web/', *):gsub ('^/all/',* ):gsub ('^/ukgwa/', *):gsub ('^/tna/',* ):gsub ('^/', *); -- remove leading /web/, /all/, /ukgwa/, /tna/, or /*
 snapdate = snapdate:match ('^[^/]+'); -- get timestamp
 if snapdate == "\*" then -- eg. /web/\*/http.., etc.
 return 'index'; -- return indicator that this url has an index date
 end

 snapdate = snapdate:gsub ('%a%a\_%d?$', *):gsub ('%-',* ); -- from date, remove any trailing "re\_", dashes

 msg = *;*
 if snapdate:match ('%\*$') then -- a trailing '\*' causes calendar display at archive .org
 snapdate = snapdate:gsub ('%\*$', *); -- remove so not part of length calc later*
 msg = inlineRed (err\_warn\_msgs.ts\_cal, 'warning'); -- make a message
 end

 if not tonumber(snapdate) then
 return nil, 'ts\_nan'; -- return nil (fatal error flag) and message selector
 end

 local dlen = snapdate:len();
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate, msg; -- return date with message if any
 else
 return snapdate, msg .. inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message(s)
 end
end

--[[--------------------------< decodeArchiveisDate >-----------------------

Given an Archive.is "long link" URI-path (e.g. /2016.08.28-144552/http://example.com)
return the date in df format (e.g. if df = dmy, return 28 August 2016)
Handles "." and "-" in snapshot date, so 2016.08.28-144552 is same as 20160828144552

 valid date string in df format - archive.is date is valid (including the text string 'short link' when url is the short form)
 empty string - wayback date is malformed (not a number, less than 8 digits, not a valid date)
 nil - wayback date is '/save/'

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeArchiveisDate(path, df)
 local snapdate

 if path:match ('^/%w+$') then -- short form url path is '/' followed by some number of base 62 digits and nothing else
 return "short link" -- e.g. http://archive.is/hD1qz
 end

 snapdate = mw.text.split (path, '/')[2]:gsub('[%.%-]', *); -- get snapshot date, e.g. 2016.08.28-144552; remove periods and hyphens*

 local dlen = string.len(snapdate)
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate; -- return date
 else
 return snapdate, inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message
 end
 end

--[[--------------------------< serviceName >-----------------------

Given a domain extracted by mw.uri.new() (eg. web.archive.org) set tail string and service ID

]]

local function serviceName(host, no\_link)
 local tracking;
 local index;

 host = host:lower():gsub ('^web%.(.+)', '%1'):gsub ('^www%.(.+)', '%1'); -- lowercase, remove web. and www. subdomains

 if services[host] then
 index = host;
 else
 for k, \_ in pairs (services) do
 if host:find ('%f[%a]'..k:gsub ('([%.%-])', '%%%1')) then
 index = k;
 break;
 end
 end
 end

 if index then
 local out = {*}; -- empty string in [1] so that concatenated result has leading single space*
 ulx.url1.service = services[index][4] or 'other';
 tracking = services[index][5] or categories.other;
 -- build tail string
 if false == services[index][1] then -- select prefix
 table.insert (out, prefixes.at);
 elseif true == services[index][1] then
 table.insert (out, prefixes.atthe);
 else
 table.insert (out, services[index][1]);
 end

 table.insert (out, make\_wikilink (services[index][2], services[index][3], no\_link)); -- add article wikilink
 if services[index][6] then -- add tail postfix if it exists
 table.insert (out, services[index][6]);
 end

 ulx.url1.tail = table.concat (out, ' '); -- put it all together; result has leading space character

 else -- here when unknown archive
 ulx.url1.service = 'other';
 tracking = categories.unknown;
 ulx.url1.tail = table.concat ({*, prefixes.at, host, inlineRed (err\_warn\_msgs.unknown\_url, error)}, ' ');*
 end

 track[tracking] = 1
end

--[[--------------------------< parseExtraArgs >-----------------------

Parse numbered arguments starting at 2, such as url2..url10, date2..date10, title2..title10
 For example: Template loop detected: Template:Webarchive
 Three url arguments not in numeric sequence (1..4..7).
 Function only processes arguments numbered 2 or greater (in this case 4 and 7)
 It creates numeric sequenced table entries like:
 urlx.url2.url = <argument value for url4>
 urlx.url3.url = <argument value for url7>
 Returns the number of URL arguments found numbered 2 or greater (in this case returns "2")

 ]]

local function parseExtraArgs(args)

 local i, j, argurl, argurl2, argdate, argtitle

 j = 2
 for i = 2, config.maxurls do
 argurl = "url" .. i
 if args[argurl] then
 argurl2 = "url" .. j
 ulx[argurl2] = {}
 ulx[argurl2]["url"] = args[argurl]
 argdate = "date" .. i
 if args[argdate] then
 ulx[argurl2]["date"] = args[argdate]
 else
 ulx[argurl2]["date"] = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end

 argtitle = "title" .. i
 if args[argtitle] then
 ulx[argurl2]["title"] = args[argtitle]
 else
 ulx[argurl2]["title"] = nil
 end
 j = j + 1
 end
 end

 if j == 2 then
 return 0
 else
 return j - 2
 end
end

--[[--------------------------< comma >-----------------------

Given a date string, return "," if it's MDY

]]

local function comma(date)
 return (date and date:match ('%a+ +%d%d?(,) +%d%d%d%d')) or *;*
end

--[[--------------------------< createRendering >-----------------------

Return a rendering of the data in ulx[][]

]]

local function createRendering()

 local displayfield
 local out = {};

 local index\_date, msg = ulx.url1.date:match ('(index)(.\*)'); -- when ulx.url1.date extract 'index' text and message text (if there is a message)
 ulx.url1.date = ulx.url1.date:gsub ('index.\*', 'index'); -- remove message

 if 'none' == ulx.url1.format then -- For Template:Wayback, Template:Webcite
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx.url1.url); -- add url

 if ulx.url1.title then
 table.insert (out, ' ') -- the required space
 table.insert (out, ulx.url1.title) -- the title
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, ulx.url1.tail); -- tail text
 if ulx.url1.date then
 table.insert (out, ' ('); -- open date text; TODO: why the html entity? replace with regular space?
 table.insert (out, 'index' == ulx.url1.date and s\_text.archive or s\_text.archived); -- add text
 table.insert (out, ' '); -- insert a space
 table.insert (out, ulx.url1.date); -- add date
 table.insert (out, ')'); -- close date text
 end
 else -- no title
 if index\_date then -- when url date is 'index'
 table.insert (out, table.concat ({' ', s\_text.Archive\_index, ']'})); -- add the index link label
 table.insert (out, msg or *); -- add date mismatch message when url date is /\*/ and |date= has valid date*
 else
 table.insert (out, table.concat ({' ', s\_text.Archived, '] '})); -- add link label for url has timestamp date (will include mismatch message if there is one)
 end
 if ulx.url1.date then
 if 'index' ~= ulx.url1.date then
 table.insert (out, ulx.url1.date); -- add date when data is not 'index'
 end
 table.insert (out, comma(ulx.url1.date)); -- add ',' if date format is mdy
 table.insert (out, ulx.url1.tail); -- add tail text
 else -- no date
 table.insert (out, ulx.url1.tail); -- add tail text
 end
 end

 if 0 < ulx.url1.extraurls then -- For multiple archive URLs
 local tot = ulx.url1.extraurls + 1
 table.insert (out, '.') -- terminate first url
 table.insert (out, table.concat ({' ', s\_text.addlarchives, ': '})); -- add header text

 for i=2, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 displayfield = ulx[index]['title'] and 'title' or 'date'; -- choose display text
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add the url
 table.insert (out, ' '); -- the required space
 table.insert (out, ulx[index][displayfield]); -- add the label
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, i==tot and '.' or ', '); -- add terminator
 end
 end
 return table.concat (out); -- make a big string and done

 else -- For Template:Cite archives
 if 'addlarchives' == ulx.url1.format then -- Multiple archive services
 table.insert (out, table.concat ({s\_text.addlarchives, ': '})); -- add header text
 else -- Multiple pages from the same archive
 table.insert (out, table.concat ({s\_text.addlpages, ' '})); -- add header text
 table.insert (out, ulx.url1.date); -- add date to header text
 table.insert (out, ': '); -- close header text
 end

 local tot = ulx.url1.extraurls + 1;
 for i=1, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add url
 table.insert (out, ' '); -- add required space

 displayfield = ulx[index]['title'];
 if 'addlarchives' == ulx.url1.format then
 if not displayfield then
 displayfield = ulx[index]['date']
 end
 else -- must be addlpages
 if not displayfield then
 displayfield = table.concat ({s\_text.Page, ' ', i});
 end
 end
 table.insert (out, displayfield); -- add title, date, page label text
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, (i==tot and '.' or ', ')); -- add terminator
 end
 return table.concat (out); -- make a big string and done
 end
end

--[[--------------------------< P A R A M E T E R \_ N A M E \_ X L A T E >--------------------------------------

for internaltionalization, translate local-language parameter names to their English equivalents

TODO: return error message if multiple aliases of the same canonical parameter name are found?

returns two tables:
 new\_args - holds canonical form parameters and their values either from translation or because the parameter was already in canonical form
 origin - maps canonical-form parameter names to their untranslated (local language) form for error messaging in the local language

unrecognized parameters are ignored

]]

local function parameter\_name\_xlate (args, params, enum\_params)
 local name; -- holds modifiable name of the parameter name during evaluation
 local enum; -- for enumerated parameters, holds the enumerator during evaluation
 local found = false; -- flag used to break out of nested for loops
 local new\_args = {}; -- a table that holds canonical and translated parameter k/v pairs
 local origin = {}; -- a table that maps original (local language) parameter names to their canonical name for local language error messaging
 local unnamed\_params; -- set true when unsupported positional parameters are detected

 for k, v in pairs (args) do -- loop through all of the arguments in the args table
 name = k; -- copy of original parameter name

 if 'string' == type (k) then
 if non\_western\_digits then -- true when non-western digits supported at this wiki
 name = mw.ustring.gsub (name, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 enum = name:match ('%d+$'); -- get parameter enumerator if it exists; nil else

 if not enum then -- no enumerator so looking for non-enumnerated parameters
 -- TODO: insert shortcut here? if params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (params) do -- loop through each parameter the params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 else -- enumerated parameters
 name = name:gsub ('%d$', '#'); -- replace enumeration digits with place holder for table search
 -- TODO: insert shortcut here? if num\_params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (enum\_params) do -- loop through each parameter the num\_params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 pname = pname:gsub ('#$', enum); -- replace the '#' place holder with the actual enumerator
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 end
 else
 unnamed\_params = true; -- flag for unsupported positional parameters
 end
 end -- for k, v
 return new\_args, origin, unnamed\_params;
end

--[[--------------------------< W E B A R C H I V E >----------------------------------------------------------

template entry point

]]

local function webarchive(frame)
 local args = getArgs (frame);

 local data = mw.loadData (table.concat ({ -- make a data module name; sandbox or live
 'Module:Webarchive/data',
 frame:getTitle():find('sandbox', 1, true) and '/sandbox' or  *-- this instance is ./sandbox then append /sandbox*
 }));
 categories = data.categories; -- fill in the forward declarations
 config = data.config;
 if data.digits.enable then
 digits = data.digits; -- for i18n; table of digits in the local wiki's language
 non\_western\_digits = true; -- use\_non\_western\_digits
 end
 err\_warn\_msgs = data.err\_warn\_msgs;
 excepted\_pages = data.excepted\_pages;
 month\_num = data.month\_num; -- for i18n; table of month names in the local wiki's language
 prefixes = data.prefixes;
 services = data.services;
 s\_text = data.s\_text;
 uncategorized\_namespaces = data.uncategorized\_namespaces;
 uncategorized\_subpages = data.uncategorized\_subpages;

 local origin = {}; -- holds a map of English to local language parameter names used in the current template; not currently used
 local unnamed\_params; -- boolean set to true when template call has unnamed parameters
 args, origin, unnamed\_params = parameter\_name\_xlate (args, data.params, data.enum\_params); -- translate parameter names in args to English

 local date, format, msg, udate, uri, url;
 local ldf = 'iso'; -- when there is no |date= parameter, render url dates in iso format

 if args.url and args.url1 then -- URL argument (first)
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.url, origin.url1});
 end

 url = args.url or args.url1;

 if not url then
 return inlineError (data.crit\_err\_msgs.empty);
 end
 -- these iabot bugs perportedly fixed; removing these causes lua script error
--[[ -- at Template:Webarchive/testcases/Production; resolve that before deleting these tests
 if mw.ustring.find( url, "https://web.http", 1, true ) then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot1);
 end
 if url == "https://web.archive.org/http:/" then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot2);
 end
]]

 if not (url:lower():find ('^http') or url:find ('^//')) then
 return inlineError (data.crit\_err\_msgs.invalid\_url );
 end

 ulx.url1 = {}
 ulx.url1.url = url

 ulx.url1.extraurls = parseExtraArgs(args)

 local good = false;
 good, uri = pcall (mw.uri.new, ulx.url1.url); -- get a table of uri parts from this url; protected mode to prevent lua error when ulx.url1.url is malformed

 if not good or nil == uri.host then -- abandon when ulx.url1.url is malformed
 return inlineError (data.crit\_err\_msgs.invalid\_url);
 end

 serviceName(uri.host, args.nolink)

 if args.date and args.date1 then -- Date argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.date, origin.date1});
 end

 date = args.date or args.date1;
 date = date and date:gsub (' +', ' '); -- replace multiple spaces with a single space

 if date and config.verifydates then
 if '\*' == date then
 date = 'index';
 ldf = 'iso'; -- set to default format
 elseif 'mdy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'mdy'; -- then |date=mdy overrides iso
 elseif 'dmy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'dmy'; -- then |date=dmy overrides iso
 elseif 'ymd' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'ymd'; -- then |date=ymd overrides iso
 else
 date, ldf = decode\_date (date); -- get an iso format date from date and get date's original format
 end
 end

 if 'wayback' == ulx.url1.service or 'locwebarchives' == ulx.url1.service or 'ukgwa' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeWaybackDate (uri.path); -- get the url date in iso format and format of date in |date=; 'index' when wayback url date is \*
 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 else -- no |date=
 udate, msg = decodeWaybackDate (uri.path);

 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 elseif 'webcite' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate = decodeWebciteDate (uri.path); -- get the url date in iso format
 if 'query' ~= udate then -- skip if query
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'),
 });
 end
 end
 end
 end
 else
 date = decodeWebciteDate( uri.path, "iso" )
 if date == "query" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif not date then -- invalid base62 string
 date = inlineRed (err\_warn\_msgs.date1, 'error');
 end
 end

 elseif 'archiveis' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeArchiveisDate (uri.path) -- get the url date in iso format
 if 'short link' ~= udate then -- skip if short link
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 end
 else -- no |date=
 udate, msg = decodeArchiveisDate( uri.path, "iso" )
 if udate == "short link" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 else -- some other service
 if not date then
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end
 end

 if 'index' == date then
 ulx.url1.date = date .. (msg or *); -- create index + message (if there is one)*
 elseif date then
 ulx.url1.date = makeDate (date, nil, nil, ldf) .. (msg or *); -- create a date in the wiki's local language + message (if there is one)*
 else
 ulx.url1.date = msg;
 end

 format = args.format; -- Format argument

 if not format then
 format = "none"
 else
 for k, v in pairs (data.format\_vals) do -- |format= accepts two specific values loop through a table of those values
 local found; -- declare a nil flag
 for \_, p in ipairs (v) do -- loop through local language variants
 if format == p then -- when |format= value matches
 format = k; -- use name from table key
 found = true; -- declare found so that we can break out of outer for loop
 break; -- break out of inner for loop
 end
 end

 if found then
 break;
 end
 end

 if format == "addlpages" then
 if not ulx.url1.date then
 format = "none"
 end
 elseif format == "addlarchives" then
 format = "addlarchives"
 else
 format = "none"
 end
 end
 ulx.url1.format = format

 if args.title and args.title1 then -- Title argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.title, origin.title1});
 end

 ulx.url1.title = args.title or args.title1;

 local rend = createRendering()
 if not rend then
 return inlineError (data.crit\_err\_msgs.unknown);
 end

 return rend .. ((unnamed\_params and inlineRed (err\_warn\_msgs.unnamed\_params, 'warning')) or *) .. createTracking();*

end

--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]

return {webarchive = webarchive}; Sabotage Times Retrieved 19 March 2019
61. ↑ Ebert, Roger. ""Robin and Marian" review", 21 April 1976.
62. ↑ "A Bridge Too Far, for allied forces and for viewers".
63. ↑ "14 unnecessarily revealing movie costumes", 14 November 2017.
64. ↑ Celebrating The 13 Strangest Moments in Zardoz (3 September 2016).
65. ↑ 30 Cult Movies That Absolutely Everybody Must See. *io9*. Gizmodo (7 March 2014).
66. ↑  (2015) *Science Fiction Double Feature: The Science Fiction Film as Cult Text*. Oxford University Press, page 75. ISBN 978-1-78138-183-0.
67. ↑ "Zardoz".
68. ↑ Time Bandits Extras. Channel 4.
69. ↑ "FIFA World Cup and Official FIFA Events: Programming" --[[ ----------------------------------

Lua module implementing the Template loop detected: Template:Webarchive template.

A merger of the functionality of three templates: Template:Wayback, Template:Webcite and Template:Cite archives

]]

--[[--------------------------< D E P E N D E N C I E S >------------------------------------------------------
]]

require('Module:No globals');
local getArgs = require ('Module:Arguments').getArgs;

--[[--------------------------< F O R W A R D D E C L A R A T I O N S >--------------------------------------
]]

local categories = {}; -- category names
local config = {}; -- global configuration settings
local digits = {}; -- for i18n; table that translates local-wiki digits to western digits
local err\_warn\_msgs = {}; -- error and warning messages
local excepted\_pages = {};
local month\_num = {}; -- for i18n; table that translates local-wiki month names to western digits
local prefixes = {}; -- service provider tail string prefixes
local services = {}; -- archive service provider data from
local s\_text = {}; -- table of static text strings used to build final rendering
local uncategorized\_namespaces = {}; -- list of namespaces that we should not categorize
local uncategorized\_subpages = {}; -- list of subpages that should not be categorized

--[[--------------------------< P A G E S C O P E I D E N T I F I E R S >----------------------------------
]]

local non\_western\_digits; -- boolean flag set true when data.digits.enable is true
local this\_page = mw.title.getCurrentTitle();

local track = {}; -- Associative array to hold tracking categories
local ulx = {}; -- Associative array to hold template data

--[[--------------------------< S U B S T I T U T E >----------------------------------------------------------

Populates numbered arguments in a message string using an argument table.

]]

local function substitute (msg, args)
 return args and mw.message.newRawMessage (msg, args):plain() or msg;
end

--[[--------------------------< tableLength >-----------------------

Given a 1-D table, return number of elements

]]

local function tableLength(T)
 local count = 0
 for \_ in pairs(T) do count = count + 1 end
 return count
end

--[=[-------------------------< M A K E \_ W I K I L I N K >----------------------------------------------------

Makes a wikilink; when both link and display text is provided, returns a wikilink in the form D; if only
link is provided, returns a wikilink in the form L; if neither are provided or link is omitted, returns an
empty string.

]=]

local function make\_wikilink (link, display, no\_link)
 if nil == no\_link then
 if link and ( *~= link) then*
 if display and ( *~= display) then*
 return table.concat ({'', display, ''});
 else
 return table.concat ({'', link, ''});
 end
 end
 return display or *; -- link not set so return the display text*

 else -- no\_link
 if display and ( *~= display) then -- if there is display text*
 return display; -- return that
 else
 return link or *; -- return the target article name or empty string*
 end
 end
end

--[[--------------------------< createTracking >-----------------------

Return data in track[] ie. tracking categories

]]

local function createTracking()
 if not excepted\_pages[this\_page.fullText] then -- namespace:title/fragment is allowed to be categorized (typically this module's / template's testcases page(s))
 if uncategorized\_namespaces[this\_page.nsText] then
 return *; -- this page not to be categorized so return empty string*
 end
 for \_,v in ipairs (uncategorized\_subpages) do -- cycle through page name patterns
 if this\_page.text:match (v) then -- test page name against each pattern
 return *; -- this subpage type not to be categorized so return empty string*
 end
 end
 end

 local out = {};
 if tableLength(track) > 0 then
 for key, \_ in pairs(track) do -- loop through table
 table.insert (out, make\_wikilink (key)); -- and convert category names to links
 end
 end
 return table.concat (out); -- concat into one big string; empty string if table is empty

end

--[[--------------------------< inlineError >-----------------------

Critical error. Render output completely in red. Add to tracking category.

This function called as the last thing before abandoning this module

]]

local function inlineError (msg, args)
 track[categories.error] = 1
 return table.concat ({
 'Error in ', -- open the error message span
 config.tname, -- insert the local language template name
 ' template: ',
 substitute (msg, args), -- insert the formatted error message
 '.', -- close the span
 createTracking() -- add the category
 })
end

--[[--------------------------< inlineRed >-----------------------

Render a text fragment in red, such as a warning as part of the final output.
Add tracking category.

 ]]

local function inlineRed(msg, trackmsg)
 if trackmsg == "warning" then
 track[categories.warning] = 1;
 elseif trackmsg == "error" then
 track[categories.error] = 1;
 end

 return '' .. msg .. ''
end

--[[--------------------------< base62 >-----------------------

Convert base-62 to base-10
Credit: https://de.wikipedia.org/wiki/Modul:Expr

]]

local function base62( value )
 local r = 1 -- default return value is input value is malformed

 if value:match ('%W') then -- value must only be in the set [0-9a-zA-Z]
 return; -- nil return when value contains extraneous characters
 end

 local n = #value -- number of characters in value
 local k = 1
 local c
 r = 0
 for i = n, 1, -1 do -- loop through all characters in value from ls digit to ms digit
 c = value:byte( i, i )
 if c >= 48 and c <= 57 then -- character is digit 0-9
 c = c - 48
 elseif c >= 65 and c <= 90 then -- character is ascii a-z
 c = c - 55
 else -- must be ascii A-Z
 c = c - 61
 end
 r = r + c \* k -- accumulate this base62 character's value
 k = k \* 62 -- bump for next
 end -- for i

 return r
end

--[[--------------------------< D E C O D E \_ D A T E >--------------------------------------------------------

Given a date string, return it in iso format along with an indicator of the date's format. Except that month names
must be recognizable as legitimate month names with proper capitalization, and that the date string must match one
of the recognized date formats, no error checking is done here; return nil else

]]

local function decode\_date (date\_str)
 local patterns = {
 ['dmy'] = {'^(%d%d?) +([^%s%d]+) +(%d%d%d%d)$', 'd', 'm', 'y'}, -- %a does not recognize unicode combining characters used by some languages
 ['mdy'] = {'^([^%s%d]+) (%d%d?), +(%d%d%d%d)$', 'm', 'd', 'y'},
 ['ymd'] = {'^(%d%d%d%d) +([^%s%d]+) (%d%d?)$', 'y', 'm', 'd'}, -- not mos compliant at en.wiki but may be acceptible at other wikis
 };

 local t = {};

 if non\_western\_digits then -- this wiki uses non-western digits?
 date\_str = mw.ustring.gsub (date\_str, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 if date\_str:match ('^%d%d%d%d%-%d%d%-%d%d$') then -- already an iso format date, return western digits form
 return date\_str, 'iso';
 end

 for k, v in pairs (patterns) do
 local c1, c2, c3 = mw.ustring.match (date\_str, patterns[k][1]); -- c1 .. c3 are captured but we don't know what they hold

 if c1 then -- set on match
 t = { -- translate unspecified captures to y, m, and d
 [patterns[k][2]] = c1, -- fill the table of captures with the captures
 [patterns[k][3]] = c2, -- take index names from src\_pattern table and assign sequential captures
 [patterns[k][4]] = c3,
 };
 if month\_num[t.m] then -- when month not already a number
 t.m = month\_num[t.m]; -- replace valid month name with a number
 else
 return nil, 'iso'; -- not a valid date form because month not valid
 end

 return mw.ustring.format ('%.4d-%.2d-%.2d', t.y, t.m, t.d), k; -- return date in iso format
 end
 end
 return nil, 'iso'; -- date could not be decoded; return nil and default iso date
end

--[[--------------------------< makeDate >-----------------------

Given year, month, day numbers, (zero-padded or not) return a full date in df format
where df may be one of:
 mdy, dmy, iso, ymd

on entry, year, month, day are presumed to be correct for the date that they represent; all are required

in this module, makeDate() is sometimes given an iso-format date in year:
 makeDate (2018-09-20, nil, nil, df)
this works because table.concat() sees only one table member

]]

local function makeDate (year, month, day, df)
 local format = {
 ['dmy'] = 'j F Y',
 ['mdy'] = 'F j, Y',
 ['ymd'] = 'Y F j',
 ['iso'] = 'Y-m-d',
 };

 local date = table.concat ({year, month, day}, '-'); -- assemble year-initial numeric-format date (zero padding not required here)

 if non\_western\_digits then -- this wiki uses non-western digits?
 date = mw.ustring.gsub (date, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return mw.getContentLanguage():formatDate (format[df], date);
end

--[[--------------------------< I S \_ V A L I D \_ D A T E >----------------------------------------------------

Returns true if date is after 31 December 1899 (why is 1900 the min year? shouldn't the internet's date-of-birth
be min year?), not after today's date, and represents a valid date (29 February 2017 is not a valid date). Applies
Gregorian leapyear rules.

all arguments are required

]]

local function is\_valid\_date (year, month, day)
 local days\_in\_month = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
 local month\_length;
 local y, m, d;
 local today = os.date ('\*t'); -- fetch a table of current date parts

 if not year or  *== year or not month or*  == month or not day or  *== day then*
 return false; -- something missing
 end

 y = tonumber (year);
 m = tonumber (month);
 d = tonumber (day);

 if 1900 > y or today.year < y or 1 > m or 12 < m then -- year and month are within bounds TODO: 1900?
 return false;
 end

 if (2==m) then -- if February
 month\_length = 28; -- then 28 days unless
 if (0==(y%4) and (0~=(y%100) or 0==(y%400))) then -- is a leap year?
 month\_length = 29; -- if leap year then 29 days in February
 end
 else
 month\_length=days\_in\_month[m];
 end

 if 1 > d or month\_length < d then -- day is within bounds
 return false;
 end
 -- here when date parts represent a valid date
 return os.time({['year']=y, ['month']=m, ['day']=d, ['hour']=0}) <= os.time(); -- date at midnight must be less than or equal to current date/time
end

--[[--------------------------< decodeWebciteDate >-----------------------

Given a URI-path to Webcite (eg. /67xHmVFWP) return the encoded date in df format

returns date string in df format - webcite date is a unix timestamp encoded as bae62
or the string 'query'

]]

local function decodeWebciteDate(path, df)

 local dt = {};
 local decode;

 dt = mw.text.split(path, "/")

 -- valid URL formats that are not base62

 -- http://www.webcitation.org/query?id=1138911916587475
 -- http://www.webcitation.org/query?url=http..&date=2012-06-01+21:40:03
 -- http://www.webcitation.org/1138911916587475
 -- http://www.webcitation.org/cache/73e53dd1f16cf8c5da298418d2a6e452870cf50e
 -- http://www.webcitation.org/getfile.php?fileid=1c46e791d68e89e12d0c2532cc3cf629b8bc8c8e

 if dt[2]:find ('query', 1, true) or
 dt[2]:find ('cache', 1, true) or
 dt[2]:find ('getfile', 1, true) or
 tonumber(dt[2]) then
 return 'query';
 end

 decode = base62(dt[2]); -- base62 string -> exponential number
 if not decode then
 return nil; -- nil return when dt[2] contains characters not in %w
 end
 dt = os.date('\*t', string.format("%d", decode):sub(1,10)) -- exponential number -> text -> first 10 characters (a unix timestamp) -> a table of date parts

 decode = makeDate (dt.year, dt.month, dt.day, 'iso'); -- date comparisons are all done in iso format with western digits
 if non\_western\_digits then -- this wiki uses non-western digits?
 decode = mw.ustring.gsub (decode, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 return decode;
end

--[[--------------------------< decodeWaybackDate >-----------------------

Given a URI-path to Wayback (eg. /web/20160901010101/http://example.com )
or Library of Congress Web Archives (eg. /all/20160901010101/http://example.com)
or UK Government Web Archive (eg. /ukgwa/20160901010101/http://example.com or /tna/20160901010101/http://example.com)

return the formatted date eg. "September 1, 2016" in df format
Handle non-digits in snapshot ID such as "re\_" and "-" and "\*"

 valid date string in df format - wayback date is valid (including the text string 'index' when date is '/\*/')
 empty string - wayback date is malformed (less than 8 digits, not a valid date)
 nil - wayback date is '/save/' or otherwise not a number

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeWaybackDate(path, df)

 local msg, snapdate;

 snapdate = path:gsub ('^/web/', *):gsub ('^/all/',* ):gsub ('^/ukgwa/', *):gsub ('^/tna/',* ):gsub ('^/', *); -- remove leading /web/, /all/, /ukgwa/, /tna/, or /*
 snapdate = snapdate:match ('^[^/]+'); -- get timestamp
 if snapdate == "\*" then -- eg. /web/\*/http.., etc.
 return 'index'; -- return indicator that this url has an index date
 end

 snapdate = snapdate:gsub ('%a%a\_%d?$', *):gsub ('%-',* ); -- from date, remove any trailing "re\_", dashes

 msg = *;*
 if snapdate:match ('%\*$') then -- a trailing '\*' causes calendar display at archive .org
 snapdate = snapdate:gsub ('%\*$', *); -- remove so not part of length calc later*
 msg = inlineRed (err\_warn\_msgs.ts\_cal, 'warning'); -- make a message
 end

 if not tonumber(snapdate) then
 return nil, 'ts\_nan'; -- return nil (fatal error flag) and message selector
 end

 local dlen = snapdate:len();
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate, msg; -- return date with message if any
 else
 return snapdate, msg .. inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message(s)
 end
end

--[[--------------------------< decodeArchiveisDate >-----------------------

Given an Archive.is "long link" URI-path (e.g. /2016.08.28-144552/http://example.com)
return the date in df format (e.g. if df = dmy, return 28 August 2016)
Handles "." and "-" in snapshot date, so 2016.08.28-144552 is same as 20160828144552

 valid date string in df format - archive.is date is valid (including the text string 'short link' when url is the short form)
 empty string - wayback date is malformed (not a number, less than 8 digits, not a valid date)
 nil - wayback date is '/save/'

 second return value is an appropriate 'message' may or may not be formatted

]]

local function decodeArchiveisDate(path, df)
 local snapdate

 if path:match ('^/%w+$') then -- short form url path is '/' followed by some number of base 62 digits and nothing else
 return "short link" -- e.g. http://archive.is/hD1qz
 end

 snapdate = mw.text.split (path, '/')[2]:gsub('[%.%-]', *); -- get snapshot date, e.g. 2016.08.28-144552; remove periods and hyphens*

 local dlen = string.len(snapdate)
 if dlen < 8 then -- we need 8 digits TODO: but shouldn't this be testing for 14 digits?
 return *, inlineRed (err\_warn\_msgs.ts\_short, 'error'); -- return empty string and error message*
 end

 local year, month, day = snapdate:match ('(%d%d%d%d)(%d%d)(%d%d)'); -- no need for snapdatelong here

 if not is\_valid\_date (year, month, day) then
 return *, inlineRed (err\_warn\_msgs.ts\_date, 'error'); -- return empty string and error message*
 end

 snapdate = table.concat ({year, month, day}, '-'); -- date comparisons are all done in iso format
 if 14 == dlen then
 return snapdate; -- return date
 else
 return snapdate, inlineRed (err\_warn\_msgs.ts\_len, 'warning'); -- return date with warning message
 end
 end

--[[--------------------------< serviceName >-----------------------

Given a domain extracted by mw.uri.new() (eg. web.archive.org) set tail string and service ID

]]

local function serviceName(host, no\_link)
 local tracking;
 local index;

 host = host:lower():gsub ('^web%.(.+)', '%1'):gsub ('^www%.(.+)', '%1'); -- lowercase, remove web. and www. subdomains

 if services[host] then
 index = host;
 else
 for k, \_ in pairs (services) do
 if host:find ('%f[%a]'..k:gsub ('([%.%-])', '%%%1')) then
 index = k;
 break;
 end
 end
 end

 if index then
 local out = {*}; -- empty string in [1] so that concatenated result has leading single space*
 ulx.url1.service = services[index][4] or 'other';
 tracking = services[index][5] or categories.other;
 -- build tail string
 if false == services[index][1] then -- select prefix
 table.insert (out, prefixes.at);
 elseif true == services[index][1] then
 table.insert (out, prefixes.atthe);
 else
 table.insert (out, services[index][1]);
 end

 table.insert (out, make\_wikilink (services[index][2], services[index][3], no\_link)); -- add article wikilink
 if services[index][6] then -- add tail postfix if it exists
 table.insert (out, services[index][6]);
 end

 ulx.url1.tail = table.concat (out, ' '); -- put it all together; result has leading space character

 else -- here when unknown archive
 ulx.url1.service = 'other';
 tracking = categories.unknown;
 ulx.url1.tail = table.concat ({*, prefixes.at, host, inlineRed (err\_warn\_msgs.unknown\_url, error)}, ' ');*
 end

 track[tracking] = 1
end

--[[--------------------------< parseExtraArgs >-----------------------

Parse numbered arguments starting at 2, such as url2..url10, date2..date10, title2..title10
 For example: Template loop detected: Template:Webarchive
 Three url arguments not in numeric sequence (1..4..7).
 Function only processes arguments numbered 2 or greater (in this case 4 and 7)
 It creates numeric sequenced table entries like:
 urlx.url2.url = <argument value for url4>
 urlx.url3.url = <argument value for url7>
 Returns the number of URL arguments found numbered 2 or greater (in this case returns "2")

 ]]

local function parseExtraArgs(args)

 local i, j, argurl, argurl2, argdate, argtitle

 j = 2
 for i = 2, config.maxurls do
 argurl = "url" .. i
 if args[argurl] then
 argurl2 = "url" .. j
 ulx[argurl2] = {}
 ulx[argurl2]["url"] = args[argurl]
 argdate = "date" .. i
 if args[argdate] then
 ulx[argurl2]["date"] = args[argdate]
 else
 ulx[argurl2]["date"] = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end

 argtitle = "title" .. i
 if args[argtitle] then
 ulx[argurl2]["title"] = args[argtitle]
 else
 ulx[argurl2]["title"] = nil
 end
 j = j + 1
 end
 end

 if j == 2 then
 return 0
 else
 return j - 2
 end
end

--[[--------------------------< comma >-----------------------

Given a date string, return "," if it's MDY

]]

local function comma(date)
 return (date and date:match ('%a+ +%d%d?(,) +%d%d%d%d')) or *;*
end

--[[--------------------------< createRendering >-----------------------

Return a rendering of the data in ulx[][]

]]

local function createRendering()

 local displayfield
 local out = {};

 local index\_date, msg = ulx.url1.date:match ('(index)(.\*)'); -- when ulx.url1.date extract 'index' text and message text (if there is a message)
 ulx.url1.date = ulx.url1.date:gsub ('index.\*', 'index'); -- remove message

 if 'none' == ulx.url1.format then -- For Template:Wayback, Template:Webcite
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx.url1.url); -- add url

 if ulx.url1.title then
 table.insert (out, ' ') -- the required space
 table.insert (out, ulx.url1.title) -- the title
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, ulx.url1.tail); -- tail text
 if ulx.url1.date then
 table.insert (out, ' ('); -- open date text; TODO: why the html entity? replace with regular space?
 table.insert (out, 'index' == ulx.url1.date and s\_text.archive or s\_text.archived); -- add text
 table.insert (out, ' '); -- insert a space
 table.insert (out, ulx.url1.date); -- add date
 table.insert (out, ')'); -- close date text
 end
 else -- no title
 if index\_date then -- when url date is 'index'
 table.insert (out, table.concat ({' ', s\_text.Archive\_index, ']'})); -- add the index link label
 table.insert (out, msg or *); -- add date mismatch message when url date is /\*/ and |date= has valid date*
 else
 table.insert (out, table.concat ({' ', s\_text.Archived, '] '})); -- add link label for url has timestamp date (will include mismatch message if there is one)
 end
 if ulx.url1.date then
 if 'index' ~= ulx.url1.date then
 table.insert (out, ulx.url1.date); -- add date when data is not 'index'
 end
 table.insert (out, comma(ulx.url1.date)); -- add ',' if date format is mdy
 table.insert (out, ulx.url1.tail); -- add tail text
 else -- no date
 table.insert (out, ulx.url1.tail); -- add tail text
 end
 end

 if 0 < ulx.url1.extraurls then -- For multiple archive URLs
 local tot = ulx.url1.extraurls + 1
 table.insert (out, '.') -- terminate first url
 table.insert (out, table.concat ({' ', s\_text.addlarchives, ': '})); -- add header text

 for i=2, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 displayfield = ulx[index]['title'] and 'title' or 'date'; -- choose display text
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add the url
 table.insert (out, ' '); -- the required space
 table.insert (out, ulx[index][displayfield]); -- add the label
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, i==tot and '.' or ', '); -- add terminator
 end
 end
 return table.concat (out); -- make a big string and done

 else -- For Template:Cite archives
 if 'addlarchives' == ulx.url1.format then -- Multiple archive services
 table.insert (out, table.concat ({s\_text.addlarchives, ': '})); -- add header text
 else -- Multiple pages from the same archive
 table.insert (out, table.concat ({s\_text.addlpages, ' '})); -- add header text
 table.insert (out, ulx.url1.date); -- add date to header text
 table.insert (out, ': '); -- close header text
 end

 local tot = ulx.url1.extraurls + 1;
 for i=1, tot do -- loop through the additionals
 local index = table.concat ({'url', i}); -- make an index
 table.insert (out, '['); -- open extlink markup
 table.insert (out, ulx[index]['url']); -- add url
 table.insert (out, ' '); -- add required space

 displayfield = ulx[index]['title'];
 if 'addlarchives' == ulx.url1.format then
 if not displayfield then
 displayfield = ulx[index]['date']
 end
 else -- must be addlpages
 if not displayfield then
 displayfield = table.concat ({s\_text.Page, ' ', i});
 end
 end
 table.insert (out, displayfield); -- add title, date, page label text
 table.insert (out, ']'); -- close extlink markup
 table.insert (out, (i==tot and '.' or ', ')); -- add terminator
 end
 return table.concat (out); -- make a big string and done
 end
end

--[[--------------------------< P A R A M E T E R \_ N A M E \_ X L A T E >--------------------------------------

for internaltionalization, translate local-language parameter names to their English equivalents

TODO: return error message if multiple aliases of the same canonical parameter name are found?

returns two tables:
 new\_args - holds canonical form parameters and their values either from translation or because the parameter was already in canonical form
 origin - maps canonical-form parameter names to their untranslated (local language) form for error messaging in the local language

unrecognized parameters are ignored

]]

local function parameter\_name\_xlate (args, params, enum\_params)
 local name; -- holds modifiable name of the parameter name during evaluation
 local enum; -- for enumerated parameters, holds the enumerator during evaluation
 local found = false; -- flag used to break out of nested for loops
 local new\_args = {}; -- a table that holds canonical and translated parameter k/v pairs
 local origin = {}; -- a table that maps original (local language) parameter names to their canonical name for local language error messaging
 local unnamed\_params; -- set true when unsupported positional parameters are detected

 for k, v in pairs (args) do -- loop through all of the arguments in the args table
 name = k; -- copy of original parameter name

 if 'string' == type (k) then
 if non\_western\_digits then -- true when non-western digits supported at this wiki
 name = mw.ustring.gsub (name, '%d', digits); -- convert this wiki's non-western digits to western digits
 end

 enum = name:match ('%d+$'); -- get parameter enumerator if it exists; nil else

 if not enum then -- no enumerator so looking for non-enumnerated parameters
 -- TODO: insert shortcut here? if params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (params) do -- loop through each parameter the params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 else -- enumerated parameters
 name = name:gsub ('%d$', '#'); -- replace enumeration digits with place holder for table search
 -- TODO: insert shortcut here? if num\_params[name] then name holds the canonical parameter name; no need to search further
 for pname, aliases in pairs (enum\_params) do -- loop through each parameter the num\_params table
 for \_, alias in ipairs (aliases) do -- loop through each alias in the parameter's aliases table
 if name == alias then
 pname = pname:gsub ('#$', enum); -- replace the '#' place holder with the actual enumerator
 new\_args[pname] = v; -- create a new entry in the new\_args table
 origin [pname] = k; -- create an entry to make canonical parameter name to original local language parameter name
 found = true; -- flag so that we can break out of these nested for loops
 break; -- no need to search the rest of the aliases table for name so go on to the next k, v pair
 end
 end

 if found then -- true when we found an alias that matched name
 found = false; -- reset the flag
 break; -- go do next args k/v pair
 end
 end
 end
 else
 unnamed\_params = true; -- flag for unsupported positional parameters
 end
 end -- for k, v
 return new\_args, origin, unnamed\_params;
end

--[[--------------------------< W E B A R C H I V E >----------------------------------------------------------

template entry point

]]

local function webarchive(frame)
 local args = getArgs (frame);

 local data = mw.loadData (table.concat ({ -- make a data module name; sandbox or live
 'Module:Webarchive/data',
 frame:getTitle():find('sandbox', 1, true) and '/sandbox' or  *-- this instance is ./sandbox then append /sandbox*
 }));
 categories = data.categories; -- fill in the forward declarations
 config = data.config;
 if data.digits.enable then
 digits = data.digits; -- for i18n; table of digits in the local wiki's language
 non\_western\_digits = true; -- use\_non\_western\_digits
 end
 err\_warn\_msgs = data.err\_warn\_msgs;
 excepted\_pages = data.excepted\_pages;
 month\_num = data.month\_num; -- for i18n; table of month names in the local wiki's language
 prefixes = data.prefixes;
 services = data.services;
 s\_text = data.s\_text;
 uncategorized\_namespaces = data.uncategorized\_namespaces;
 uncategorized\_subpages = data.uncategorized\_subpages;

 local origin = {}; -- holds a map of English to local language parameter names used in the current template; not currently used
 local unnamed\_params; -- boolean set to true when template call has unnamed parameters
 args, origin, unnamed\_params = parameter\_name\_xlate (args, data.params, data.enum\_params); -- translate parameter names in args to English

 local date, format, msg, udate, uri, url;
 local ldf = 'iso'; -- when there is no |date= parameter, render url dates in iso format

 if args.url and args.url1 then -- URL argument (first)
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.url, origin.url1});
 end

 url = args.url or args.url1;

 if not url then
 return inlineError (data.crit\_err\_msgs.empty);
 end
 -- these iabot bugs perportedly fixed; removing these causes lua script error
--[[ -- at Template:Webarchive/testcases/Production; resolve that before deleting these tests
 if mw.ustring.find( url, "https://web.http", 1, true ) then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot1);
 end
 if url == "https://web.archive.org/http:/" then -- track bug - TODO: IAbot bug; not known if the bug has been fixed; deferred
 track[categories.error] = 1;
 return inlineError (data.crit\_err\_msgs.iabot2);
 end
]]

 if not (url:lower():find ('^http') or url:find ('^//')) then
 return inlineError (data.crit\_err\_msgs.invalid\_url );
 end

 ulx.url1 = {}
 ulx.url1.url = url

 ulx.url1.extraurls = parseExtraArgs(args)

 local good = false;
 good, uri = pcall (mw.uri.new, ulx.url1.url); -- get a table of uri parts from this url; protected mode to prevent lua error when ulx.url1.url is malformed

 if not good or nil == uri.host then -- abandon when ulx.url1.url is malformed
 return inlineError (data.crit\_err\_msgs.invalid\_url);
 end

 serviceName(uri.host, args.nolink)

 if args.date and args.date1 then -- Date argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.date, origin.date1});
 end

 date = args.date or args.date1;
 date = date and date:gsub (' +', ' '); -- replace multiple spaces with a single space

 if date and config.verifydates then
 if '\*' == date then
 date = 'index';
 ldf = 'iso'; -- set to default format
 elseif 'mdy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'mdy'; -- then |date=mdy overrides iso
 elseif 'dmy' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'dmy'; -- then |date=dmy overrides iso
 elseif 'ymd' == date then
 date = nil; -- if date extracted from URL,
 ldf = 'ymd'; -- then |date=ymd overrides iso
 else
 date, ldf = decode\_date (date); -- get an iso format date from date and get date's original format
 end
 end

 if 'wayback' == ulx.url1.service or 'locwebarchives' == ulx.url1.service or 'ukgwa' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeWaybackDate (uri.path); -- get the url date in iso format and format of date in |date=; 'index' when wayback url date is \*
 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 else -- no |date=
 udate, msg = decodeWaybackDate (uri.path);

 if not udate then -- this is the only 'fatal' error return
 return inlineError (data.crit\_err\_msgs[msg]);
 end

 if  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 elseif 'webcite' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate = decodeWebciteDate (uri.path); -- get the url date in iso format
 if 'query' ~= udate then -- skip if query
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'),
 });
 end
 end
 end
 end
 else
 date = decodeWebciteDate( uri.path, "iso" )
 if date == "query" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif not date then -- invalid base62 string
 date = inlineRed (err\_warn\_msgs.date1, 'error');
 end
 end

 elseif 'archiveis' == ulx.url1.service then
 if date then
 if config.verifydates then
 if ldf then
 udate, msg = decodeArchiveisDate (uri.path) -- get the url date in iso format
 if 'short link' ~= udate then -- skip if short link
 if udate ~= date then -- date comparison using iso format dates
 date = udate;
 msg = table.concat ({
 inlineRed (err\_warn\_msgs.mismatch, 'warning'), -- add warning message
 msg, -- add message if there is one
 });
 end
 end
 end
 end
 else -- no |date=
 udate, msg = decodeArchiveisDate( uri.path, "iso" )
 if udate == "short link" then
 date = nil; -- unset
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 elseif  *== udate then*
 date = nil; -- unset
 else
 date = udate;
 end
 end

 else -- some other service
 if not date then
 msg = inlineRed (err\_warn\_msgs.date\_miss, 'warning');
 end
 end

 if 'index' == date then
 ulx.url1.date = date .. (msg or *); -- create index + message (if there is one)*
 elseif date then
 ulx.url1.date = makeDate (date, nil, nil, ldf) .. (msg or *); -- create a date in the wiki's local language + message (if there is one)*
 else
 ulx.url1.date = msg;
 end

 format = args.format; -- Format argument

 if not format then
 format = "none"
 else
 for k, v in pairs (data.format\_vals) do -- |format= accepts two specific values loop through a table of those values
 local found; -- declare a nil flag
 for \_, p in ipairs (v) do -- loop through local language variants
 if format == p then -- when |format= value matches
 format = k; -- use name from table key
 found = true; -- declare found so that we can break out of outer for loop
 break; -- break out of inner for loop
 end
 end

 if found then
 break;
 end
 end

 if format == "addlpages" then
 if not ulx.url1.date then
 format = "none"
 end
 elseif format == "addlarchives" then
 format = "addlarchives"
 else
 format = "none"
 end
 end
 ulx.url1.format = format

 if args.title and args.title1 then -- Title argument
 return inlineError (data.crit\_err\_msgs.conflicting, {origin.title, origin.title1});
 end

 ulx.url1.title = args.title or args.title1;

 local rend = createRendering()
 if not rend then
 return inlineError (data.crit\_err\_msgs.unknown);
 end

 return rend .. ((unnamed\_params and inlineRed (err\_warn\_msgs.unnamed\_params, 'warning')) or *) .. createTracking();*

end

--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]

return {webarchive = webarchive}; FIFA Films Retrieved 28 January 2013
70. ↑ Mell, Eila (24 January 2015). *Casting Might-Have-Beens: A Film by Film Directory of Actors Considered for Roles Given to Others*. McFarland. ISBN 978-1-4766-0976-8.
71. ↑ 71.0 71.1 1988 BAFTA Awards.
72. ↑ "Highlander: 35 years since Scotland stole the show in cult film starring Queen, Sean Connery and Christopher Lambert".
73. ↑ The Untouchables Review.
74. ↑ The 60th Academy Awards (1988) Nominees and Winners. Academy of Motion Picture Arts and Sciences (AMPAS).
75. ↑ "Ford's father figure", 5 May 1997.
76. ↑  (2009) "8: Sean Connery's Star Persona and the Queer Middle Ages", *Queer movie medievalisms*. Farnham: Ashgate, page 161. ISBN 978-0-7546-7592-1.
77. ↑ Robson, Ben. "The name's Connery, Sean Connery: the life of Scotland's James Bond", *The Times*, 21 August 2008.
78. ↑ 100 Greatest ... (100 Greatest Movie Stars (Part 1)). ITN Source.
79. ↑ An ignominious exit (21 March 2019).
80. ↑ "Connery 'turning back on movies'", *BBC News*, 1 August 2005.
81. ↑ "Sean Connery lost $450m refusing Gandalf role", 21 November 2012.
82. ↑ Ransom Riggs. "5 million-dollar mistakes by movie stars", CNN, 20 October 2008.
83. ↑ "Harry Potter: The Actors Who Almost Played Dumbledore", *ScreenRant*, 1 January 2020.
84. ↑ Norrington, Stephen (Director) (16 December 2003) The League of Extraordinary Gentlemen (DVD) United States: 20th Century Fox
85. ↑ IGN: Sean Connery Back as Bond.
86. ↑ Lipsey, Sid. "Review: Connery brings Bond back to the USSR", CNN, 10 November 2005.
87. ↑ IGN: Sean Connery Back as Bond.
88. ↑ 88.0 88.1 Dalton, Ben (31 October 2020). Sean Connery, the original James Bond, dies aged 90.
89. ↑ "Sexy? It's all in the hand-shake", 9 July 2005.
90. ↑ "Connery bows out of Indiana film", *BBC News*, 8 June 2007.
91. ↑ Sean Connery immortalised with Estonian bust.
92. ↑ Carson, Alan. "Sir Sean makes film comeback as a retired vet", 12 April 2010.
93. ↑ Friends Say It's Love.
94. ↑ Bond girl Lana Wood talks about Sean Connery affair.
95. ↑ "Norman Mailer's Norristown mistress: I've been defamed", Philadelphia Inquirer.
96. ↑ The Private Life and Times of Magda Konopka.
97. ↑ "Jealous Connery beat me, says ex-wife".
98. ↑ Neal, Aly. "No more free passes to famous men who abuse women", 12 February 2013.
99. ↑ "Sean Connery: 'Abuse is never justified' Actor speaks out after cancelling Holyrood festival appearance", *The Herald*, 25 June 2006.
100. ↑ "Connery: to hit a woman is wrong".
101. ↑ "Former James Bond actor Sean Connery dies aged 90", *Reuters*.
102. ↑ "Connery: Bond and beyond", *BBC News*, 21 December 1999.
103. ↑ "Pop star Lynsey de Paul reveals the truth about her love-life", *Evening Standard*, 10 April 2007.
104. ↑ We half expected someone to tuck us in with a goodnight kiss (en) (1 August 2004).
105. ↑ No doubting Thomas. Executive Golf Magazine.
106. ↑ Rogers, Ron. "Hanshi's Corner 1106", Midori Yama Budokai.
107. ↑ "Sir Sean Connery says he's lucky to avoid Hurricane Dorian after Bahamas battered by storm", Edinburgh Live.
108. ↑ Template:London Gazette
109. ↑ "Sir Sean's pride at knighthood", *BBC News*, 5 July 2000.
110. ↑ "Dutch prince buys villa next to James Bond actor", *BBC News*, 16 April 2012.
111. ↑ Farndale, Nigel (4 October 2010). Michael Caine interview – for his autobiography The Elephant to Hollywood.
112. ↑ Gruesome Beast 5: The Sea-Beasts (en).
113. ↑ Coats of arms (31 May 2016).
114. ↑ Christie, Kevan (26 August 2008). Celtic fans give me pelters since I switched loyalty to Rangers, says Sir Sean Connery.
115. ↑ "Peter Alliss: The colourful, and controversial, voice of golf".
116. ↑ "Sean Connery and Slazengers jumpers".
117. ↑ ""The best" – Jack Nicklaus pays tribute to Sir Sean Connery".
118. ↑ Seenan, Gerard. "Connery goes on the SNP offensive", 27 April 1999.
119. ↑ Pender, Paul. "patriotgames", 2 May 1999.  [dead link]
120. ↑ 120.0 120.1 "Connery funds SNP through Jersey account", *BBC News*, 7 March 2003.
121. ↑ Christopher Bray, *Sean Connery: The Measure of a Man* (London: Faber, 2011), p. 140
122. ↑ "Sir Sean lays bare his tax details", *BBC News*, 6 March 2003.
123. ↑ Collinson, Patrick. "Join the club and become a tax exile", 21 February 2004.
124. ↑ Cramb, Auslan. "Sir Sean Connery's tax exile status keeps him away from independence debate, says brother", 16 September 2014.
125. ↑ "Sean Connery's wife faces €22 million fine over Marbella villa sale".
126. ↑ Gayle, Damien. "Sean Connery's wife charged with Spanish property tax fraud", 27 November 2015.
127. ↑ 127.0 127.1 "Sean Connery: James Bond actor dies aged 90", *BBC News*, 31 October 2020.
128. ↑ Obituary: Sir Sean Connery (31 October 2020).
129. ↑ "Obituary: Sir Sean Connery", *The Sunday Times*, 31 October 2020.
130. ↑ "Sean Connery, Oscar Winner and James Bond Star, Dies at 90", *Variety*, 31 October 2020.
131. ↑ Sean Connery widow reveals he had suffered from dementia (1 November 2020).
132. ↑ "Sir Sean Connery: Scottish actor and Bond legend died from pneumonia and heart failure", *Edinburgh Evening News*, 29 November 2020.
133. ↑ O'Connor, Rachael. "Sean Connery's ashes to be scattered in Scotland as it was his 'final wish', his wife says".
134. ↑ Template:Cite tweet
135. ↑ Earl, William (31 October 2020). Hollywood Mourns Sean Connery: 'He Revolutionized the World'.
136. ↑ Del Rosario, Alexandra (31 October 2020). Alec Baldwin Pays Tribute To 'The Hunt For Red October' Co-Star Sean Connery: "You Made Life Better". Yahoo! Sport.
137. ↑ Calvario, Liz (31 October 2020). Sean Connery Dead at 90: Arnold Schwarzenegger, Catherine Zeta-Jones and More Celebs Honor Actor.
138. ↑ "Sean Connery: Harrison Ford pays tribute to 'dear friend'", BBC.
139. ↑ Dessem, Matthew (31 October 2020). Sean Connery Has Died. Friends, Fans, and the Other James Bonds Are Saluting Him on Social Media..
140. ↑ 140.0 140.1 Daniel Craig, Pierce Brosnan, Sam Neill, George Lucas and More of Hollywood Pay Tribute to Sean Connery (31 October 2020).
141. ↑ "Sir Michael Caine remembers 'great star, wonderful friend' Sir Sean Connery", *The Herald*, 31 October 2020.
142. ↑ Flockhart, Susan. "Would The Greatest Living Scot Please Stand Up?; Here they are", 25 January 2004.
143. ↑ "Sir Sean Connery named Scotland's greatest living treasure", STV News, 25 November 2011.
144. ↑ Sexy Celebrity Pictures. CBS News.
145. ↑ Cieply, Michael. "*Last Emperor* Reigns Over Oscar Ceremonies: Best Picture Winner Adds Eight Other Awards; Cher and Douglas Take Top Prizes for Acting", 12 April 1988.
146. ↑ 1988 Film Actor in a Supporting Role; BAFTA Awards.
147. ↑ 147.0 147.1 Film in 1990; BAFTA Awards.
148. ↑ BAFTA Awards.
149. ↑ 149.0 149.1 HFPA. HPFA.
150. ↑ "'Emperor' Reigns at Golden Globes", 25 January 1988.
151. ↑ "Globes Enter the '90s With a Nod Toward Social Relevance", 22 January 1990.
152. ↑ Winners & Nominees 1996 – Golden Globes. *The Golden Globes*. Hollywood Foreign Press Association.
153. ↑ "En images: Les rôles iconiques de Sean Connery".
154. ↑ 100 BAFTA Moments – Sean Connery's Emotional Reaction to Receiving the BAFTA Fellowship (23 January 2015).
155. ↑ "Sean Connery".
156. ↑ "Sir Sean's pride at knighthood", *BBC News*, 5 July 2000.
157. ↑ "European Film Academy Lifetime Achievement Award".

## Bibliography

* (1999) *When the Snow Melts: The Autobiography of Cubby Broccoli*. Trans-Atlantic Publications.
* (1985) *Hollywood Hunks and Heroes*. New York City: Exeter Books, page 33. ISBN 978-0-671-07528-6.
* (2002) *James Bond: The Legacy*. London: Boxtree. ISBN 978-0-7522-6498-1.
* Sellers, Robert (1999). *Sean Connery: A Celebration*. Robert Hale. ISBN 978-0-7090-6125-0.
* Yule, Andrew (1992). *Sean Connery: Neither Shaken Nor Stirred*. Little, Brown Book Group. ISBN 978-0-7515-4097-0.

## External links

* Official website
* Sean Connery at Wikipedia

* Sean Connery at James Bond Wiki
* Sean Connery at the Internet Movie Database
* Sean Connery at the British Film Institute

**Soundtracks:** *Moonraker*