CHiPs

Template:Short description
Template:About
Template:Use mdy dates

***CHiPs*** is an American crime drama television series created by Rick Rosner and originally aired on NBC from September 15, 1977, to May 1, 1983. It follows the lives of two motorcycle officers of the California Highway Patrol (CHP). The series ran for 139 episodes over six seasons, plus one reunion television film in October 1998.

## Overview

Template:Section unsourced
*CHiPs* is an action crime drama in a standard hour-long time slot, which at the time required 48 minutes of actual programming. A signature of the show, especially in the later seasons, were frequent over-the-top freeway pileups. For filming, traffic on Los Angeles freeways was non-existent and most chase scenes were done on back roads.

The show was created by Rick Rosner, and starred Erik Estrada as macho, rambunctious Officer Francis ("Frank") Llewellyn "Ponch" Poncherello and Larry Wilcox as his straitlaced partner, Officer Jonathan ("Jon") Andrew Baker. With Ponch the more trouble-prone of the pair, and Jon generally the more level-headed one trying to keep him out of trouble with the duo's gruff yet fatherly immediate supervisor Sergeant Joseph Getraer (Robert Pine), the two were Highway Patrolmen of the Central Los Angeles office of the California Highway Patrol (CHP, hence the name *CHiPs*).

As real-life CHP motor officers rarely ride in pairs, in early episodes this was explained away by placing the trouble-prone Ponch on probationary status, with Jon assigned as his field training officer. Eventually, by the end of the first season, this subplot faded away (Ponch completed his probation) as audiences were used to seeing the two working as a team.

## Cast

 File:CHiP's.jpg
* Larry Wilcox as Officer Jonathan Andrew Baker (1977–82)
* Erik Estrada as Officer Francis "Ponch" Poncherello
* Robert Pine as Sergeant Joseph "Joe" Getraer
* Lew Saunders as Officer Gene Fritz (1977–79)
* Brodie Greer as Officer Barry "Bear" Baricza (1977–82)
* Paul Linke as Officer Arthur "Grossie" Grossman
* Lou Wagner as Harlan Arliss, Automobile/Motorcycle Mechanic, CHP (1978–83)
* Brianne Leary as Officer Sindy Cahill (1978–79)
* Randi Oakes as Officer Bonnie Clark (1979–82)
* Michael Dorn as Officer Jedediah Turner (1979–82)
* Caitlyn Jenner as Officer Steve McLeish (1981–82) (credited as "Bruce Jenner")
* Tom Reilly as Officer Robert "Bobby" "Hot Dog" Nelson (1982–83)
* Tina Gayle as Officer Kathy Linahan (1982–83)
* Bruce Penhall as Cadet/Officer Bruce Nelson (1982–83)
* Clarence Gilyard Jr. as Officer Benjamin Webster (1982–83)

### Cast changes

In the fifth season (1981–82), Estrada went on strike over a dispute over syndication profits. As a result, he did not appear in three episodes; for that period he was replaced by Jenner (Officer Steve McLeish).

Despite their successful pairing on-screen, Wilcox and Estrada did not always get along behind the camera. Wilcox fell out with the producers over what he saw as continual favoritism toward Estrada, and did not return for the sixth and final season. Wilcox was replaced by Tom Reilly (Officer Bobby Nelson).

Bruce Penhall, a native of Balboa Island, Newport Beach, and a motorcycle speedway rider who had won the 1981 and 1982 Speedway World Championships, was also introduced as cadet–probationary officer Bruce Nelson, Bobby's younger brother in 1982–83. The Season 6 episode "Speedway Fever" (aired November 7, 1982) centered on Penhall's character Nelson winning the 1982 Speedway World Final at the Los Angeles Memorial Coliseum, with scenes filmed in the pits during the meeting. The episode also used television coverage of the final, with dubbed commentary. Penhall later admitted that having a bodyguard and having to have makeup done in the pits in full view of his competitors at the World Final only added to the pressure he was under both as a rider and a rookie actor and that it felt weird having to "buddy up to Ponch" in front of the other riders while the World Final was taking place. In order to become a full-time member of the *CHiPs* cast, Penhall had officially announced his retirement from speedway racing on the podium of the 1982 World Final.

## Production

Template:More citations needed
According to a 1998 *TV Guide* article, show creator Rick Rosner was a reserve deputy with the Los Angeles County Sheriff's Department. During a coffee break on an evening patrol shift in the mid-1970s he saw two young CHP officers on motorcycles which gave him the idea for this series. He later created *240-Robert*, which seemed like a hybrid of *CHiPs* and *Emergency!*.

 File:CHP 70's helmet.jpg
Episodes occasionally mention Jon Baker's service in Vietnam. This makes his character one of the earliest regular (and one of the more positive) portrayals of a Vietnam veteran on television. Larry Wilcox himself served 13 months in Vietnam as a Marine artilleryman.

Production made use of freeways in the Los Angeles area that had been recently completed but were not yet opened to the public. For Season 1, the intersection of Interstate 210 and California State Route 2 in La Canada Flintridge was used often (along with a short stretch of Highway 2). For Season 2, a section of Interstate 210 five miles to the west in La Crescenta, California, was used, until it too was opened to the public. For Seasons 3 - 5, the filming location was moved another 10 miles to the west, to the intersection of the Interstate 210 and California State Route 118 in Sylmar, California. When that section of freeway was finally opened, production shifted again to a short stub of a highway in Long Beach, California, as well as a long stretch of Pershing Drive, near Los Angeles International Airport. The only time production moved out of Los Angeles was for the episode *Drive, Lady, Drive* and used the Riverside International Raceway in Moreno Valley for the racing scenes.

Motor officers in *CHiPs* rode Kawasaki Z1-P & Z900-C2 in seasons 1 & 2 and KZ1000-C1 from season 3 onwards.

Despite the Ford Motor Company's credit as a vehicle provider for four of the series' six seasons, cars and trucks were supplied by several manufacturers. All of the police cars were Dodge models (´74 and ´78 Dodge Monaco), as they were actual CHP cruisers bought at police auction for the show. In the third-season episode, *Hot Wheels* (Episode 8) the show featured AMC Matador police cars in a one-off appearance.

Although doubles were used for far-off shots and various stunt or action sequences, Wilcox and Estrada did a great deal of their own motorcycle riding and performed many smaller stunts themselves. Although Wilcox emerged relatively injury-free, Estrada suffered various injuries several times throughout the run of the series. In several early first-season episodes, a huge bruise or scab can be seen on his arm after he was flung from one of the motorcycles and skidded along the ground. His worst accident came when he was seriously injured in a motorcycle accident while filming a season three episode in August 1979, fracturing several ribs and breaking both wrists. The accident and Estrada's subsequent hospitalization was incorporated into the series' storyline.

Prior to being cast in *CHiPs*, Estrada had no experience with motorcycles, so he underwent an intensive eight-week course, learning how to ride. In 2007, it was revealed that he did not hold a motorcycle license at the time *CHiPs* was in production, and only qualified for a license after three attempts, while preparing for an appearance on the reality television show *Back to the Grind*.

NBC aired reruns of this series on its 1982 daytime schedule from April to September.

During the original run of the series, syndicated reruns of older episodes was retitled *CHiPs Patrol* to avoid confusion. Later syndicated reruns after the show went out of production reverted to the original title.

## Episodes

*Main article: List of CHiPs episodes*
List of CHiPs episodes
*CHiPs* episodes were usually a combination of light comedy and drama. A typical episode would start with Ponch and Jon on routine patrol or being assigned to an interesting beat, such as Malibu or the Sunset Strip. In roll call briefing, Sgt. Getraer would alert his officers to be on the lookout for a particular criminal operation, such as people staging accidents as part of an insurance scam, or punks breaking into cars. A few interesting, unrelated vignettes often transpired during "routine" traffic enforcement.

A light-hearted subplot would also be included, such as Harlan trying to hide a stray dog from Getraer at the office. A more serious theme, such as Ponch trying to keep a kid from his old neighborhood out of a potential life of crime, might also be included. After a few failed attempts to apprehend the gang that had been menacing L.A.'s freeways, the episode would invariably culminate in Ponch and Jon leading a chase of the suspects (often assisted by other members of their division), climaxing with a spectacular series of stunt vehicle crashes.

The show then typically featured a *dénouement* of Ponch and Jon participating in a new activity (such as jet skiing or skydiving), designed to showcase the pair's glamorous Southern California lifestyle. Often, Ponch would attempt to impress a woman he had met during the episode with his athletic prowess or disco dancing, only to fail and provide Jon, Getraer, and others with many laughs. As the preliminary end credits would start, the image would freeze multiple times, showing various characters laughing or otherwise enjoying the social scene.

## Broadcast history

*(all times Eastern/Pacific Time; subtract one hour for Central/Mountain Time)*

* September 1977 – March 1978: NBC Thursday, 8–9PM
* April 1978: NBC Saturday, 8–9PM
* May – August 1978: NBC Thursday, 8–9PM
* September 1978 – March 1980: NBC Saturday, 8–9PM
* March 1980 – March 1983: NBC Sunday, 8–9PM
* April – May 1983: NBC Sunday, 7–8PM
* May – July 1983: NBC Sunday, 8–9PM

NBC aired reruns of the series weekdays at 3PM EST between April 26, 1982 – September 10, 1982. The show aired on MeTV from December 19, 2016 to May 26, 2017. The show currently airs on Charge!.

In the United Kingdom, the series was broadcast by ITV but was not screened nationally. The series started in January 1979 in the London region, but began with season two (the first episode shown was episode 2x02 "The Volunteers") by February most other ITV regions originally screened in the Saturday teatime slot around 17:35 but moved to the Sunday teatime slot in 1980. By 1981, as with many imported programmes of the era, the series was being broadcast at different times during the weekend throughout the year by the different ITV regions. The series shared its Saturday teatime slot with other series such as *The A-Team*, *Knight Rider*, *Magnum, P.I.* and *Whiz Kids*.

During 1984, most ITV stations continued with the Saturday teatime slot except for Anglia Television, Scottish Television (STV) and Television South West (TSW), who broadcast episodes during the weekend mornings or Sunday afternoons. By early 1985, the series was being broadcast during Saturday mornings by Anglia, Central, Grampian, Granada, STV and Tyne Tees. In other regions it had a Saturday lunchtime slot of 13:20 where, from September 1985, it rotated the slot with episodes of *Airwolf*.

Most ITV areas completed the series by 1986, while LWT, TVS and TSW finished series six in 1987 after starting in 1985. A few companies repeated the series in 1987. It was previously shown on Bravo between 2002 to 2004. Now currently being repeated on Forces TV.

The entire series was shown in New Zealand on TVNZ from 1978. In Australia, from the same year, the Seven Network broadcast the series in its entirety, one episode per week usually in the prime 7.30PM timeslot.

## Home media

Warner Home Video released the first two seasons of *CHiPs* on DVD in Regions 1, 2 and 4 between 2007 and 2008. On March 3, 2015 (over six years later), the third season was released on DVD in Region 1. The fourth season was released in Region 1 on March 15, 2016.
The fifth season was released in Region 1 on March 14, 2017.
The sixth season and the complete series were released in Region 1 on June 6, 2017.

All 139 episodes are at the iTunes Store.

## *CHiPs*

### Genre

Crime
Drama

### Starring

Larry Wilcox
Erik Estrada
Robert Pine
Paul Korver
David Ramsey
Brodie Greer
Bruce Penhall
Paul Linke
Judge Judy Sheindlin

## Production

### Producer(s)

Erik Estrada
Christopher Morgan
Larry Wilcox

### Distributor

TNT
Warner Bros. Domestic Television Distribution

***CHiPs '99*** is a 1998 American made-for-television crime drama film and a sequel to the series. It was directed by Jon Cassar. Several cast members from the original series make a return. Original cast with promotions were Jon Baker as a Captain and Joe Getraer as the CHP Commissioner. Other original cast members were Officer Frank Poncherello returning from a 15-year hiatus from the CHP, Officer Barry Baricza and Arthur (Artie) "Grossie" Grossman as a Detective. Bruce Penhall also returns as newly promoted Sergeant Bruce Nelson.

* Larry Wilcox as Captain Jonathan (Jon) A. Baker
* Erik Estrada as Officer Francis (Frank) Llewelyn "Ponch" Poncherello
* Robert Pine as CHP Commissioner Joseph (Joe) Getraer
* Paul Korver as Officer Peter Roulette
* David Ramsey as Officer Sergeant McFall
* Brodie Greer as Officer Barry "Bear" Baricza
* Bruce Penhall as Officer/Sergeant Bruce Nelson
* Paul Linke as Detective Arthur (Artie) "Grossie" Grossman
* Judge Judy Sheindlin as Herself

### Feature film

*Main article: CHiPs (film)*
A film remake was released on March 24, 2017, with Dax Shepard co-producing with Andrew Panay, writing, directing and starring as Officer Jon Baker, Michael Peña as Frank "Ponch" Poncherello and Vincent D’Onofrio as the film's villain.

### Merchandise

A series of 8 inch and 3Template:Fraction inch action figures was released by Mego in the late 1970s. Due to the materials used to construct the figures, many of them have discolored (typically turning green) or started to decompose over the years, making good conditioned examples quite hard to find on the collectors market.[*citation needed*] There was also a series of six die-cast model vehicles produced by Imperial Toys.

In the UK, as was common with many popular US series of the era, a series of tie-in annuals were produced by World International Publishing Ltd, containing stories, photos, puzzles and features on the stars. There are four annuals in total, one each for 1980–83. [*citation needed*]. A comic strip adaptation was drawn by Jim Baikie for *Look-In* magazine.

In 2006, a limited edition soundtrack was released on CD by Turner Classic Movies' music division via Film Score Monthly, featuring the original recordings of the main theme by John Parker (Parker's theme replaced an unused composition by Mike Post and Pete Carpenter, who scored the pilot) and in-episode musical scores from many episodes of the second season, as composed and conducted by Alan Silvestri, the series' primary (and from seasons three to five sole) composer until the final season. Silvestri also arranged the theme as heard from season two onwards, and it is this version that is heard hereTemplate:Nsmdnsthe soundtrack album also includes the "Trick or Treat" score composed and conducted by Bruce Broughton, his only work for the series. In 2008, music from the third season was released; an album of music from the fourth season followed in 2010.

## References

1. ↑ McNeil, Alex. *Total Television*. 1980. New York: Penguin Books, 1991.
2. ↑ Rubin, Sylvia. "Estrada, Wilcox Cash In With New 'CHiPs '99' / Popular '70s show gets updated in TNT movie", *The San Francisco Chronicle*, October 27, 1998.
3. ↑ Lardine, Bob. Larry Wilcox Busses His New Bride, but 'CHiPs' Co-Star Erik Estrada Gets a Kiss-Off. *People*. Time Inc..
4. ↑ "Reruns retitled". *Journal of the Audio Engineering Society* (Audio Engineering Society): 190. March 1986.
5. ↑ CHiPs DVD news: Press Release for CHiPs - The Complete 3rd Season - TVShowsOnDVD.com. *TVShowsOnDVD.com*.
6. ↑ CHiPs DVD news: Press Release for CHiPs - The Complete 4th Season - TVShowsOnDVD.com. *tvshowsondvd.com*.
7. ↑ David Lambert (December 5, 2016). CHiPs - 'The Complete 5th Season' DVDs are Scheduled: Date, Price, More!. *tvshowsondvd.com*.
8. ↑ Ponch and Jon Together on the Cover of 'The Complete 5th Season' --[[ ----------------------------------

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};
9. ↑ David Lambert (December 14, 2016). CHiPs - DVD Street Date Gets Closer for 'The Complete 5th Season'. *tvshowsondvd.com*.
10. ↑ David Lambert (March 16, 2017). CHiPs - The Complete 6th and Final Season, The Complete Series DVDs! Date, pricing, plus front and rear cover art for both titles!. *tvshowsondvd.com*.
11. ↑ *CHiPs* season 1. iTunes Store (June 4, 2007). Retrieved on August 11, 2011.
12. ↑ *CHiPs* season 2. iTunes Store (July 7, 2008). Retrieved on August 11, 2011, while Vudu has only the first two seasons available for online download through them.
13. ↑ "Dax Shepard Driving Warner Bros 'CHiPS' Film; Michael Pena To Play Ponch", deadline.com, September 2, 2014.
14. ↑ "Dax Shepard Making 'CHiPS' Movie for Warner Bros.", *The Hollywood Reporter*, September 2, 2014.
15. ↑ Kit, Borys (May 26, 2015). 'CHiPs' Movie Casting Vincent D'Onofrio as Villain (Exclusive). *The Hollywood Reporter*.
16. ↑ Jim Baikie.
17. ↑ Liner notes, *CHiPs: Season Two 1978-79*, Film Score Monthly, FSM0910

## External links

* *CHiPs* at the Internet Movie Database
* *CHiPs '99* at the Internet Movie Database
* Template:Imcdb movie
* CHiPs Online wiki

Template:Sequence
Template:CHiPs
Template:Portal bar
Template:Authority control