فهرست منبع

React Project DONE

Illia Kozyr 1 سال پیش
والد
کامیت
c722a49f64
100فایلهای تغییر یافته به همراه51017 افزوده شده و 74 حذف شده
  1. 0 20
      <!DOCTYPE>...html
  2. 0 54
      Chat/index.html
  3. 0 0
      Fakogram REACT project/fakogram/.gitignore
  4. 0 0
      Fakogram REACT project/fakogram/README.md
  5. 30015 0
      Fakogram REACT project/fakogram/package-lock.json
  6. 48 0
      Fakogram REACT project/fakogram/package.json
  7. 0 0
      Fakogram REACT project/fakogram/public/favicon.ico
  8. 0 0
      Fakogram REACT project/fakogram/public/index.html
  9. 0 0
      Fakogram REACT project/fakogram/public/logo192.png
  10. 0 0
      Fakogram REACT project/fakogram/public/logo512.png
  11. 0 0
      Fakogram REACT project/fakogram/public/manifest.json
  12. 0 0
      Fakogram REACT project/fakogram/public/robots.txt
  13. 351 0
      Fakogram REACT project/fakogram/src/App.css
  14. 61 0
      Fakogram REACT project/fakogram/src/App.js
  15. 0 0
      Fakogram REACT project/fakogram/src/App.test.js
  16. 124 0
      Fakogram REACT project/fakogram/src/actions/authActions.js
  17. 239 0
      Fakogram REACT project/fakogram/src/actions/chatsActions.js
  18. 90 0
      Fakogram REACT project/fakogram/src/actions/findActions.js
  19. 52 0
      Fakogram REACT project/fakogram/src/actions/index.js
  20. 16 0
      Fakogram REACT project/fakogram/src/actions/mediaActions.js
  21. 289 0
      Fakogram REACT project/fakogram/src/actions/msgActions.js
  22. 70 0
      Fakogram REACT project/fakogram/src/actions/socketActions.js
  23. 40 0
      Fakogram REACT project/fakogram/src/components/Avatar.js
  24. 16 0
      Fakogram REACT project/fakogram/src/components/AvatarStub.js
  25. 16 0
      Fakogram REACT project/fakogram/src/components/LogoutBtn.js
  26. 11 0
      Fakogram REACT project/fakogram/src/components/NickName.js
  27. 74 0
      Fakogram REACT project/fakogram/src/components/SendMsg.js
  28. 1 0
      Fakogram REACT project/fakogram/src/constants.js
  29. 112 0
      Fakogram REACT project/fakogram/src/helpers/UserSearch.js
  30. 24 0
      Fakogram REACT project/fakogram/src/helpers/getGql.js
  31. 6 0
      Fakogram REACT project/fakogram/src/helpers/index.js
  32. 10 0
      Fakogram REACT project/fakogram/src/helpers/passValidator.js
  33. 5 0
      Fakogram REACT project/fakogram/src/helpers/redirect.js
  34. 0 0
      Fakogram REACT project/fakogram/src/index.css
  35. 17 0
      Fakogram REACT project/fakogram/src/index.js
  36. 0 0
      Fakogram REACT project/fakogram/src/logo.svg
  37. 16 0
      Fakogram REACT project/fakogram/src/pages/AboutUs.js
  38. 14 0
      Fakogram REACT project/fakogram/src/pages/ChangeDoneForChat.js
  39. 81 0
      Fakogram REACT project/fakogram/src/pages/ChangePassPage.js
  40. 14 0
      Fakogram REACT project/fakogram/src/pages/ChangesDonePage.js
  41. 210 0
      Fakogram REACT project/fakogram/src/pages/ChatsPage.js
  42. 54 0
      Fakogram REACT project/fakogram/src/pages/Header.js
  43. 66 0
      Fakogram REACT project/fakogram/src/pages/LoginPage.js
  44. 51 0
      Fakogram REACT project/fakogram/src/pages/MsgPage.js
  45. 105 0
      Fakogram REACT project/fakogram/src/pages/NewChatPage.js
  46. 100 0
      Fakogram REACT project/fakogram/src/pages/ProfilePage.js
  47. 120 0
      Fakogram REACT project/fakogram/src/pages/RegPage.js
  48. 428 0
      Fakogram REACT project/fakogram/src/reducers/index.js
  49. 0 0
      Fakogram REACT project/fakogram/src/reportWebVitals.js
  50. 0 0
      Fakogram REACT project/fakogram/src/setupTests.js
  51. 1 0
      Fakogram REACT project/node_modules/.bin/acorn
  52. 1 0
      Fakogram REACT project/node_modules/.bin/atob
  53. 1 0
      Fakogram REACT project/node_modules/.bin/errno
  54. 1 0
      Fakogram REACT project/node_modules/.bin/json5
  55. 1 0
      Fakogram REACT project/node_modules/.bin/loose-envify
  56. 1 0
      Fakogram REACT project/node_modules/.bin/miller-rabin
  57. 1 0
      Fakogram REACT project/node_modules/.bin/mkdirp
  58. 1 0
      Fakogram REACT project/node_modules/.bin/resolve
  59. 1 0
      Fakogram REACT project/node_modules/.bin/semver
  60. 1 0
      Fakogram REACT project/node_modules/.bin/sha.js
  61. 1 0
      Fakogram REACT project/node_modules/.bin/uglifyjs
  62. 1 0
      Fakogram REACT project/node_modules/.bin/webpack
  63. 3765 0
      Fakogram REACT project/node_modules/.package-lock.json
  64. 19 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/CHANGELOG.md
  65. 21 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/LICENSE
  66. 33 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/README.md
  67. 17 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/lib/index.js
  68. 70 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/lib/inject.js
  69. 1 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/.bin/acorn
  70. 10 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/.npmignore
  71. 62 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/AUTHORS
  72. 286 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/CHANGELOG.md
  73. 19 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/LICENSE
  74. 409 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/README.md
  75. 67 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/bin/acorn
  76. 0 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/.keep
  77. 3401 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.es.js
  78. 3433 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.js
  79. 1364 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.es.js
  80. 1374 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.js
  81. 342 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.es.js
  82. 360 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.js
  83. 46 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/package.json
  84. 60 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/bin/acorn.js
  85. 819 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/expression.js
  86. 81 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/identifier.js
  87. 77 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/index.js
  88. 26 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/location.js
  89. 42 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/locutil.js
  90. 562 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/expression.js
  91. 48 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/index.js
  92. 1 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/parseutil.js
  93. 161 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/state.js
  94. 450 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/statement.js
  95. 108 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/tokenize.js
  96. 219 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/lval.js
  97. 50 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/node.js
  98. 128 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/options.js
  99. 128 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/parseutil.js
  100. 0 0
      Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/state.js

+ 0 - 20
<!DOCTYPE>...html

@@ -1,20 +0,0 @@
-<!doctype html>
-<html lang="en">
-<head>
-    <meta charset="UTF-8">
-    <meta name="viewport"
-          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
-    <meta http-equiv="X-UA-Compatible" content="ie=edge">
-    <title>Not Telegram</title>
-</head>
-<body>
-    <div class="">
-
-    </div>
-
-    <script>
-
-
-    </script>
-</body>
-</html>

+ 0 - 54
Chat/index.html

@@ -1,54 +0,0 @@
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Static File Index.HTML</title>
-        <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
-    </head>
-    <body>
-        <style>
-
-            .chat__header {
-              text-align: left;
-            }
-            .chat__message-content {
-              border-radius: 5px;
-              padding: 7px;
-              background-color: #ccc;
-              display: inline-block;
-              margin-left: 5px;
-            }
-            </style>
-            <body>
-                 
-            <main class="main">
-                <div class="chat"> 
-                    <h1 class="chat__header">Chat</h1>
-                <div id="content" class = "chat__header">
-                    <div class="chat__item">
-                        <h1 id = "chat__message-content" class="chat__message-content"></h1>
-                    </div>
-                    <div class="send_form">
-                        Nick :<input type="text" id = 'nick' > 
-                        Message :<input type="text" id = 'msg'>
-                        <button id="sendButton">Отправить</button>
-                    </div>
-                   
-                </div>
-            </main>
-            
-            <script>
-                const socket = io('http://socketchat.ed.asmer.org.ua')
-                socket.on('msg', msg => {
-                    console.log(msg)
-                    const my_P = document.createElement("div");
-                    my_P.innerHTML = '<b>' + msg.nick + ":" +"</b>" + msg.message
-                    document.getElementById("chat__message-content").appendChild(my_P)
-                })
-                
-                sendButton.onclick = () => {
-                    console.log(nick.value , msg.value)
-                    socket.emit('msg', {nick: nick.value, message: msg.value})
-                }
-            </script>
-    </body>
-</html>

REACT/HW 20/.gitignore → Fakogram REACT project/fakogram/.gitignore


REACT/HW 20/README.md → Fakogram REACT project/fakogram/README.md


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 30015 - 0
Fakogram REACT project/fakogram/package-lock.json


+ 48 - 0
Fakogram REACT project/fakogram/package.json

@@ -0,0 +1,48 @@
+{
+  "name": "fakogram",
+  "version": "0.1.0",
+  "private": true,
+  "dependencies": {
+    "@testing-library/jest-dom": "^5.16.5",
+    "@testing-library/react": "^13.4.0",
+    "@testing-library/user-event": "^13.5.0",
+    "bootstrap": "^5.2.1",
+    "react": "^18.2.0",
+    "react-bootstrap": "^2.5.0",
+    "react-dom": "^18.2.0",
+    "react-dropzone": "^14.2.2",
+    "react-password-checklist": "^1.4.1",
+    "react-redux": "^8.0.2",
+    "react-router-dom": "^5.3.3",
+    "react-scripts": "5.0.1",
+    "redux": "^4.2.0",
+    "redux-thunk": "^2.4.1",
+    "socket.io": "^4.5.2",
+    "socket.io-client": "^4.5.2",
+    "web-vitals": "^2.1.4"
+  },
+  "scripts": {
+    "start": "react-scripts start",
+    "build": "react-scripts build",
+    "test": "react-scripts test",
+    "eject": "react-scripts eject"
+  },
+  "eslintConfig": {
+    "extends": [
+      "react-app",
+      "react-app/jest"
+    ]
+  },
+  "browserslist": {
+    "production": [
+      ">0.2%",
+      "not dead",
+      "not op_mini all"
+    ],
+    "development": [
+      "last 1 chrome version",
+      "last 1 firefox version",
+      "last 1 safari version"
+    ]
+  }
+}

REACT/HW 20/public/favicon.ico → Fakogram REACT project/fakogram/public/favicon.ico


REACT/HW 20/public/index.html → Fakogram REACT project/fakogram/public/index.html


REACT/HW 20/public/logo192.png → Fakogram REACT project/fakogram/public/logo192.png


REACT/HW 20/public/logo512.png → Fakogram REACT project/fakogram/public/logo512.png


REACT/HW 20/public/manifest.json → Fakogram REACT project/fakogram/public/manifest.json


REACT/HW 20/public/robots.txt → Fakogram REACT project/fakogram/public/robots.txt


+ 351 - 0
Fakogram REACT project/fakogram/src/App.css

@@ -0,0 +1,351 @@
+#root {
+    padding: 0 15px;
+}
+
+.navbar.navbar-light.bg-primary {
+  width: 1340px;
+}
+
+.formContainerLogin,
+.formContainer {
+    display: flex;
+    flex-direction: column;
+    max-width: 500px;
+    margin: 0 auto;
+    padding-top: 250px;
+    /* padding-right: 300px; */
+}
+
+.formContainer {
+    padding-top: 100px;
+}
+
+.textLogin {
+    text-align: center;
+    padding: 10px;
+}
+
+.btn-setting.btn.btn-primary {
+    margin: 20px 0;
+    width: 100%;
+}
+.d-flex.loginForm {
+    display: flex;
+    flex-direction: column;
+}
+
+.registerLink {
+    text-align: center;
+}
+
+.form-control-editing.form-control.fix {
+    margin-bottom: 20px;
+}
+.sc-bczRLJ.eHNgUP.validator {
+    margin-bottom: 20px;
+}
+
+.logo {
+    font-size: 30px;
+    text-decoration: none;
+    color: rgb(43, 31, 182);
+}
+
+.nav {
+    text-decoration: none;
+    font-size: 30px;
+}
+
+.profileContainer {
+    display: flex;
+    justify-content: center;
+}
+
+.loginNickSetting {
+    text-align: center;
+    min-width: 500px;
+    margin: 40px;
+}
+
+.passwordSetting {
+    text-align: center;
+    min-width: 500px;
+    margin: 40px;
+}
+
+.buttonSetting {
+    margin-top: 20px;
+}
+
+.textProfile {
+    text-align: center;
+}
+
+.small {
+    width: 132px;
+    height: 132px;
+    margin: 0 auto;
+    overflow: hidden;
+    border-radius: 50%;
+}
+
+.profileStyle {
+    width: 132px;
+    height: 132px;
+    margin-right: 50px;
+    overflow: hidden;
+    border-radius: 50%;
+}
+
+.smallForChat {
+    width: 60px;
+    height: 60px;
+    margin: 0 10px;
+    overflow: hidden;
+    border-radius: 50%;
+}
+
+.avatarStub {
+    width: 60px;
+    height: 60px;
+    margin: 0 10px;
+    overflow: hidden;
+    border-radius: 50%;
+    background-color: blue;
+}
+
+.loginAvatar {
+    text-align: center;
+}
+
+.chatsContainer {
+    margin: 0;
+    padding: 0;
+    min-width: 400px;
+    min-height: 94vh;
+    background-color: white;
+}
+
+.mainContainer {
+  display: flex;
+}
+
+.chatsList {
+    display: flex;
+    margin-bottom: 5px;
+    align-items: center;
+    text-decoration: none;
+    max-width: 400px;
+    padding: 10px;
+}
+.chatsList:hover {
+    background-color: lightgray;
+}
+
+.chatsList h1 {
+    font-size: 1.5rem;
+}
+
+.chatAvatarText {
+    padding: 6px;
+    color: white;
+    font-size: 30px;
+    text-align: center;
+}
+
+.chatTitle {
+    color: black;
+}
+
+.stubAvatar {
+    width: 60px;
+    height: 60px;
+    margin: 0 10px;
+    overflow: hidden;
+    border-radius: 50%;
+}
+
+.burger.navbar-toggler.collapsed {
+    margin-left: 10px;
+    background-color: blueviolet;
+}
+
+.newChatButton {
+    padding-top: 5px;
+    text-decoration: none;
+    color: white;
+    text-align: center;
+    background-color: #0d6efd;
+    font-size: 30px;
+    border-radius: 50%;
+    width: 60px;
+    height: 60px;
+    position: fixed;
+    top: 91vh;
+    left: 32.5%;
+}
+
+.df {
+    display: flex;
+    flex-direction: column;
+}
+
+.changepasLink {
+    padding-top: 20px;
+    text-decoration: none;
+    font-size: 20px;
+}
+
+.passwordSetting {
+    padding-top: 100px;
+    max-width: 400px;
+    margin: 0 auto;
+}
+
+.textProfile {
+    margin-bottom: 40px;
+}
+
+.dropZoneStyle {
+    padding-left: 10px;
+    max-width: 500px;
+    height: 150px;
+    margin: 0 auto;
+}
+
+.dropZoneStyle:hover {
+    cursor: pointer;
+}
+
+.dropZoneStyleBr {
+    padding-left: 10px;
+    max-width: 500px;
+    height: 150px;
+    margin: 0 auto;
+    border: 1px solid 0d6efd;
+}
+
+.inputContainer {
+    display: flex;
+    flex-direction: column;
+}
+
+.inputContainer label {
+    margin-bottom: 10px;
+    color: #0d6efd;
+}
+
+.inputContainer input {
+    min-height: 50px;
+    padding-left: 10px;
+    margin-bottom: 10px;
+}
+
+.changesSaved {
+    text-align: center;
+    padding-top: 200px;
+}
+
+.aboutUsStyle {
+    padding-top: 200px;
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+}
+
+.chatPageContainer {
+    display: flex;
+}
+
+.newChatContainer {
+    padding-top: 150px;
+}
+
+.chatAside {
+  list-style: none;
+  padding: 0;
+}
+
+.chatMain{
+  min-width: 100vh;
+  height: 75vh;
+  display: flex;
+  flex-direction: column;
+  /* flex-wrap: nowrap; */
+  overflow: auto;
+  padding: 20px;
+  
+}
+
+
+.msgLi {
+  max-width: 500px;
+  border: 1px solid gray;
+  margin: 10px;
+  background-color: rgb(76, 145, 199);
+  border-radius: 15px;
+  padding: 8px;
+  /* margin-left: 30vh; */
+ 
+
+}
+
+.msgsContainer{
+  display: flex;
+  justify-content: flex-end;
+}
+
+
+
+.msgOther {
+  max-width: 500px;
+  border: 1px solid gray;
+  margin: 10px;
+  background-color:rgb(244, 244, 244);
+  border-radius: 15px;
+  padding: 8px;
+
+}
+
+.chatLi ul{
+  margin-left: 10px;
+}
+
+.sendMsgBlock{
+  display: flex;
+  flex-direction: column;
+  padding-right: 30px;
+}
+
+.sendMsgBlock textarea {
+  /* margin: 20px 0px 0px 0px; */
+  padding: 10px;
+  width: 90vh;
+
+}
+
+.sendMsgBlock button {
+  margin: 20px 30px 20px 50px;
+
+  
+}
+
+.sendBlock {
+  display: flex;
+  
+}
+
+.sendBlock img {
+  margin: 20px;
+}
+
+.flexContainer{
+  margin: 0 auto;
+}
+
+.sandFile {
+  width: 30px;
+ 
+
+}
+

+ 61 - 0
Fakogram REACT project/fakogram/src/App.js

@@ -0,0 +1,61 @@
+import "./App.css";
+import "bootstrap/dist/css/bootstrap.min.css";
+import { store, socket } from "./reducers";
+import createHistory from "history/createBrowserHistory";
+import { Provider, connect } from "react-redux";
+import { Router, Route, Switch } from "react-router-dom";
+import { CLogin } from "./pages/LoginPage";
+import { CRegistration } from "./pages/RegPage";
+import Header from "./pages/Header";
+import { CProfilePage } from "./pages/ProfilePage";
+import { ChatPage, CChatsPage } from "./pages/ChatsPage";
+import { CNewChatPage } from "./pages/NewChatPage";
+import { CChangePass } from "./pages/ChangePassPage";
+import { ChangesDone } from "./pages/ChangesDonePage";
+import { ChangesDoneForChats } from './pages/ChangeDoneForChat'
+import { AboutUs } from "./pages/AboutUs";
+import { Redirect } from "react-router-dom";
+import { OneChat } from './pages/MsgPage'
+
+export const history = createHistory();
+
+function App() {
+    return (
+        <div className="container">
+            <Router history={history}>
+                <Provider store={store}>
+                    <Switch>
+                        <Route path="/login" component={() => <></>} />
+                        <Route path="/registration" component={() => <></>} />
+                        <Header />
+                    </Switch>
+                    <Route path="/login" component={CLogin} />
+                    <Route path="/registration" component={CRegistration} />
+                    <Route path="/profile" component={CProfilePage} />
+                    
+                    <Route path="/newchat" component={CNewChatPage} />
+                    <Route path="/changepas" component={CChangePass} />
+                    <Route path="/changesdone" component={ChangesDone} />
+                    <Route path="/changesdonechats" component={ChangesDoneForChats} />
+                    <Route path="/aboutus" component={AboutUs} />
+                    <div className="chatPageContainer">
+                    <Route path="/main/" component={CChatsPage} />
+                    {/* <Route path="/main/:_id" component={OneChat} /> */}
+                    </div>
+                    
+                    <Redirect
+                        to={
+                            store.getState().auth.token === undefined
+                                ? "/login"
+                                : "/main"
+                        }
+                    />
+                </Provider>
+            </Router>
+        </div>
+    );
+}
+
+
+
+export default App;

REACT/HW 20/src/App.test.js → Fakogram REACT project/fakogram/src/App.test.js


+ 124 - 0
Fakogram REACT project/fakogram/src/actions/authActions.js

@@ -0,0 +1,124 @@
+import { history } from '../App'
+import { gql } from '../helpers'
+import {
+    actionPromise,
+    actionAuthLogin,
+    actionAuthLogout,
+    actionAboutMe,
+    actionChatsClear,
+} from '../reducers'
+import { actionUploadFile } from './mediaActions'
+
+export const actionFullLogout = () => async (dispatch) => {
+    history.push('/login')
+    await dispatch(actionAuthLogout())
+    await dispatch(actionChatsClear())
+}
+
+const actionLogin = (login, password) =>
+    actionPromise(
+        'login',
+        gql(
+            `query log($login: String, $password: String) {
+         login(login: $login, password: $password)
+      }`,
+            { login, password }
+        )
+    )
+
+export const actionFullLogin = (login, password) => async (dispatch) => {
+    history.push('/main')
+    const token = await dispatch(actionLogin(login, password))
+    if (token) {
+        await dispatch(actionAuthLogin(token))
+        await dispatch(actionAboutMe())
+    }
+}
+
+const actionRegister = (login, password, nick) =>
+    actionPromise(
+        'register',
+        gql(
+            `mutation reg($user:UserInput) {
+         UserUpsert(user:$user) {
+         _id 
+         }
+      }
+      `,
+            { user: { login, password, nick } }
+        )
+    )
+
+export const actionFullRegister =
+    (login, password, nick) => async (dispatch) => {
+        const regId = await dispatch(actionRegister(login, password, nick))
+        if (regId) {
+            await dispatch(actionFullLogin(login, password))
+        }
+    }
+
+const actionUpdateUserAvatar = (userId, avatarId) =>
+    actionPromise(
+        'updateUserAv',
+        gql(
+            `mutation updateUserAv($user:UserInput) {
+         UserUpsert(user:$user) {
+            _id   
+            login  
+            nick
+            avatar {
+               url
+            }
+         }
+      }`,
+            { user: { _id: userId, avatar: { _id: avatarId } } }
+        )
+    )
+
+const actionUpdateUserLogin = (userId, newLogin, newNick) =>
+    actionPromise(
+        'updateUser',
+        gql(
+            `mutation updateUser($user:UserInput) {
+         UserUpsert(user:$user) {
+            _id   
+            login  
+            nick
+         }
+      }`,
+            { user: { _id: userId, login: newLogin, nick: newNick } }
+        )
+    )
+
+export const actionSetUserInfo =
+    (name, file, newLogin, newNick) => async (dispatch, getState) => {
+        const { auth } = getState()
+        const userId = auth.payload?.sub?.id
+        if (file) {
+            const fileObj = await dispatch(actionUploadFile(name, file))
+            await dispatch(actionUpdateUserAvatar(userId, fileObj?._id))
+        }
+        await dispatch(actionUpdateUserLogin(userId, newLogin, newNick))
+        await dispatch(actionAboutMe())
+    }
+
+const actionChangePass = (_id, password) =>
+    actionPromise(
+        'register',
+        gql(
+            `mutation reg($user:UserInput) {
+         UserUpsert(user:$user) {
+         _id 
+         }
+      }
+      `,
+            { user: { _id, password } }
+        )
+    )
+
+export const actionSetUserPass = (password) => async (dispatch, getState) => {
+    const { auth } = getState()
+    const userId = auth.payload?.sub?.id
+
+    await dispatch(actionChangePass(userId, password))
+}

+ 239 - 0
Fakogram REACT project/fakogram/src/actions/chatsActions.js

@@ -0,0 +1,239 @@
+import { history } from '../App'
+import { gql } from '../helpers'
+import {
+    actionPromise,
+    actionChatList,
+    actionChatOne,
+    actionChatLeft,
+    actionAboutMe,
+    store,
+} from '../reducers'
+import { actionGetAllLastMsg } from './msgActions'
+import { actionUploadFile } from './mediaActions'
+
+// в массив newMemders передавать объекты только с полем _id
+const actionUpdateChat = (title, members, chatId) =>
+    actionPromise(
+        'updateChat',
+        gql(
+            `mutation updateChat($chat:ChatInput) {
+      ChatUpsert(chat:$chat) {
+         _id
+         title
+         avatar {
+            _id
+            url
+         }
+         owner {
+            _id
+            login
+            avatar {
+               _id
+               url
+            }
+         }
+         members {
+            _id
+            login
+            nick
+            avatar {
+               _id
+               url
+            }
+         }
+         lastModified    
+      }
+   }`,
+            { chat: { _id: chatId, title, members } }
+        )
+    )
+
+// MediaUpsert нужен только для добавления данных для загруженного файла
+// и дальнейшего отображения его через эти данные (через аватары, сообщения)
+const actionUpdateChatAvatar = (mediaId, chatId) =>
+    actionPromise(
+        'uploadFile',
+        gql(
+            `mutation uploadFile($media: MediaInput) {  
+        MediaUpsert(media: $media) {
+            _id
+            url   
+        }
+    }`,
+            { media: { _id: mediaId, chatAvatars: { _id: chatId } } }
+        )
+    )
+
+export const actionSetChatInfo =
+    (name, file, title, members, chatId) => async (dispatch) => {
+        const chat = await dispatch(actionUpdateChat(title, members, chatId))
+
+        if (file && chat._id) {
+            const fileObj = await dispatch(actionUploadFile(name, file))
+            const chatAvatar = await dispatch(
+                actionUpdateChatAvatar(fileObj?._id, chat._id)
+            )
+            await dispatch(actionChatOne({ _id: chat._id, avatar: chatAvatar }))
+        }
+    }
+
+// поиск по значению в массиве объектов - { 'members._id': userId }
+export const actionGetChatsByUser = (userId, skipCount = 0, limitCount = 50) =>
+    actionPromise(
+        'userChats',
+        gql(
+            `query userChats($q: String) {
+      ChatFind (query: $q){
+         _id
+         title
+         avatar {
+            _id
+            url
+         }
+         owner {
+            _id
+            login
+            avatar {
+               _id
+               url
+            }
+         }
+         members {
+            _id
+            login
+            nick
+            avatar {
+               _id
+               url
+            }
+         }
+         lastModified
+      }     
+   }`,
+            {
+                q: JSON.stringify([
+                    {
+                        $or: [{ ___owner: userId }, { 'members._id': userId }],
+                    },
+                    {
+                        sort: [{ lastModified: -1 }],
+                        skip: [skipCount],
+                        limit: [limitCount],
+                    },
+                ]),
+            }
+        )
+    )
+
+export const actionFullChatList =
+    (userId, currentCount, limitCount = 50) =>
+    async (dispatch) => {
+        const payload = await dispatch(
+            actionGetChatsByUser(userId, currentCount, limitCount)
+        )
+        if (payload) {
+            await dispatch(actionChatList(payload))
+
+            await dispatch(actionGetAllLastMsg(payload))
+        }
+    }
+
+export const actionGetChatById = (chatId) =>
+    actionPromise(
+        'chatById',
+        gql(
+            `query chatById($q: String) {
+      ChatFindOne (query: $q){
+         _id
+         title
+         avatar {
+            _id
+            url
+         }
+         owner {
+            _id
+            login
+            avatar {
+               _id
+               url
+            }
+         }
+         members {
+            _id
+            login
+            nick
+            avatar {
+               _id
+               url
+            }
+         }
+         lastModified
+         
+         
+      }     
+   }`,
+            {
+                q: JSON.stringify([{ _id: chatId }]),
+            }
+        )
+    )
+
+export const actionChatsCount = (userId) =>
+    actionPromise(
+        'chatsCount',
+        gql(
+            `query chatsCount($q: String) {
+      ChatCount (query: $q)  
+   }`,
+            {
+                q: JSON.stringify([{ ___owner: userId }]),
+            }
+        )
+    )
+
+// происходит когда юзер уходит сам, иначе в чат добавляются юзер, а не наоборот
+const actionUpdateUserChats = (userId, newChats) =>
+    actionPromise(
+        'updateUserChats',
+        gql(
+            `mutation updateUserChats($user:UserInput) {
+      UserUpsert(user:$user) {
+         _id   
+         login  
+         nick
+         chats {
+            title
+            _id
+         }
+      }
+   }`,
+            { user: { _id: userId, chats: newChats } }
+        )
+    )
+
+export const removeUserChat = (chatId) => async (dispatch, getState) => {
+    const state = getState()
+    const myId = state.promise.myProfile.payload._id
+    const oldChats = state.promise.myProfile.payload.chats
+
+    const newChats = oldChats.filter((chat) => chat._id !== chatId)
+    await dispatch(actionUpdateUserChats(myId, newChats))
+
+    const ownerId = state.chats[chatId]?.owner?._id
+    // тут событие ухода из чата не приходит по сокету,
+    // поэтому нужно делать все то, что и в сокете
+
+    if (myId !== ownerId) {
+        dispatch(actionChatLeft({ _id: chatId }))
+        const [, , histId] = history.location.pathname.split('/')
+        if (histId === chatId) {
+            history.push('/')
+        }
+    } else {
+        const chat = await dispatch(actionGetChatById(chatId))
+        await dispatch(actionChatOne(chat))
+    }
+
+    await dispatch(actionAboutMe())
+}
+

+ 90 - 0
Fakogram REACT project/fakogram/src/actions/findActions.js

@@ -0,0 +1,90 @@
+import { gql } from '../helpers'
+import { actionPromise } from '../reducers'
+
+export const actionFindUsers = (text, skipCount = 0, limitCount = 20) =>
+    actionPromise(
+        'findUsers',
+        gql(
+            `query findUsers($q: String) {
+      UserFind (query: $q){
+         _id
+         createdAt
+         login
+         nick
+         avatar {
+            _id
+            url
+         }
+      }     
+   }`,
+            {
+                q: JSON.stringify([
+                    {
+                        $or: [{ login: `/${text}/` }, { nick: `/${text}/` }],
+                    },
+                    {
+                        sort: [{ login: 1 }],
+                        skip: [skipCount],
+                        limit: [limitCount],
+                    },
+                ]),
+            }
+        )
+    )
+
+// поиск чатов конкретного юзера по названию
+export const actionFindChatsByUser = (
+    userId,
+    word,
+    skipCount = 0,
+    limitCount = 20
+) =>
+    actionPromise(
+        'findChatsByUser',
+        gql(
+            `query findChatsByUser($q: String) {
+      ChatFind (query: $q){
+         _id
+         _id
+         title
+         avatar {
+            _id
+            url
+         }
+         owner {
+            _id
+            login
+            avatar {
+               _id
+               url
+            }
+         }
+         members {
+            _id
+            login
+            nick
+            avatar {
+               _id
+               url
+            }
+         }
+         lastModified  
+      }     
+   }`,
+            {
+                q: JSON.stringify([
+                    {
+                        title: `/${word}/`,
+                        $or: [{ ___owner: userId }, { 'members._id': userId }],
+                    },
+                    {
+                        sort: [{ title: 1 }],
+                        skip: [skipCount],
+                        limit: [limitCount],
+                    },
+                ]),
+            }
+        )
+    )
+
+// можно добавить еще поиск чатов по мемберам

+ 52 - 0
Fakogram REACT project/fakogram/src/actions/index.js

@@ -0,0 +1,52 @@
+import {
+    actionFullLogout,
+    actionFullLogin,
+    actionFullRegister,
+    actionSetUserInfo,
+    actionSetUserPass,
+} from "./authActions";
+import { actionOnMsg, actionOnChat, actionOnChatLeft } from "./socketActions";
+import {
+    actionSetChatInfo,
+    actionGetChatsByUser,
+    actionFullChatList,
+    actionGetChatById,
+    actionChatsCount,
+    removeUserChat,
+} from "./chatsActions";
+import { actionFindUsers, actionFindChatsByUser } from "./findActions";
+import { actionUploadFile } from "./mediaActions";
+import {
+    actionGetMsgsByChat,
+    actionFullMsgsByChat,
+    actionGetAllLastMsg,
+    actionMsgsCount,
+    actionGetMsgById,
+    actionSendMsg,
+} from "./msgActions";
+
+export {
+    actionFullLogout,
+    actionFullLogin,
+    actionFullRegister,
+    actionSetUserInfo,
+    actionSetUserPass,
+    actionOnMsg,
+    actionOnChat,
+    actionOnChatLeft,
+    actionSetChatInfo,
+    actionGetChatsByUser,
+    actionFullChatList,
+    actionGetChatById,
+    actionChatsCount,
+    removeUserChat,
+    actionFindUsers,
+    actionFindChatsByUser,
+    actionUploadFile,
+    actionGetMsgsByChat,
+    actionFullMsgsByChat,
+    actionGetAllLastMsg,
+    actionMsgsCount,
+    actionGetMsgById,
+    actionSendMsg,
+};

+ 16 - 0
Fakogram REACT project/fakogram/src/actions/mediaActions.js

@@ -0,0 +1,16 @@
+import { actionPromise } from '../reducers'
+
+export const actionUploadFile = (name, file) => {
+    const fd = new FormData()
+    fd.append(name, file)
+    return actionPromise(
+        'uploadFile',
+        fetch('http://chat.ed.asmer.org.ua/upload', {
+            method: 'POST',
+            headers: localStorage.authToken
+                ? { Authorization: 'Bearer ' + localStorage.authToken }
+                : {},
+            body: fd,
+        }).then((res) => res.json())
+    )
+}

+ 289 - 0
Fakogram REACT project/fakogram/src/actions/msgActions.js

@@ -0,0 +1,289 @@
+import { gql } from '../helpers'
+import {
+    actionPromise,
+    actionMsgList,
+    actionMsgOne,
+    actionChatOne,
+    store,
+} from '../reducers'
+import { actionUploadFile } from './mediaActions'
+
+export const actionGetMsgsByChat = (chatId, skipCount = 0, limitCount = 50) =>
+    actionPromise(
+        'chatMsgs',
+        gql(
+            `query chatMsgs($q: String) {
+      MessageFind (query: $q){
+         _id
+         createdAt
+         owner {
+            _id
+            login
+            nick
+            avatar {
+               url
+            }
+         }
+         text
+         chat {
+            _id
+         }
+         media {
+            _id
+            url
+            type
+            originalFileName            
+         }
+
+         forwardWith {
+            _id
+         }
+         replies {
+            _id
+         }
+
+         replyTo {
+            _id
+         }
+         forwarded {
+            _id
+         }
+      }     
+   }`,
+            {
+                q: JSON.stringify([
+                    { 'chat._id': { $in: [chatId] } },
+                    {
+                        sort: [{ _id: -1 }],
+                        skip: [skipCount],
+                        limit: [limitCount],
+                    },
+                ]),
+            }
+        )
+    )
+
+export const actionFullMsgsByChat =
+    (chatId, currentCount, limitCount = 50) =>
+    async (dispatch, getState) => {
+        const chat = getState().chats[chatId]
+
+        if (
+            !chat ||
+            !chat.messages ||
+            (chat.messages[0]?._id !== chat.firstMsgId &&
+                (chat.messages?.length ?? 0) < currentCount + limitCount)
+        ) {
+
+            const payload = await dispatch(
+                actionGetMsgsByChat(chatId, currentCount, limitCount)
+            )
+            if (payload) {
+                await dispatch(actionMsgList(payload))
+            }
+        }
+    }
+
+const actionFirstMsgByChat = (chatId) =>
+    actionPromise(
+        'firstMsg',
+        gql(
+            `query firstMsg($q: String) {
+      MessageFind (query: $q){
+         _id
+      }     
+   }`,
+            {
+                q: JSON.stringify([
+                    { 'chat._id': chatId },
+                    {
+                        sort: [{ _id: 1 }],
+                        skip: [0],
+                        limit: [1],
+                    },
+                ]),
+            }
+        )
+    )
+
+export const actionGetAllLastMsg = (chats) => async (dispatch, getState) => {
+    const msgReq = chats.map((chat) =>
+        Promise.all([
+            dispatch(actionGetMsgsByChat(chat._id, 0, 1)),
+
+            getState().chats[chat._id]?.firstMsgId
+                ? Promise.resolve([])
+                : dispatch(actionFirstMsgByChat(chat._id)),
+        ])
+    )
+
+    for await (const [lastMsgs, firstMsgs] of msgReq) {
+        lastMsgs.length && dispatch(actionMsgOne(lastMsgs[0]))
+        firstMsgs.length &&
+            dispatch(
+                actionChatOne({
+                    _id: lastMsgs[0].chat._id,
+                    firstMsgId: firstMsgs[0]._id,
+                })
+            )
+    }
+}
+
+export const actionMsgsCount = (chatId) =>
+    actionPromise(
+        'msgsCount',
+        gql(
+            `query msgsCount($q: String) {
+      MessageCount (query: $q)  
+   }`,
+            {
+                q: JSON.stringify([{ 'chat._id': chatId }]),
+            }
+        )
+    )
+
+export const actionGetMsgById = (msgId) =>
+    actionPromise(
+        'msgById',
+        gql(
+            `query msgById($q: String) {
+      MessageFindOne (query: $q){
+         _id
+         createdAt
+         owner {
+            _id
+            login
+            nick
+            avatar {
+               url
+            }
+         }
+         text
+         chat {
+            _id
+         }
+         media {
+            _id
+            url
+            type
+            originalFileName            
+         }
+
+         forwardWith {
+            _id
+         }
+         replies {
+            _id
+         }
+
+         replyTo {
+            _id
+         }
+         forwarded {
+            _id
+         }
+      }     
+   }`,
+            {
+                q: JSON.stringify([{ _id: msgId }]),
+            }
+        )
+    )
+
+const actionUpdateMsg = (chatId, text, media, msgId) =>
+    actionPromise(
+        'updateMsg',
+        gql(
+            `mutation updateMsg($msg: MessageInput) {
+      MessageUpsert(message: $msg) {
+         _id
+         createdAt
+         owner {
+            _id
+            login
+            nick
+            avatar {
+               url
+            }
+         }
+         text
+         chat {
+            _id
+         }
+         media {
+            _id
+            url
+            type
+            originalFileName            
+         }
+
+
+         forwardWith {
+            _id
+         }
+         replies {
+            _id
+         }
+
+         replyTo {
+            _id
+         }
+         forwarded {
+            _id
+         }
+      }
+   }`,
+            {
+                msg: {
+                    _id: msgId,
+                    text,
+                    chat: { _id: chatId },
+                    media,
+                    // replyTo: {_id: undefined}
+                },
+            }
+        )
+    )
+
+// медиа - массив объектов с ид медиа
+export const actionSendMsg =
+    (chatId, text, inputName, files, msgId) => async (dispatch) => {
+        // тут нужно отделить уже залитые файлы от тех которые лежат локально
+        // локальные залить и получить ид, с залитых просто получить ид
+        const mediaToUpload = []
+        const media = []
+        for (const file of files) {
+            if (file.url.match(/blob/)) {
+                mediaToUpload.push(dispatch(actionUploadFile(inputName, file)))
+            } else {
+                let fileObj = file
+                media.push({ _id: fileObj?._id })
+            }
+        }
+
+        const fileArr = await Promise.all(mediaToUpload)
+        if (fileArr) {
+            for (const uploadedFile of fileArr) {
+                media.push({ _id: uploadedFile?._id })
+            }
+        }
+
+        const payload = await dispatch(
+            actionUpdateMsg(chatId, text, media, msgId)
+        ) // eslint-disable-line
+        // if (payload) {
+        //    await dispatch(actionMsgOne(payload))
+        //    let chatUpdated = await dispatch(actionGetChatById(chatId))
+        //    await dispatch(actionChatOne(chatUpdated))
+        // }
+    }
+
+// const actionRemoveMsg = (msgId) => (
+//    actionPromise('removeMsg', gql(`mutation removeMsg($msg: MessageInput) {
+//       MessageDelete(message: $msg) {
+//          _id
+//       }
+//    }`, { msg: { _id: msgId } }
+//    ))
+// )
+

+ 70 - 0
Fakogram REACT project/fakogram/src/actions/socketActions.js

@@ -0,0 +1,70 @@
+import { history } from "../App";
+import {
+    actionAboutMe,
+    actionMsgOne,
+    actionMsgList,
+    actionChatOne,
+    actionChatLeft,
+} from "../reducers";
+
+import { actionGetMsgsByChat, actionGetMsgById, actionGetChatById } from ".";
+
+
+
+// данные из сокета приходят не полные,
+// поэтому потом приходится затягивать доп данные из графа
+
+export const actionOnMsg = (msg) => async (dispatch, getState) => {
+    const state = getState();
+    const myId = state.auth.payload?.sub?.id;
+    const ownerId = msg.owner?._id;
+
+    const chatId = msg.chat?._id;
+
+    await dispatch(actionMsgOne(msg));
+
+    const msgFull = await dispatch(actionGetMsgById(msg._id));
+    await dispatch(actionMsgOne(msgFull));
+
+    const chatUpdated = await dispatch(actionGetChatById(chatId));
+    await dispatch(actionChatOne(chatUpdated));
+};
+
+export const actionOnChat = (chat) => async (dispatch, getState) => {
+    const state = getState();
+    const myId = state.auth.payload?.sub?.id;
+    // приходится делать так, так как овнер не приходит по сокету
+    const ownerId = state.chats[chat._id]?.owner?._id;
+
+    dispatch(actionChatOne(chat));
+
+    const chatFull = await dispatch(actionGetChatById(chat._id));
+    await dispatch(actionChatOne(chatFull));
+
+    const chatMsgs = await dispatch(actionGetMsgsByChat(chat._id));
+    await dispatch(actionMsgList(chatMsgs));
+
+    await dispatch(actionAboutMe());
+};
+
+export const actionOnChatLeft = (chat) => async (dispatch, getState) => {
+    const state = getState();
+    const myId = state.auth.payload?.sub?.id;
+    const ownerId = state.chats[chat._id]?.owner?._id;
+
+    // если чат чужой, то удаляем его и апдейтим роутер
+    // если мой, то просто обновляем статус чата
+    if (myId !== ownerId) {
+        dispatch(actionChatLeft(chat));
+        const [, , histId] = history.location.pathname.split("/");
+        if (histId === chat._id) {
+            history.push("/");
+        }
+    } else {
+        dispatch(actionChatOne(chat));
+        const chatFull = await dispatch(actionGetChatById(chat._id));
+        await dispatch(actionChatOne(chatFull));
+    }
+
+    await dispatch(actionAboutMe());
+};

+ 40 - 0
Fakogram REACT project/fakogram/src/components/Avatar.js

@@ -0,0 +1,40 @@
+import React from "react";
+import { connect } from "react-redux";
+import { backURL } from "../constants";
+
+function getUrl(obj) {
+    if (obj.avatar?.url) {
+        return backURL + obj.avatar?.url;
+    } else {
+        return false;
+    }
+}
+
+export const UserAvatar = ({ profile, text = "", className = "small" }) => {
+    return (
+        <>
+            <div style={{display: "flex", alignItems: 'center'}}>
+                <img className={className} src={getUrl(profile)} />
+                <p>{text}</p>
+            </div>
+            
+        </>
+    );
+};
+
+export const CMyAvatar = connect((state) => ({
+    profile: state.promise.myProfile?.payload || {},
+}))(UserAvatar);
+
+export const ChatAvatar = ({ chat, className = "small" }) => {
+    return (
+        <>
+            <div className={className} style={{backgroundColor: "gray"}}></div>
+        </>
+    )
+}
+
+export const CChatAvatar = connect((state) => ({
+    profile: state.promise.userChats?.payload || {},
+}))(UserAvatar);
+

+ 16 - 0
Fakogram REACT project/fakogram/src/components/AvatarStub.js

@@ -0,0 +1,16 @@
+import React from "react";
+
+const r = () => Math.floor(Math.random() * 256);
+const g = () => Math.floor(Math.random() * 256);
+const b = () => Math.floor(Math.random() * 256);
+export const color = () => {
+    return "#" + r().toString(16) + g().toString(16) + b().toString(16);
+};
+
+export const AvatarStub = (props) => {
+    return (
+        <div className="stubAvatar" style={{backgroundColor: props.color}}>
+            <p className="chatAvatarText">{((props.login).split(' ').map(function(item){return item[0]}).join(''))}</p>
+        </div>
+    );
+};

+ 16 - 0
Fakogram REACT project/fakogram/src/components/LogoutBtn.js

@@ -0,0 +1,16 @@
+import React from 'react'
+import { connect } from 'react-redux'
+import Button from 'react-bootstrap/esm/Button'
+import { Link } from 'react-router-dom'
+
+import { actionFullLogout } from '../actions'
+
+const LogoutBtn = ({ onLogout }) => (
+    <>
+        <Link className='nav' to='/login' onClick={() => onLogout()}>Sign Out</Link>
+    </>
+)
+
+export const CLogoutBtn = connect(null, { onLogout: actionFullLogout })(
+    LogoutBtn
+)

+ 11 - 0
Fakogram REACT project/fakogram/src/components/NickName.js

@@ -0,0 +1,11 @@
+import React from "react";
+import { connect } from "react-redux";
+
+const NickName = ({ nick, login }) => (
+    <>
+        <h2>{nick}</h2>
+        <p>{login}</p>
+    </>
+);
+export const CNickName = connect((state) => ({nick: state.promise?.myProfile?.payload?.nick || " ", login: state.promise?.myProfile?.payload?.login || " "}))(NickName);
+

+ 74 - 0
Fakogram REACT project/fakogram/src/components/SendMsg.js

@@ -0,0 +1,74 @@
+import React, { useState, useEffect } from 'react'
+import Button from 'react-bootstrap/esm/Button'
+import { connect } from 'react-redux'
+
+
+// import { MsgDropZone } from './MsgDropZone'
+import { actionSendMsg } from '../actions'
+import { backURL } from '../constants'
+
+const SendingField = ({ chatId, onSend, msg }) => {
+    const [text, setText] = useState(msg?.text || '')
+    const [files, setFiles] = useState(
+        msg?.media.map((mediaFile) => ({
+            ...mediaFile,
+            url: backURL + mediaFile.url,
+        })) || []
+    )
+    const [msgId, setMsgId] = useState(msg?._id || null)
+
+    useEffect(() => {
+        setText(msg?.text || '')
+        setFiles(
+            msg?.media.map((mediaFile) => ({
+                ...mediaFile,
+                url: backURL + mediaFile.url,
+            })) || []
+        )
+        setMsgId(msg?._id || null)
+    }, [msg])
+
+    return (
+        <div className="sendingField">
+            <div className="buttonSendBox">
+            
+                        <div className="sendBlock">
+                            <img src="https://img.icons8.com/ios-filled/344/folder-invoices--v2.png" className="sandFile"/>
+                            <textarea placeholder="Write a message..." rows="2"  value={text} onChange={(e) => setText(e.target.value)}/>
+                        </div>
+                        
+                        <Button 
+                        endIcon={"@"}
+                        onClick={() => {
+                            ;(text.match(/^\s*$/) && files.length === 0) ||
+                                onSend(chatId, text.trim(), 'media', files, msgId)
+                            setText('')
+                            setFiles([])
+                            setMsgId()
+                        }}
+                        >Send a message</Button>
+                    
+                <Button
+                    className="buttonSend"
+                    variant="contained"
+                    endIcon={"@"}
+                    onClick={() => {
+                        ;(text.match(/^\s*$/) && files.length === 0) ||
+                            onSend(chatId, text.trim(), 'media', files, msgId)
+                        setText('')
+                        setFiles([])
+                        setMsgId()
+                    }}
+                >
+                    Отправить
+                </Button>
+            </div>
+        </div>
+    )
+}
+
+
+
+export const CSendingField = connect(null, { onSend: actionSendMsg })(
+    SendingField
+)

+ 1 - 0
Fakogram REACT project/fakogram/src/constants.js

@@ -0,0 +1 @@
+export const backURL = 'http://chat.ed.asmer.org.ua/'

+ 112 - 0
Fakogram REACT project/fakogram/src/helpers/UserSearch.js

@@ -0,0 +1,112 @@
+import React, { useState, useEffect, useRef } from "react";
+import { actionFindUsers } from '../actions'
+import {store} from '../reducers'
+import { connect } from "react-redux";
+
+
+const UserSearch = ({
+    findedUsers,
+    onSearch,
+    alreadySearched = [],
+    onAdd,
+    open,
+}) => {
+    const [finded, setFinded] = useState([])
+    const [input, setInput] = useState(null)
+
+    useEffect(() => {
+        let timeout
+        if (input !== null) {
+            timeout = setTimeout(() => {
+                onSearch(input)
+            }, 500)
+        }
+        return () => {
+            clearTimeout(timeout)
+        }
+    }, [input])
+
+    useEffect(() => {
+        setFinded(findedUsers)
+    }, [findedUsers])
+
+    useEffect(() => {
+        setInput(null)
+        setFinded([])
+    }, [open])
+
+    return (
+        <div className="userSearchBox">
+            <div className="searchField">
+                <input setInput={setInput} text={'Найти пользователя'} />
+            </div>
+
+            <div className="usersBox">
+                <div className="usersList">
+                    {finded.map((user) => (
+                        <input
+                            key={user._id}
+                            user={user}
+                            
+                            onAction={() => onAdd(user)}
+                            disabled={
+                                !!alreadySearched.find(
+                                    (searchedUser) =>
+                                        searchedUser._id === user._id
+                                )
+                            }
+                        />
+                    ))}
+                </div>
+            </div>
+        </div>
+    )
+}
+
+const useLocalStoredState = (defaultState, localStorageKey) => {
+    const json = localStorage[localStorageKey];
+
+    try {
+        defaultState = JSON.parse(json);
+    } catch (e) {}
+
+    const [state, setState] = useState(defaultState);
+
+    localStorage.setItem(localStorageKey, JSON.stringify(state));
+
+    return [state, setState];
+};
+
+export const Input = () => {
+    const [text, setText] = useLocalStoredState(" ", "inputText");
+
+    return <input value={text} onChange={(e) => setText(e.target.value)} />;
+};
+
+const ThemeContext = React.createContext();
+
+export const InputDebounce = ({}) => {
+    const [text, setText] = useState("");
+
+    const timeoutRef = useRef();
+
+    useEffect(() => {
+        clearInterval(timeoutRef.current);
+
+        if (text)
+            timeoutRef.current = setTimeout(
+                () => console.log(store.dispatch(actionFindUsers())),
+                2000
+            );
+    }, [text]);
+
+    return <input value={text} onChange={(e) => setText(e.target.value)} />;
+};
+
+
+export const CUserSearch = connect(
+    (state) => ({ findedUsers: state.promise.findUsers?.payload || [] }),
+    { onSearch: actionFindUsers }
+)(InputDebounce)
+
+

+ 24 - 0
Fakogram REACT project/fakogram/src/helpers/getGql.js

@@ -0,0 +1,24 @@
+import { backURL } from '../constants'
+
+const getGQL =
+    (url) =>
+    async (query, variables = {}) => {
+        const incomingData = await fetch(url, {
+            method: 'POST',
+            headers: {
+                'Content-Type': 'application/json',
+                ...(localStorage.authToken
+                    ? { Authorization: 'Bearer ' + localStorage.authToken }
+                    : {}),
+            },
+            body: JSON.stringify({ query, variables }),
+        })
+        const obj = await incomingData.json()
+        if (!obj.data && obj.errors) {
+            throw new Error(JSON.stringify(obj.errors))
+        } else {
+            return obj.data[Object.keys(obj.data)[0]]
+        }
+    }
+
+export const gql = getGQL(backURL + 'graphql')

+ 6 - 0
Fakogram REACT project/fakogram/src/helpers/index.js

@@ -0,0 +1,6 @@
+import { gql } from './getGql'
+import {authLoginValidator} from './redirect'
+
+
+
+export { gql, authLoginValidator }

+ 10 - 0
Fakogram REACT project/fakogram/src/helpers/passValidator.js

@@ -0,0 +1,10 @@
+export const passValidator = (password, passwordAgain, n = "8") => {
+    if (password === passwordAgain) {
+        return (
+            password.length >= n &&
+            (/[a-zа-яё]/ && /[A-ZА-ЯЁ]/ && /[\d]/).test(password)
+        );
+    } else {
+        return false
+    }
+};

+ 5 - 0
Fakogram REACT project/fakogram/src/helpers/redirect.js

@@ -0,0 +1,5 @@
+import { connect } from "react-redux";
+import { store } from "../reducers";
+
+export const authLoginValidator = () => store.getState().auth.token
+

REACT/HW 20/src/index.css → Fakogram REACT project/fakogram/src/index.css


+ 17 - 0
Fakogram REACT project/fakogram/src/index.js

@@ -0,0 +1,17 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+
+const root = ReactDOM.createRoot(document.getElementById('root'));
+root.render(
+  
+    <App />
+  
+);
+
+// If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+reportWebVitals();

REACT/HW 20/src/logo.svg → Fakogram REACT project/fakogram/src/logo.svg


+ 16 - 0
Fakogram REACT project/fakogram/src/pages/AboutUs.js

@@ -0,0 +1,16 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+export const AboutUs = () => {
+    return(
+        <div className="aboutUsStyle">
+            <h2>
+            Contacts of the creator this wonderful project:
+            </h2>
+            <a className='nav' target="_blank" href="https://t.me/ilunya_kozyr">Telegram</a>
+            <a className='nav' target="_blank" href="mailto:ilunya.kozyr@gmail.com">Email</a>
+            <a className='nav' target="_blank" href="https://github.com/IlliaKozyr">GitHub</a>
+            <a className='nav' target="_blank" href="https://linkedin.com/in/ilunya-kozyr">Linkedin</a>
+        </div>
+    )
+}

+ 14 - 0
Fakogram REACT project/fakogram/src/pages/ChangeDoneForChat.js

@@ -0,0 +1,14 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+export const ChangesDoneForChats = () => {
+    return (
+        <div className="changesSaved">
+            <h1>Changes saved ✔</h1>
+
+            <Link to="/main/" className="changepasLink">
+                Back to all chats
+            </Link>
+        </div>
+    );
+};

+ 81 - 0
Fakogram REACT project/fakogram/src/pages/ChangePassPage.js

@@ -0,0 +1,81 @@
+import React, { useState } from "react";
+import FloatingLabel from "react-bootstrap/FloatingLabel";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/esm/Button";
+import { Link } from "react-router-dom";
+import { actionSetUserPass } from "../actions";
+import { connect } from "react-redux";
+import PasswordChecklist from "react-password-checklist";
+import { passValidator } from "../helpers/passValidator";
+
+const ChangePass = ({ onPassword, minLength = "5" }) => {
+    const [password, setPassword] = useState("");
+    const [passwordAgain, setPasswordAgain] = useState("");
+    return (
+        <div className="passwordSetting">
+            <h1 className="textProfile">Change password</h1>
+            <div className="inputContainer">
+                <label for="passwordInput">Enter a new password: </label>
+                <input
+                    className="form-control-editing form-control"
+                    id="passwordInput"
+                    type="password"
+                    value={password}
+                    onChange={(e) => {
+                        setPassword(e.target.value);
+                    }}
+                />
+            </div>
+
+            <div className="inputContainer">
+                <label for="passwordAgainInput">
+                    Re-enter the new password:
+                </label>
+                <input
+                    className="form-control-editing form-control"
+                    id="passwordAgainInput"
+                    type="password"
+                    value={passwordAgain}
+                    onChange={(e) => {
+                        setPasswordAgain(e.target.value);
+                    }}
+                />
+            </div>
+            <PasswordChecklist
+                rules={["minLength", "number", "capital", "match"]}
+                className="validator"
+                minLength={8}
+                value={password}
+                valueAgain={passwordAgain}
+                onChange={(isValid) => {}}
+            />
+
+            <div className="df">
+                <Button
+                    variant="primary"
+                    className="buttonSetting"
+                    onClick={() => {
+                        onPassword(password);
+                        console.log(password, passwordAgain);
+                    }}
+                    disabled={!passValidator(password, passwordAgain)}
+                >
+                    <Link
+                        to="/changesdone"
+                        style={{ color: "white", textDecoration: "none" }}
+                    >
+                        Apply Changes
+                    </Link>
+                </Button>
+
+                <Link to="/profile" className="changepasLink">
+                    Back to profile
+                </Link>
+            </div>
+        </div>
+    );
+};
+
+export const CChangePass = connect(null, { onPassword: actionSetUserPass })(
+    ChangePass
+);

+ 14 - 0
Fakogram REACT project/fakogram/src/pages/ChangesDonePage.js

@@ -0,0 +1,14 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+export const ChangesDone = () => {
+    return (
+        <div className="changesSaved">
+            <h1>Changes saved ✔</h1>
+
+            <Link to="/profile" className="changepasLink">
+                Back to profile
+            </Link>
+        </div>
+    );
+};

+ 210 - 0
Fakogram REACT project/fakogram/src/pages/ChatsPage.js

@@ -0,0 +1,210 @@
+import React, { useState, useEffect } from "react";
+import { connect } from "react-redux";
+import { backURL } from "../constants";
+import { Link } from "react-router-dom";
+import { AvatarStub, color } from "../components/AvatarStub";
+import { actionFullMsgsByChat } from "../actions";
+import { actionUserFindOne, store } from "../reducers";
+import { OneChat } from "./MsgPage";
+import Button from "react-bootstrap/esm/Button";
+import { CSendingField } from "../components/SendMsg";
+
+// const ChatsPage = ({ chats = [], }) => {
+//     return (
+//         <>
+//             <div className="chatsContainer">
+//                 {chats.map((chat, _id) => (
+//                     <>
+
+//                         <Link className="chatsList"  to={`/main/${chat._id}`}>
+//                             {chat.avatar?.url ? (
+//                                 <img
+//                                     className="smallForChat"
+//                                     src={backURL + chat.avatar?.url}
+//                                 />
+//                             ) : (
+//                                 <AvatarStub
+//                                     login={
+//                                         chat.title !== null
+//                                             ? chat.title
+//                                             : "chat without title"
+//                                     }
+//                                     color={color()}
+//                                 />
+//                             )}
+//                             <h5 className="chatTitle">
+//                                 {chat.title !== null
+//                                     ? chat.title
+//                                     : "chat without title"}
+//                             </h5>
+
+//                         </Link>
+//                     </>
+//                 ))}
+//                 <Link className="newChatButton" to="/newchat">
+//                     +
+//                 </Link>
+//             </div>
+//             <div>
+//                 {chats.map((chat) =>  <CChatList chatId={chat._id} chat={chat.messages} key={chat._id}/>)}
+
+//             </div>
+//         </>
+//     );
+// };
+
+// export const CChatsPage = connect(
+//     (state) => ({
+//         chats: Object.values(state.chats).filter((el) => el._id),
+//         // chat_Id: state.promise
+//     }),
+// )(ChatsPage);
+
+export const ChatPage = ({
+    match: {
+        params: { _id = store.getState().auth?.payload?.sub.id },
+    },
+    chats,
+    getData,
+    userName,
+}) => {
+    const [chatList, setChatList] = useState(chats || []);
+    const [messageList, setMessageList] = useState([]);
+
+    useEffect(() => {
+        async function getDataFunc() {
+            const res = await getData(_id);
+
+            setChatList(res.chats);
+            setMessageList(res.chats?.message);
+        }
+
+        getDataFunc();
+    }, [_id]);
+
+    const StrValid = "30";
+
+    function handleClick(_id) {
+        const filteredChatList = chatList.filter((item) => item._id === _id);
+        setMessageList(filteredChatList[0].messages);
+    }
+
+    return (
+        <>
+            <div className="mainContainer">
+                <aside className="chatsContainer">
+                    <ul className="chatAside">
+                        {chatList.map((item, index) => (
+                            <Link
+                                className="chatsList"
+                                to={`/main/${item._id}`}
+                                key={item._id}
+                            >
+                                {item.avatar?.url ? (
+                                    <img
+                                        className="smallForChat"
+                                        src={backURL + item.avatar?.url}
+                                    />
+                                ) : (
+                                    <AvatarStub
+                                        login={
+                                            item.title !== null
+                                                ? item.title
+                                                : "chat without title"
+                                        }
+                                        color={color()}
+                                    />
+                                )}
+                                <li
+                                    onClick={() => handleClick(item._id)}
+                                    className="chatLi"
+                                    key={item._id}
+                                >
+                                    <h4>{item.title}</h4>
+                                    <h6>
+                                        {item.lastMessage?.text.length >
+                                        parseInt(StrValid)
+                                            ? item.lastMessage?.text.substr(
+                                                  0,
+                                                  30
+                                              ) + "..."
+                                            : item.lastMessage?.text.substr(
+                                                  0,
+                                                  30
+                                              )}
+                                    </h6>
+                                </li>
+                            </Link>
+                        ))}
+                    </ul>
+                    <Link className="newChatButton" to="/newchat">
+                        +
+                    </Link>
+                </aside>
+                <div className="flexContainer">
+                    <main className="chatMain" id="chatMain">
+                        {messageList && messageList.length > 0 && (
+                            <div className="chatMain">
+                                {messageList.map((item1, index) => (
+                                    <div
+                                        className={
+                                            item1.owner.nick ===
+                                            store.getState().promise.myProfile
+                                                .payload.nick
+                                                ? "msgsContainer"
+                                                : "msgOtherContainer"
+                                        }
+                                    >
+                                        <div
+                                            className={
+                                                item1.owner.nick ===
+                                                store.getState().promise
+                                                    .myProfile.payload.nick
+                                                    ? "msgLi"
+                                                    : "msgOther"
+                                            }
+                                            key={index}
+                                        >
+                                            <h6>{item1.owner.nick}</h6>
+                                            <p>
+                                                {item1.text
+                                                    ? item1.text
+                                                    : "No messages"}
+                                            </p>
+                                        </div>
+                                    </div>
+                                ))}
+                            </div>
+                        )}
+                    </main>
+                    {messageList === undefined ? (
+                        <></>
+                    ) : (
+                        <div className="sendMsgBlock">
+                            <div className="sendBlock">
+                                <img
+                                    src="https://img.icons8.com/ios-filled/344/folder-invoices--v2.png"
+                                    className="sandFile"
+                                />
+                                <textarea
+                                    placeholder="Write a message..."
+                                    rows="2"
+                                />
+                            </div>
+
+                            <Button>Send a message</Button>
+                        </div>
+                    )}
+                </div>
+            </div>
+        </>
+    );
+};
+
+export const CChatsPage = connect(
+    (state) => ({
+        chats: state.promise.myProfile?.chats,
+        // _id: state.auth?.payload?.sub.id,
+    }),
+    { getData: actionUserFindOne }
+)(ChatPage);

+ 54 - 0
Fakogram REACT project/fakogram/src/pages/Header.js

@@ -0,0 +1,54 @@
+import Container from "react-bootstrap/Container";
+import Nav from "react-bootstrap/Nav";
+import Navbar from "react-bootstrap/Navbar";
+import Offcanvas from "react-bootstrap/Offcanvas";
+import { Link } from "react-router-dom";
+import { CMyAvatar } from "../components/Avatar";
+import { CLogoutBtn } from "../components/LogoutBtn";
+import { CNickName } from "../components/NickName";
+
+function Header() {
+    return (
+        <>
+            {[false].map((expand) => (
+                <Navbar key={expand} bg="primary" expand={expand}>
+                    <Container fluid>
+                        <Navbar.Toggle
+                            aria-controls={`offcanvasNavbar-expand-${expand}`}
+                            className="burger"
+                        />
+                        <Navbar.Offcanvas
+                            id={`offcanvasNavbar-expand-${expand}`}
+                            aria-labelledby={`offcanvasNavbarLabel-expand-${expand}`}
+                        >
+                            <Offcanvas.Header closeButton>
+                                <Link className="logo" to="/main/">
+                                    fakogram
+                                </Link>
+                            </Offcanvas.Header>
+                            <Offcanvas.Body>
+                                <div className="loginAvatar">
+                                    <CMyAvatar />
+
+                                    <CNickName />
+                                </div>
+
+                                <Nav className="justify-content-end flex-grow-1 pe-3">
+                                    <Link className="nav" to="/profile">
+                                        Profile
+                                    </Link>
+                                    <Link className="nav" to="aboutus">
+                                        About Us
+                                    </Link>
+                                    <CLogoutBtn />
+                                </Nav>
+                            </Offcanvas.Body>
+                        </Navbar.Offcanvas>
+                    </Container>
+                </Navbar>
+            ))}
+        </>
+    );
+}
+
+export default Header;

+ 66 - 0
Fakogram REACT project/fakogram/src/pages/LoginPage.js

@@ -0,0 +1,66 @@
+import React from "react";
+import FloatingLabel from "react-bootstrap/FloatingLabel";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/Button";
+import Alert from "react-bootstrap/Alert";
+import { useState } from "react";
+import { store } from "../reducers/index";
+import { actionFullLogin } from "../actions";
+import { Link } from "react-router-dom";
+import { connect } from "react-redux";
+
+const Login = ({ onLogin }) => {
+    const [login, setLogin] = useState("");
+    const [password, setPassword] = useState("");
+    return (
+        <div className="formContainerLogin">
+            <h1 className="textLogin">Login</h1>
+            <FloatingLabel
+                controlId="floatingInput"
+                label="Enter Login"
+                className="mb-3"
+                onChange={(e) => {
+                    setLogin(e.target.value);
+                }}
+            >
+                <Form.Control
+                    type="text"
+                    placeholder="text"
+                    className="form-control-editing"
+                />
+            </FloatingLabel>
+            <FloatingLabel
+                controlId="floatingPassword"
+                label="Enter Password"
+                onChange={(e) => {
+                    setPassword(e.target.value);
+                }}
+            >
+                <Form.Control
+                    type="password"
+                    placeholder="Password"
+                    className="form-control-editing"
+                />
+            </FloatingLabel>
+
+            <div className="d-flex loginForm">
+                <Button
+                    variant="primary"
+                    type="submit"
+                    className="btn-setting"
+                    onClick={() => {
+                        onLogin(login, password);
+                    }}
+                    disabled={!login || !password}
+                >
+                    <b>Login</b>
+                </Button>
+                <Link to="/registration" className="registerLink alert-link">
+                    Don't have an account? Register
+                </Link>
+            </div>
+        </div>
+    );
+};
+
+export const CLogin = connect(null, { onLogin: actionFullLogin })(Login);

+ 51 - 0
Fakogram REACT project/fakogram/src/pages/MsgPage.js

@@ -0,0 +1,51 @@
+import React, {useState, useEffect} from "react";
+import { connect } from "react-redux";
+
+
+export const OneChat = ({chats, _id, getData}) => {
+
+    
+
+    const [chatList, setChatList] = useState(chats || []);
+    const [messageList, setMessageList] = useState([]);
+
+    useEffect(() => {
+        async function getDataFunc() {
+            const res = await getData(_id);
+
+            setChatList(res.chats);
+            setMessageList(res.chats?.message);
+        }
+
+        getDataFunc();
+    }, [_id]);
+
+    function handleClick(_id) {
+        const filteredChatList = chatList.filter((item) => item._id === _id);
+        setMessageList(filteredChatList[0].messages);
+    }
+
+    {console.log(messageList, "messageListmessageListmessageList")}
+    return (
+        <main className="chatMain">
+            {messageList && messageList.length > 0 && (
+                <ul className="chatMain">
+                    {console.log(messageList, "messageListmessageListmessageList")}
+                    {messageList.map((item1, index) => (
+                        <li className="msgLi" key={index}>
+                            <h3>{item1.text}</h3>
+                        </li>
+                    ))}
+                </ul>
+            )}
+        </main>
+    );
+};
+
+export const COneChat = connect(
+    (state) => ({
+        chats: state.promise.myProfile?.chats,
+        // _id: state.auth?.payload?.sub.id,
+    }),
+)(OneChat);
+

+ 105 - 0
Fakogram REACT project/fakogram/src/pages/NewChatPage.js

@@ -0,0 +1,105 @@
+import React, { useState } from "react";
+import { connect } from "react-redux";
+import { useDropzone } from "react-dropzone";
+import { Link } from "react-router-dom";
+import Button from "react-bootstrap/esm/Button";
+import {Input, InputDebounce} from '../helpers/UserSearch'
+
+
+import { actionSetChatInfo } from "../actions";
+
+import { CChatAvatar } from "../components/Avatar";
+
+const ChatPage = ({ onChat, chat, myProfile, create }) => {
+    const [img, setImg] = useState(null);
+    const [title, setTitle] = useState(chat?.title || "");
+    const [members, setMembers] = useState(chat?.members || [myProfile])
+    
+    const { getRootProps, getInputProps, isDragActive } = useDropzone({
+        accept: "image/*",
+        maxFiles: 1,
+        onDrop: (acceptedFiles) => {
+            setImg(acceptedFiles[0]);
+        },
+    });
+
+    function prepareMembers(members) {
+        const newMembers = []
+
+        for (const member of members) {
+            if (create) {
+                if (member._id !== myProfile?._id) {
+                    newMembers.push({ _id: member._id })
+                }
+            } else {
+                newMembers.push({ _id: member._id })
+            }
+        }
+        return newMembers
+    }
+
+    return (
+        <div className="newChatContainer">
+            <div {...getRootProps({ className: "dropZoneStyle" })}>
+                <input {...getInputProps()} />
+                {isDragActive ? (
+                    <p className="dropZoneStyleBr">Drop the files here ...</p>
+                ) : (
+                    <CChatAvatar text="upload chat avatar" className="profileStyle" />
+                )}
+            </div>
+            <div className="profileContainer">
+                <div className="loginNickSetting">
+                    <div className="inputContainer">
+                        <label for="loginInput">Enter the name of the chat:  </label>
+                        <input
+                            className="form-control-editing form-control"
+                            id="loginInput"
+                            type="text"
+                            value={title}
+                            onChange={(e) => {
+                                setTitle(e.target.value);
+                            }}
+                        />
+                    </div>
+
+                    <div className="inputContainer">
+                        
+                    </div>
+                       
+                    <div className="df">
+                        <Button
+                            variant="primary"
+                            className="buttonSetting"
+                            onClick={() => {
+                                onChat("media", img, title, prepareMembers(members), chat?.id);
+                                console.log("media", title, members, img);
+                            }}
+                        >
+                            <Link
+                                to="/changesdonechats"
+                                style={{
+                                    color: "white",
+                                    textDecoration: "none",
+                                }}
+                            >
+                                Apply Changes
+                            </Link>
+                        </Button>
+
+                        <Link to="/main" className="changepasLink">
+                            Back to all chats
+                        </Link>
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
+
+export const CNewChatPage = connect(
+    (state) => ({
+        myProfile: state.promise.myProfile?.payload || {},
+    }),
+    { onChat: actionSetChatInfo }
+)(ChatPage);

+ 100 - 0
Fakogram REACT project/fakogram/src/pages/ProfilePage.js

@@ -0,0 +1,100 @@
+import React, { useCallback, useState, useEffect } from "react";
+import FloatingLabel from "react-bootstrap/FloatingLabel";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/esm/Button";
+import { useDropzone } from "react-dropzone";
+import { Link } from "react-router-dom";
+import { CMyAvatar } from "../components/Avatar";
+import { actionSetUserInfo } from "../actions";
+import { connect } from "react-redux";
+
+const ProfilePage = ({ myProfile, onChanges }) => {
+    const [login, setLogin] = useState(myProfile.login);
+    const [nick, setNick] = useState(myProfile.nick);
+    const [img, setImg] = useState(null);
+
+    const { getRootProps, getInputProps, isDragActive } = useDropzone({
+        accept: "image/*",
+        maxFiles: 1,
+        onDrop: (acceptedFiles) => {
+            setImg(acceptedFiles[0]);
+        },
+    });
+
+    // if(authLoginValidator === undefined) return <Redirect to='/login' />
+
+    return (
+        <div style={{ paddingTop: "100px" }}>
+            <h1 className="textProfile">My profile</h1>
+            <div {...getRootProps({ className: "dropZoneStyle" })}>
+                <input {...getInputProps()} />
+                {isDragActive ? (
+                    <p className="dropZoneStyleBr">Drop the files here ...</p>
+                ) : (
+                    <CMyAvatar text="change avatar" className="profileStyle" />
+                )}
+            </div>
+            <div className="profileContainer">
+                <div className="loginNickSetting">
+                    <div className="inputContainer">
+                        <label for="loginInput">Enter a new Login: </label>
+                        <input
+                            className="form-control-editing form-control"
+                            id="loginInput"
+                            type="text"
+                            value={login}
+                            onChange={(e) => {
+                                setLogin(e.target.value);
+                            }}
+                        />
+                    </div>
+
+                    <div className="inputContainer">
+                        <label for="nickInput">Enter a new Nick: </label>
+                        <input
+                            className="form-control-editing form-control"
+                            id="nickInput"
+                            type="text"
+                            value={nick}
+                            onChange={(e) => {
+                                setNick(e.target.value);
+                            }}
+                        />
+                    </div>
+
+                    <div className="df">
+                        <Button
+                            variant="primary"
+                            className="buttonSetting"
+                            onClick={() => {
+                                onChanges("media", img, login, nick);
+                                console.log("media", login, nick, img);
+                            }}
+                        >
+                            <Link
+                                to="/changesdone"
+                                style={{
+                                    color: "white",
+                                    textDecoration: "none",
+                                }}
+                            >
+                                Apply Changes
+                            </Link>
+                        </Button>
+
+                        <Link to="/changepas" className="changepasLink">
+                            Сhange password
+                        </Link>
+                    </div>
+                </div>
+            </div>
+        </div>
+    );
+};
+
+export const CProfilePage = connect(
+    (state) => ({
+        myProfile: state.promise?.myProfile?.payload || {},
+    }),
+    { onChanges: actionSetUserInfo }
+)(ProfilePage);

+ 120 - 0
Fakogram REACT project/fakogram/src/pages/RegPage.js

@@ -0,0 +1,120 @@
+import React, { Component, useState } from "react";
+import FloatingLabel from "react-bootstrap/FloatingLabel";
+import Form from "react-bootstrap/Form";
+import Button from "react-bootstrap/Button";
+import { Link } from "react-router-dom";
+import PasswordChecklist from "react-password-checklist";
+import { store } from "../reducers";
+import { actionFullRegister } from "../actions";
+import { connect } from "react-redux";
+import { passValidator } from "../helpers/passValidator";
+
+const Registration = ({ onReg }) => {
+    const [login, setLogin] = useState("");
+    const [nick, setNick] = useState("");
+    const [password, setPassword] = useState("");
+    const [passwordAgain, setPasswordAgain] = useState("");
+
+    return (
+        <div className="formContainer">
+            <h1 className="textLogin">Registration</h1>
+            <FloatingLabel
+                controlId="floatingInput"
+                label="Enter Login"
+                onChange={(e) => setLogin(e.target.value)}
+                className="mb-3"
+            >
+                <Form.Control
+                    type="text"
+                    placeholder="text"
+                    className="form-control-editing"
+                    value={login}
+                />
+            </FloatingLabel>
+            <PasswordChecklist
+                rules={["minLength"]}
+                minLength={5}
+                value={login}
+                valueAgain={passwordAgain}
+                onChange={(isValid) => {}}
+                className="validator"
+                messages={{
+                    minLength: "Login has more than 5 characters.",
+                }}
+            />
+            <FloatingLabel
+                controlId="floatingInput"
+                label="Enter Nick"
+                onChange={(e) => setNick(e.target.value)}
+                className="mb-3"
+            >
+                <Form.Control
+                    type="text"
+                    placeholder="text"
+                    className="form-control-editing"
+                    value={nick}
+                />
+            </FloatingLabel>
+            <PasswordChecklist
+                rules={["minLength"]}
+                minLength={5}
+                value={nick}
+                valueAgain={passwordAgain}
+                onChange={(isValid) => {}}
+                className="validator"
+                messages={{
+                    minLength: "Login has more than 5 characters.",
+                }}
+            />
+            <FloatingLabel controlId="floatingPassword" label="Enter Password">
+                <Form.Control
+                    type="password"
+                    onChange={(e) => setPassword(e.target.value)}
+                    placeholder="Password:"
+                    className="form-control-editing fix"
+                />
+            </FloatingLabel>
+            <FloatingLabel controlId="floatingPassword" label="Repeat Password">
+                <Form.Control
+                    type="password"
+                    onChange={(e) => setPasswordAgain(e.target.value)}
+                    placeholder="Password Again"
+                    className="form-control-editing fix"
+                />
+            </FloatingLabel>
+
+            <PasswordChecklist
+                rules={["minLength", "number", "capital", "match"]}
+                minLength={8}
+                value={password}
+                valueAgain={passwordAgain}
+                onChange={(isValid) => {}}
+                className="validator"
+            />
+            <div className="d-flex loginForm">
+                <Button
+                    variant="primary"
+                    type="submit"
+                    className="btn-setting"
+                    onClick={() => {
+                        onReg(login, password, nick);
+                    }}
+                    disabled={
+                        login.length >= "5" && nick.length >= "5"
+                            ? !passValidator(password, passwordAgain)
+                            : true
+                    }
+                >
+                    <b>Register</b>
+                </Button>
+                <Link to="/login" className="registerLink alert-link">
+                    Have an account? Login
+                </Link>
+            </div>
+        </div>
+    );
+};
+
+export const CRegistration = connect(null, { onReg: actionFullRegister })(
+    Registration
+);

+ 428 - 0
Fakogram REACT project/fakogram/src/reducers/index.js

@@ -0,0 +1,428 @@
+import React, {useEffect} from 'react'
+import { gql } from '../helpers'
+import { actionChatsCount } from '../actions'
+import { createStore, combineReducers, applyMiddleware } from 'redux'
+import thunk from 'redux-thunk'
+import {
+    actionOnMsg,
+    actionOnChat,
+    actionOnChatLeft,
+    actionFullLogout,
+} from '../actions'
+import io from 'socket.io-client'
+import { actionFullChatList, actionFullMsgsByChat, actionGetChatById } from "../actions";
+
+
+export function promiseReducer(state, { type, status, payload, error, name }) {
+    if (!state) {
+        return {}
+    }
+    if (type === 'PROMISE') {
+        return {
+            ...state,
+            [name]: {
+                status: status,
+                payload:
+                    (status === 'PENDING' &&
+                        state[name] &&
+                        state[name].payload) ||
+                    payload,
+                error: error,
+            },
+        }
+        //для пользы при работе с промисами надо бы пока PENDING не делать payload undefined
+        //при наличии старого payload
+    }
+    return state
+}
+
+const actionPending = (name) => ({ type: 'PROMISE', status: 'PENDING', name })
+const actionResolved = (name, payload) => ({
+    type: 'PROMISE',
+    status: 'RESOLVED',
+    name,
+    payload,
+})
+const actionRejected = (name, error) => ({
+    type: 'PROMISE',
+    status: 'REJECTED',
+    name,
+    error,
+})
+
+export const actionPromise = (name, promise) => async (dispatch) => {
+    dispatch(actionPending(name))
+    try {
+        let data = await promise
+        dispatch(actionResolved(name, data))
+        return data
+    } catch (error) {
+        dispatch(actionRejected(name, error))
+    }
+}
+
+
+
+// ------------------
+
+
+
+function jwtDecode(token) {
+    try {
+        const decoded = JSON.parse(atob(token.split('.')[1]))
+        return decoded
+    } catch (err) {
+        console.log(err)
+    }
+}
+
+export function authReducer(state, { type, token }) {
+    if (!state) {
+        if (localStorage.authToken) {
+            token = localStorage.authToken
+            type = 'AUTH_LOGIN'
+        } else {
+            return {}
+        }
+    }
+    if (type === 'AUTH_LOGIN') {
+        const payload = jwtDecode(token)
+        if (typeof payload === 'object') {
+            localStorage.authToken = token
+            return {
+                ...state,
+                token,
+                payload,
+            }
+        } else {
+            console.error(
+                'Токен ' + localStorage.authToken + ' неверный и был удален'
+            )
+            delete localStorage.authToken
+            return state || {}
+        }
+    }
+    if (type === 'AUTH_LOGOUT') {
+        delete localStorage.authToken
+        return {}
+    }
+    return state
+}
+
+export const actionAuthLogin = (token) => ({ type: 'AUTH_LOGIN', token })
+export const actionAuthLogout = () => ({ type: 'AUTH_LOGOUT' })
+
+
+
+// -----------------------------------
+
+
+
+// const chats = {
+//   chats: [
+//     {_id: '333', title: 'moiChat2', avatar: null, lastModified: 'segodnya', owner: {login: 'ya'}, members:[]},
+//     {_id: '222', title: 'moiChat', avatar: null, lastModified: 'vchera', owner: {login: 'ya'}, members:[]}
+//   ],
+//   messages: {
+//     '222': [
+//       {text: 'uuu'}, {text: 'uuuuuu'}
+//     ],
+//     '333': [
+//       {text: 'UUU'}, {text: 'U'}
+//     ]
+//   }
+// }
+
+// payload - или массив чатов или массив сообщений или 1 чат
+export function chatsReducer(state, { type, payload }) {
+    if (!state) {
+        return {
+        }   
+    }
+    function refreshMsgs(newMsgs, oldMsgs) {
+        const msgState = [...oldMsgs]
+
+        for (const newMsg of newMsgs || []) {
+            const currIndex = msgState.findIndex(
+                (oldMsg) => oldMsg._id === newMsg._id
+            )
+
+            if (currIndex === -1) {
+                msgState.push(newMsg)
+            } else {
+                msgState[currIndex] = newMsg
+            }
+        }
+        const newMsgState = msgState.sort((a, b) => {
+            if (a._id > b._id) {
+                return 1
+            }
+            if (a._id < b._id) {
+                return -1
+            }
+            return 0
+        })
+
+        return newMsgState
+    }
+
+    function getInfoAboutNext(msgState) {
+        const informedState = []
+
+        for (let i = 0; i < msgState.length; i++) {
+            const msg = msgState[i]
+
+            msg.nextMsg = msgState[i + 1] || null
+            informedState.push(msg)
+        }
+
+        return informedState
+    }
+
+    function sortChats(unsortedChats) {
+        return Object.fromEntries(
+            Object.entries(unsortedChats).sort((a, b) => {
+                if (a[1].lastModified > b[1].lastModified) {
+                    return -1
+                }
+                if (a[1].lastModified < b[1].lastModified) {
+                    return 1
+                }
+                return 0
+            })
+        )
+    }
+
+    const types = {
+        CHATS() {
+            if (payload) {
+                const oldChats = { ...state }
+
+                // перебираем новые чаты
+                for (const chat of payload) {
+                    // находим старый чат с ид нового
+                    const oldChat = oldChats[chat._id]
+                    // если его еще нет, то просто записываем
+                    if (!oldChat) {
+                        oldChats[chat._id] = { ...chat } 
+                        // если есть, то идем по свойствам нового чата
+                    } else
+                        for (const key in chat) {
+                            // записываем значение свойства нового и старого чата
+                            const oldValue = oldChat[key]
+                            const newValue = chat[key]
+
+                            // проверяем наличие значений
+                            // если оба значения или только новое, переходим к проверке на массив сообщений
+                            if (newValue) {
+                                // если массив сообщений, то вызываем соответствующие функции слияния
+                                if (key === 'messages') {
+                                    oldChats[chat._id][key] = getInfoAboutNext(
+                                        refreshMsgs(newValue, oldValue)
+                                    )
+                                } else {
+                                    oldChats[chat._id][key] = newValue //-----------------------------------
+                                }
+
+                                // если есть только старое, записать старое (можно ничего не делать)
+                            } else {
+                                oldChats[chat._id][key] = oldValue //-------------------------------------
+                            }
+                        }
+                }
+
+                const newState = sortChats(oldChats)
+
+                return newState
+            }
+            return state
+        },
+
+        CHAT_LEFT() {
+            const { [payload._id]: removed, ...newState } = state // eslint-disable-line
+            return newState
+        },
+
+        CHATS_CLEAR() {
+            return {}
+        },
+
+        MSGS() {
+            if (payload && payload.length > 0) {
+                const chatId = payload[0]?.chat?._id
+
+                const msgState = state[chatId]?.messages || []
+
+                const newMsgState = getInfoAboutNext(
+                    refreshMsgs(payload, msgState)
+                )
+
+                const newState = {
+                    ...state,
+                    [chatId]: {
+                        ...state[chatId],
+                        messages: newMsgState,
+                    },
+                }
+
+                return newState
+            }
+            return state
+        },
+    }
+    if (type in types) {
+        return types[type]()
+    }
+    return state
+}
+
+export const actionChatList = (chats) => ({ type: 'CHATS', payload: chats })
+export const actionChatOne = (chat) => ({ type: 'CHATS', payload: [chat] })
+export const actionChatLeft = (chat) => ({ type: 'CHAT_LEFT', payload: chat })
+export const actionChatsClear = () => ({ type: 'CHATS_CLEAR' })
+
+export const actionMsgList = (msgs) => ({ type: 'MSGS', payload: msgs })
+export const actionMsgOne = (msg) => ({ type: 'MSGS', payload: [msg] })
+
+
+
+// -------------------------------
+
+
+
+
+
+export const actionUserFindOne = (userId, name = 'findUserOne') =>
+    actionPromise(
+        name,
+        gql(
+            `query findUserOne($q: String) {
+      UserFindOne (query: $q){
+         _id
+         createdAt
+         login
+         nick
+         avatar {
+            _id
+            url
+         }
+         chats{
+            avatar {
+                _id
+                url
+             }
+            messages {
+                _id
+                createdAt
+                text
+                        owner {
+                          _id
+                          createdAt
+                          login
+                          nick
+                        }
+                media {
+                  _id
+                  createdAt
+                  text
+                  url
+                  originalFileName
+                  type
+                }
+              }
+            _id
+            createdAt
+            title
+            lastMessage {
+                _id
+                createdAt
+                text
+            }
+        }
+    }
+}
+`,
+            {
+                q: JSON.stringify([{ _id: userId }]),
+            }
+        )
+    )
+
+export const actionAboutMe = () => async (dispatch, getState) => {
+    let { auth } = getState()
+    let id = auth?.payload?.sub?.id
+    if (id) {
+        await dispatch(actionUserFindOne(id, 'myProfile'))
+        await dispatch(actionChatsCount(id))
+    }
+}
+
+
+
+// -----------------------
+
+
+
+
+// let initialState = localStorage.getItem('state')
+
+export const store = createStore(
+    combineReducers({
+        auth: authReducer,
+        chats: chatsReducer,
+        promise: promiseReducer,
+    }),
+    // initialState ? {chats: JSON.parse(initialState)} : {},
+    applyMiddleware(thunk)
+)
+
+store.dispatch(actionAboutMe())
+
+// store.subscribe(() => console.log(store.getState()))
+// window.onbeforeunload = () => window.localStorage.setItem('state', JSON.stringify(store.getState().chats) )
+
+///////////////////////////////////////////////////////////////////
+
+export const socket = io('ws://chat.ed.asmer.org.ua')
+
+socket.on('jwt_ok', (data) => console.log(data))
+socket.on('jwt_fail', (error) => {
+    console.log(error)
+    store.dispatch(actionFullLogout())
+})
+
+socket.on('msg', (msg) => {
+    console.log('пришло смс')
+    store.dispatch(actionOnMsg(msg))
+})
+
+socket.on('chat', (chat) => {
+    console.log('нас добавили в чат')
+    store.dispatch(actionOnChat(chat))
+
+    const state = store.getState()
+    socket.disconnect(true)
+    socket.connect()
+    socket.emit('jwt', state.auth.token)
+})
+
+socket.on('chat_left', (chat) => {
+    console.log('нас выкинули из чата')
+    store.dispatch(actionOnChatLeft(chat))
+})
+
+store.subscribe(() => console.log(store.getState()));
+console.log(store.getState())
+
+if(store.getState().auth.token){
+    store.dispatch(actionFullChatList(store.getState().auth.payload?.sub.id))
+}
+
+
+
+const bodyColor = () => {return document.body.style.background = '#eee'}
+bodyColor()
+
+// store.dispatch(actionGetChatById("633b2f0c55e76f7ddb1eae97"))
+
+  

REACT/HW 20/src/reportWebVitals.js → Fakogram REACT project/fakogram/src/reportWebVitals.js


REACT/HW 20/src/setupTests.js → Fakogram REACT project/fakogram/src/setupTests.js


+ 1 - 0
Fakogram REACT project/node_modules/.bin/acorn

@@ -0,0 +1 @@
+../acorn/bin/acorn

+ 1 - 0
Fakogram REACT project/node_modules/.bin/atob

@@ -0,0 +1 @@
+../atob/bin/atob.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/errno

@@ -0,0 +1 @@
+../errno/cli.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/json5

@@ -0,0 +1 @@
+../json5/lib/cli.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/loose-envify

@@ -0,0 +1 @@
+../loose-envify/cli.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/miller-rabin

@@ -0,0 +1 @@
+../miller-rabin/bin/miller-rabin

+ 1 - 0
Fakogram REACT project/node_modules/.bin/mkdirp

@@ -0,0 +1 @@
+../mkdirp/bin/cmd.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/resolve

@@ -0,0 +1 @@
+../resolve/bin/resolve

+ 1 - 0
Fakogram REACT project/node_modules/.bin/semver

@@ -0,0 +1 @@
+../semver/bin/semver

+ 1 - 0
Fakogram REACT project/node_modules/.bin/sha.js

@@ -0,0 +1 @@
+../sha.js/bin.js

+ 1 - 0
Fakogram REACT project/node_modules/.bin/uglifyjs

@@ -0,0 +1 @@
+../uglify-js/bin/uglifyjs

+ 1 - 0
Fakogram REACT project/node_modules/.bin/webpack

@@ -0,0 +1 @@
+../webpack/bin/webpack.js

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3765 - 0
Fakogram REACT project/node_modules/.package-lock.json


+ 19 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/CHANGELOG.md

@@ -0,0 +1,19 @@
+# 2.0.2
+
+- Fixing parsing of `yield import()`.
+
+# 2.0.1
+
+- Removing unnecessary `in-publish` dependency.
+
+# 2.0.0
+
+- Updating acorn version to >= 4.
+
+# 1.0.1
+
+- Fixes for publishing the module.
+
+# 1.0.0
+
+- Initial release of plugin.

+ 21 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2016 Jordan Gensler
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 33 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/README.md

@@ -0,0 +1,33 @@
+# Dynamic import support in acorn
+
+This is plugin for [Acorn](http://marijnhaverbeke.nl/acorn/) - a tiny, fast JavaScript parser, written completely in JavaScript.
+
+For more information, check out the [proposal repo](https://github.com/tc39/proposal-dynamic-import).
+
+## Usage
+
+You can use this module directly in order to get Acorn instance with plugin installed:
+
+```js
+import acorn from 'acorn-dynamic-import';
+// or...
+const acorn = require('acorn-dynamic-import').default;
+```
+
+Or you can use `inject.js` for injecting plugin into your own version of Acorn like this:
+
+```js
+const acorn = require('acorn-dynamic-import/lib/inject').default(require('./custom-acorn'));
+```
+
+Then, use the `plugins` option whenever you need to support dynamicImport while parsing:
+
+```js
+const ast = acorn.parse(code, {
+  plugins: { dynamicImport: true }
+});
+```
+
+## License
+
+This plugin is issued under the [MIT license](./LICENSE).

+ 17 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/lib/index.js

@@ -0,0 +1,17 @@
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _acorn = require('acorn');
+
+var acorn = _interopRequireWildcard(_acorn);
+
+var _inject = require('./inject');
+
+var _inject2 = _interopRequireDefault(_inject);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
+
+exports['default'] = (0, _inject2['default'])(acorn);

+ 70 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/lib/inject.js

@@ -0,0 +1,70 @@
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+exports['default'] = injectDynamicImport;
+/* eslint-disable no-underscore-dangle */
+
+function injectDynamicImport(acorn) {
+  var tt = acorn.tokTypes;
+
+  // NOTE: This allows `yield import()` to parse correctly.
+  tt._import.startsExpr = true;
+
+  function parseDynamicImport() {
+    var node = this.startNode();
+    this.next();
+    if (this.type !== tt.parenL) {
+      this.unexpected();
+    }
+    return this.finishNode(node, 'Import');
+  }
+
+  function peekNext() {
+    return this.input[this.pos];
+  }
+
+  // eslint-disable-next-line no-param-reassign
+  acorn.plugins.dynamicImport = function () {
+    function dynamicImportPlugin(instance) {
+      instance.extend('parseStatement', function (nextMethod) {
+        return function () {
+          function parseStatement() {
+            var node = this.startNode();
+            if (this.type === tt._import) {
+              var nextToken = peekNext.call(this);
+              if (nextToken === tt.parenL.label) {
+                var expr = this.parseExpression();
+                return this.parseExpressionStatement(node, expr);
+              }
+            }
+
+            for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+              args[_key] = arguments[_key];
+            }
+
+            return nextMethod.apply(this, args);
+          }
+
+          return parseStatement;
+        }();
+      });
+
+      instance.extend('parseExprAtom', function (nextMethod) {
+        return function () {
+          function parseExprAtom(refDestructuringErrors) {
+            if (this.type === tt._import) {
+              return parseDynamicImport.call(this);
+            }
+            return nextMethod.call(this, refDestructuringErrors);
+          }
+
+          return parseExprAtom;
+        }();
+      });
+    }
+
+    return dynamicImportPlugin;
+  }();
+
+  return acorn;
+}

+ 1 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/.bin/acorn

@@ -0,0 +1 @@
+../acorn/bin/acorn

+ 10 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/.npmignore

@@ -0,0 +1,10 @@
+/.tern-port
+/test
+/local
+/rollup
+/bin/generate-identifier-regex.js
+/bin/update_authors.sh
+.editorconfig
+.gitattributes
+.tern-project
+.travis.yml

+ 62 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/AUTHORS

@@ -0,0 +1,62 @@
+List of Acorn contributors. Updated before every release.
+
+Adrian Rakovsky
+Alistair Braidwood
+Amila Welihinda
+Andres Suarez
+Angelo
+Aparajita Fishman
+Arian Stolwijk
+Artem Govorov
+Brandon Mills
+Charles Hughes
+Conrad Irwin
+Daniel Tschinder
+David Bonnet
+Domenico Matteo
+Forbes Lindesay
+Gilad Peleg
+impinball
+Ingvar Stepanyan
+Jackson Ray Hamilton
+Jesse McCarthy
+Jiaxing Wang
+Joel Kemp
+Johannes Herr
+Jordan Klassen
+Jürg Lehni
+Kai Cataldo
+keeyipchan
+Keheliya Gallaba
+Kevin Irish
+Kevin Kwok
+krator
+Marijn Haverbeke
+Martin Carlberg
+Mat Garcia
+Mathias Bynens
+Mathieu 'p01' Henri
+Matthew Bastien
+Max Schaefer
+Max Zerzouri
+Mihai Bazon
+Mike Rennie
+naoh
+Nicholas C. Zakas
+Nick Fitzgerald
+Olivier Thomann
+Oskar Schöldström
+Paul Harper
+Peter Rust
+PlNG
+Prayag Verma
+ReadmeCritic
+r-e-d
+Richard Gibson
+Rich Harris
+Sebastian McKenzie
+Simen Bekkhus
+Timothy Gu
+Toru Nagashima
+Wexpo Lyu
+zsjforcn

+ 286 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/CHANGELOG.md

@@ -0,0 +1,286 @@
+## 4.0.11 (2017-02-07)
+
+### Bug fixes
+
+Allow all forms of member expressions to be parenthesized as lvalue.
+
+## 4.0.10 (2017-02-07)
+
+### Bug fixes
+
+Don't expect semicolons after default-exported functions or classes,
+even when they are expressions.
+
+Check for use of `'use strict'` directives in non-simple parameter
+functions, even when already in strict mode.
+
+## 4.0.9 (2017-02-06)
+
+### Bug fixes
+
+Fix incorrect error raised for parenthesized simple assignment
+targets, so that `(x) = 1` parses again.
+
+## 4.0.8 (2017-02-03)
+
+### Bug fixes
+
+Solve spurious parenthesized pattern errors by temporarily erring on
+the side of accepting programs that our delayed errors don't handle
+correctly yet.
+
+## 4.0.7 (2017-02-02)
+
+### Bug fixes
+
+Accept invalidly rejected code like `(x).y = 2` again.
+
+Don't raise an error when a function _inside_ strict code has a
+non-simple parameter list.
+
+## 4.0.6 (2017-02-02)
+
+### Bug fixes
+
+Fix exponential behavior (manifesting itself as a complete hang for
+even relatively small source files) introduced by the new 'use strict'
+check.
+
+## 4.0.5 (2017-02-02)
+
+### Bug fixes
+
+Disallow parenthesized pattern expressions.
+
+Allow keywords as export names.
+
+Don't allow the `async` keyword to be parenthesized.
+
+Properly raise an error when a keyword contains a character escape.
+
+Allow `"use strict"` to appear after other string literal expressions.
+
+Disallow labeled declarations.
+
+## 4.0.4 (2016-12-19)
+
+### Bug fixes
+
+Fix issue with loading acorn_loose.js with an AMD loader.
+
+Fix crash when `export` was followed by a keyword that can't be
+exported.
+
+## 4.0.3 (2016-08-16)
+
+### Bug fixes
+
+Allow regular function declarations inside single-statement `if`
+branches in loose mode. Forbid them entirely in strict mode.
+
+Properly parse properties named `async` in ES2017 mode.
+
+Fix bug where reserved words were broken in ES2017 mode.
+
+## 4.0.2 (2016-08-11)
+
+### Bug fixes
+
+Don't ignore period or 'e' characters after octal numbers.
+
+Fix broken parsing for call expressions in default parameter values
+of arrow functions.
+
+## 4.0.1 (2016-08-08)
+
+### Bug fixes
+
+Fix false positives in duplicated export name errors.
+
+## 4.0.0 (2016-08-07)
+
+### Breaking changes
+
+The default `ecmaVersion` option value is now 7.
+
+A number of internal method signatures changed, so plugins might need
+to be updated.
+
+### Bug fixes
+
+The parser now raises errors on duplicated export names.
+
+`arguments` and `eval` can now be used in shorthand properties.
+
+Duplicate parameter names in non-simple argument lists now always
+produce an error.
+
+### New features
+
+The `ecmaVersion` option now also accepts year-style version numbers
+(2015, etc).
+
+Support for `async`/`await` syntax when `ecmaVersion` is >= 8.
+
+Support for trailing commas in call expressions when `ecmaVersion`
+is >= 8.
+
+## 3.3.0 (2016-07-25)
+
+### Bug fixes
+
+Fix bug in tokenizing of regexp operator after a function declaration.
+
+Fix parser crash when parsing an array pattern with a hole.
+
+### New features
+
+Implement check against complex argument lists in functions that
+enable strict mode in ES7.
+
+## 3.2.0 (2016-06-07)
+
+### Bug fixes
+
+Improve handling of lack of unicode regexp support in host
+environment.
+
+Properly reject shorthand properties whose name is a keyword.
+
+Don't crash when the loose parser is called without options object.
+
+### New features
+
+Visitors created with `visit.make` now have their base as _prototype_,
+rather than copying properties into a fresh object.
+
+Make it possible to use `visit.ancestor` with a walk state.
+
+## 3.1.0 (2016-04-18)
+
+### Bug fixes
+
+Fix issue where the loose parser created invalid TemplateElement nodes
+for unclosed template literals.
+
+Properly tokenize the division operator directly after a function
+expression.
+
+Allow trailing comma in destructuring arrays.
+
+### New features
+
+The walker now allows defining handlers for `CatchClause` nodes.
+
+## 3.0.4 (2016-02-25)
+
+### Fixes
+
+Allow update expressions as left-hand-side of the ES7 exponential
+operator.
+
+## 3.0.2 (2016-02-10)
+
+### Fixes
+
+Fix bug that accidentally made `undefined` a reserved word when
+parsing ES7.
+
+## 3.0.0 (2016-02-10)
+
+### Breaking changes
+
+The default value of the `ecmaVersion` option is now 6 (used to be 5).
+
+Support for comprehension syntax (which was dropped from the draft
+spec) has been removed.
+
+### Fixes
+
+`let` and `yield` are now “contextual keywords”, meaning you can
+mostly use them as identifiers in ES5 non-strict code.
+
+A parenthesized class or function expression after `export default` is
+now parsed correctly.
+
+### New features
+
+When `ecmaVersion` is set to 7, Acorn will parse the exponentiation
+operator (`**`).
+
+The identifier character ranges are now based on Unicode 8.0.0.
+
+Plugins can now override the `raiseRecoverable` method to override the
+way non-critical errors are handled.
+
+## 2.7.0 (2016-01-04)
+
+### Fixes
+
+Stop allowing rest parameters in setters.
+
+Make sure the loose parser always attaches a `local` property to
+`ImportNamespaceSpecifier` nodes.
+
+Disallow `y` rexexp flag in ES5.
+
+Disallow `\00` and `\000` escapes in strict mode.
+
+Raise an error when an import name is a reserved word.
+
+## 2.6.4 (2015-11-12)
+
+### Fixes
+
+Fix crash in loose parser when parsing invalid object pattern.
+
+### New features
+
+Support plugins in the loose parser.
+
+## 2.6.2 (2015-11-10)
+
+### Fixes
+
+Don't crash when no options object is passed.
+
+## 2.6.0 (2015-11-09)
+
+### Fixes
+
+Add `await` as a reserved word in module sources.
+
+Disallow `yield` in a parameter default value for a generator.
+
+Forbid using a comma after a rest pattern in an array destructuring.
+
+### New features
+
+Support parsing stdin in command-line tool.
+
+## 2.5.2 (2015-10-27)
+
+### Fixes
+
+Fix bug where the walker walked an exported `let` statement as an
+expression.
+
+## 2.5.0 (2015-10-27)
+
+### Fixes
+
+Fix tokenizer support in the command-line tool.
+
+In the loose parser, don't allow non-string-literals as import
+sources.
+
+Stop allowing `new.target` outside of functions.
+
+Remove legacy `guard` and `guardedHandler` properties from try nodes.
+
+Stop allowing multiple `__proto__` properties on an object literal in
+strict mode.
+
+Don't allow rest parameters to be non-identifier patterns.
+
+Check for duplicate paramter names in arrow functions.

+ 19 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/LICENSE

@@ -0,0 +1,19 @@
+Copyright (C) 2012-2016 by various contributors (see AUTHORS)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.

+ 409 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/README.md

@@ -0,0 +1,409 @@
+# Acorn
+
+[![Build Status](https://travis-ci.org/ternjs/acorn.svg?branch=master)](https://travis-ci.org/ternjs/acorn)
+[![NPM version](https://img.shields.io/npm/v/acorn.svg)](https://www.npmjs.com/package/acorn)
+[![CDNJS](https://img.shields.io/cdnjs/v/acorn.svg)](https://cdnjs.com/libraries/acorn)  
+[Author funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?force)](https://marijnhaverbeke.nl/fund/)
+
+A tiny, fast JavaScript parser, written completely in JavaScript.
+
+## Community
+
+Acorn is open source software released under an
+[MIT license](https://github.com/ternjs/acorn/blob/master/LICENSE).
+
+You are welcome to
+[report bugs](https://github.com/ternjs/acorn/issues) or create pull
+requests on [github](https://github.com/ternjs/acorn). For questions
+and discussion, please use the
+[Tern discussion forum](https://discuss.ternjs.net).
+
+## Installation
+
+The easiest way to install acorn is with [`npm`][npm].
+
+[npm]: https://www.npmjs.com/
+
+```sh
+npm install acorn
+```
+
+Alternately, download the source.
+
+```sh
+git clone https://github.com/ternjs/acorn.git
+```
+
+## Components
+
+When run in a CommonJS (node.js) or AMD environment, exported values
+appear in the interfaces exposed by the individual files, as usual.
+When loaded in the browser (Acorn works in any JS-enabled browser more
+recent than IE5) without any kind of module management, a single
+global object `acorn` will be defined, and all the exported properties
+will be added to that.
+
+### Main parser
+
+This is implemented in `dist/acorn.js`, and is what you get when you
+`require("acorn")` in node.js.
+
+**parse**`(input, options)` is used to parse a JavaScript program.
+The `input` parameter is a string, `options` can be undefined or an
+object setting some of the options listed below. The return value will
+be an abstract syntax tree object as specified by the
+[ESTree spec][estree].
+
+When  encountering   a  syntax   error,  the   parser  will   raise  a
+`SyntaxError` object with a meaningful  message. The error object will
+have a `pos` property that indicates the character offset at which the
+error occurred,  and a `loc`  object that contains a  `{line, column}`
+object referring to that same position.
+
+[estree]: https://github.com/estree/estree
+
+- **ecmaVersion**: Indicates the ECMAScript version to parse. Must be
+  either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support for strict
+  mode, the set of reserved words, and support for new syntax features.
+  Default is 7.
+
+  **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
+  implemented by Acorn.
+
+- **sourceType**: Indicate the mode the code should be parsed in. Can be
+  either `"script"` or `"module"`. This influences global strict mode
+  and parsing of `import` and `export` declarations.
+
+- **onInsertedSemicolon**: If given a callback, that callback will be
+  called whenever a missing semicolon is inserted by the parser. The
+  callback will be given the character offset of the point where the
+  semicolon is inserted as argument, and if `locations` is on, also a
+  `{line, column}` object representing this position.
+
+- **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
+  commas.
+
+- **allowReserved**: If `false`, using a reserved word will generate
+  an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
+  versions. When given the value `"never"`, reserved words and
+  keywords can also not be used as property names (as in Internet
+  Explorer's old parser).
+
+- **allowReturnOutsideFunction**: By default, a return statement at
+  the top level raises an error. Set this to `true` to accept such
+  code.
+
+- **allowImportExportEverywhere**: By default, `import` and `export`
+  declarations can only appear at a program's top level. Setting this
+  option to `true` allows them anywhere where a statement is allowed.
+
+- **allowHashBang**: When this is enabled (off by default), if the
+  code starts with the characters `#!` (as in a shellscript), the
+  first line will be treated as a comment.
+
+- **locations**: When `true`, each node has a `loc` object attached
+  with `start` and `end` subobjects, each of which contains the
+  one-based line and zero-based column numbers in `{line, column}`
+  form. Default is `false`.
+
+- **onToken**: If a function is passed for this option, each found
+  token will be passed in same format as tokens returned from
+  `tokenizer().getToken()`.
+
+  If array is passed, each found token is pushed to it.
+
+  Note that you are not allowed to call the parser from the
+  callback—that will corrupt its internal state.
+
+- **onComment**: If a function is passed for this option, whenever a
+  comment is encountered the function will be called with the
+  following parameters:
+
+  - `block`: `true` if the comment is a block comment, false if it
+    is a line comment.
+  - `text`: The content of the comment.
+  - `start`: Character offset of the start of the comment.
+  - `end`: Character offset of the end of the comment.
+
+  When the `locations` options is on, the `{line, column}` locations
+  of the comment’s start and end are passed as two additional
+  parameters.
+
+  If array is passed for this option, each found comment is pushed
+  to it as object in Esprima format:
+
+  ```javascript
+  {
+    "type": "Line" | "Block",
+    "value": "comment text",
+    "start": Number,
+    "end": Number,
+    // If `locations` option is on:
+    "loc": {
+      "start": {line: Number, column: Number}
+      "end": {line: Number, column: Number}
+    },
+    // If `ranges` option is on:
+    "range": [Number, Number]
+  }
+  ```
+
+  Note that you are not allowed to call the parser from the
+  callback—that will corrupt its internal state.
+
+- **ranges**: Nodes have their start and end characters offsets
+  recorded in `start` and `end` properties (directly on the node,
+  rather than the `loc` object, which holds line/column data. To also
+  add a [semi-standardized][range] `range` property holding a
+  `[start, end]` array with the same numbers, set the `ranges` option
+  to `true`.
+
+- **program**: It is possible to parse multiple files into a single
+  AST by passing the tree produced by parsing the first file as the
+  `program` option in subsequent parses. This will add the toplevel
+  forms of the parsed file to the "Program" (top) node of an existing
+  parse tree.
+
+- **sourceFile**: When the `locations` option is `true`, you can pass
+  this option to add a `source` attribute in every node’s `loc`
+  object. Note that the contents of this option are not examined or
+  processed in any way; you are free to use whatever format you
+  choose.
+
+- **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
+  will be added (regardless of the `location` option) directly to the
+  nodes, rather than the `loc` object.
+
+- **preserveParens**: If this option is `true`, parenthesized expressions
+  are represented by (non-standard) `ParenthesizedExpression` nodes
+  that have a single `expression` property containing the expression
+  inside parentheses.
+
+[range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
+
+**parseExpressionAt**`(input, offset, options)` will parse a single
+expression in a string, and return its AST. It will not complain if
+there is more of the string left after the expression.
+
+**getLineInfo**`(input, offset)` can be used to get a `{line,
+column}` object for a given program string and character offset.
+
+**tokenizer**`(input, options)` returns an object with a `getToken`
+method that can be called repeatedly to get the next token, a `{start,
+end, type, value}` object (with added `loc` property when the
+`locations` option is enabled and `range` property when the `ranges`
+option is enabled). When the token's type is `tokTypes.eof`, you
+should stop calling the method, since it will keep returning that same
+token forever.
+
+In ES6 environment, returned result can be used as any other
+protocol-compliant iterable:
+
+```javascript
+for (let token of acorn.tokenizer(str)) {
+  // iterate over the tokens
+}
+
+// transform code to array of tokens:
+var tokens = [...acorn.tokenizer(str)];
+```
+
+**tokTypes** holds an object mapping names to the token type objects
+that end up in the `type` properties of tokens.
+
+#### Note on using with [Escodegen][escodegen]
+
+Escodegen supports generating comments from AST, attached in
+Esprima-specific format. In order to simulate same format in
+Acorn, consider following example:
+
+```javascript
+var comments = [], tokens = [];
+
+var ast = acorn.parse('var x = 42; // answer', {
+	// collect ranges for each node
+	ranges: true,
+	// collect comments in Esprima's format
+	onComment: comments,
+	// collect token ranges
+	onToken: tokens
+});
+
+// attach comments using collected information
+escodegen.attachComments(ast, comments, tokens);
+
+// generate code
+console.log(escodegen.generate(ast, {comment: true}));
+// > 'var x = 42;    // answer'
+```
+
+[escodegen]: https://github.com/estools/escodegen
+
+### dist/acorn_loose.js ###
+
+This file implements an error-tolerant parser. It exposes a single
+function. The loose parser is accessible in node.js via `require("acorn/dist/acorn_loose")`.
+
+**parse_dammit**`(input, options)` takes the same arguments and
+returns the same syntax tree as the `parse` function in `acorn.js`,
+but never raises an error, and will do its best to parse syntactically
+invalid code in as meaningful a way as it can. It'll insert identifier
+nodes with name `"✖"` as placeholders in places where it can't make
+sense of the input. Depends on `acorn.js`, because it uses the same
+tokenizer.
+
+### dist/walk.js ###
+
+Implements an abstract syntax tree walker. Will store its interface in
+`acorn.walk` when loaded without a module system.
+
+**simple**`(node, visitors, base, state)` does a 'simple' walk over
+a tree. `node` should be the AST node to walk, and `visitors` an
+object with properties whose names correspond to node types in the
+[ESTree spec][estree]. The properties should contain functions
+that will be called with the node object and, if applicable the state
+at that point. The last two arguments are optional. `base` is a walker
+algorithm, and `state` is a start state. The default walker will
+simply visit all statements and expressions and not produce a
+meaningful state. (An example of a use of state is to track scope at
+each point in the tree.)
+
+**ancestor**`(node, visitors, base, state)` does a 'simple' walk over
+a tree, building up an array of ancestor nodes (including the current node)
+and passing the array to the callbacks as a third parameter.
+
+**recursive**`(node, state, functions, base)` does a 'recursive'
+walk, where the walker functions are responsible for continuing the
+walk on the child nodes of their target node. `state` is the start
+state, and `functions` should contain an object that maps node types
+to walker functions. Such functions are called with `(node, state, c)`
+arguments, and can cause the walk to continue on a sub-node by calling
+the `c` argument on it with `(node, state)` arguments. The optional
+`base` argument provides the fallback walker functions for node types
+that aren't handled in the `functions` object. If not given, the
+default walkers will be used.
+
+**make**`(functions, base)` builds a new walker object by using the
+walker functions in `functions` and filling in the missing ones by
+taking defaults from `base`.
+
+**findNodeAt**`(node, start, end, test, base, state)` tries to
+locate a node in a tree at the given start and/or end offsets, which
+satisfies the predicate `test`. `start` and `end` can be either `null`
+(as wildcard) or a number. `test` may be a string (indicating a node
+type) or a function that takes `(nodeType, node)` arguments and
+returns a boolean indicating whether this node is interesting. `base`
+and `state` are optional, and can be used to specify a custom walker.
+Nodes are tested from inner to outer, so if two nodes match the
+boundaries, the inner one will be preferred.
+
+**findNodeAround**`(node, pos, test, base, state)` is a lot like
+`findNodeAt`, but will match any node that exists 'around' (spanning)
+the given position.
+
+**findNodeAfter**`(node, pos, test, base, state)` is similar to
+`findNodeAround`, but will match all nodes *after* the given position
+(testing outer nodes before inner nodes).
+
+## Command line interface
+
+The `bin/acorn` utility can be used to parse a file from the command
+line. It accepts as arguments its input file and the following
+options:
+
+- `--ecma3|--ecma5|--ecma6|--ecma7`: Sets the ECMAScript version to parse. Default is
+  version 5.
+
+- `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
+
+- `--locations`: Attaches a "loc" object to each node with "start" and
+  "end" subobjects, each of which contains the one-based line and
+  zero-based column numbers in `{line, column}` form.
+
+- `--allow-hash-bang`: If the code starts with the characters #! (as in a shellscript), the first line will be treated as a comment.
+
+- `--compact`: No whitespace is used in the AST output.
+
+- `--silent`: Do not output the AST, just return the exit status.
+
+- `--help`: Print the usage information and quit.
+
+The utility spits out the syntax tree as JSON data.
+
+## Build system
+
+Acorn is written in ECMAScript 6, as a set of small modules, in the
+project's `src` directory, and compiled down to bigger ECMAScript 3
+files in `dist` using [Browserify](http://browserify.org) and
+[Babel](http://babeljs.io/). If you are already using Babel, you can
+consider including the modules directly.
+
+The command-line test runner (`npm test`) uses the ES6 modules. The
+browser-based test page (`test/index.html`) uses the compiled modules.
+The `bin/build-acorn.js` script builds the latter from the former.
+
+If you are working on Acorn, you'll probably want to try the code out
+directly, without an intermediate build step. In your scripts, you can
+register the Babel require shim like this:
+
+    require("babel-core/register")
+
+That will allow you to directly `require` the ES6 modules.
+
+## Plugins
+
+Acorn is designed support allow plugins which, within reasonable
+bounds, redefine the way the parser works. Plugins can add new token
+types and new tokenizer contexts (if necessary), and extend methods in
+the parser object. This is not a clean, elegant API—using it requires
+an understanding of Acorn's internals, and plugins are likely to break
+whenever those internals are significantly changed. But still, it is
+_possible_, in this way, to create parsers for JavaScript dialects
+without forking all of Acorn. And in principle it is even possible to
+combine such plugins, so that if you have, for example, a plugin for
+parsing types and a plugin for parsing JSX-style XML literals, you
+could load them both and parse code with both JSX tags and types.
+
+A plugin should register itself by adding a property to
+`acorn.plugins`, which holds a function. Calling `acorn.parse`, a
+`plugins` option can be passed, holding an object mapping plugin names
+to configuration values (or just `true` for plugins that don't take
+options). After the parser object has been created, the initialization
+functions for the chosen plugins are called with `(parser,
+configValue)` arguments. They are expected to use the `parser.extend`
+method to extend parser methods. For example, the `readToken` method
+could be extended like this:
+
+```javascript
+parser.extend("readToken", function(nextMethod) {
+  return function(code) {
+    console.log("Reading a token!")
+    return nextMethod.call(this, code)
+  }
+})
+```
+
+The `nextMethod` argument passed to `extend`'s second argument is the
+previous value of this method, and should usually be called through to
+whenever the extended method does not handle the call itself.
+
+Similarly, the loose parser allows plugins to register themselves via
+`acorn.pluginsLoose`.  The extension mechanism is the same as for the
+normal parser:
+
+```javascript
+looseParser.extend("readToken", function(nextMethod) {
+  return function() {
+    console.log("Reading a token in the loose parser!")
+    return nextMethod.call(this)
+  }
+})
+```
+
+### Existing plugins
+
+ - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
+ - [`acorn-es7-plugin`](https://github.com/MatAtBread/acorn-es7-plugin/): Parse [async/await syntax proposal](https://github.com/tc39/ecmascript-asyncawait)
+ - [`acorn-object-spread`](https://github.com/UXtemple/acorn-object-spread): Parse [object spread syntax proposal](https://github.com/sebmarkbage/ecmascript-rest-spread)
+ - [`acorn-es7`](https://www.npmjs.com/package/acorn-es7): Parse [decorator syntax proposal](https://github.com/wycats/javascript-decorators)
+ - [`acorn-objj`](https://www.npmjs.com/package/acorn-objj): [Objective-J](http://www.cappuccino-project.org/learn/objective-j.html) language parser built as Acorn plugin

+ 67 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/bin/acorn

@@ -0,0 +1,67 @@
+#!/usr/bin/env node
+'use strict';
+
+var path = require('path');
+var fs = require('fs');
+var acorn = require('../dist/acorn.js');
+
+var infile;
+var forceFile;
+var silent = false;
+var compact = false;
+var tokenize = false;
+var options = {}
+
+function help(status) {
+  var print = (status == 0) ? console.log : console.error
+  print("usage: " + path.basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]")
+  print("        [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]")
+  process.exit(status)
+}
+
+for (var i = 2; i < process.argv.length; ++i) {
+  var arg = process.argv[i]
+  if ((arg == "-" || arg[0] != "-") && !infile) infile = arg
+  else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i]
+  else if (arg == "--locations") options.locations = true
+  else if (arg == "--allow-hash-bang") options.allowHashBang = true
+  else if (arg == "--silent") silent = true
+  else if (arg == "--compact") compact = true
+  else if (arg == "--help") help(0)
+  else if (arg == "--tokenize") tokenize = true
+  else if (arg == "--module") options.sourceType = 'module'
+  else {
+    var match = arg.match(/^--ecma(\d+)$/)
+    if (match)
+      options.ecmaVersion = +match[1]
+    else
+      help(1)
+  }
+}
+
+function run(code) {
+  var result
+  if (!tokenize) {
+    try { result = acorn.parse(code, options) }
+    catch(e) { console.error(e.message); process.exit(1) }
+  } else {
+    result = []
+    var tokenizer = acorn.tokenizer(code, options), token
+    while (true) {
+      try { token = tokenizer.getToken() }
+      catch(e) { console.error(e.message); process.exit(1) }
+      result.push(token)
+      if (token.type == acorn.tokTypes.eof) break
+    }
+  }
+  if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2))
+}
+
+if (forceFile || infile && infile != "-") {
+  run(fs.readFileSync(infile, "utf8"))
+} else {
+  var code = ""
+  process.stdin.resume()
+  process.stdin.on("data", function (chunk) { return code += chunk; })
+  process.stdin.on("end", function () { return run(code); })
+}

HW 13/.idea/.gitignore → Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/.keep


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3401 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.es.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 3433 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1364 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.es.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1374 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/acorn_loose.js


+ 342 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.es.js

@@ -0,0 +1,342 @@
+// AST walker module for Mozilla Parser API compatible trees
+
+// A simple walk is one where you simply specify callbacks to be
+// called on specific nodes. The last two arguments are optional. A
+// simple use would be
+//
+//     walk.simple(myTree, {
+//         Expression: function(node) { ... }
+//     });
+//
+// to do something with all expressions. All Parser API node types
+// can be used to identify node types, as well as Expression,
+// Statement, and ScopeBody, which denote categories of nodes.
+//
+// The base argument can be used to pass a custom (recursive)
+// walker, and state can be used to give this walked an initial
+// state.
+
+function simple(node, visitors, base, state, override) {
+  if (!base) base = exports.base
+  ;(function c(node, st, override) {
+    var type = override || node.type, found = visitors[type]
+    base[type](node, st, c)
+    if (found) found(node, st)
+  })(node, state, override)
+}
+
+// An ancestor walk keeps an array of ancestor nodes (including the
+// current node) and passes them to the callback as third parameter
+// (and also as state parameter when no other state is present).
+function ancestor(node, visitors, base, state) {
+  if (!base) base = exports.base
+  var ancestors = []
+  ;(function c(node, st, override) {
+    var type = override || node.type, found = visitors[type]
+    var isNew = node != ancestors[ancestors.length - 1]
+    if (isNew) ancestors.push(node)
+    base[type](node, st, c)
+    if (found) found(node, st || ancestors, ancestors)
+    if (isNew) ancestors.pop()
+  })(node, state)
+}
+
+// A recursive walk is one where your functions override the default
+// walkers. They can modify and replace the state parameter that's
+// threaded through the walk, and can opt how and whether to walk
+// their child nodes (by calling their third argument on these
+// nodes).
+function recursive(node, state, funcs, base, override) {
+  var visitor = funcs ? exports.make(funcs, base) : base
+  ;(function c(node, st, override) {
+    visitor[override || node.type](node, st, c)
+  })(node, state, override)
+}
+
+function makeTest(test) {
+  if (typeof test == "string")
+    return function (type) { return type == test; }
+  else if (!test)
+    return function () { return true; }
+  else
+    return test
+}
+
+var Found = function Found(node, state) { this.node = node; this.state = state };
+
+// Find a node with a given start, end, and type (all are optional,
+// null can be used as wildcard). Returns a {node, state} object, or
+// undefined when it doesn't find a matching node.
+function findNodeAt(node, start, end, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      var type = override || node.type
+      if ((start == null || node.start <= start) &&
+          (end == null || node.end >= end))
+        base[type](node, st, c)
+      if ((start == null || node.start == start) &&
+          (end == null || node.end == end) &&
+          test(type, node))
+        throw new Found(node, st)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the innermost node of a given type that contains the given
+// position. Interface similar to findNodeAt.
+function findNodeAround(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      var type = override || node.type
+      if (node.start > pos || node.end < pos) return
+      base[type](node, st, c)
+      if (test(type, node)) throw new Found(node, st)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the outermost matching node after a given position.
+function findNodeAfter(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      if (node.end < pos) return
+      var type = override || node.type
+      if (node.start >= pos && test(type, node)) throw new Found(node, st)
+      base[type](node, st, c)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the outermost matching node before a given position.
+function findNodeBefore(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  var max
+  ;(function c(node, st, override) {
+    if (node.start > pos) return
+    var type = override || node.type
+    if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
+      max = new Found(node, st)
+    base[type](node, st, c)
+  })(node, state)
+  return max
+}
+
+// Fallback to an Object.create polyfill for older environments.
+var create = Object.create || function(proto) {
+  function Ctor() {}
+  Ctor.prototype = proto
+  return new Ctor
+}
+
+// Used to create a custom walker. Will fill in all missing node
+// type properties with the defaults.
+function make(funcs, base) {
+  if (!base) base = exports.base
+  var visitor = create(base)
+  for (var type in funcs) visitor[type] = funcs[type]
+  return visitor
+}
+
+function skipThrough(node, st, c) { c(node, st) }
+function ignore(_node, _st, _c) {}
+
+// Node walkers.
+
+var base = {}
+
+base.Program = base.BlockStatement = function (node, st, c) {
+  for (var i = 0; i < node.body.length; ++i)
+    c(node.body[i], st, "Statement")
+}
+base.Statement = skipThrough
+base.EmptyStatement = ignore
+base.ExpressionStatement = base.ParenthesizedExpression =
+  function (node, st, c) { return c(node.expression, st, "Expression"); }
+base.IfStatement = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.consequent, st, "Statement")
+  if (node.alternate) c(node.alternate, st, "Statement")
+}
+base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }
+base.BreakStatement = base.ContinueStatement = ignore
+base.WithStatement = function (node, st, c) {
+  c(node.object, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.SwitchStatement = function (node, st, c) {
+  c(node.discriminant, st, "Expression")
+  for (var i = 0; i < node.cases.length; ++i) {
+    var cs = node.cases[i]
+    if (cs.test) c(cs.test, st, "Expression")
+    for (var j = 0; j < cs.consequent.length; ++j)
+      c(cs.consequent[j], st, "Statement")
+  }
+}
+base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) {
+  if (node.argument) c(node.argument, st, "Expression")
+}
+base.ThrowStatement = base.SpreadElement =
+  function (node, st, c) { return c(node.argument, st, "Expression"); }
+base.TryStatement = function (node, st, c) {
+  c(node.block, st, "Statement")
+  if (node.handler) c(node.handler, st)
+  if (node.finalizer) c(node.finalizer, st, "Statement")
+}
+base.CatchClause = function (node, st, c) {
+  c(node.param, st, "Pattern")
+  c(node.body, st, "ScopeBody")
+}
+base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForStatement = function (node, st, c) {
+  if (node.init) c(node.init, st, "ForInit")
+  if (node.test) c(node.test, st, "Expression")
+  if (node.update) c(node.update, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForInStatement = base.ForOfStatement = function (node, st, c) {
+  c(node.left, st, "ForInit")
+  c(node.right, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForInit = function (node, st, c) {
+  if (node.type == "VariableDeclaration") c(node, st)
+  else c(node, st, "Expression")
+}
+base.DebuggerStatement = ignore
+
+base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }
+base.VariableDeclaration = function (node, st, c) {
+  for (var i = 0; i < node.declarations.length; ++i)
+    c(node.declarations[i], st)
+}
+base.VariableDeclarator = function (node, st, c) {
+  c(node.id, st, "Pattern")
+  if (node.init) c(node.init, st, "Expression")
+}
+
+base.Function = function (node, st, c) {
+  if (node.id) c(node.id, st, "Pattern")
+  for (var i = 0; i < node.params.length; i++)
+    c(node.params[i], st, "Pattern")
+  c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody")
+}
+// FIXME drop these node types in next major version
+// (They are awkward, and in ES6 every block can be a scope.)
+base.ScopeBody = function (node, st, c) { return c(node, st, "Statement"); }
+base.ScopeExpression = function (node, st, c) { return c(node, st, "Expression"); }
+
+base.Pattern = function (node, st, c) {
+  if (node.type == "Identifier")
+    c(node, st, "VariablePattern")
+  else if (node.type == "MemberExpression")
+    c(node, st, "MemberPattern")
+  else
+    c(node, st)
+}
+base.VariablePattern = ignore
+base.MemberPattern = skipThrough
+base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }
+base.ArrayPattern =  function (node, st, c) {
+  for (var i = 0; i < node.elements.length; ++i) {
+    var elt = node.elements[i]
+    if (elt) c(elt, st, "Pattern")
+  }
+}
+base.ObjectPattern = function (node, st, c) {
+  for (var i = 0; i < node.properties.length; ++i)
+    c(node.properties[i].value, st, "Pattern")
+}
+
+base.Expression = skipThrough
+base.ThisExpression = base.Super = base.MetaProperty = ignore
+base.ArrayExpression = function (node, st, c) {
+  for (var i = 0; i < node.elements.length; ++i) {
+    var elt = node.elements[i]
+    if (elt) c(elt, st, "Expression")
+  }
+}
+base.ObjectExpression = function (node, st, c) {
+  for (var i = 0; i < node.properties.length; ++i)
+    c(node.properties[i], st)
+}
+base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration
+base.SequenceExpression = base.TemplateLiteral = function (node, st, c) {
+  for (var i = 0; i < node.expressions.length; ++i)
+    c(node.expressions[i], st, "Expression")
+}
+base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
+  c(node.argument, st, "Expression")
+}
+base.BinaryExpression = base.LogicalExpression = function (node, st, c) {
+  c(node.left, st, "Expression")
+  c(node.right, st, "Expression")
+}
+base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) {
+  c(node.left, st, "Pattern")
+  c(node.right, st, "Expression")
+}
+base.ConditionalExpression = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.consequent, st, "Expression")
+  c(node.alternate, st, "Expression")
+}
+base.NewExpression = base.CallExpression = function (node, st, c) {
+  c(node.callee, st, "Expression")
+  if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
+    c(node.arguments[i], st, "Expression")
+}
+base.MemberExpression = function (node, st, c) {
+  c(node.object, st, "Expression")
+  if (node.computed) c(node.property, st, "Expression")
+}
+base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
+  if (node.declaration)
+    c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression")
+  if (node.source) c(node.source, st, "Expression")
+}
+base.ExportAllDeclaration = function (node, st, c) {
+  c(node.source, st, "Expression")
+}
+base.ImportDeclaration = function (node, st, c) {
+  for (var i = 0; i < node.specifiers.length; i++)
+    c(node.specifiers[i], st)
+  c(node.source, st, "Expression")
+}
+base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore
+
+base.TaggedTemplateExpression = function (node, st, c) {
+  c(node.tag, st, "Expression")
+  c(node.quasi, st)
+}
+base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }
+base.Class = function (node, st, c) {
+  if (node.id) c(node.id, st, "Pattern")
+  if (node.superClass) c(node.superClass, st, "Expression")
+  for (var i = 0; i < node.body.body.length; i++)
+    c(node.body.body[i], st)
+}
+base.MethodDefinition = base.Property = function (node, st, c) {
+  if (node.computed) c(node.key, st, "Expression")
+  c(node.value, st, "Expression")
+}
+
+export { simple, ancestor, recursive, findNodeAt, findNodeAround, findNodeAfter, findNodeBefore, make, base };

+ 360 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/dist/walk.js

@@ -0,0 +1,360 @@
+(function (global, factory) {
+  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+  typeof define === 'function' && define.amd ? define(['exports'], factory) :
+  (factory((global.acorn = global.acorn || {}, global.acorn.walk = global.acorn.walk || {})));
+}(this, (function (exports) { 'use strict';
+
+// AST walker module for Mozilla Parser API compatible trees
+
+// A simple walk is one where you simply specify callbacks to be
+// called on specific nodes. The last two arguments are optional. A
+// simple use would be
+//
+//     walk.simple(myTree, {
+//         Expression: function(node) { ... }
+//     });
+//
+// to do something with all expressions. All Parser API node types
+// can be used to identify node types, as well as Expression,
+// Statement, and ScopeBody, which denote categories of nodes.
+//
+// The base argument can be used to pass a custom (recursive)
+// walker, and state can be used to give this walked an initial
+// state.
+
+function simple(node, visitors, base, state, override) {
+  if (!base) base = exports.base
+  ;(function c(node, st, override) {
+    var type = override || node.type, found = visitors[type]
+    base[type](node, st, c)
+    if (found) found(node, st)
+  })(node, state, override)
+}
+
+// An ancestor walk keeps an array of ancestor nodes (including the
+// current node) and passes them to the callback as third parameter
+// (and also as state parameter when no other state is present).
+function ancestor(node, visitors, base, state) {
+  if (!base) base = exports.base
+  var ancestors = []
+  ;(function c(node, st, override) {
+    var type = override || node.type, found = visitors[type]
+    var isNew = node != ancestors[ancestors.length - 1]
+    if (isNew) ancestors.push(node)
+    base[type](node, st, c)
+    if (found) found(node, st || ancestors, ancestors)
+    if (isNew) ancestors.pop()
+  })(node, state)
+}
+
+// A recursive walk is one where your functions override the default
+// walkers. They can modify and replace the state parameter that's
+// threaded through the walk, and can opt how and whether to walk
+// their child nodes (by calling their third argument on these
+// nodes).
+function recursive(node, state, funcs, base, override) {
+  var visitor = funcs ? exports.make(funcs, base) : base
+  ;(function c(node, st, override) {
+    visitor[override || node.type](node, st, c)
+  })(node, state, override)
+}
+
+function makeTest(test) {
+  if (typeof test == "string")
+    return function (type) { return type == test; }
+  else if (!test)
+    return function () { return true; }
+  else
+    return test
+}
+
+var Found = function Found(node, state) { this.node = node; this.state = state };
+
+// Find a node with a given start, end, and type (all are optional,
+// null can be used as wildcard). Returns a {node, state} object, or
+// undefined when it doesn't find a matching node.
+function findNodeAt(node, start, end, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      var type = override || node.type
+      if ((start == null || node.start <= start) &&
+          (end == null || node.end >= end))
+        base[type](node, st, c)
+      if ((start == null || node.start == start) &&
+          (end == null || node.end == end) &&
+          test(type, node))
+        throw new Found(node, st)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the innermost node of a given type that contains the given
+// position. Interface similar to findNodeAt.
+function findNodeAround(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      var type = override || node.type
+      if (node.start > pos || node.end < pos) return
+      base[type](node, st, c)
+      if (test(type, node)) throw new Found(node, st)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the outermost matching node after a given position.
+function findNodeAfter(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  try {
+    ;(function c(node, st, override) {
+      if (node.end < pos) return
+      var type = override || node.type
+      if (node.start >= pos && test(type, node)) throw new Found(node, st)
+      base[type](node, st, c)
+    })(node, state)
+  } catch (e) {
+    if (e instanceof Found) return e
+    throw e
+  }
+}
+
+// Find the outermost matching node before a given position.
+function findNodeBefore(node, pos, test, base, state) {
+  test = makeTest(test)
+  if (!base) base = exports.base
+  var max
+  ;(function c(node, st, override) {
+    if (node.start > pos) return
+    var type = override || node.type
+    if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node))
+      max = new Found(node, st)
+    base[type](node, st, c)
+  })(node, state)
+  return max
+}
+
+// Fallback to an Object.create polyfill for older environments.
+var create = Object.create || function(proto) {
+  function Ctor() {}
+  Ctor.prototype = proto
+  return new Ctor
+}
+
+// Used to create a custom walker. Will fill in all missing node
+// type properties with the defaults.
+function make(funcs, base) {
+  if (!base) base = exports.base
+  var visitor = create(base)
+  for (var type in funcs) visitor[type] = funcs[type]
+  return visitor
+}
+
+function skipThrough(node, st, c) { c(node, st) }
+function ignore(_node, _st, _c) {}
+
+// Node walkers.
+
+var base = {}
+
+base.Program = base.BlockStatement = function (node, st, c) {
+  for (var i = 0; i < node.body.length; ++i)
+    c(node.body[i], st, "Statement")
+}
+base.Statement = skipThrough
+base.EmptyStatement = ignore
+base.ExpressionStatement = base.ParenthesizedExpression =
+  function (node, st, c) { return c(node.expression, st, "Expression"); }
+base.IfStatement = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.consequent, st, "Statement")
+  if (node.alternate) c(node.alternate, st, "Statement")
+}
+base.LabeledStatement = function (node, st, c) { return c(node.body, st, "Statement"); }
+base.BreakStatement = base.ContinueStatement = ignore
+base.WithStatement = function (node, st, c) {
+  c(node.object, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.SwitchStatement = function (node, st, c) {
+  c(node.discriminant, st, "Expression")
+  for (var i = 0; i < node.cases.length; ++i) {
+    var cs = node.cases[i]
+    if (cs.test) c(cs.test, st, "Expression")
+    for (var j = 0; j < cs.consequent.length; ++j)
+      c(cs.consequent[j], st, "Statement")
+  }
+}
+base.ReturnStatement = base.YieldExpression = base.AwaitExpression = function (node, st, c) {
+  if (node.argument) c(node.argument, st, "Expression")
+}
+base.ThrowStatement = base.SpreadElement =
+  function (node, st, c) { return c(node.argument, st, "Expression"); }
+base.TryStatement = function (node, st, c) {
+  c(node.block, st, "Statement")
+  if (node.handler) c(node.handler, st)
+  if (node.finalizer) c(node.finalizer, st, "Statement")
+}
+base.CatchClause = function (node, st, c) {
+  c(node.param, st, "Pattern")
+  c(node.body, st, "ScopeBody")
+}
+base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForStatement = function (node, st, c) {
+  if (node.init) c(node.init, st, "ForInit")
+  if (node.test) c(node.test, st, "Expression")
+  if (node.update) c(node.update, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForInStatement = base.ForOfStatement = function (node, st, c) {
+  c(node.left, st, "ForInit")
+  c(node.right, st, "Expression")
+  c(node.body, st, "Statement")
+}
+base.ForInit = function (node, st, c) {
+  if (node.type == "VariableDeclaration") c(node, st)
+  else c(node, st, "Expression")
+}
+base.DebuggerStatement = ignore
+
+base.FunctionDeclaration = function (node, st, c) { return c(node, st, "Function"); }
+base.VariableDeclaration = function (node, st, c) {
+  for (var i = 0; i < node.declarations.length; ++i)
+    c(node.declarations[i], st)
+}
+base.VariableDeclarator = function (node, st, c) {
+  c(node.id, st, "Pattern")
+  if (node.init) c(node.init, st, "Expression")
+}
+
+base.Function = function (node, st, c) {
+  if (node.id) c(node.id, st, "Pattern")
+  for (var i = 0; i < node.params.length; i++)
+    c(node.params[i], st, "Pattern")
+  c(node.body, st, node.expression ? "ScopeExpression" : "ScopeBody")
+}
+// FIXME drop these node types in next major version
+// (They are awkward, and in ES6 every block can be a scope.)
+base.ScopeBody = function (node, st, c) { return c(node, st, "Statement"); }
+base.ScopeExpression = function (node, st, c) { return c(node, st, "Expression"); }
+
+base.Pattern = function (node, st, c) {
+  if (node.type == "Identifier")
+    c(node, st, "VariablePattern")
+  else if (node.type == "MemberExpression")
+    c(node, st, "MemberPattern")
+  else
+    c(node, st)
+}
+base.VariablePattern = ignore
+base.MemberPattern = skipThrough
+base.RestElement = function (node, st, c) { return c(node.argument, st, "Pattern"); }
+base.ArrayPattern =  function (node, st, c) {
+  for (var i = 0; i < node.elements.length; ++i) {
+    var elt = node.elements[i]
+    if (elt) c(elt, st, "Pattern")
+  }
+}
+base.ObjectPattern = function (node, st, c) {
+  for (var i = 0; i < node.properties.length; ++i)
+    c(node.properties[i].value, st, "Pattern")
+}
+
+base.Expression = skipThrough
+base.ThisExpression = base.Super = base.MetaProperty = ignore
+base.ArrayExpression = function (node, st, c) {
+  for (var i = 0; i < node.elements.length; ++i) {
+    var elt = node.elements[i]
+    if (elt) c(elt, st, "Expression")
+  }
+}
+base.ObjectExpression = function (node, st, c) {
+  for (var i = 0; i < node.properties.length; ++i)
+    c(node.properties[i], st)
+}
+base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration
+base.SequenceExpression = base.TemplateLiteral = function (node, st, c) {
+  for (var i = 0; i < node.expressions.length; ++i)
+    c(node.expressions[i], st, "Expression")
+}
+base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
+  c(node.argument, st, "Expression")
+}
+base.BinaryExpression = base.LogicalExpression = function (node, st, c) {
+  c(node.left, st, "Expression")
+  c(node.right, st, "Expression")
+}
+base.AssignmentExpression = base.AssignmentPattern = function (node, st, c) {
+  c(node.left, st, "Pattern")
+  c(node.right, st, "Expression")
+}
+base.ConditionalExpression = function (node, st, c) {
+  c(node.test, st, "Expression")
+  c(node.consequent, st, "Expression")
+  c(node.alternate, st, "Expression")
+}
+base.NewExpression = base.CallExpression = function (node, st, c) {
+  c(node.callee, st, "Expression")
+  if (node.arguments) for (var i = 0; i < node.arguments.length; ++i)
+    c(node.arguments[i], st, "Expression")
+}
+base.MemberExpression = function (node, st, c) {
+  c(node.object, st, "Expression")
+  if (node.computed) c(node.property, st, "Expression")
+}
+base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
+  if (node.declaration)
+    c(node.declaration, st, node.type == "ExportNamedDeclaration" || node.declaration.id ? "Statement" : "Expression")
+  if (node.source) c(node.source, st, "Expression")
+}
+base.ExportAllDeclaration = function (node, st, c) {
+  c(node.source, st, "Expression")
+}
+base.ImportDeclaration = function (node, st, c) {
+  for (var i = 0; i < node.specifiers.length; i++)
+    c(node.specifiers[i], st)
+  c(node.source, st, "Expression")
+}
+base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore
+
+base.TaggedTemplateExpression = function (node, st, c) {
+  c(node.tag, st, "Expression")
+  c(node.quasi, st)
+}
+base.ClassDeclaration = base.ClassExpression = function (node, st, c) { return c(node, st, "Class"); }
+base.Class = function (node, st, c) {
+  if (node.id) c(node.id, st, "Pattern")
+  if (node.superClass) c(node.superClass, st, "Expression")
+  for (var i = 0; i < node.body.body.length; i++)
+    c(node.body.body[i], st)
+}
+base.MethodDefinition = base.Property = function (node, st, c) {
+  if (node.computed) c(node.key, st, "Expression")
+  c(node.value, st, "Expression")
+}
+
+exports.simple = simple;
+exports.ancestor = ancestor;
+exports.recursive = recursive;
+exports.findNodeAt = findNodeAt;
+exports.findNodeAround = findNodeAround;
+exports.findNodeAfter = findNodeAfter;
+exports.findNodeBefore = findNodeBefore;
+exports.make = make;
+exports.base = base;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));

+ 46 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/package.json

@@ -0,0 +1,46 @@
+{
+  "name": "acorn",
+  "description": "ECMAScript parser",
+  "homepage": "https://github.com/ternjs/acorn",
+  "main": "dist/acorn.js",
+  "jsnext:main": "dist/acorn.es.js",
+  "version": "4.0.13",
+  "engines": {
+    "node": ">=0.4.0"
+  },
+  "maintainers": [
+    {
+      "name": "Marijn Haverbeke",
+      "email": "marijnh@gmail.com",
+      "web": "http://marijnhaverbeke.nl"
+    },
+    {
+      "name": "Ingvar Stepanyan",
+      "email": "me@rreverser.com",
+      "web": "http://rreverser.com/"
+    }
+  ],
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/ternjs/acorn.git"
+  },
+  "license": "MIT",
+  "scripts": {
+    "prepublish": "npm test",
+    "test": "node test/run.js",
+    "pretest": "npm run build",
+    "build": "npm run build:main && npm run build:walk && npm run build:loose && npm run build:bin",
+    "build:main": "rollup -c rollup/config.main.js",
+    "build:walk": "rollup -c rollup/config.walk.js",
+    "build:loose": "rollup -c rollup/config.loose.js",
+    "build:bin": "rollup -c rollup/config.bin.js"
+  },
+  "bin": {
+    "acorn": "./bin/acorn"
+  },
+  "devDependencies": {
+    "rollup": "^0.34.1",
+    "rollup-plugin-buble": "^0.11.0",
+    "unicode-9.0.0": "^0.7.0"
+  }
+}

+ 60 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/bin/acorn.js

@@ -0,0 +1,60 @@
+import {basename} from "path"
+import {readFileSync as readFile} from "fs"
+import * as acorn from "acorn"
+
+let infile, forceFile, silent = false, compact = false, tokenize = false
+const options = {}
+
+function help(status) {
+  const print = (status == 0) ? console.log : console.error
+  print("usage: " + basename(process.argv[1]) + " [--ecma3|--ecma5|--ecma6|--ecma7|...|--ecma2015|--ecma2016|...]")
+  print("        [--tokenize] [--locations] [---allow-hash-bang] [--compact] [--silent] [--module] [--help] [--] [infile]")
+  process.exit(status)
+}
+
+for (let i = 2; i < process.argv.length; ++i) {
+  const arg = process.argv[i]
+  if ((arg == "-" || arg[0] != "-") && !infile) infile = arg
+  else if (arg == "--" && !infile && i + 2 == process.argv.length) forceFile = infile = process.argv[++i]
+  else if (arg == "--locations") options.locations = true
+  else if (arg == "--allow-hash-bang") options.allowHashBang = true
+  else if (arg == "--silent") silent = true
+  else if (arg == "--compact") compact = true
+  else if (arg == "--help") help(0)
+  else if (arg == "--tokenize") tokenize = true
+  else if (arg == "--module") options.sourceType = 'module'
+  else {
+    let match = arg.match(/^--ecma(\d+)$/)
+    if (match)
+      options.ecmaVersion = +match[1]
+    else
+      help(1)
+  }
+}
+
+function run(code) {
+  let result
+  if (!tokenize) {
+    try { result = acorn.parse(code, options) }
+    catch(e) { console.error(e.message); process.exit(1) }
+  } else {
+    result = []
+    let tokenizer = acorn.tokenizer(code, options), token
+    while (true) {
+      try { token = tokenizer.getToken() }
+      catch(e) { console.error(e.message); process.exit(1) }
+      result.push(token)
+      if (token.type == acorn.tokTypes.eof) break
+    }
+  }
+  if (!silent) console.log(JSON.stringify(result, null, compact ? null : 2))
+}
+
+if (forceFile || infile && infile != "-") {
+  run(readFile(infile, "utf8"))
+} else {
+  let code = ""
+  process.stdin.resume()
+  process.stdin.on("data", chunk => code += chunk)
+  process.stdin.on("end", () => run(code))
+}

+ 819 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/expression.js

@@ -0,0 +1,819 @@
+// A recursive descent parser operates by defining functions for all
+// syntactic elements, and recursively calling those, each function
+// advancing the input stream and returning an AST node. Precedence
+// of constructs (for example, the fact that `!x[1]` means `!(x[1])`
+// instead of `(!x)[1]` is handled by the fact that the parser
+// function that parses unary prefix operators is called first, and
+// in turn calls the function that parses `[]` subscripts — that
+// way, it'll receive the node for `x[1]` already parsed, and wraps
+// *that* in the unary operator node.
+//
+// Acorn uses an [operator precedence parser][opp] to handle binary
+// operator precedence, because it is much more compact than using
+// the technique outlined above, which uses different, nesting
+// functions to specify precedence, for all of the ten binary
+// precedence levels that JavaScript defines.
+//
+// [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
+
+import {types as tt} from "./tokentype"
+import {Parser} from "./state"
+import {DestructuringErrors} from "./parseutil"
+
+const pp = Parser.prototype
+
+// Check if property name clashes with already added.
+// Object/class getters and setters are not allowed to clash —
+// either with each other or with an init property — and in
+// strict mode, init properties are also not allowed to be repeated.
+
+pp.checkPropClash = function(prop, propHash) {
+  if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
+    return
+  let {key} = prop, name
+  switch (key.type) {
+  case "Identifier": name = key.name; break
+  case "Literal": name = String(key.value); break
+  default: return
+  }
+  let {kind} = prop
+  if (this.options.ecmaVersion >= 6) {
+    if (name === "__proto__" && kind === "init") {
+      if (propHash.proto) this.raiseRecoverable(key.start, "Redefinition of __proto__ property")
+      propHash.proto = true
+    }
+    return
+  }
+  name = "$" + name
+  let other = propHash[name]
+  if (other) {
+    let isGetSet = kind !== "init"
+    if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init))
+      this.raiseRecoverable(key.start, "Redefinition of property")
+  } else {
+    other = propHash[name] = {
+      init: false,
+      get: false,
+      set: false
+    }
+  }
+  other[kind] = true
+}
+
+// ### Expression parsing
+
+// These nest, from the most general expression type at the top to
+// 'atomic', nondivisible expression types at the bottom. Most of
+// the functions will simply let the function(s) below them parse,
+// and, *if* the syntactic construct they handle is present, wrap
+// the AST node that the inner parser gave them in another node.
+
+// Parse a full expression. The optional arguments are used to
+// forbid the `in` operator (in for loops initalization expressions)
+// and provide reference for storing '=' operator inside shorthand
+// property assignment in contexts where both object expression
+// and object pattern might appear (so it's possible to raise
+// delayed syntax error at correct position).
+
+pp.parseExpression = function(noIn, refDestructuringErrors) {
+  let startPos = this.start, startLoc = this.startLoc
+  let expr = this.parseMaybeAssign(noIn, refDestructuringErrors)
+  if (this.type === tt.comma) {
+    let node = this.startNodeAt(startPos, startLoc)
+    node.expressions = [expr]
+    while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refDestructuringErrors))
+    return this.finishNode(node, "SequenceExpression")
+  }
+  return expr
+}
+
+// Parse an assignment expression. This includes applications of
+// operators like `+=`.
+
+pp.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
+  if (this.inGenerator && this.isContextual("yield")) return this.parseYield()
+
+  let ownDestructuringErrors = false, oldParenAssign = -1
+  if (refDestructuringErrors) {
+    oldParenAssign = refDestructuringErrors.parenthesizedAssign
+    refDestructuringErrors.parenthesizedAssign = -1
+  } else {
+    refDestructuringErrors = new DestructuringErrors
+    ownDestructuringErrors = true
+  }
+
+  let startPos = this.start, startLoc = this.startLoc
+  if (this.type == tt.parenL || this.type == tt.name)
+    this.potentialArrowAt = this.start
+  let left = this.parseMaybeConditional(noIn, refDestructuringErrors)
+  if (afterLeftParse) left = afterLeftParse.call(this, left, startPos, startLoc)
+  if (this.type.isAssign) {
+    this.checkPatternErrors(refDestructuringErrors, true)
+    if (!ownDestructuringErrors) DestructuringErrors.call(refDestructuringErrors)
+    let node = this.startNodeAt(startPos, startLoc)
+    node.operator = this.value
+    node.left = this.type === tt.eq ? this.toAssignable(left) : left
+    refDestructuringErrors.shorthandAssign = -1 // reset because shorthand default was used correctly
+    this.checkLVal(left)
+    this.next()
+    node.right = this.parseMaybeAssign(noIn)
+    return this.finishNode(node, "AssignmentExpression")
+  } else {
+    if (ownDestructuringErrors) this.checkExpressionErrors(refDestructuringErrors, true)
+  }
+  if (oldParenAssign > -1) refDestructuringErrors.parenthesizedAssign = oldParenAssign
+  return left
+}
+
+// Parse a ternary conditional (`?:`) operator.
+
+pp.parseMaybeConditional = function(noIn, refDestructuringErrors) {
+  let startPos = this.start, startLoc = this.startLoc
+  let expr = this.parseExprOps(noIn, refDestructuringErrors)
+  if (this.checkExpressionErrors(refDestructuringErrors)) return expr
+  if (this.eat(tt.question)) {
+    let node = this.startNodeAt(startPos, startLoc)
+    node.test = expr
+    node.consequent = this.parseMaybeAssign()
+    this.expect(tt.colon)
+    node.alternate = this.parseMaybeAssign(noIn)
+    return this.finishNode(node, "ConditionalExpression")
+  }
+  return expr
+}
+
+// Start the precedence parser.
+
+pp.parseExprOps = function(noIn, refDestructuringErrors) {
+  let startPos = this.start, startLoc = this.startLoc
+  let expr = this.parseMaybeUnary(refDestructuringErrors, false)
+  if (this.checkExpressionErrors(refDestructuringErrors)) return expr
+  return this.parseExprOp(expr, startPos, startLoc, -1, noIn)
+}
+
+// Parse binary operators with the operator precedence parsing
+// algorithm. `left` is the left-hand side of the operator.
+// `minPrec` provides context that allows the function to stop and
+// defer further parser to one of its callers when it encounters an
+// operator that has a lower precedence than the set it is parsing.
+
+pp.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
+  let prec = this.type.binop
+  if (prec != null && (!noIn || this.type !== tt._in)) {
+    if (prec > minPrec) {
+      let logical = this.type === tt.logicalOR || this.type === tt.logicalAND
+      let op = this.value
+      this.next()
+      let startPos = this.start, startLoc = this.startLoc
+      let right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn)
+      let node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical)
+      return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
+    }
+  }
+  return left
+}
+
+pp.buildBinary = function(startPos, startLoc, left, right, op, logical) {
+  let node = this.startNodeAt(startPos, startLoc)
+  node.left = left
+  node.operator = op
+  node.right = right
+  return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
+}
+
+// Parse unary operators, both prefix and postfix.
+
+pp.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
+  let startPos = this.start, startLoc = this.startLoc, expr
+  if (this.inAsync && this.isContextual("await")) {
+    expr = this.parseAwait(refDestructuringErrors)
+    sawUnary = true
+  } else if (this.type.prefix) {
+    let node = this.startNode(), update = this.type === tt.incDec
+    node.operator = this.value
+    node.prefix = true
+    this.next()
+    node.argument = this.parseMaybeUnary(null, true)
+    this.checkExpressionErrors(refDestructuringErrors, true)
+    if (update) this.checkLVal(node.argument)
+    else if (this.strict && node.operator === "delete" &&
+             node.argument.type === "Identifier")
+      this.raiseRecoverable(node.start, "Deleting local variable in strict mode")
+    else sawUnary = true
+    expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression")
+  } else {
+    expr = this.parseExprSubscripts(refDestructuringErrors)
+    if (this.checkExpressionErrors(refDestructuringErrors)) return expr
+    while (this.type.postfix && !this.canInsertSemicolon()) {
+      let node = this.startNodeAt(startPos, startLoc)
+      node.operator = this.value
+      node.prefix = false
+      node.argument = expr
+      this.checkLVal(expr)
+      this.next()
+      expr = this.finishNode(node, "UpdateExpression")
+    }
+  }
+
+  if (!sawUnary && this.eat(tt.starstar))
+    return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false)
+  else
+    return expr
+}
+
+// Parse call, dot, and `[]`-subscript expressions.
+
+pp.parseExprSubscripts = function(refDestructuringErrors) {
+  let startPos = this.start, startLoc = this.startLoc
+  let expr = this.parseExprAtom(refDestructuringErrors)
+  let skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")"
+  if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) return expr
+  let result = this.parseSubscripts(expr, startPos, startLoc)
+  if (refDestructuringErrors && result.type === "MemberExpression") {
+    if (refDestructuringErrors.parenthesizedAssign >= result.start) refDestructuringErrors.parenthesizedAssign = -1
+    if (refDestructuringErrors.parenthesizedBind >= result.start) refDestructuringErrors.parenthesizedBind = -1
+  }
+  return result
+}
+
+pp.parseSubscripts = function(base, startPos, startLoc, noCalls) {
+  let maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
+      this.lastTokEnd == base.end && !this.canInsertSemicolon()
+  for (let computed;;) {
+    if ((computed = this.eat(tt.bracketL)) || this.eat(tt.dot)) {
+      let node = this.startNodeAt(startPos, startLoc)
+      node.object = base
+      node.property = computed ? this.parseExpression() : this.parseIdent(true)
+      node.computed = !!computed
+      if (computed) this.expect(tt.bracketR)
+      base = this.finishNode(node, "MemberExpression")
+    } else if (!noCalls && this.eat(tt.parenL)) {
+      let refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos
+      this.yieldPos = 0
+      this.awaitPos = 0
+      let exprList = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false, refDestructuringErrors)
+      if (maybeAsyncArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
+        this.checkPatternErrors(refDestructuringErrors, false)
+        this.checkYieldAwaitInDefaultParams()
+        this.yieldPos = oldYieldPos
+        this.awaitPos = oldAwaitPos
+        return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList, true)
+      }
+      this.checkExpressionErrors(refDestructuringErrors, true)
+      this.yieldPos = oldYieldPos || this.yieldPos
+      this.awaitPos = oldAwaitPos || this.awaitPos
+      let node = this.startNodeAt(startPos, startLoc)
+      node.callee = base
+      node.arguments = exprList
+      base = this.finishNode(node, "CallExpression")
+    } else if (this.type === tt.backQuote) {
+      let node = this.startNodeAt(startPos, startLoc)
+      node.tag = base
+      node.quasi = this.parseTemplate()
+      base = this.finishNode(node, "TaggedTemplateExpression")
+    } else {
+      return base
+    }
+  }
+}
+
+// Parse an atomic expression — either a single token that is an
+// expression, an expression started by a keyword like `function` or
+// `new`, or an expression wrapped in punctuation like `()`, `[]`,
+// or `{}`.
+
+pp.parseExprAtom = function(refDestructuringErrors) {
+  let node, canBeArrow = this.potentialArrowAt == this.start
+  switch (this.type) {
+  case tt._super:
+    if (!this.inFunction)
+      this.raise(this.start, "'super' outside of function or class")
+
+  case tt._this:
+    let type = this.type === tt._this ? "ThisExpression" : "Super"
+    node = this.startNode()
+    this.next()
+    return this.finishNode(node, type)
+
+  case tt.name:
+    let startPos = this.start, startLoc = this.startLoc
+    let id = this.parseIdent(this.type !== tt.name)
+    if (this.options.ecmaVersion >= 8 && id.name === "async" && !this.canInsertSemicolon() && this.eat(tt._function))
+      return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true)
+    if (canBeArrow && !this.canInsertSemicolon()) {
+      if (this.eat(tt.arrow))
+        return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false)
+      if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === tt.name) {
+        id = this.parseIdent()
+        if (this.canInsertSemicolon() || !this.eat(tt.arrow))
+          this.unexpected()
+        return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
+      }
+    }
+    return id
+
+  case tt.regexp:
+    let value = this.value
+    node = this.parseLiteral(value.value)
+    node.regex = {pattern: value.pattern, flags: value.flags}
+    return node
+
+  case tt.num: case tt.string:
+    return this.parseLiteral(this.value)
+
+  case tt._null: case tt._true: case tt._false:
+    node = this.startNode()
+    node.value = this.type === tt._null ? null : this.type === tt._true
+    node.raw = this.type.keyword
+    this.next()
+    return this.finishNode(node, "Literal")
+
+  case tt.parenL:
+    let start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow)
+    if (refDestructuringErrors) {
+      if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
+        refDestructuringErrors.parenthesizedAssign = start
+      if (refDestructuringErrors.parenthesizedBind < 0)
+        refDestructuringErrors.parenthesizedBind = start
+    }
+    return expr
+
+  case tt.bracketL:
+    node = this.startNode()
+    this.next()
+    node.elements = this.parseExprList(tt.bracketR, true, true, refDestructuringErrors)
+    return this.finishNode(node, "ArrayExpression")
+
+  case tt.braceL:
+    return this.parseObj(false, refDestructuringErrors)
+
+  case tt._function:
+    node = this.startNode()
+    this.next()
+    return this.parseFunction(node, false)
+
+  case tt._class:
+    return this.parseClass(this.startNode(), false)
+
+  case tt._new:
+    return this.parseNew()
+
+  case tt.backQuote:
+    return this.parseTemplate()
+
+  default:
+    this.unexpected()
+  }
+}
+
+pp.parseLiteral = function(value) {
+  let node = this.startNode()
+  node.value = value
+  node.raw = this.input.slice(this.start, this.end)
+  this.next()
+  return this.finishNode(node, "Literal")
+}
+
+pp.parseParenExpression = function() {
+  this.expect(tt.parenL)
+  let val = this.parseExpression()
+  this.expect(tt.parenR)
+  return val
+}
+
+pp.parseParenAndDistinguishExpression = function(canBeArrow) {
+  let startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8
+  if (this.options.ecmaVersion >= 6) {
+    this.next()
+
+    let innerStartPos = this.start, innerStartLoc = this.startLoc
+    let exprList = [], first = true, lastIsComma = false
+    let refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart, innerParenStart
+    this.yieldPos = 0
+    this.awaitPos = 0
+    while (this.type !== tt.parenR) {
+      first ? first = false : this.expect(tt.comma)
+      if (allowTrailingComma && this.afterTrailingComma(tt.parenR, true)) {
+        lastIsComma = true
+        break
+      } else if (this.type === tt.ellipsis) {
+        spreadStart = this.start
+        exprList.push(this.parseParenItem(this.parseRest()))
+        if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element")
+        break
+      } else {
+        if (this.type === tt.parenL && !innerParenStart) {
+          innerParenStart = this.start
+        }
+        exprList.push(this.parseMaybeAssign(false, refDestructuringErrors, this.parseParenItem))
+      }
+    }
+    let innerEndPos = this.start, innerEndLoc = this.startLoc
+    this.expect(tt.parenR)
+
+    if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
+      this.checkPatternErrors(refDestructuringErrors, false)
+      this.checkYieldAwaitInDefaultParams()
+      if (innerParenStart) this.unexpected(innerParenStart)
+      this.yieldPos = oldYieldPos
+      this.awaitPos = oldAwaitPos
+      return this.parseParenArrowList(startPos, startLoc, exprList)
+    }
+
+    if (!exprList.length || lastIsComma) this.unexpected(this.lastTokStart)
+    if (spreadStart) this.unexpected(spreadStart)
+    this.checkExpressionErrors(refDestructuringErrors, true)
+    this.yieldPos = oldYieldPos || this.yieldPos
+    this.awaitPos = oldAwaitPos || this.awaitPos
+
+    if (exprList.length > 1) {
+      val = this.startNodeAt(innerStartPos, innerStartLoc)
+      val.expressions = exprList
+      this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc)
+    } else {
+      val = exprList[0]
+    }
+  } else {
+    val = this.parseParenExpression()
+  }
+
+  if (this.options.preserveParens) {
+    let par = this.startNodeAt(startPos, startLoc)
+    par.expression = val
+    return this.finishNode(par, "ParenthesizedExpression")
+  } else {
+    return val
+  }
+}
+
+pp.parseParenItem = function(item) {
+  return item
+}
+
+pp.parseParenArrowList = function(startPos, startLoc, exprList) {
+  return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
+}
+
+// New's precedence is slightly tricky. It must allow its argument to
+// be a `[]` or dot subscript expression, but not a call — at least,
+// not without wrapping it in parentheses. Thus, it uses the noCalls
+// argument to parseSubscripts to prevent it from consuming the
+// argument list.
+
+const empty = []
+
+pp.parseNew = function() {
+  let node = this.startNode()
+  let meta = this.parseIdent(true)
+  if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
+    node.meta = meta
+    node.property = this.parseIdent(true)
+    if (node.property.name !== "target")
+      this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target")
+    if (!this.inFunction)
+      this.raiseRecoverable(node.start, "new.target can only be used in functions")
+    return this.finishNode(node, "MetaProperty")
+  }
+  let startPos = this.start, startLoc = this.startLoc
+  node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true)
+  if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, this.options.ecmaVersion >= 8, false)
+  else node.arguments = empty
+  return this.finishNode(node, "NewExpression")
+}
+
+// Parse template expression.
+
+pp.parseTemplateElement = function() {
+  let elem = this.startNode()
+  elem.value = {
+    raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, '\n'),
+    cooked: this.value
+  }
+  this.next()
+  elem.tail = this.type === tt.backQuote
+  return this.finishNode(elem, "TemplateElement")
+}
+
+pp.parseTemplate = function() {
+  let node = this.startNode()
+  this.next()
+  node.expressions = []
+  let curElt = this.parseTemplateElement()
+  node.quasis = [curElt]
+  while (!curElt.tail) {
+    this.expect(tt.dollarBraceL)
+    node.expressions.push(this.parseExpression())
+    this.expect(tt.braceR)
+    node.quasis.push(curElt = this.parseTemplateElement())
+  }
+  this.next()
+  return this.finishNode(node, "TemplateLiteral")
+}
+
+// Parse an object literal or binding pattern.
+
+pp.parseObj = function(isPattern, refDestructuringErrors) {
+  let node = this.startNode(), first = true, propHash = {}
+  node.properties = []
+  this.next()
+  while (!this.eat(tt.braceR)) {
+    if (!first) {
+      this.expect(tt.comma)
+      if (this.afterTrailingComma(tt.braceR)) break
+    } else first = false
+
+    let prop = this.startNode(), isGenerator, isAsync, startPos, startLoc
+    if (this.options.ecmaVersion >= 6) {
+      prop.method = false
+      prop.shorthand = false
+      if (isPattern || refDestructuringErrors) {
+        startPos = this.start
+        startLoc = this.startLoc
+      }
+      if (!isPattern)
+        isGenerator = this.eat(tt.star)
+    }
+    this.parsePropertyName(prop)
+    if (!isPattern && this.options.ecmaVersion >= 8 && !isGenerator && !prop.computed &&
+        prop.key.type === "Identifier" && prop.key.name === "async" && this.type !== tt.parenL &&
+        this.type !== tt.colon && !this.canInsertSemicolon()) {
+      isAsync = true
+      this.parsePropertyName(prop, refDestructuringErrors)
+    } else {
+      isAsync = false
+    }
+    this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors)
+    this.checkPropClash(prop, propHash)
+    node.properties.push(this.finishNode(prop, "Property"))
+  }
+  return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
+}
+
+pp.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors) {
+  if ((isGenerator || isAsync) && this.type === tt.colon)
+    this.unexpected()
+
+  if (this.eat(tt.colon)) {
+    prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors)
+    prop.kind = "init"
+  } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
+    if (isPattern) this.unexpected()
+    prop.kind = "init"
+    prop.method = true
+    prop.value = this.parseMethod(isGenerator, isAsync)
+  } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
+             (prop.key.name === "get" || prop.key.name === "set") &&
+             (this.type != tt.comma && this.type != tt.braceR)) {
+    if (isGenerator || isAsync || isPattern) this.unexpected()
+    prop.kind = prop.key.name
+    this.parsePropertyName(prop)
+    prop.value = this.parseMethod(false)
+    let paramCount = prop.kind === "get" ? 0 : 1
+    if (prop.value.params.length !== paramCount) {
+      let start = prop.value.start
+      if (prop.kind === "get")
+        this.raiseRecoverable(start, "getter should have no params")
+      else
+        this.raiseRecoverable(start, "setter should have exactly one param")
+    } else {
+      if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
+        this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params")
+    }
+  } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
+    if (this.keywords.test(prop.key.name) ||
+        (this.strict ? this.reservedWordsStrict : this.reservedWords).test(prop.key.name) ||
+        (this.inGenerator && prop.key.name == "yield") ||
+        (this.inAsync && prop.key.name == "await"))
+      this.raiseRecoverable(prop.key.start, "'" + prop.key.name + "' can not be used as shorthand property")
+    prop.kind = "init"
+    if (isPattern) {
+      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
+    } else if (this.type === tt.eq && refDestructuringErrors) {
+      if (refDestructuringErrors.shorthandAssign < 0)
+        refDestructuringErrors.shorthandAssign = this.start
+      prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key)
+    } else {
+      prop.value = prop.key
+    }
+    prop.shorthand = true
+  } else this.unexpected()
+}
+
+pp.parsePropertyName = function(prop) {
+  if (this.options.ecmaVersion >= 6) {
+    if (this.eat(tt.bracketL)) {
+      prop.computed = true
+      prop.key = this.parseMaybeAssign()
+      this.expect(tt.bracketR)
+      return prop.key
+    } else {
+      prop.computed = false
+    }
+  }
+  return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true)
+}
+
+// Initialize empty function node.
+
+pp.initFunction = function(node) {
+  node.id = null
+  if (this.options.ecmaVersion >= 6) {
+    node.generator = false
+    node.expression = false
+  }
+  if (this.options.ecmaVersion >= 8)
+    node.async = false
+}
+
+// Parse object or class method.
+
+pp.parseMethod = function(isGenerator, isAsync) {
+  let node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,
+      oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction
+
+  this.initFunction(node)
+  if (this.options.ecmaVersion >= 6)
+    node.generator = isGenerator
+  if (this.options.ecmaVersion >= 8)
+    node.async = !!isAsync
+
+  this.inGenerator = node.generator
+  this.inAsync = node.async
+  this.yieldPos = 0
+  this.awaitPos = 0
+  this.inFunction = true
+
+  this.expect(tt.parenL)
+  node.params = this.parseBindingList(tt.parenR, false, this.options.ecmaVersion >= 8)
+  this.checkYieldAwaitInDefaultParams()
+  this.parseFunctionBody(node, false)
+
+  this.inGenerator = oldInGen
+  this.inAsync = oldInAsync
+  this.yieldPos = oldYieldPos
+  this.awaitPos = oldAwaitPos
+  this.inFunction = oldInFunc
+  return this.finishNode(node, "FunctionExpression")
+}
+
+// Parse arrow function expression with given parameters.
+
+pp.parseArrowExpression = function(node, params, isAsync) {
+  let oldInGen = this.inGenerator, oldInAsync = this.inAsync,
+      oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction
+
+  this.initFunction(node)
+  if (this.options.ecmaVersion >= 8)
+    node.async = !!isAsync
+
+  this.inGenerator = false
+  this.inAsync = node.async
+  this.yieldPos = 0
+  this.awaitPos = 0
+  this.inFunction = true
+
+  node.params = this.toAssignableList(params, true)
+  this.parseFunctionBody(node, true)
+
+  this.inGenerator = oldInGen
+  this.inAsync = oldInAsync
+  this.yieldPos = oldYieldPos
+  this.awaitPos = oldAwaitPos
+  this.inFunction = oldInFunc
+  return this.finishNode(node, "ArrowFunctionExpression")
+}
+
+// Parse function body and check parameters.
+
+pp.parseFunctionBody = function(node, isArrowFunction) {
+  let isExpression = isArrowFunction && this.type !== tt.braceL
+  let oldStrict = this.strict, useStrict = false
+
+  if (isExpression) {
+    node.body = this.parseMaybeAssign()
+    node.expression = true
+  } else {
+    let nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params)
+    if (!oldStrict || nonSimple) {
+      useStrict = this.strictDirective(this.end)
+      // If this is a strict mode function, verify that argument names
+      // are not repeated, and it does not try to bind the words `eval`
+      // or `arguments`.
+      if (useStrict && nonSimple)
+        this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list")
+    }
+    // Start a new scope with regard to labels and the `inFunction`
+    // flag (restore them to their old value afterwards).
+    let oldLabels = this.labels
+    this.labels = []
+    if (useStrict) this.strict = true
+    node.body = this.parseBlock(true)
+    node.expression = false
+    this.labels = oldLabels
+  }
+
+  if (oldStrict || useStrict) {
+    this.strict = true
+    if (node.id)
+      this.checkLVal(node.id, true)
+    this.checkParams(node)
+    this.strict = oldStrict
+  } else if (isArrowFunction || !this.isSimpleParamList(node.params)) {
+    this.checkParams(node)
+  }
+}
+
+pp.isSimpleParamList = function(params) {
+  for (let i = 0; i < params.length; i++)
+    if (params[i].type !== "Identifier") return false
+  return true
+}
+
+// Checks function params for various disallowed patterns such as using "eval"
+// or "arguments" and duplicate parameters.
+
+pp.checkParams = function(node) {
+  let nameHash = {}
+  for (let i = 0; i < node.params.length; i++) this.checkLVal(node.params[i], true, nameHash)
+}
+
+// Parses a comma-separated list of expressions, and returns them as
+// an array. `close` is the token type that ends the list, and
+// `allowEmpty` can be turned on to allow subsequent commas with
+// nothing in between them to be parsed as `null` (which is needed
+// for array literals).
+
+pp.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
+  let elts = [], first = true
+  while (!this.eat(close)) {
+    if (!first) {
+      this.expect(tt.comma)
+      if (allowTrailingComma && this.afterTrailingComma(close)) break
+    } else first = false
+
+    let elt
+    if (allowEmpty && this.type === tt.comma)
+      elt = null
+    else if (this.type === tt.ellipsis) {
+      elt = this.parseSpread(refDestructuringErrors)
+      if (refDestructuringErrors && this.type === tt.comma && refDestructuringErrors.trailingComma < 0)
+        refDestructuringErrors.trailingComma = this.start
+    } else {
+      elt = this.parseMaybeAssign(false, refDestructuringErrors)
+    }
+    elts.push(elt)
+  }
+  return elts
+}
+
+// Parse the next token as an identifier. If `liberal` is true (used
+// when parsing properties), it will also convert keywords into
+// identifiers.
+
+pp.parseIdent = function(liberal) {
+  let node = this.startNode()
+  if (liberal && this.options.allowReserved == "never") liberal = false
+  if (this.type === tt.name) {
+    if (!liberal && (this.strict ? this.reservedWordsStrict : this.reservedWords).test(this.value) &&
+        (this.options.ecmaVersion >= 6 ||
+         this.input.slice(this.start, this.end).indexOf("\\") == -1))
+      this.raiseRecoverable(this.start, "The keyword '" + this.value + "' is reserved")
+    if (this.inGenerator && this.value === "yield")
+      this.raiseRecoverable(this.start, "Can not use 'yield' as identifier inside a generator")
+    if (this.inAsync && this.value === "await")
+      this.raiseRecoverable(this.start, "Can not use 'await' as identifier inside an async function")
+    node.name = this.value
+  } else if (liberal && this.type.keyword) {
+    node.name = this.type.keyword
+  } else {
+    this.unexpected()
+  }
+  this.next()
+  return this.finishNode(node, "Identifier")
+}
+
+// Parses yield expression inside generator.
+
+pp.parseYield = function() {
+  if (!this.yieldPos) this.yieldPos = this.start
+
+  let node = this.startNode()
+  this.next()
+  if (this.type == tt.semi || this.canInsertSemicolon() || (this.type != tt.star && !this.type.startsExpr)) {
+    node.delegate = false
+    node.argument = null
+  } else {
+    node.delegate = this.eat(tt.star)
+    node.argument = this.parseMaybeAssign()
+  }
+  return this.finishNode(node, "YieldExpression")
+}
+
+pp.parseAwait = function() {
+  if (!this.awaitPos) this.awaitPos = this.start
+
+  let node = this.startNode()
+  this.next()
+  node.argument = this.parseMaybeUnary(null, true)
+  return this.finishNode(node, "AwaitExpression")
+}

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 81 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/identifier.js


+ 77 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/index.js

@@ -0,0 +1,77 @@
+// Acorn is a tiny, fast JavaScript parser written in JavaScript.
+//
+// Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
+// various contributors and released under an MIT license.
+//
+// Git repositories for Acorn are available at
+//
+//     http://marijnhaverbeke.nl/git/acorn
+//     https://github.com/ternjs/acorn.git
+//
+// Please use the [github bug tracker][ghbt] to report issues.
+//
+// [ghbt]: https://github.com/ternjs/acorn/issues
+//
+// This file defines the main parser interface. The library also comes
+// with a [error-tolerant parser][dammit] and an
+// [abstract syntax tree walker][walk], defined in other files.
+//
+// [dammit]: acorn_loose.js
+// [walk]: util/walk.js
+
+import {Parser} from "./state"
+import "./parseutil"
+import "./statement"
+import "./lval"
+import "./expression"
+import "./location"
+
+export {Parser, plugins} from "./state"
+export {defaultOptions} from "./options"
+export {Position, SourceLocation, getLineInfo} from "./locutil"
+export {Node} from "./node"
+export {TokenType, types as tokTypes, keywords as keywordTypes} from "./tokentype"
+export {TokContext, types as tokContexts} from "./tokencontext"
+export {isIdentifierChar, isIdentifierStart} from "./identifier"
+export {Token} from "./tokenize"
+export {isNewLine, lineBreak, lineBreakG} from "./whitespace"
+
+export const version = "4.0.11"
+
+// The main exported interface (under `self.acorn` when in the
+// browser) is a `parse` function that takes a code string and
+// returns an abstract syntax tree as specified by [Mozilla parser
+// API][api].
+//
+// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
+
+export function parse(input, options) {
+  return new Parser(options, input).parse()
+}
+
+// This function tries to parse a single expression at a given
+// offset in a string. Useful for parsing mixed-language formats
+// that embed JavaScript expressions.
+
+export function parseExpressionAt(input, pos, options) {
+  let p = new Parser(options, input, pos)
+  p.nextToken()
+  return p.parseExpression()
+}
+
+// Acorn is organized as a tokenizer and a recursive-descent parser.
+// The `tokenizer` export provides an interface to the tokenizer.
+
+export function tokenizer(input, options) {
+  return new Parser(options, input)
+}
+
+// This is a terrible kludge to support the existing, pre-ES6
+// interface where the loose parser module retroactively adds exports
+// to this module.
+export let parse_dammit, LooseParser, pluginsLoose
+export function addLooseExports(parse, Parser, plugins) {
+  parse_dammit = parse
+  LooseParser = Parser
+  pluginsLoose = plugins
+}

+ 26 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/location.js

@@ -0,0 +1,26 @@
+import {Parser} from "./state"
+import {Position, getLineInfo} from "./locutil"
+
+const pp = Parser.prototype
+
+// This function is used to raise exceptions on parse errors. It
+// takes an offset integer (into the current `input`) to indicate
+// the location of the error, attaches the position to the end
+// of the error message, and then raises a `SyntaxError` with that
+// message.
+
+pp.raise = function(pos, message) {
+  let loc = getLineInfo(this.input, pos)
+  message += " (" + loc.line + ":" + loc.column + ")"
+  let err = new SyntaxError(message)
+  err.pos = pos; err.loc = loc; err.raisedAt = this.pos
+  throw err
+}
+
+pp.raiseRecoverable = pp.raise
+
+pp.curPosition = function() {
+  if (this.options.locations) {
+    return new Position(this.curLine, this.pos - this.lineStart)
+  }
+}

+ 42 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/locutil.js

@@ -0,0 +1,42 @@
+import {lineBreakG} from "./whitespace"
+
+// These are used when `options.locations` is on, for the
+// `startLoc` and `endLoc` properties.
+
+export class Position {
+  constructor(line, col) {
+    this.line = line
+    this.column = col
+  }
+
+  offset(n) {
+    return new Position(this.line, this.column + n)
+  }
+}
+
+export class SourceLocation {
+  constructor(p, start, end) {
+    this.start = start
+    this.end = end
+    if (p.sourceFile !== null) this.source = p.sourceFile
+  }
+}
+
+// The `getLineInfo` function is mostly useful when the
+// `locations` option is off (for performance reasons) and you
+// want to find the line/column position for a given character
+// offset. `input` should be the code string that the offset refers
+// into.
+
+export function getLineInfo(input, offset) {
+  for (let line = 1, cur = 0;;) {
+    lineBreakG.lastIndex = cur
+    let match = lineBreakG.exec(input)
+    if (match && match.index < offset) {
+      ++line
+      cur = match.index + match[0].length
+    } else {
+      return new Position(line, offset - cur)
+    }
+  }
+}

+ 562 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/expression.js

@@ -0,0 +1,562 @@
+import {LooseParser} from "./state"
+import {isDummy} from "./parseutil"
+import {tokTypes as tt} from "../index"
+
+const lp = LooseParser.prototype
+
+lp.checkLVal = function(expr) {
+  if (!expr) return expr
+  switch (expr.type) {
+  case "Identifier":
+  case "MemberExpression":
+    return expr
+
+  case "ParenthesizedExpression":
+    expr.expression = this.checkLVal(expr.expression)
+    return expr
+
+  default:
+    return this.dummyIdent()
+  }
+}
+
+lp.parseExpression = function(noIn) {
+  let start = this.storeCurrentPos()
+  let expr = this.parseMaybeAssign(noIn)
+  if (this.tok.type === tt.comma) {
+    let node = this.startNodeAt(start)
+    node.expressions = [expr]
+    while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn))
+    return this.finishNode(node, "SequenceExpression")
+  }
+  return expr
+}
+
+lp.parseParenExpression = function() {
+  this.pushCx()
+  this.expect(tt.parenL)
+  let val = this.parseExpression()
+  this.popCx()
+  this.expect(tt.parenR)
+  return val
+}
+
+lp.parseMaybeAssign = function(noIn) {
+  if (this.toks.isContextual("yield")) {
+    let node = this.startNode()
+    this.next()
+    if (this.semicolon() || this.canInsertSemicolon() || (this.tok.type != tt.star && !this.tok.type.startsExpr)) {
+      node.delegate = false
+      node.argument = null
+    } else {
+      node.delegate = this.eat(tt.star)
+      node.argument = this.parseMaybeAssign()
+    }
+    return this.finishNode(node, "YieldExpression")
+  }
+
+  let start = this.storeCurrentPos()
+  let left = this.parseMaybeConditional(noIn)
+  if (this.tok.type.isAssign) {
+    let node = this.startNodeAt(start)
+    node.operator = this.tok.value
+    node.left = this.tok.type === tt.eq ? this.toAssignable(left) : this.checkLVal(left)
+    this.next()
+    node.right = this.parseMaybeAssign(noIn)
+    return this.finishNode(node, "AssignmentExpression")
+  }
+  return left
+}
+
+lp.parseMaybeConditional = function(noIn) {
+  let start = this.storeCurrentPos()
+  let expr = this.parseExprOps(noIn)
+  if (this.eat(tt.question)) {
+    let node = this.startNodeAt(start)
+    node.test = expr
+    node.consequent = this.parseMaybeAssign()
+    node.alternate = this.expect(tt.colon) ? this.parseMaybeAssign(noIn) : this.dummyIdent()
+    return this.finishNode(node, "ConditionalExpression")
+  }
+  return expr
+}
+
+lp.parseExprOps = function(noIn) {
+  let start = this.storeCurrentPos()
+  let indent = this.curIndent, line = this.curLineStart
+  return this.parseExprOp(this.parseMaybeUnary(false), start, -1, noIn, indent, line)
+}
+
+lp.parseExprOp = function(left, start, minPrec, noIn, indent, line) {
+  if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) return left
+  let prec = this.tok.type.binop
+  if (prec != null && (!noIn || this.tok.type !== tt._in)) {
+    if (prec > minPrec) {
+      let node = this.startNodeAt(start)
+      node.left = left
+      node.operator = this.tok.value
+      this.next()
+      if (this.curLineStart != line && this.curIndent < indent && this.tokenStartsLine()) {
+        node.right = this.dummyIdent()
+      } else {
+        let rightStart = this.storeCurrentPos()
+        node.right = this.parseExprOp(this.parseMaybeUnary(false), rightStart, prec, noIn, indent, line)
+      }
+      this.finishNode(node, /&&|\|\|/.test(node.operator) ? "LogicalExpression" : "BinaryExpression")
+      return this.parseExprOp(node, start, minPrec, noIn, indent, line)
+    }
+  }
+  return left
+}
+
+lp.parseMaybeUnary = function(sawUnary) {
+  let start = this.storeCurrentPos(), expr
+  if (this.options.ecmaVersion >= 8 && this.inAsync && this.toks.isContextual("await")) {
+    expr = this.parseAwait()
+    sawUnary = true
+  } else if (this.tok.type.prefix) {
+    let node = this.startNode(), update = this.tok.type === tt.incDec
+    if (!update) sawUnary = true
+    node.operator = this.tok.value
+    node.prefix = true
+    this.next()
+    node.argument = this.parseMaybeUnary(true)
+    if (update) node.argument = this.checkLVal(node.argument)
+    expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression")
+  } else if (this.tok.type === tt.ellipsis) {
+    let node = this.startNode()
+    this.next()
+    node.argument = this.parseMaybeUnary(sawUnary)
+    expr = this.finishNode(node, "SpreadElement")
+  } else {
+    expr = this.parseExprSubscripts()
+    while (this.tok.type.postfix && !this.canInsertSemicolon()) {
+      let node = this.startNodeAt(start)
+      node.operator = this.tok.value
+      node.prefix = false
+      node.argument = this.checkLVal(expr)
+      this.next()
+      expr = this.finishNode(node, "UpdateExpression")
+    }
+  }
+
+  if (!sawUnary && this.eat(tt.starstar)) {
+    let node = this.startNodeAt(start)
+    node.operator = "**"
+    node.left = expr
+    node.right = this.parseMaybeUnary(false)
+    return this.finishNode(node, "BinaryExpression")
+  }
+
+  return expr
+}
+
+lp.parseExprSubscripts = function() {
+  let start = this.storeCurrentPos()
+  return this.parseSubscripts(this.parseExprAtom(), start, false, this.curIndent, this.curLineStart)
+}
+
+lp.parseSubscripts = function(base, start, noCalls, startIndent, line) {
+  for (;;) {
+    if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine()) {
+      if (this.tok.type == tt.dot && this.curIndent == startIndent)
+        --startIndent
+      else
+        return base
+    }
+
+    let maybeAsyncArrow = base.type === "Identifier" && base.name === "async" && !this.canInsertSemicolon()
+
+    if (this.eat(tt.dot)) {
+      let node = this.startNodeAt(start)
+      node.object = base
+      if (this.curLineStart != line && this.curIndent <= startIndent && this.tokenStartsLine())
+        node.property = this.dummyIdent()
+      else
+        node.property = this.parsePropertyAccessor() || this.dummyIdent()
+      node.computed = false
+      base = this.finishNode(node, "MemberExpression")
+    } else if (this.tok.type == tt.bracketL) {
+      this.pushCx()
+      this.next()
+      let node = this.startNodeAt(start)
+      node.object = base
+      node.property = this.parseExpression()
+      node.computed = true
+      this.popCx()
+      this.expect(tt.bracketR)
+      base = this.finishNode(node, "MemberExpression")
+    } else if (!noCalls && this.tok.type == tt.parenL) {
+      let exprList = this.parseExprList(tt.parenR)
+      if (maybeAsyncArrow && this.eat(tt.arrow))
+        return this.parseArrowExpression(this.startNodeAt(start), exprList, true)
+      let node = this.startNodeAt(start)
+      node.callee = base
+      node.arguments = exprList
+      base = this.finishNode(node, "CallExpression")
+    } else if (this.tok.type == tt.backQuote) {
+      let node = this.startNodeAt(start)
+      node.tag = base
+      node.quasi = this.parseTemplate()
+      base = this.finishNode(node, "TaggedTemplateExpression")
+    } else {
+      return base
+    }
+  }
+}
+
+lp.parseExprAtom = function() {
+  let node
+  switch (this.tok.type) {
+  case tt._this:
+  case tt._super:
+    let type = this.tok.type === tt._this ? "ThisExpression" : "Super"
+    node = this.startNode()
+    this.next()
+    return this.finishNode(node, type)
+
+  case tt.name:
+    let start = this.storeCurrentPos()
+    let id = this.parseIdent()
+    let isAsync = false
+    if (id.name === "async" && !this.canInsertSemicolon()) {
+      if (this.eat(tt._function))
+        return this.parseFunction(this.startNodeAt(start), false, true)
+      if (this.tok.type === tt.name) {
+        id = this.parseIdent()
+        isAsync = true
+      }
+    }
+    return this.eat(tt.arrow) ? this.parseArrowExpression(this.startNodeAt(start), [id], isAsync) : id
+
+  case tt.regexp:
+    node = this.startNode()
+    let val = this.tok.value
+    node.regex = {pattern: val.pattern, flags: val.flags}
+    node.value = val.value
+    node.raw = this.input.slice(this.tok.start, this.tok.end)
+    this.next()
+    return this.finishNode(node, "Literal")
+
+  case tt.num: case tt.string:
+    node = this.startNode()
+    node.value = this.tok.value
+    node.raw = this.input.slice(this.tok.start, this.tok.end)
+    this.next()
+    return this.finishNode(node, "Literal")
+
+  case tt._null: case tt._true: case tt._false:
+    node = this.startNode()
+    node.value = this.tok.type === tt._null ? null : this.tok.type === tt._true
+    node.raw = this.tok.type.keyword
+    this.next()
+    return this.finishNode(node, "Literal")
+
+  case tt.parenL:
+    let parenStart = this.storeCurrentPos()
+    this.next()
+    let inner = this.parseExpression()
+    this.expect(tt.parenR)
+    if (this.eat(tt.arrow)) {
+      // (a,)=>a // SequenceExpression makes dummy in the last hole. Drop the dummy.
+      let params = inner.expressions || [inner]
+      if (params.length && isDummy(params[params.length - 1]))
+        params.pop()
+      return this.parseArrowExpression(this.startNodeAt(parenStart), params)
+    }
+    if (this.options.preserveParens) {
+      let par = this.startNodeAt(parenStart)
+      par.expression = inner
+      inner = this.finishNode(par, "ParenthesizedExpression")
+    }
+    return inner
+
+  case tt.bracketL:
+    node = this.startNode()
+    node.elements = this.parseExprList(tt.bracketR, true)
+    return this.finishNode(node, "ArrayExpression")
+
+  case tt.braceL:
+    return this.parseObj()
+
+  case tt._class:
+    return this.parseClass(false)
+
+  case tt._function:
+    node = this.startNode()
+    this.next()
+    return this.parseFunction(node, false)
+
+  case tt._new:
+    return this.parseNew()
+
+  case tt.backQuote:
+    return this.parseTemplate()
+
+  default:
+    return this.dummyIdent()
+  }
+}
+
+lp.parseNew = function() {
+  let node = this.startNode(), startIndent = this.curIndent, line = this.curLineStart
+  let meta = this.parseIdent(true)
+  if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
+    node.meta = meta
+    node.property = this.parseIdent(true)
+    return this.finishNode(node, "MetaProperty")
+  }
+  let start = this.storeCurrentPos()
+  node.callee = this.parseSubscripts(this.parseExprAtom(), start, true, startIndent, line)
+  if (this.tok.type == tt.parenL) {
+    node.arguments = this.parseExprList(tt.parenR)
+  } else {
+    node.arguments = []
+  }
+  return this.finishNode(node, "NewExpression")
+}
+
+lp.parseTemplateElement = function() {
+  let elem = this.startNode()
+  elem.value = {
+    raw: this.input.slice(this.tok.start, this.tok.end).replace(/\r\n?/g, '\n'),
+    cooked: this.tok.value
+  }
+  this.next()
+  elem.tail = this.tok.type === tt.backQuote
+  return this.finishNode(elem, "TemplateElement")
+}
+
+lp.parseTemplate = function() {
+  let node = this.startNode()
+  this.next()
+  node.expressions = []
+  let curElt = this.parseTemplateElement()
+  node.quasis = [curElt]
+  while (!curElt.tail) {
+    this.next()
+    node.expressions.push(this.parseExpression())
+    if (this.expect(tt.braceR)) {
+      curElt = this.parseTemplateElement()
+    } else {
+      curElt = this.startNode()
+      curElt.value = {cooked: '', raw: ''}
+      curElt.tail = true
+      this.finishNode(curElt, "TemplateElement")
+    }
+    node.quasis.push(curElt)
+  }
+  this.expect(tt.backQuote)
+  return this.finishNode(node, "TemplateLiteral")
+}
+
+lp.parseObj = function() {
+  let node = this.startNode()
+  node.properties = []
+  this.pushCx()
+  let indent = this.curIndent + 1, line = this.curLineStart
+  this.eat(tt.braceL)
+  if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart }
+  while (!this.closes(tt.braceR, indent, line)) {
+    let prop = this.startNode(), isGenerator, isAsync, start
+    if (this.options.ecmaVersion >= 6) {
+      start = this.storeCurrentPos()
+      prop.method = false
+      prop.shorthand = false
+      isGenerator = this.eat(tt.star)
+    }
+    this.parsePropertyName(prop)
+    if (!prop.computed &&
+        prop.key.type === "Identifier" && prop.key.name === "async" && this.tok.type !== tt.parenL &&
+        this.tok.type !== tt.colon && !this.canInsertSemicolon()) {
+      this.parsePropertyName(prop)
+      isAsync = true
+    } else {
+      isAsync = false
+    }
+    if (isDummy(prop.key)) { if (isDummy(this.parseMaybeAssign())) this.next(); this.eat(tt.comma); continue }
+    if (this.eat(tt.colon)) {
+      prop.kind = "init"
+      prop.value = this.parseMaybeAssign()
+    } else if (this.options.ecmaVersion >= 6 && (this.tok.type === tt.parenL || this.tok.type === tt.braceL)) {
+      prop.kind = "init"
+      prop.method = true
+      prop.value = this.parseMethod(isGenerator, isAsync)
+    } else if (this.options.ecmaVersion >= 5 && prop.key.type === "Identifier" &&
+               !prop.computed && (prop.key.name === "get" || prop.key.name === "set") &&
+               (this.tok.type != tt.comma && this.tok.type != tt.braceR)) {
+      prop.kind = prop.key.name
+      this.parsePropertyName(prop)
+      prop.value = this.parseMethod(false)
+    } else {
+      prop.kind = "init"
+      if (this.options.ecmaVersion >= 6) {
+        if (this.eat(tt.eq)) {
+          let assign = this.startNodeAt(start)
+          assign.operator = "="
+          assign.left = prop.key
+          assign.right = this.parseMaybeAssign()
+          prop.value = this.finishNode(assign, "AssignmentExpression")
+        } else {
+          prop.value = prop.key
+        }
+      } else {
+        prop.value = this.dummyIdent()
+      }
+      prop.shorthand = true
+    }
+    node.properties.push(this.finishNode(prop, "Property"))
+    this.eat(tt.comma)
+  }
+  this.popCx()
+  if (!this.eat(tt.braceR)) {
+    // If there is no closing brace, make the node span to the start
+    // of the next token (this is useful for Tern)
+    this.last.end = this.tok.start
+    if (this.options.locations) this.last.loc.end = this.tok.loc.start
+  }
+  return this.finishNode(node, "ObjectExpression")
+}
+
+lp.parsePropertyName = function(prop) {
+  if (this.options.ecmaVersion >= 6) {
+    if (this.eat(tt.bracketL)) {
+      prop.computed = true
+      prop.key = this.parseExpression()
+      this.expect(tt.bracketR)
+      return
+    } else {
+      prop.computed = false
+    }
+  }
+  let key = (this.tok.type === tt.num || this.tok.type === tt.string) ? this.parseExprAtom() : this.parseIdent()
+  prop.key = key || this.dummyIdent()
+}
+
+lp.parsePropertyAccessor = function() {
+  if (this.tok.type === tt.name || this.tok.type.keyword) return this.parseIdent()
+}
+
+lp.parseIdent = function() {
+  let name = this.tok.type === tt.name ? this.tok.value : this.tok.type.keyword
+  if (!name) return this.dummyIdent()
+  let node = this.startNode()
+  this.next()
+  node.name = name
+  return this.finishNode(node, "Identifier")
+}
+
+lp.initFunction = function(node) {
+  node.id = null
+  node.params = []
+  if (this.options.ecmaVersion >= 6) {
+    node.generator = false
+    node.expression = false
+  }
+  if (this.options.ecmaVersion >= 8)
+    node.async = false
+}
+
+// Convert existing expression atom to assignable pattern
+// if possible.
+
+lp.toAssignable = function(node, binding) {
+  if (!node || node.type == "Identifier" || (node.type == "MemberExpression" && !binding)) {
+    // Okay
+  } else if (node.type == "ParenthesizedExpression") {
+    node.expression = this.toAssignable(node.expression, binding)
+  } else if (this.options.ecmaVersion < 6) {
+    return this.dummyIdent()
+  } else if (node.type == "ObjectExpression") {
+    node.type = "ObjectPattern"
+    let props = node.properties
+    for (let i = 0; i < props.length; i++)
+      props[i].value = this.toAssignable(props[i].value, binding)
+  } else if (node.type == "ArrayExpression") {
+    node.type = "ArrayPattern"
+    this.toAssignableList(node.elements, binding)
+  } else if (node.type == "SpreadElement") {
+    node.type = "RestElement"
+    node.argument = this.toAssignable(node.argument, binding)
+  } else if (node.type == "AssignmentExpression") {
+    node.type = "AssignmentPattern"
+    delete node.operator
+  } else {
+    return this.dummyIdent()
+  }
+  return node
+}
+
+lp.toAssignableList = function(exprList, binding) {
+  for (let i = 0; i < exprList.length; i++)
+    exprList[i] = this.toAssignable(exprList[i], binding)
+  return exprList
+}
+
+lp.parseFunctionParams = function(params) {
+  params = this.parseExprList(tt.parenR)
+  return this.toAssignableList(params, true)
+}
+
+lp.parseMethod = function(isGenerator, isAsync) {
+  let node = this.startNode(), oldInAsync = this.inAsync
+  this.initFunction(node)
+  if (this.options.ecmaVersion >= 6)
+    node.generator = !!isGenerator
+  if (this.options.ecmaVersion >= 8)
+    node.async = !!isAsync
+  this.inAsync = node.async
+  node.params = this.parseFunctionParams()
+  node.expression = this.options.ecmaVersion >= 6 && this.tok.type !== tt.braceL
+  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
+  this.inAsync = oldInAsync
+  return this.finishNode(node, "FunctionExpression")
+}
+
+lp.parseArrowExpression = function(node, params, isAsync) {
+  let oldInAsync = this.inAsync
+  this.initFunction(node)
+  if (this.options.ecmaVersion >= 8)
+    node.async = !!isAsync
+  this.inAsync = node.async
+  node.params = this.toAssignableList(params, true)
+  node.expression = this.tok.type !== tt.braceL
+  node.body = node.expression ? this.parseMaybeAssign() : this.parseBlock()
+  this.inAsync = oldInAsync
+  return this.finishNode(node, "ArrowFunctionExpression")
+}
+
+lp.parseExprList = function(close, allowEmpty) {
+  this.pushCx()
+  let indent = this.curIndent, line = this.curLineStart, elts = []
+  this.next() // Opening bracket
+  while (!this.closes(close, indent + 1, line)) {
+    if (this.eat(tt.comma)) {
+      elts.push(allowEmpty ? null : this.dummyIdent())
+      continue
+    }
+    let elt = this.parseMaybeAssign()
+    if (isDummy(elt)) {
+      if (this.closes(close, indent, line)) break
+      this.next()
+    } else {
+      elts.push(elt)
+    }
+    this.eat(tt.comma)
+  }
+  this.popCx()
+  if (!this.eat(close)) {
+    // If there is no closing brace, make the node span to the start
+    // of the next token (this is useful for Tern)
+    this.last.end = this.tok.start
+    if (this.options.locations) this.last.loc.end = this.tok.loc.start
+  }
+  return elts
+}
+
+lp.parseAwait = function() {
+  let node = this.startNode()
+  this.next()
+  node.argument = this.parseMaybeUnary()
+  return this.finishNode(node, "AwaitExpression")
+}

+ 48 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/index.js

@@ -0,0 +1,48 @@
+// Acorn: Loose parser
+//
+// This module provides an alternative parser (`parse_dammit`) that
+// exposes that same interface as `parse`, but will try to parse
+// anything as JavaScript, repairing syntax error the best it can.
+// There are circumstances in which it will raise an error and give
+// up, but they are very rare. The resulting AST will be a mostly
+// valid JavaScript AST (as per the [Mozilla parser API][api], except
+// that:
+//
+// - Return outside functions is allowed
+//
+// - Label consistency (no conflicts, break only to existing labels)
+//   is not enforced.
+//
+// - Bogus Identifier nodes with a name of `"✖"` are inserted whenever
+//   the parser got too confused to return anything meaningful.
+//
+// [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
+//
+// The expected use for this is to *first* try `acorn.parse`, and only
+// if that fails switch to `parse_dammit`. The loose parser might
+// parse badly indented code incorrectly, so **don't** use it as
+// your default parser.
+//
+// Quite a lot of acorn.js is duplicated here. The alternative was to
+// add a *lot* of extra cruft to that file, making it less readable
+// and slower. Copying and editing the code allowed me to make
+// invasive changes and simplifications without creating a complicated
+// tangle.
+
+import {addLooseExports, defaultOptions} from "../index"
+import {LooseParser, pluginsLoose} from "./state"
+import "./tokenize"
+import "./statement"
+import "./expression"
+
+export {LooseParser, pluginsLoose} from "./state"
+
+defaultOptions.tabSize = 4
+
+export function parse_dammit(input, options) {
+  let p = new LooseParser(input, options)
+  p.next()
+  return p.parseTopLevel()
+}
+
+addLooseExports(parse_dammit, LooseParser, pluginsLoose)

+ 1 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/parseutil.js

@@ -0,0 +1 @@
+export function isDummy(node) { return node.name == "✖" }

+ 161 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/state.js

@@ -0,0 +1,161 @@
+import {tokenizer, SourceLocation, tokTypes as tt, Node, lineBreak, isNewLine} from "../index"
+
+// Registered plugins
+export const pluginsLoose = {}
+
+export class LooseParser {
+  constructor(input, options = {}) {
+    this.toks = tokenizer(input, options)
+    this.options = this.toks.options
+    this.input = this.toks.input
+    this.tok = this.last = {type: tt.eof, start: 0, end: 0}
+    if (this.options.locations) {
+      let here = this.toks.curPosition()
+      this.tok.loc = new SourceLocation(this.toks, here, here)
+    }
+    this.ahead = [] // Tokens ahead
+    this.context = [] // Indentation contexted
+    this.curIndent = 0
+    this.curLineStart = 0
+    this.nextLineStart = this.lineEnd(this.curLineStart) + 1
+    this.inAsync = false
+    // Load plugins
+    this.options.pluginsLoose = options.pluginsLoose || {}
+    this.loadPlugins(this.options.pluginsLoose)
+  }
+
+  startNode() {
+    return new Node(this.toks, this.tok.start, this.options.locations ? this.tok.loc.start : null)
+  }
+
+  storeCurrentPos() {
+    return this.options.locations ? [this.tok.start, this.tok.loc.start] : this.tok.start
+  }
+
+  startNodeAt(pos) {
+    if (this.options.locations) {
+      return new Node(this.toks, pos[0], pos[1])
+    } else {
+      return new Node(this.toks, pos)
+    }
+  }
+
+  finishNode(node, type) {
+    node.type = type
+    node.end = this.last.end
+    if (this.options.locations)
+      node.loc.end = this.last.loc.end
+    if (this.options.ranges)
+      node.range[1] = this.last.end
+    return node
+  }
+
+  dummyNode(type) {
+    let dummy = this.startNode()
+    dummy.type = type
+    dummy.end = dummy.start
+    if (this.options.locations)
+      dummy.loc.end = dummy.loc.start
+    if (this.options.ranges)
+      dummy.range[1] = dummy.start
+    this.last = {type: tt.name, start: dummy.start, end: dummy.start, loc: dummy.loc}
+    return dummy
+  }
+
+  dummyIdent() {
+    let dummy = this.dummyNode("Identifier")
+    dummy.name = "✖"
+    return dummy
+  }
+
+  dummyString() {
+    let dummy = this.dummyNode("Literal")
+    dummy.value = dummy.raw = "✖"
+    return dummy
+  }
+
+  eat(type) {
+    if (this.tok.type === type) {
+      this.next()
+      return true
+    } else {
+      return false
+    }
+  }
+
+  isContextual(name) {
+    return this.tok.type === tt.name && this.tok.value === name
+  }
+
+  eatContextual(name) {
+    return this.tok.value === name && this.eat(tt.name)
+  }
+
+  canInsertSemicolon() {
+    return this.tok.type === tt.eof || this.tok.type === tt.braceR ||
+      lineBreak.test(this.input.slice(this.last.end, this.tok.start))
+  }
+
+  semicolon() {
+    return this.eat(tt.semi)
+  }
+
+  expect(type) {
+    if (this.eat(type)) return true
+    for (let i = 1; i <= 2; i++) {
+      if (this.lookAhead(i).type == type) {
+        for (let j = 0; j < i; j++) this.next()
+        return true
+      }
+    }
+  }
+
+  pushCx() {
+    this.context.push(this.curIndent)
+  }
+
+  popCx() {
+    this.curIndent = this.context.pop()
+  }
+
+  lineEnd(pos) {
+    while (pos < this.input.length && !isNewLine(this.input.charCodeAt(pos))) ++pos
+    return pos
+  }
+
+  indentationAfter(pos) {
+    for (let count = 0;; ++pos) {
+      let ch = this.input.charCodeAt(pos)
+      if (ch === 32) ++count
+      else if (ch === 9) count += this.options.tabSize
+      else return count
+    }
+  }
+
+  closes(closeTok, indent, line, blockHeuristic) {
+    if (this.tok.type === closeTok || this.tok.type === tt.eof) return true
+    return line != this.curLineStart && this.curIndent < indent && this.tokenStartsLine() &&
+      (!blockHeuristic || this.nextLineStart >= this.input.length ||
+       this.indentationAfter(this.nextLineStart) < indent)
+  }
+
+  tokenStartsLine() {
+    for (let p = this.tok.start - 1; p >= this.curLineStart; --p) {
+      let ch = this.input.charCodeAt(p)
+      if (ch !== 9 && ch !== 32) return false
+    }
+    return true
+  }
+
+  extend(name, f) {
+    this[name] = f(this[name])
+  }
+
+  loadPlugins(pluginConfigs) {
+    for (let name in pluginConfigs) {
+      let plugin = pluginsLoose[name]
+      if (!plugin) throw new Error("Plugin '" + name + "' not found")
+      plugin(this, pluginConfigs[name])
+    }
+  }
+}

+ 450 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/statement.js

@@ -0,0 +1,450 @@
+import {LooseParser} from "./state"
+import {isDummy} from "./parseutil"
+import {getLineInfo, tokTypes as tt} from "../index"
+
+const lp = LooseParser.prototype
+
+lp.parseTopLevel = function() {
+  let node = this.startNodeAt(this.options.locations ? [0, getLineInfo(this.input, 0)] : 0)
+  node.body = []
+  while (this.tok.type !== tt.eof) node.body.push(this.parseStatement())
+  this.last = this.tok
+  if (this.options.ecmaVersion >= 6) {
+    node.sourceType = this.options.sourceType
+  }
+  return this.finishNode(node, "Program")
+}
+
+lp.parseStatement = function() {
+  let starttype = this.tok.type, node = this.startNode(), kind
+
+  if (this.toks.isLet()) {
+    starttype = tt._var
+    kind = "let"
+  }
+
+  switch (starttype) {
+  case tt._break: case tt._continue:
+    this.next()
+    let isBreak = starttype === tt._break
+    if (this.semicolon() || this.canInsertSemicolon()) {
+      node.label = null
+    } else {
+      node.label = this.tok.type === tt.name ? this.parseIdent() : null
+      this.semicolon()
+    }
+    return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
+
+  case tt._debugger:
+    this.next()
+    this.semicolon()
+    return this.finishNode(node, "DebuggerStatement")
+
+  case tt._do:
+    this.next()
+    node.body = this.parseStatement()
+    node.test = this.eat(tt._while) ? this.parseParenExpression() : this.dummyIdent()
+    this.semicolon()
+    return this.finishNode(node, "DoWhileStatement")
+
+  case tt._for:
+    this.next()
+    this.pushCx()
+    this.expect(tt.parenL)
+    if (this.tok.type === tt.semi) return this.parseFor(node, null)
+    let isLet = this.toks.isLet()
+    if (isLet || this.tok.type === tt._var || this.tok.type === tt._const) {
+      let init = this.parseVar(true, isLet ? "let" : this.tok.value)
+      if (init.declarations.length === 1 && (this.tok.type === tt._in || this.isContextual("of"))) {
+        return this.parseForIn(node, init)
+      }
+      return this.parseFor(node, init)
+    }
+    let init = this.parseExpression(true)
+    if (this.tok.type === tt._in || this.isContextual("of"))
+      return this.parseForIn(node, this.toAssignable(init))
+    return this.parseFor(node, init)
+
+  case tt._function:
+    this.next()
+    return this.parseFunction(node, true)
+
+  case tt._if:
+    this.next()
+    node.test = this.parseParenExpression()
+    node.consequent = this.parseStatement()
+    node.alternate = this.eat(tt._else) ? this.parseStatement() : null
+    return this.finishNode(node, "IfStatement")
+
+  case tt._return:
+    this.next()
+    if (this.eat(tt.semi) || this.canInsertSemicolon()) node.argument = null
+    else { node.argument = this.parseExpression(); this.semicolon() }
+    return this.finishNode(node, "ReturnStatement")
+
+  case tt._switch:
+    let blockIndent = this.curIndent, line = this.curLineStart
+    this.next()
+    node.discriminant = this.parseParenExpression()
+    node.cases = []
+    this.pushCx()
+    this.expect(tt.braceL)
+
+    let cur
+    while (!this.closes(tt.braceR, blockIndent, line, true)) {
+      if (this.tok.type === tt._case || this.tok.type === tt._default) {
+        let isCase = this.tok.type === tt._case
+        if (cur) this.finishNode(cur, "SwitchCase")
+        node.cases.push(cur = this.startNode())
+        cur.consequent = []
+        this.next()
+        if (isCase) cur.test = this.parseExpression()
+        else cur.test = null
+        this.expect(tt.colon)
+      } else {
+        if (!cur) {
+          node.cases.push(cur = this.startNode())
+          cur.consequent = []
+          cur.test = null
+        }
+        cur.consequent.push(this.parseStatement())
+      }
+    }
+    if (cur) this.finishNode(cur, "SwitchCase")
+    this.popCx()
+    this.eat(tt.braceR)
+    return this.finishNode(node, "SwitchStatement")
+
+  case tt._throw:
+    this.next()
+    node.argument = this.parseExpression()
+    this.semicolon()
+    return this.finishNode(node, "ThrowStatement")
+
+  case tt._try:
+    this.next()
+    node.block = this.parseBlock()
+    node.handler = null
+    if (this.tok.type === tt._catch) {
+      let clause = this.startNode()
+      this.next()
+      this.expect(tt.parenL)
+      clause.param = this.toAssignable(this.parseExprAtom(), true)
+      this.expect(tt.parenR)
+      clause.body = this.parseBlock()
+      node.handler = this.finishNode(clause, "CatchClause")
+    }
+    node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null
+    if (!node.handler && !node.finalizer) return node.block
+    return this.finishNode(node, "TryStatement")
+
+  case tt._var:
+  case tt._const:
+    return this.parseVar(false, kind || this.tok.value)
+
+  case tt._while:
+    this.next()
+    node.test = this.parseParenExpression()
+    node.body = this.parseStatement()
+    return this.finishNode(node, "WhileStatement")
+
+  case tt._with:
+    this.next()
+    node.object = this.parseParenExpression()
+    node.body = this.parseStatement()
+    return this.finishNode(node, "WithStatement")
+
+  case tt.braceL:
+    return this.parseBlock()
+
+  case tt.semi:
+    this.next()
+    return this.finishNode(node, "EmptyStatement")
+
+  case tt._class:
+    return this.parseClass(true)
+
+  case tt._import:
+    return this.parseImport()
+
+  case tt._export:
+    return this.parseExport()
+
+  default:
+    if (this.toks.isAsyncFunction()) {
+      this.next()
+      this.next()
+      return this.parseFunction(node, true, true)
+    }
+    let expr = this.parseExpression()
+    if (isDummy(expr)) {
+      this.next()
+      if (this.tok.type === tt.eof) return this.finishNode(node, "EmptyStatement")
+      return this.parseStatement()
+    } else if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) {
+      node.body = this.parseStatement()
+      node.label = expr
+      return this.finishNode(node, "LabeledStatement")
+    } else {
+      node.expression = expr
+      this.semicolon()
+      return this.finishNode(node, "ExpressionStatement")
+    }
+  }
+}
+
+lp.parseBlock = function() {
+  let node = this.startNode()
+  this.pushCx()
+  this.expect(tt.braceL)
+  let blockIndent = this.curIndent, line = this.curLineStart
+  node.body = []
+  while (!this.closes(tt.braceR, blockIndent, line, true))
+    node.body.push(this.parseStatement())
+  this.popCx()
+  this.eat(tt.braceR)
+  return this.finishNode(node, "BlockStatement")
+}
+
+lp.parseFor = function(node, init) {
+  node.init = init
+  node.test = node.update = null
+  if (this.eat(tt.semi) && this.tok.type !== tt.semi) node.test = this.parseExpression()
+  if (this.eat(tt.semi) && this.tok.type !== tt.parenR) node.update = this.parseExpression()
+  this.popCx()
+  this.expect(tt.parenR)
+  node.body = this.parseStatement()
+  return this.finishNode(node, "ForStatement")
+}
+
+lp.parseForIn = function(node, init) {
+  let type = this.tok.type === tt._in ? "ForInStatement" : "ForOfStatement"
+  this.next()
+  node.left = init
+  node.right = this.parseExpression()
+  this.popCx()
+  this.expect(tt.parenR)
+  node.body = this.parseStatement()
+  return this.finishNode(node, type)
+}
+
+lp.parseVar = function(noIn, kind) {
+  let node = this.startNode()
+  node.kind = kind
+  this.next()
+  node.declarations = []
+  do {
+    let decl = this.startNode()
+    decl.id = this.options.ecmaVersion >= 6 ? this.toAssignable(this.parseExprAtom(), true) : this.parseIdent()
+    decl.init = this.eat(tt.eq) ? this.parseMaybeAssign(noIn) : null
+    node.declarations.push(this.finishNode(decl, "VariableDeclarator"))
+  } while (this.eat(tt.comma))
+  if (!node.declarations.length) {
+    let decl = this.startNode()
+    decl.id = this.dummyIdent()
+    node.declarations.push(this.finishNode(decl, "VariableDeclarator"))
+  }
+  if (!noIn) this.semicolon()
+  return this.finishNode(node, "VariableDeclaration")
+}
+
+lp.parseClass = function(isStatement) {
+  let node = this.startNode()
+  this.next()
+  if (isStatement == null) isStatement = this.tok.type === tt.name
+  if (this.tok.type === tt.name) node.id = this.parseIdent()
+  else if (isStatement) node.id = this.dummyIdent()
+  else node.id = null
+  node.superClass = this.eat(tt._extends) ? this.parseExpression() : null
+  node.body = this.startNode()
+  node.body.body = []
+  this.pushCx()
+  let indent = this.curIndent + 1, line = this.curLineStart
+  this.eat(tt.braceL)
+  if (this.curIndent + 1 < indent) { indent = this.curIndent; line = this.curLineStart }
+  while (!this.closes(tt.braceR, indent, line)) {
+    if (this.semicolon()) continue
+    let method = this.startNode(), isGenerator, isAsync
+    if (this.options.ecmaVersion >= 6) {
+      method.static = false
+      isGenerator = this.eat(tt.star)
+    }
+    this.parsePropertyName(method)
+    if (isDummy(method.key)) { if (isDummy(this.parseMaybeAssign())) this.next(); this.eat(tt.comma); continue }
+    if (method.key.type === "Identifier" && !method.computed && method.key.name === "static" &&
+        (this.tok.type != tt.parenL && this.tok.type != tt.braceL)) {
+      method.static = true
+      isGenerator = this.eat(tt.star)
+      this.parsePropertyName(method)
+    } else {
+      method.static = false
+    }
+    if (!method.computed &&
+        method.key.type === "Identifier" && method.key.name === "async" && this.tok.type !== tt.parenL &&
+        !this.canInsertSemicolon()) {
+      this.parsePropertyName(method)
+      isAsync = true
+    } else {
+      isAsync = false
+    }
+    if (this.options.ecmaVersion >= 5 && method.key.type === "Identifier" &&
+        !method.computed && (method.key.name === "get" || method.key.name === "set") &&
+        this.tok.type !== tt.parenL && this.tok.type !== tt.braceL) {
+      method.kind = method.key.name
+      this.parsePropertyName(method)
+      method.value = this.parseMethod(false)
+    } else {
+      if (!method.computed && !method.static && !isGenerator && !isAsync && (
+        method.key.type === "Identifier" && method.key.name === "constructor" ||
+          method.key.type === "Literal" && method.key.value === "constructor")) {
+        method.kind = "constructor"
+      } else {
+        method.kind =  "method"
+      }
+      method.value = this.parseMethod(isGenerator, isAsync)
+    }
+    node.body.body.push(this.finishNode(method, "MethodDefinition"))
+  }
+  this.popCx()
+  if (!this.eat(tt.braceR)) {
+    // If there is no closing brace, make the node span to the start
+    // of the next token (this is useful for Tern)
+    this.last.end = this.tok.start
+    if (this.options.locations) this.last.loc.end = this.tok.loc.start
+  }
+  this.semicolon()
+  this.finishNode(node.body, "ClassBody")
+  return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
+}
+
+lp.parseFunction = function(node, isStatement, isAsync) {
+  let oldInAsync = this.inAsync
+  this.initFunction(node)
+  if (this.options.ecmaVersion >= 6) {
+    node.generator = this.eat(tt.star)
+  }
+  if (this.options.ecmaVersion >= 8) {
+    node.async = !!isAsync
+  }
+  if (isStatement == null) isStatement = this.tok.type === tt.name
+  if (this.tok.type === tt.name) node.id = this.parseIdent()
+  else if (isStatement) node.id = this.dummyIdent()
+  this.inAsync = node.async
+  node.params = this.parseFunctionParams()
+  node.body = this.parseBlock()
+  this.inAsync = oldInAsync
+  return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
+}
+
+lp.parseExport = function() {
+  let node = this.startNode()
+  this.next()
+  if (this.eat(tt.star)) {
+    node.source = this.eatContextual("from") ? this.parseExprAtom() : this.dummyString()
+    return this.finishNode(node, "ExportAllDeclaration")
+  }
+  if (this.eat(tt._default)) {
+    // export default (function foo() {}) // This is FunctionExpression.
+    let isAsync
+    if (this.tok.type === tt._function || (isAsync = this.toks.isAsyncFunction())) {
+      let fNode = this.startNode()
+      this.next()
+      if (isAsync) this.next()
+      node.declaration = this.parseFunction(fNode, null, isAsync)
+    } else if (this.tok.type === tt._class) {
+      node.declaration = this.parseClass(null)
+    } else {
+      node.declaration = this.parseMaybeAssign()
+      this.semicolon()
+    }
+    return this.finishNode(node, "ExportDefaultDeclaration")
+  }
+  if (this.tok.type.keyword || this.toks.isLet() || this.toks.isAsyncFunction()) {
+    node.declaration = this.parseStatement()
+    node.specifiers = []
+    node.source = null
+  } else {
+    node.declaration = null
+    node.specifiers = this.parseExportSpecifierList()
+    node.source = this.eatContextual("from") ? this.parseExprAtom() : null
+    this.semicolon()
+  }
+  return this.finishNode(node, "ExportNamedDeclaration")
+}
+
+lp.parseImport = function() {
+  let node = this.startNode()
+  this.next()
+  if (this.tok.type === tt.string) {
+    node.specifiers = []
+    node.source = this.parseExprAtom()
+    node.kind = ''
+  } else {
+    let elt
+    if (this.tok.type === tt.name && this.tok.value !== "from") {
+      elt = this.startNode()
+      elt.local = this.parseIdent()
+      this.finishNode(elt, "ImportDefaultSpecifier")
+      this.eat(tt.comma)
+    }
+    node.specifiers = this.parseImportSpecifierList()
+    node.source = this.eatContextual("from") && this.tok.type == tt.string ? this.parseExprAtom() : this.dummyString()
+    if (elt) node.specifiers.unshift(elt)
+  }
+  this.semicolon()
+  return this.finishNode(node, "ImportDeclaration")
+}
+
+lp.parseImportSpecifierList = function() {
+  let elts = []
+  if (this.tok.type === tt.star) {
+    let elt = this.startNode()
+    this.next()
+    elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent()
+    elts.push(this.finishNode(elt, "ImportNamespaceSpecifier"))
+  } else {
+    let indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart
+    this.pushCx()
+    this.eat(tt.braceL)
+    if (this.curLineStart > continuedLine) continuedLine = this.curLineStart
+    while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
+      let elt = this.startNode()
+      if (this.eat(tt.star)) {
+        elt.local = this.eatContextual("as") ? this.parseIdent() : this.dummyIdent()
+        this.finishNode(elt, "ImportNamespaceSpecifier")
+      } else {
+        if (this.isContextual("from")) break
+        elt.imported = this.parseIdent()
+        if (isDummy(elt.imported)) break
+        elt.local = this.eatContextual("as") ? this.parseIdent() : elt.imported
+        this.finishNode(elt, "ImportSpecifier")
+      }
+      elts.push(elt)
+      this.eat(tt.comma)
+    }
+    this.eat(tt.braceR)
+    this.popCx()
+  }
+  return elts
+}
+
+lp.parseExportSpecifierList = function() {
+  let elts = []
+  let indent = this.curIndent, line = this.curLineStart, continuedLine = this.nextLineStart
+  this.pushCx()
+  this.eat(tt.braceL)
+  if (this.curLineStart > continuedLine) continuedLine = this.curLineStart
+  while (!this.closes(tt.braceR, indent + (this.curLineStart <= continuedLine ? 1 : 0), line)) {
+    if (this.isContextual("from")) break
+    let elt = this.startNode()
+    elt.local = this.parseIdent()
+    if (isDummy(elt.local)) break
+    elt.exported = this.eatContextual("as") ? this.parseIdent() : elt.local
+    this.finishNode(elt, "ExportSpecifier")
+    elts.push(elt)
+    this.eat(tt.comma)
+  }
+  this.eat(tt.braceR)
+  this.popCx()
+  return elts
+}

+ 108 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/loose/tokenize.js

@@ -0,0 +1,108 @@
+import {tokTypes as tt, Token, isNewLine, SourceLocation, getLineInfo, lineBreakG} from "../index"
+import {LooseParser} from "./state"
+
+const lp = LooseParser.prototype
+
+function isSpace(ch) {
+  return (ch < 14 && ch > 8) || ch === 32 || ch === 160 || isNewLine(ch)
+}
+
+lp.next = function() {
+  this.last = this.tok
+  if (this.ahead.length)
+    this.tok = this.ahead.shift()
+  else
+    this.tok = this.readToken()
+
+  if (this.tok.start >= this.nextLineStart) {
+    while (this.tok.start >= this.nextLineStart) {
+      this.curLineStart = this.nextLineStart
+      this.nextLineStart = this.lineEnd(this.curLineStart) + 1
+    }
+    this.curIndent = this.indentationAfter(this.curLineStart)
+  }
+}
+
+lp.readToken = function() {
+  for (;;) {
+    try {
+      this.toks.next()
+      if (this.toks.type === tt.dot &&
+          this.input.substr(this.toks.end, 1) === "." &&
+          this.options.ecmaVersion >= 6) {
+        this.toks.end++
+        this.toks.type = tt.ellipsis
+      }
+      return new Token(this.toks)
+    } catch(e) {
+      if (!(e instanceof SyntaxError)) throw e
+
+      // Try to skip some text, based on the error message, and then continue
+      let msg = e.message, pos = e.raisedAt, replace = true
+      if (/unterminated/i.test(msg)) {
+        pos = this.lineEnd(e.pos + 1)
+        if (/string/.test(msg)) {
+          replace = {start: e.pos, end: pos, type: tt.string, value: this.input.slice(e.pos + 1, pos)}
+        } else if (/regular expr/i.test(msg)) {
+          let re = this.input.slice(e.pos, pos)
+          try { re = new RegExp(re) } catch(e) {}
+          replace = {start: e.pos, end: pos, type: tt.regexp, value: re}
+        } else if (/template/.test(msg)) {
+          replace = {start: e.pos, end: pos,
+                     type: tt.template,
+                     value: this.input.slice(e.pos, pos)}
+        } else {
+          replace = false
+        }
+      } else if (/invalid (unicode|regexp|number)|expecting unicode|octal literal|is reserved|directly after number|expected number in radix/i.test(msg)) {
+        while (pos < this.input.length && !isSpace(this.input.charCodeAt(pos))) ++pos
+      } else if (/character escape|expected hexadecimal/i.test(msg)) {
+        while (pos < this.input.length) {
+          let ch = this.input.charCodeAt(pos++)
+          if (ch === 34 || ch === 39 || isNewLine(ch)) break
+        }
+      } else if (/unexpected character/i.test(msg)) {
+        pos++
+        replace = false
+      } else if (/regular expression/i.test(msg)) {
+        replace = true
+      } else {
+        throw e
+      }
+      this.resetTo(pos)
+      if (replace === true) replace = {start: pos, end: pos, type: tt.name, value: "✖"}
+      if (replace) {
+        if (this.options.locations)
+          replace.loc = new SourceLocation(
+            this.toks,
+            getLineInfo(this.input, replace.start),
+            getLineInfo(this.input, replace.end))
+        return replace
+      }
+    }
+  }
+}
+
+lp.resetTo = function(pos) {
+  this.toks.pos = pos
+  let ch = this.input.charAt(pos - 1)
+  this.toks.exprAllowed = !ch || /[\[\{\(,;:?\/*=+\-~!|&%^<>]/.test(ch) ||
+    /[enwfd]/.test(ch) &&
+    /\b(keywords|case|else|return|throw|new|in|(instance|type)of|delete|void)$/.test(this.input.slice(pos - 10, pos))
+
+  if (this.options.locations) {
+    this.toks.curLine = 1
+    this.toks.lineStart = lineBreakG.lastIndex = 0
+    let match
+    while ((match = lineBreakG.exec(this.input)) && match.index < pos) {
+      ++this.toks.curLine
+      this.toks.lineStart = match.index + match[0].length
+    }
+  }
+}
+
+lp.lookAhead = function(n) {
+  while (n > this.ahead.length)
+    this.ahead.push(this.readToken())
+  return this.ahead[n - 1]
+}

+ 219 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/lval.js

@@ -0,0 +1,219 @@
+import {types as tt} from "./tokentype"
+import {Parser} from "./state"
+import {has} from "./util"
+
+const pp = Parser.prototype
+
+// Convert existing expression atom to assignable pattern
+// if possible.
+
+pp.toAssignable = function(node, isBinding) {
+  if (this.options.ecmaVersion >= 6 && node) {
+    switch (node.type) {
+      case "Identifier":
+      if (this.inAsync && node.name === "await")
+        this.raise(node.start, "Can not use 'await' as identifier inside an async function")
+      break
+
+    case "ObjectPattern":
+    case "ArrayPattern":
+      break
+
+    case "ObjectExpression":
+      node.type = "ObjectPattern"
+      for (let i = 0; i < node.properties.length; i++) {
+        let prop = node.properties[i]
+        if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter")
+        this.toAssignable(prop.value, isBinding)
+      }
+      break
+
+    case "ArrayExpression":
+      node.type = "ArrayPattern"
+      this.toAssignableList(node.elements, isBinding)
+      break
+
+    case "AssignmentExpression":
+      if (node.operator === "=") {
+        node.type = "AssignmentPattern"
+        delete node.operator
+        this.toAssignable(node.left, isBinding)
+        // falls through to AssignmentPattern
+      } else {
+        this.raise(node.left.end, "Only '=' operator can be used for specifying default value.")
+        break
+      }
+
+    case "AssignmentPattern":
+      break
+
+    case "ParenthesizedExpression":
+      node.expression = this.toAssignable(node.expression, isBinding)
+      break
+
+    case "MemberExpression":
+      if (!isBinding) break
+
+    default:
+      this.raise(node.start, "Assigning to rvalue")
+    }
+  }
+  return node
+}
+
+// Convert list of expression atoms to binding list.
+
+pp.toAssignableList = function(exprList, isBinding) {
+  let end = exprList.length
+  if (end) {
+    let last = exprList[end - 1]
+    if (last && last.type == "RestElement") {
+      --end
+    } else if (last && last.type == "SpreadElement") {
+      last.type = "RestElement"
+      let arg = last.argument
+      this.toAssignable(arg, isBinding)
+      if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern")
+        this.unexpected(arg.start)
+      --end
+    }
+
+    if (isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
+      this.unexpected(last.argument.start)
+  }
+  for (let i = 0; i < end; i++) {
+    let elt = exprList[i]
+    if (elt) this.toAssignable(elt, isBinding)
+  }
+  return exprList
+}
+
+// Parses spread element.
+
+pp.parseSpread = function(refDestructuringErrors) {
+  let node = this.startNode()
+  this.next()
+  node.argument = this.parseMaybeAssign(false, refDestructuringErrors)
+  return this.finishNode(node, "SpreadElement")
+}
+
+pp.parseRest = function(allowNonIdent) {
+  let node = this.startNode()
+  this.next()
+
+  // RestElement inside of a function parameter must be an identifier
+  if (allowNonIdent) node.argument = this.type === tt.name ? this.parseIdent() : this.unexpected()
+  else node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected()
+
+  return this.finishNode(node, "RestElement")
+}
+
+// Parses lvalue (assignable) atom.
+
+pp.parseBindingAtom = function() {
+  if (this.options.ecmaVersion < 6) return this.parseIdent()
+  switch (this.type) {
+  case tt.name:
+    return this.parseIdent()
+
+  case tt.bracketL:
+    let node = this.startNode()
+    this.next()
+    node.elements = this.parseBindingList(tt.bracketR, true, true)
+    return this.finishNode(node, "ArrayPattern")
+
+  case tt.braceL:
+    return this.parseObj(true)
+
+  default:
+    this.unexpected()
+  }
+}
+
+pp.parseBindingList = function(close, allowEmpty, allowTrailingComma, allowNonIdent) {
+  let elts = [], first = true
+  while (!this.eat(close)) {
+    if (first) first = false
+    else this.expect(tt.comma)
+    if (allowEmpty && this.type === tt.comma) {
+      elts.push(null)
+    } else if (allowTrailingComma && this.afterTrailingComma(close)) {
+      break
+    } else if (this.type === tt.ellipsis) {
+      let rest = this.parseRest(allowNonIdent)
+      this.parseBindingListItem(rest)
+      elts.push(rest)
+      if (this.type === tt.comma) this.raise(this.start, "Comma is not permitted after the rest element")
+      this.expect(close)
+      break
+    } else {
+      let elem = this.parseMaybeDefault(this.start, this.startLoc)
+      this.parseBindingListItem(elem)
+      elts.push(elem)
+    }
+  }
+  return elts
+}
+
+pp.parseBindingListItem = function(param) {
+  return param
+}
+
+// Parses assignment pattern around given atom if possible.
+
+pp.parseMaybeDefault = function(startPos, startLoc, left) {
+  left = left || this.parseBindingAtom()
+  if (this.options.ecmaVersion < 6 || !this.eat(tt.eq)) return left
+  let node = this.startNodeAt(startPos, startLoc)
+  node.left = left
+  node.right = this.parseMaybeAssign()
+  return this.finishNode(node, "AssignmentPattern")
+}
+
+// Verify that a node is an lval — something that can be assigned
+// to.
+
+pp.checkLVal = function(expr, isBinding, checkClashes) {
+  switch (expr.type) {
+  case "Identifier":
+    if (this.strict && this.reservedWordsStrictBind.test(expr.name))
+      this.raiseRecoverable(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode")
+    if (checkClashes) {
+      if (has(checkClashes, expr.name))
+        this.raiseRecoverable(expr.start, "Argument name clash")
+      checkClashes[expr.name] = true
+    }
+    break
+
+  case "MemberExpression":
+    if (isBinding) this.raiseRecoverable(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression")
+    break
+
+  case "ObjectPattern":
+    for (let i = 0; i < expr.properties.length; i++)
+      this.checkLVal(expr.properties[i].value, isBinding, checkClashes)
+    break
+
+  case "ArrayPattern":
+    for (let i = 0; i < expr.elements.length; i++) {
+      let elem = expr.elements[i]
+      if (elem) this.checkLVal(elem, isBinding, checkClashes)
+    }
+    break
+
+  case "AssignmentPattern":
+    this.checkLVal(expr.left, isBinding, checkClashes)
+    break
+
+  case "RestElement":
+    this.checkLVal(expr.argument, isBinding, checkClashes)
+    break
+
+  case "ParenthesizedExpression":
+    this.checkLVal(expr.expression, isBinding, checkClashes)
+    break
+
+  default:
+    this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue")
+  }
+}

+ 50 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/node.js

@@ -0,0 +1,50 @@
+import {Parser} from "./state"
+import {SourceLocation} from "./locutil"
+
+export class Node {
+  constructor(parser, pos, loc) {
+    this.type = ""
+    this.start = pos
+    this.end = 0
+    if (parser.options.locations)
+      this.loc = new SourceLocation(parser, loc)
+    if (parser.options.directSourceFile)
+      this.sourceFile = parser.options.directSourceFile
+    if (parser.options.ranges)
+      this.range = [pos, 0]
+  }
+}
+
+// Start an AST node, attaching a start offset.
+
+const pp = Parser.prototype
+
+pp.startNode = function() {
+  return new Node(this, this.start, this.startLoc)
+}
+
+pp.startNodeAt = function(pos, loc) {
+  return new Node(this, pos, loc)
+}
+
+// Finish an AST node, adding `type` and `end` properties.
+
+function finishNodeAt(node, type, pos, loc) {
+  node.type = type
+  node.end = pos
+  if (this.options.locations)
+    node.loc.end = loc
+  if (this.options.ranges)
+    node.range[1] = pos
+  return node
+}
+
+pp.finishNode = function(node, type) {
+  return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
+}
+
+// Finish node at given position
+
+pp.finishNodeAt = function(node, type, pos, loc) {
+  return finishNodeAt.call(this, node, type, pos, loc)
+}

+ 128 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/options.js

@@ -0,0 +1,128 @@
+import {has, isArray} from "./util"
+import {SourceLocation} from "./locutil"
+
+// A second optional argument can be given to further configure
+// the parser process. These options are recognized:
+
+export const defaultOptions = {
+  // `ecmaVersion` indicates the ECMAScript version to parse. Must
+  // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support
+  // for strict mode, the set of reserved words, and support for
+  // new syntax features. The default is 7.
+  ecmaVersion: 7,
+  // `sourceType` indicates the mode the code should be parsed in.
+  // Can be either `"script"` or `"module"`. This influences global
+  // strict mode and parsing of `import` and `export` declarations.
+  sourceType: "script",
+  // `onInsertedSemicolon` can be a callback that will be called
+  // when a semicolon is automatically inserted. It will be passed
+  // th position of the comma as an offset, and if `locations` is
+  // enabled, it is given the location as a `{line, column}` object
+  // as second argument.
+  onInsertedSemicolon: null,
+  // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
+  // trailing commas.
+  onTrailingComma: null,
+  // By default, reserved words are only enforced if ecmaVersion >= 5.
+  // Set `allowReserved` to a boolean value to explicitly turn this on
+  // an off. When this option has the value "never", reserved words
+  // and keywords can also not be used as property names.
+  allowReserved: null,
+  // When enabled, a return at the top level is not considered an
+  // error.
+  allowReturnOutsideFunction: false,
+  // When enabled, import/export statements are not constrained to
+  // appearing at the top of the program.
+  allowImportExportEverywhere: false,
+  // When enabled, hashbang directive in the beginning of file
+  // is allowed and treated as a line comment.
+  allowHashBang: false,
+  // When `locations` is on, `loc` properties holding objects with
+  // `start` and `end` properties in `{line, column}` form (with
+  // line being 1-based and column 0-based) will be attached to the
+  // nodes.
+  locations: false,
+  // A function can be passed as `onToken` option, which will
+  // cause Acorn to call that function with object in the same
+  // format as tokens returned from `tokenizer().getToken()`. Note
+  // that you are not allowed to call the parser from the
+  // callback—that will corrupt its internal state.
+  onToken: null,
+  // A function can be passed as `onComment` option, which will
+  // cause Acorn to call that function with `(block, text, start,
+  // end)` parameters whenever a comment is skipped. `block` is a
+  // boolean indicating whether this is a block (`/* */`) comment,
+  // `text` is the content of the comment, and `start` and `end` are
+  // character offsets that denote the start and end of the comment.
+  // When the `locations` option is on, two more parameters are
+  // passed, the full `{line, column}` locations of the start and
+  // end of the comments. Note that you are not allowed to call the
+  // parser from the callback—that will corrupt its internal state.
+  onComment: null,
+  // Nodes have their start and end characters offsets recorded in
+  // `start` and `end` properties (directly on the node, rather than
+  // the `loc` object, which holds line/column data. To also add a
+  // [semi-standardized][range] `range` property holding a `[start,
+  // end]` array with the same numbers, set the `ranges` option to
+  // `true`.
+  //
+  // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
+  ranges: false,
+  // It is possible to parse multiple files into a single AST by
+  // passing the tree produced by parsing the first file as
+  // `program` option in subsequent parses. This will add the
+  // toplevel forms of the parsed file to the `Program` (top) node
+  // of an existing parse tree.
+  program: null,
+  // When `locations` is on, you can pass this to record the source
+  // file in every node's `loc` object.
+  sourceFile: null,
+  // This value, if given, is stored in every node, whether
+  // `locations` is on or off.
+  directSourceFile: null,
+  // When enabled, parenthesized expressions are represented by
+  // (non-standard) ParenthesizedExpression nodes
+  preserveParens: false,
+  plugins: {}
+}
+
+// Interpret and default an options object
+
+export function getOptions(opts) {
+  let options = {}
+
+  for (let opt in defaultOptions)
+    options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]
+
+  if (options.ecmaVersion >= 2015)
+    options.ecmaVersion -= 2009
+
+  if (options.allowReserved == null)
+    options.allowReserved = options.ecmaVersion < 5
+
+  if (isArray(options.onToken)) {
+    let tokens = options.onToken
+    options.onToken = (token) => tokens.push(token)
+  }
+  if (isArray(options.onComment))
+    options.onComment = pushComment(options, options.onComment)
+
+  return options
+}
+
+function pushComment(options, array) {
+  return function (block, text, start, end, startLoc, endLoc) {
+    let comment = {
+      type: block ? 'Block' : 'Line',
+      value: text,
+      start: start,
+      end: end
+    }
+    if (options.locations)
+      comment.loc = new SourceLocation(this, startLoc, endLoc)
+    if (options.ranges)
+      comment.range = [start, end]
+    array.push(comment)
+  }
+}
+

+ 128 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/parseutil.js

@@ -0,0 +1,128 @@
+import {types as tt} from "./tokentype"
+import {Parser} from "./state"
+import {lineBreak, skipWhiteSpace} from "./whitespace"
+
+const pp = Parser.prototype
+
+// ## Parser utilities
+
+const literal = /^(?:'((?:[^\']|\.)*)'|"((?:[^\"]|\.)*)"|;)/
+pp.strictDirective = function(start) {
+  for (;;) {
+    skipWhiteSpace.lastIndex = start
+    start += skipWhiteSpace.exec(this.input)[0].length
+    let match = literal.exec(this.input.slice(start))
+    if (!match) return false
+    if ((match[1] || match[2]) == "use strict") return true
+    start += match[0].length
+  }
+}
+
+// Predicate that tests whether the next token is of the given
+// type, and if yes, consumes it as a side effect.
+
+pp.eat = function(type) {
+  if (this.type === type) {
+    this.next()
+    return true
+  } else {
+    return false
+  }
+}
+
+// Tests whether parsed token is a contextual keyword.
+
+pp.isContextual = function(name) {
+  return this.type === tt.name && this.value === name
+}
+
+// Consumes contextual keyword if possible.
+
+pp.eatContextual = function(name) {
+  return this.value === name && this.eat(tt.name)
+}
+
+// Asserts that following token is given contextual keyword.
+
+pp.expectContextual = function(name) {
+  if (!this.eatContextual(name)) this.unexpected()
+}
+
+// Test whether a semicolon can be inserted at the current position.
+
+pp.canInsertSemicolon = function() {
+  return this.type === tt.eof ||
+    this.type === tt.braceR ||
+    lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
+}
+
+pp.insertSemicolon = function() {
+  if (this.canInsertSemicolon()) {
+    if (this.options.onInsertedSemicolon)
+      this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc)
+    return true
+  }
+}
+
+// Consume a semicolon, or, failing that, see if we are allowed to
+// pretend that there is a semicolon at this position.
+
+pp.semicolon = function() {
+  if (!this.eat(tt.semi) && !this.insertSemicolon()) this.unexpected()
+}
+
+pp.afterTrailingComma = function(tokType, notNext) {
+  if (this.type == tokType) {
+    if (this.options.onTrailingComma)
+      this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc)
+    if (!notNext)
+      this.next()
+    return true
+  }
+}
+
+// Expect a token of a given type. If found, consume it, otherwise,
+// raise an unexpected token error.
+
+pp.expect = function(type) {
+  this.eat(type) || this.unexpected()
+}
+
+// Raise an unexpected token error.
+
+pp.unexpected = function(pos) {
+  this.raise(pos != null ? pos : this.start, "Unexpected token")
+}
+
+export class DestructuringErrors {
+  constructor() {
+    this.shorthandAssign = this.trailingComma = this.parenthesizedAssign = this.parenthesizedBind = -1
+  }
+}
+
+pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
+  if (!refDestructuringErrors) return
+  if (refDestructuringErrors.trailingComma > -1)
+    this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element")
+  let parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind
+  if (parens > -1) this.raiseRecoverable(parens, "Parenthesized pattern")
+}
+
+pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
+  let pos = refDestructuringErrors ? refDestructuringErrors.shorthandAssign : -1
+  if (!andThrow) return pos >= 0
+  if (pos > -1) this.raise(pos, "Shorthand property assignments are valid only in destructuring patterns")
+}
+
+pp.checkYieldAwaitInDefaultParams = function() {
+  if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
+    this.raise(this.yieldPos, "Yield expression cannot be a default value")
+  if (this.awaitPos)
+    this.raise(this.awaitPos, "Await expression cannot be a default value")
+}
+
+pp.isSimpleAssignTarget = function(expr) {
+  if (expr.type === "ParenthesizedExpression")
+    return this.isSimpleAssignTarget(expr.expression)
+  return expr.type === "Identifier" || expr.type === "MemberExpression"
+}

+ 0 - 0
Fakogram REACT project/node_modules/acorn-dynamic-import/node_modules/acorn/src/state.js


برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است