Restoring the file structure from a cocos2d-x JS Android APK, post decryption?

I am currently learning how to reverse engineer an APK and have made significant progress. Here’s what I’ve accomplished so far:

  1. Decryption & Code Browsing: Converted the Dalvik bytecode (.dex files) to readable Java and JavaScript code.
  2. Unbundling: Unbundled the decrypted JavaScript files. (Though they are still minified)
  3. UUID Decryption: Figured out how to decrypt UUIDs into filenames and vice versa, and found resource paths for some UUIDs.

However, I’m stuck on figuring out the correct folder structure for certain assets within the “Main” folder.

What I’ve Discovered So Far

Here’s what I know about the asset packs in the “Main” folder:

  • Each asset pack has a UUID, which corresponds to an image containing multiple assets.
  • There is a JSON file for each asset pack, but these don’t provide much useful information regarding the folder structure.
  • Each asset in the image has its own JSON file that includes:
    • The pack name near the beginning.
    • Details about the asset’s position in the image.
  • The manifest contains every asset’s location, but only assets listed in /resources/config.json have “paths” to help re-map them.

My Questions

  1. How can I determine the correct folder structure for these assets?
  2. Is there a pattern or tool that can help map these assets to their appropriate locations?

Important Note: There is NO map file – the manifest lists the obfuscated names and their md5 or sha-256 depending on which one you look at, My goal is to reverse engineer back to the original format that the code references.

Code Samples & Structure

I’ve included some relevant code snippets and file structure details to illustrate what I’m working with:

Example config.json (UUIDs without paths):

{
    "paths": {},
    "types": [],
    "uuids": [
        "05mU7WsllFO4elu4Re6/pm",
        "fcTsdoxZlLpKd3It99/+h6"
    ],
    "scenes": {
        "db://assets/main.fire": 127,
        "db://assets/start.fire": 120
    },
    "redirect": [1, 0, 2, 0, 4, ... 0, 146, 0],
    "deps": ["resources", "internal"],
    "packs": {},
    "name": "main",
    "importBase": "import",
    "nativeBase": "native",
    "debug": false,
    "isZip": false,
    "encrypted": true
}

Example of Bundled Code Before Unbundling:

(but you can see the bottom section provides a filestructure / names for the bundles, which is how I reverse engineered and unbundled it)

{
    1: [function(e, t, i) {
        "use strict";
        const n = i;
        n.bignum = e("bn.js");
        n.define = e("./asn1/api").define;
        n.base = e("./asn1/base");
        n.constants = e("./asn1/constants");
        n.decoders = e("./asn1/decoders");
        n.encoders = e("./asn1/encoders");
    }, {
        "./asn1/api": 2,
        "./asn1/base": 4,
        "./asn1/constants": 8,
        "./asn1/decoders": 10,
        "./asn1/encoders": 13,
        "bn.js": 15
    }],

File Structure

Here’s a partial view of the file structure I’m working with:

Directory: T:assets
  Subdirectory: ad-viewer
  Subdirectory: assets
  Subdirectory: dexopt
  Subdirectory: jsb-adapter
  Subdirectory: src
  File: audience_network.dex
  File: cid
  File: main.js
  File: project.json
  File: tt_mime_type.pro

Directory: T:assetsassets
  Subdirectory: internal
  Subdirectory: localizeData
  Subdirectory: main
  Subdirectory: manifest
  Subdirectory: resources
  Subdirectory: Script

Directory: T:assetsassetsinternal
  Subdirectory: import
  Subdirectory: native
  File: config.json
  File: index.js

Directory: T:assetsassetsinternalimport
  Subdirectory: 09

Directory: T:assetsassetsinternalimport9
  File: 0967b326a.json

Directory: T:assetsassetsinternalnative
  Subdirectory: 02

Directory: T:assetsassetsinternalnative2
  File: 0275e94c-56a7-410f-bd1a-fc7483f7d14a.png

Directory: T:assetsassetslocalizeData
  File: config.json
  File: index.js

Directory: T:assetsassetsmain
  Subdirectory: import
  Subdirectory: native
  File: config.json
  File: index.js

Directory: T:assetsassetsmainimport
  Subdirectory: 05
  Subdirectory: 06
  Subdirectory: 08
  Subdirectory: 12
.....
Directory: T:assetsassetsmanifest
  Subdirectory: import
  Subdirectory: native
  File: config.json
  File: index.js

Directory: T:assetsassetsmanifestimport
  Subdirectory: 83

Directory: T:assetsassetsmanifestimport83
  File: 83f57686-53e5-4bc7-bdf0-33bcd506f93b.json

Directory: T:assetsassetsmanifestnative
  Subdirectory: 83

Directory: T:assetsassetsmanifestnative83
  File: 83f57686-53e5-4bc7-bdf0-33bcd506f93b.manifest

Directory: T:assetsassetsresources
  Subdirectory: import
  Subdirectory: native
  File: config.json
  File: index.js

Directory: T:assetsassetsresourcesimport
  Subdirectory: 00
  Subdirectory: 01
  Subdirectory: 02
....
Directory: T:assetsassetsScript
  Subdirectory: import
  File: config.json
  File: index.js

Directory: T:assetsassetsScriptimport
  Subdirectory: c8

Directory: T:assetsassetsScriptimportc8
  File: c85c3dbd-5a7d-424c-8e07-965706736336.json

Directory: T:assetsdexopt
  File: baseline.prof
  File: baseline.profm

Directory: T:assetsjsb-adapter
  File: jsb-builtin.js
  File: jsb-engine.js

Directory: T:assetssrc
  Subdirectory: assets
  File: cocos2d-jsb.js
  File: settings.js

Directory: T:assetssrcassets
  Subdirectory: libs

Directory: T:assetssrcassetslibs
  File: thinkingdata.mg.cocoscreator.min.js

Specific Asset Example

  • Asset pack UUID: 1e58fbfa7
    • Image file: assetsassetsmainnative1e1e58fbfa7.png
    • JSON file: assetsassetsmainimport1e1e58fbfa7.json
      JSON Contents:
[
    1,
    0,
    0,
    [
        "cc.Texture2D"
    ],
    0,
    [
        "0,9729,9729,33071,33071,0,0,0",
        -1
    ],
    [
        0
    ],
    0,
    [],
    [],
    []
]

Traceback

I search for that string (1e58fbfa7) in all files and find a matching JSON for each of the assets on that image, here is an example of one:
(I do understand what these are – they are stating where the asset that relates to that file / UUID is on the pack)

[
    1,
    [
        "1e58fbfa7"
    ],
    [
        "_textureSetter"
    ],
    [
        "cc.SpriteFrame"
    ],
    0,
    [
        {
            "name": "UI_Bt_world",
            "rect": [
                342,
                446,
                127,
                115
            ],
            "offset": [
                0,
                0.5
            ],
            "originalSize": [
                129,
                116
            ],
            "capInsets": [
                0,
                0,
                0,
                0
            ]
        }
    ],
    [
        0
    ],
    0,
    [
        0
    ],
    [
        0
    ],
    [
        0
    ]
]

That JSON is assetsassetsmainimport3a3aa50555-73a6-416d-b35a-cfab79466fa7.json

If I convert that to a UUID (3apQVVc6ZBbbNaz6t5Rm+n) I will find it in two locations, config.json (snippet provided above) and another location (assetsassetsmainimport9f9fde386a-2232-446d-9554-549e101dde19.json) which is somewhat similar to the config.json, but not quite… snippet:

[
    1,
    [
        "ecpdLyjvZBwrvm+cedCcQy",
...
    [
        "node",
        "_spriteFrame",
        "_N$file",
...
   [
        [
            "cc.Node",
            [
                "_name",
...
               "_children"
            ],
            -2,
            4,
...
                ]
            ],
            [
                0,
                "58H6b2PPdJip4dKNTXDv0T",
                1,
                0
            ],
            [
                4,
                4278190080
            ],
            [
                5,
                1242,
                2688
            ]
        ]
    ],
    0,
    [
        0,
        12,
...
        96,
        97,
        1
    ]
]

I convert that file name into a UUID (9f3jhqIjJEbZVUVJ4QHd4Z) and find it in yet another file (assetsassetsmainimportd7d726ed83-41aa-4389-bd34-dd1e963ba515.json)…

[
    1,
    [
        "9f3jhqIjJEbZVUVJ4QHd4Z"
    ],
    [
        "mainNode",
        "node",
        "scene"
    ],
    [
        [
            "cc.SceneAsset",
            [
                "_name",
                "asyncLoadAssets"
            ],
            1
        ],
        [
            "cc.Scene",
            [
                "_name",
...
    [
        0,
        -1,
        2,
        0,
        1,
        2,
        0,
        2,
        1,
        2
    ],
    [
        0
    ],
    [
        0
    ],
    [
        0
    ]
]

I went even deeper, converted that file name to a UUID (d7Ju2DQapDib003R6WO6UV) and looked and found it in one location…. the original config file. So now I’m back to the beginning!

Pancakeswap trading bot

`
from web3 import Web3
import json
import config
import time

bsc = ‘https://data-seed-prebsc-1-s1.binance.org:8545’
web3 = Web3(Web3.HTTPProvider(bsc))

print(web3.is_connected())

panRouterContractAddress = (‘0xd77C2afeBf3dC665af07588BF798bd938968c72E’)

panabi = ‘[{“inputs”:[{“components”:[{“internalType”:”address”,”name”:”permit2″,”type”:”address”},{“internalType”:”address”,”name”:”WETH9″,”type”:”address”},{“internalType”:”address”,”name”:”seaportV1_5″,”type”:”address”},{“internalType”:”address”,”name”:”seaportV1_4″,”type”:”address”},{“internalType”:”address”,”name”:”openseaConduit”,”type”:”address”},{“internalType”:”address”,”name”:”x2y2″,”type”:”address”},{“internalType”:”address”,”name”:”looksRareV2″,”type”:”address”},{“internalType”:”address”,”name”:”routerRewardsDistributor”,”type”:”address”},{“internalType”:”address”,”name”:”looksRareRewardsDistributor”,”type”:”address”},{“internalType”:”address”,”name”:”looksRareToken”,”type”:”address”},{“internalType”:”address”,”name”:”v2Factory”,”type”:”address”},{“internalType”:”address”,”name”:”v3Factory”,”type”:”address”},{“internalType”:”address”,”name”:”v3Deployer”,”type”:”address”},{“internalType”:”bytes32″,”name”:”v2InitCodeHash”,”type”:”bytes32″},{“internalType”:”bytes32″,”name”:”v3InitCodeHash”,”type”:”bytes32″},{“internalType”:”address”,”name”:”stableFactory”,”type”:”address”},{“internalType”:”address”,”name”:”stableInfo”,”type”:”address”},{“internalType”:”address”,”name”:”pancakeNFTMarket”,”type”:”address”}],”internalType”:”struct RouterParameters”,”name”:”params”,”type”:”tuple”}],”stateMutability”:”nonpayable”,”type”:”constructor”},{“inputs”:[],”name”:”BalanceTooLow”,”type”:”error”},{“inputs”:[],”name”:”BuyPancakeNFTFailed”,”type”:”error”},{“inputs”:[],”name”:”BuyPunkFailed”,”type”:”error”},{“inputs”:[],”name”:”ContractLocked”,”type”:”error”},{“inputs”:[],”name”:”ETHNotAccepted”,”type”:”error”},{“inputs”:[{“internalType”:”uint256″,”name”:”commandIndex”,”type”:”uint256″},{“internalType”:”bytes”,”name”:”message”,”type”:”bytes”}],”name”:”ExecutionFailed”,”type”:”error”},{“inputs”:[],”name”:”FromAddressIsNotOwner”,”type”:”error”},{“inputs”:[],”name”:”InsufficientETH”,”type”:”error”},{“inputs”:[],”name”:”InsufficientToken”,”type”:”error”},{“inputs”:[],”name”:”InvalidBips”,”type”:”error”},{“inputs”:[{“internalType”:”uint256″,”name”:”commandType”,”type”:”uint256″}],”name”:”InvalidCommandType”,”type”:”error”},{“inputs”:[],”name”:”InvalidOwnerERC1155″,”type”:”error”},{“inputs”:[],”name”:”InvalidOwnerERC721″,”type”:”error”},{“inputs”:[],”name”:”InvalidPath”,”type”:”error”},{“inputs”:[],”name”:”InvalidPoolAddress”,”type”:”error”},{“inputs”:[],”name”:”InvalidPoolLength”,”type”:”error”},{“inputs”:[],”name”:”InvalidReserves”,”type”:”error”},{“inputs”:[],”name”:”InvalidSpender”,”type”:”error”},{“inputs”:[],”name”:”LengthMismatch”,”type”:”error”},{“inputs”:[],”name”:”SliceOutOfBounds”,”type”:”error”},{“inputs”:[],”name”:”StableInvalidPath”,”type”:”error”},{“inputs”:[],”name”:”StableTooLittleReceived”,”type”:”error”},{“inputs”:[],”name”:”StableTooMuchRequested”,”type”:”error”},{“inputs”:[],”name”:”TransactionDeadlinePassed”,”type”:”error”},{“inputs”:[],”name”:”UnableToClaim”,”type”:”error”},{“inputs”:[],”name”:”UnsafeCast”,”type”:”error”},{“inputs”:[],”name”:”V2InvalidPath”,”type”:”error”},{“inputs”:[],”name”:”V2TooLittleReceived”,”type”:”error”},{“inputs”:[],”name”:”V2TooMuchRequested”,”type”:”error”},{“inputs”:[],”name”:”V3InvalidAmountOut”,”type”:”error”},{“inputs”:[],”name”:”V3InvalidCaller”,”type”:”error”},{“inputs”:[],”name”:”V3InvalidSwap”,”type”:”error”},{“inputs”:[],”name”:”V3TooLittleReceived”,”type”:”error”},{“inputs”:[],”name”:”V3TooMuchRequested”,”type”:”error”},{“anonymous”:false,”inputs”:[{“indexed”:true,”internalType”:”address”,”name”:”previousOwner”,”type”:”address”},{“indexed”:true,”internalType”:”address”,”name”:”newOwner”,”type”:”address”}],”name”:”OwnershipTransferred”,”type”:”event”},{“anonymous”:false,”inputs”:[{“indexed”:false,”internalType”:”address”,”name”:”account”,”type”:”address”}],”name”:”Paused”,”type”:”event”},{“anonymous”:false,”inputs”:[{“indexed”:false,”internalType”:”uint256″,”name”:”amount”,”type”:”uint256″}],”name”:”RewardsSent”,”type”:”event”},{“anonymous”:false,”inputs”:[{“indexed”:true,”internalType”:”address”,”name”:”factory”,”type”:”address”},{“indexed”:true,”internalType”:”address”,”name”:”info”,”type”:”address”}],”name”:”SetStableSwap”,”type”:”event”},{“anonymous”:false,”inputs”:[{“indexed”:false,”internalType”:”address”,”name”:”account”,”type”:”address”}],”name”:”Unpaused”,”type”:”event”},{“inputs”:[{“internalType”:”bytes”,”name”:”looksRareClaim”,”type”:”bytes”}],”name”:”collectRewards”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[{“internalType”:”bytes”,”name”:”commands”,”type”:”bytes”},{“internalType”:”bytes[]”,”name”:”inputs”,”type”:”bytes[]”}],”name”:”execute”,”outputs”:[],”stateMutability”:”payable”,”type”:”function”},{“inputs”:[{“internalType”:”bytes”,”name”:”commands”,”type”:”bytes”},{“internalType”:”bytes[]”,”name”:”inputs”,”type”:”bytes[]”},{“internalType”:”uint256″,”name”:”deadline”,”type”:”uint256″}],”name”:”execute”,”outputs”:[],”stateMutability”:”payable”,”type”:”function”},{“inputs”:[{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”uint256[]”,”name”:””,”type”:”uint256[]”},{“internalType”:”uint256[]”,”name”:””,”type”:”uint256[]”},{“internalType”:”bytes”,”name”:””,”type”:”bytes”}],”name”:”onERC1155BatchReceived”,”outputs”:[{“internalType”:”bytes4″,”name”:””,”type”:”bytes4″}],”stateMutability”:”pure”,”type”:”function”},{“inputs”:[{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”uint256″,”name”:””,”type”:”uint256″},{“internalType”:”uint256″,”name”:””,”type”:”uint256″},{“internalType”:”bytes”,”name”:””,”type”:”bytes”}],”name”:”onERC1155Received”,”outputs”:[{“internalType”:”bytes4″,”name”:””,”type”:”bytes4″}],”stateMutability”:”pure”,”type”:”function”},{“inputs”:[{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”address”,”name”:””,”type”:”address”},{“internalType”:”uint256″,”name”:””,”type”:”uint256″},{“internalType”:”bytes”,”name”:””,”type”:”bytes”}],”name”:”onERC721Received”,”outputs”:[{“internalType”:”bytes4″,”name”:””,”type”:”bytes4″}],”stateMutability”:”pure”,”type”:”function”},{“inputs”:[],”name”:”owner”,”outputs”:[{“internalType”:”address”,”name”:””,”type”:”address”}],”stateMutability”:”view”,”type”:”function”},{“inputs”:[{“internalType”:”int256″,”name”:”amount0Delta”,”type”:”int256″},{“internalType”:”int256″,”name”:”amount1Delta”,”type”:”int256″},{“internalType”:”bytes”,”name”:”data”,”type”:”bytes”}],”name”:”pancakeV3SwapCallback”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[],”name”:”pause”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[],”name”:”paused”,”outputs”:[{“internalType”:”bool”,”name”:””,”type”:”bool”}],”stateMutability”:”view”,”type”:”function”},{“inputs”:[],”name”:”renounceOwnership”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[{“internalType”:”address”,”name”:”_factory”,”type”:”address”},{“internalType”:”address”,”name”:”_info”,”type”:”address”}],”name”:”setStableSwap”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[],”name”:”stableSwapFactory”,”outputs”:[{“internalType”:”address”,”name”:””,”type”:”address”}],”stateMutability”:”view”,”type”:”function”},{“inputs”:[],”name”:”stableSwapInfo”,”outputs”:[{“internalType”:”address”,”name”:””,”type”:”address”}],”stateMutability”:”view”,”type”:”function”},{“inputs”:[{“internalType”:”bytes4″,”name”:”interfaceId”,”type”:”bytes4″}],”name”:”supportsInterface”,”outputs”:[{“internalType”:”bool”,”name”:””,”type”:”bool”}],”stateMutability”:”pure”,”type”:”function”},{“inputs”:[{“internalType”:”address”,”name”:”newOwner”,”type”:”address”}],”name”:”transferOwnership”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“inputs”:[],”name”:”unpause”,”outputs”:[],”stateMutability”:”nonpayable”,”type”:”function”},{“stateMutability”:”payable”,”type”:”receive”}]’

senderaddress = ‘0x4182692466cF31f1EdbF6E06A7181CF0450F0fe6’

balance = web3.eth.get_balance(senderaddress)

humanReadable = web3.from_wei(balance,’ether’)

tokenToBuy = web3.to_checksum_address(input(“Enter TokenAddress: “))
spend = web3.to_checksum_address(‘0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd’)

contract = web3.eth.contract(address=panRouterContractAddress, abi=panabi)

nonce = web3.eth.get_transaction_count(senderaddress)

start = time.time()

pancakeswap2_txn = contract.function.execute(senderaddress,[spend,tokenToBuy],

(int(time.time()) + 10000)
).build_transaction({
‘from’: senderaddress,
‘value’: web3.to_wei(0.0354829243424823411,’ether’),
‘gas’: 250000,
‘gasPrice’: web3.to_wei(‘5′,’gwei’),
‘nonce’:nonce,
})

def monkey(private):
signed_txn = web3.eth.account.sign_transaction(dict(pancakeswap2_txn, private_key=config.private))
tx_hash = web3.eth.send_raw_transaction(signed_txn.rawTransaction)

print(web3.to_hex(tx_hash))

#swapExactETHForTokens
#toHex #to_hex

`

Control text opacity based on scroll using javascript

I have a div with two spans inside it. The position of spans is that span1 uses a sticky position from the center of the div while span2 is at the bottom of the div. The idea is that, as the user scrolls, span1, which is initially at opacity 0 becomes visible and after further scrolling, span2 becomes visible. I tried achieving this by manually tweaking the points they become visible. Is there an optimal way to achieve this? I am attaching my code as reference

window.addEventListener('scroll', function() {
  const message = document.querySelector('.message');
  const deathSpan = document.querySelector('.message > span');
  const vhDiv = document.querySelector('.vh');

  const rect = message.getBoundingClientRect();
  const windowHeight = window.innerHeight;


  const fadeStart1 = windowHeight * 0.3;
  const fadeEnd1 = windowHeight * 0.6;


  const fadeStart2 = windowHeight * 0.5;
  const fadeEnd2 = windowHeight * 0.9;


  if (rect.top <= fadeEnd1 && rect.bottom >= fadeStart1) {
    let opacity1 = (fadeEnd1 - rect.top) / (fadeEnd1 - fadeStart1);
    opacity1 = Math.min(Math.max(opacity1, 0), 1);
    deathSpan.style.opacity = opacity1;
  } else {
    deathSpan.style.opacity = 0;
  }


  if (rect.top <= fadeEnd2 && rect.bottom >= fadeStart2) {
    let opacity2 = (fadeEnd2 - rect.top) / (fadeEnd2 - fadeStart2);
    opacity2 = Math.min(Math.max(opacity2, 0), 1);
    vhDiv.style.opacity = opacity2;
  } else {
    vhDiv.style.opacity = 0;
  }
});
.above-divs a{
font-size:10rem;
background-color: black;
color: white;

}


.message {
  width: 100%;
  height: 150vh;
  display: flex;
  position: relative;
  background-color: rgb(0, 0, 0);
  align-items: center;
}

.message span {
  font-size: 10vw;
  color: rgb(255, 255, 255);
}

.message>span {
  position: sticky;
  top: 50%;
  opacity: 0;
  transition: opacity 0.5s ease;
}

.vh {
  position: absolute;
  bottom: 0;
  right: 10%;
  opacity: 0;
  transition: opacity 0.5s ease;
}
<div class="above-divs">
  <a href="">hello</a>
</div>



<div class="message">
  <span>Text1 (span1)</span>
  <div class="vh">
    <span>Text2 (span2)</span>
  </div>
</div>

How to change a JavaScript value through HTML button? [closed]

I’m making a typing game and I need the user to be able to change the timer’s time using a button. ’30’ changes the timer to 30s, ’60’ changes the timer to 60s, so and so on.

JS:
var gameTime = (30) * 1000;
changing the value in the brackets changes the timer’s time(s).

HTML:
<button id=thirty type="submit" onClick="onClick=myFunction(this.value)">30s</button>
planning on having about 3 or 4 timer options.

How do I create a function in JS that does this? I would also need it to change the HTML title (>30s<) to its respected value.

How to search for all zip codes within a radius (in miles) using latitude, longitude, and an API for the US? [closed]

I’m working on a project where I need to find all zip codes within a specified radius (in miles) from a given location defined by latitude and longitude in the US. The input will consist of:

Latitude
Longitude
Radius (in miles)
I need to retrieve a list of zip codes that fall within that radius.

I’ve explored various options but haven’t found a dedicated API from Google that allows for this type of search based on coordinates and radius. Does Google offer any API that can achieve this? If not, are there any other reliable sources or APIs that provide this information specifically for the US?

Requirements:

  1. The solution should return all zip codes within the specified radius based on the provided latitude and longitude.
  2. The radius unit should be in miles.
  3. The solution should be specific to the United States.

What I’ve Tried:

  1. Investigated Google Maps Geocoding API, but it seems to focus more
    on individual locations rather than retrieving bulk postal code data based on coordinates.
  2. Looked into Google Places API, but I couldn’t determine how to
    implement radius-based postal code searches.
  3. Downloaded a list of zip codes along with their latitude and
    longitude from an online source, but I’m uncertain about the
    accuracy and completeness of this data.

Questions:

  1. Is there a way to achieve this using Google APIs?
  2. If Google APIs are not suitable, what are some authentic sources or APIs that specialize in US postal code data and support radius-based searches?
  3. How can I validate the accuracy of the downloaded zip code data with latitude and longitude?

Freeze all windows/apps and just show the electron.js app fullcsreen

I am trying to build a desktop app using electron.js. I want it to behave something similar to how online test taking applications are, where user can access nothing but only that test app, except that this behavior should be happening for my electron app. I want this freeze to toggle on click of a button in my app.

After getting some code from AI assistant, I got this, but it ain’t working and being a novice in Electron.js I am unable to move ahead.

Index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
  <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  <title>Hello World!</title>
</head>

<body>
  <h1>Block Other Applications</h1>
  <button id="blockButton">Block Other Apps</button>

  <!-- You can also require other files to run in this process -->
  <script>
    const { ipcRenderer } = require('electron');

    document.getElementById('blockButton').onclick = () => {
      alert('Blocking!')
      ipcRenderer.send('block-apps');
    };
  </script>
</body>

</html>

main.js

const path = require('node:path')

app.whenReady().then(createMainWindow);

ipcMain.on('block-apps', (event) => {
  createOverlayWindow();
});

ipcMain.on('restore-apps', (event) => {
  if (overlayWindow) {
    overlayWindow.close();
    overlayWindow = null;
  }
});

app.on('window-all-closed', () => {
  app.quit();
});

//Code to create an overlay
let mainWindow;
let overlayWindow;

function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  });

  mainWindow.loadFile('index.html');
}

function createOverlayWindow() {
  overlayWindow = new BrowserWindow({
    width: 1920, // Set based on your screen resolution
    height: 1200, // Set based on your screen resolution
    frame: false,
    transparent: true,
    alwaysOnTop: true,
    resizable: false,
    movable: false,
    fullscreen: true,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  });

  overlayWindow.loadFile('overlay.html');
}

overlay.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Overlay</title>
  <style>
    body {
      background-color: rgba(0, 0, 0, 0.8);
      color: white;
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100vh;
      font-size: 2em;
    }
  </style>
</head>
<body>
  <div>
    Other applications are blocked.
    <br><br>
    <button id="restoreButton">Restore Access</button>
  </div>

  <script>
    const { ipcRenderer } = require('electron');

    document.getElementById('restoreButton').onclick = () => {
      ipcRenderer.send('restore-apps');
    };
  </script>
</body>
</html>

Javascript Connect Four game doesn’t check for a winner diagonally

I’ve created the below Connect Four game using JavaScript/jQuery but the code isn’t stopping when a player chooses 4 spaces diagonally. It doesn’t show the congratulations message and it doesn’t stop the players from playing further. There are no error messages in the console log, so I don’t see why its not working as it should.

$(document).ready(function() {

  var player1Name = "";
  var player2Name = "";
  var turn = "";
  var grid = [
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0],
    [0, 0, 0, 0, 0, 0, 0]
  ];
  var hasWinner = 0;
  var moveCount = 0;
  var i = 0;
  var x = 0;
  var y = 0;

  function boardMsg(x) { // Display message function.
    return $("#message_area").text(x);
  }

  function setTurn() { // Randomly select a player to go first.
    var r = Math.floor((Math.random() * 2) + 1);
    hasWinner = 0;
    if (r == 1) {
      turn = player1Name;
      boardMsg("It's " + player1Name + "'s turn.");
    } else {
      turn = player2Name;
      boardMsg("It's " + player2Name + "'s turn.");
    }
  }

  function init() { // Initialise the grid.
    turn = "";
    grid = [
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0],
      [0, 0, 0, 0, 0, 0, 0]
    ];
    boardMsg("");
    $(".col").map(function() {
      $(this).removeClass("player1 player2");
    }).get();
    hasWinner = 0;
    moveCount = 0;
  }

  $("#playButton").click(function() { // Start a new game.
    if (hasWinner == 1) {
      init();
    }
    player1Name = $("#player-1-inp").val();
    player2Name = $("#player-2-inp").val();
    if (player1Name == "" || player2Name == "") {
      $("<div>Please enter player names.</div>").dialog({
        title: "ALERT!"
      });
      return;
    }
    setTurn();
  });

  $(".col").click(function() { // Process mouse clicks for both players.
    player1Name = $("#player-1-inp").val();
    player2Name = $("#player-2-inp").val();
    if (player1Name == "" || player2Name == "") {
      $("<div>Please enter player names.</div>").dialog({
        title: "ALERT!"
      });
      return;
    }
    var row = $(this).parent().index();
    var col = $(this).index();
    if (grid[row][col] !== 0) {
      $("<div>This position has already been filled.</div>").dialog({
        title: "ALERT!"
      });
      return;
    }
    if (hasWinner == 1) {
      $("<div>To start another game, click Play again.</div>").dialog({
        title: "CONGRATULATIONS!"
      });
      return;
    }
    if (turn == player1Name) {
      moveCount++;
      $(this).addClass("player1");
      grid[row][col] = 1;
      var ifWon = winnerCheck(1, player1Name);
      if (!ifWon) {
        if (moveCount >= 49) {
          boardMsg("Match Drawn!");
          moveCount = 0;
          hasWinner = 1;
          $("<div>To start a new game, click the Play button.</div>").dialog({
            title: "MATCH DRAWN!"
          });
          return;
        } else {
          turn = player2Name;
          boardMsg("It's " + player2Name + "'s turn.");
        }
        return;
      } else {
        return;
      }
    } else if (turn == player2Name) {
      moveCount++;
      $(this).addClass("player2");
      grid[row][col] = 2;
      var ifWon = winnerCheck(2, player2Name);
      if (!ifWon) {
        if (moveCount >= 49) {
          boardMsg("Match Drawn!");
          moveCount = 0;
          hasWinner = 1;
          $("<div>To start a new game, click the Play button.</div>").dialog({
            title: "MATCH DRAWN!"
          });
          return;
        } else {
          turn = player1Name;
          boardMsg("It's " + player1Name + "'s turn.");
        }
        return;
      } else {
        return;
      }
    }
  });

  function winnerCheck(n, playerName) { // Check for winner.
    for (i = 0; i < 7; i++) { // check for winner by row.
      if (
        (grid[i][0] == n && grid[i][1] == n && grid[i][2] == n && grid[i][3] == n) ||
        (grid[i][1] == n && grid[i][2] == n && grid[i][3] == n && grid[i][4] == n) ||
        (grid[i][2] == n && grid[i][3] == n && grid[i][4] == n && grid[i][5] == n) ||
        (grid[i][3] == n && grid[i][4] == n && grid[i][5] == n && grid[i][6] == n)) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    for (i = 0; i < 7; i++) { // check for winner by column.
      if (
        (grid[0][i] == n && grid[1][i] == n && grid[2][i] == n && grid[3][i] == n) ||
        (grid[1][i] == n && grid[2][i] == n && grid[3][i] == n && grid[4][i] == n) ||
        (grid[2][i] == n && grid[3][i] == n && grid[4][i] == n && grid[5][i] == n) ||
        (grid[3][i] == n && grid[4][i] == n && grid[5][i] == n && grid[6][i] == n)) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    // diagonal winner forwards
    if (x < 4 && y < 4) {
      if (grid[x][y] == n && grid[x + 1][y + 1] == n && grid[x + 2][y + 2] == n && grid[x + 3][y + 3] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x < 5 && x > 0 && y < 5 && y > 0) {
      if (grid[x][y] == n && grid[x + 1][y + 1] == n && grid[x + 2][y + 2] == n && grid[x - 1][y - 1] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x < 6 && x > 1 && y < 6 && y > 1) {
      if (grid[x][y] == n && grid[x + 1][y + 1] == n && grid[x - 1][y - 1] == n && grid[x - 2][y - 2] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x > 2 && y > 2) {
      if (grid[x][y] == n && grid[x - 1][y - 1] == n && grid[x - 2][y - 2] == n && grid[x - 3][y - 3] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    // diagonal winner backwards
    if (x < 4 && y > 2) {
      if (grid[x][y] == n && grid[x + 1][y - 1] == n && grid[x + 2][y - 2] == n && grid[x + 3][y - 3] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x > 0 && x < 6 && y < 5 && y > 0) {
      if (grid[x][y] == n && grid[x + 1][y - 1] == n && grid[x + 2][y - 2] == n && grid[x - 1][y + 1] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x > 1 && x < 5 && y < 4 && y > 1) {
      if (grid[x][y] == n && grid[x + 1][y - 1] == n && grid[x - 2][y + 2] == n && grid[x - 1][y + 1] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }

    if (x > 2 && y < 4) {
      if (grid[x][y] == n && grid[x - 3][y + 3] == n && grid[x - 2][y + 2] == n && grid[x - 1][y + 1] == n) {
        boardMsg("Congratulations " + playerName + " you have won!");
        hasWinner = 1;
        moveCount = 0;
        $("<div>To start a new game, click the Play button.</div>").dialog({
          title: "CONGRATULATIONS!"
        });
        return true;
      }
    }
    return false;
  }
});
<h1> Connect Four </h1>
<div id="game_board">
  <div class="row">
    <div class="col" id="0"> </div>
    <div class="col" id="1"> </div>
    <div class="col" id="2"> </div>
    <div class="col" id="3"> </div>
    <div class="col" id="4"> </div>
    <div class="col" id="5"> </div>
    <div class="col" id="6"> </div>
  </div>
  <div class="row">
    <div class="col" id="7"> </div>
    <div class="col" id="8"> </div>
    <div class="col" id="9"> </div>
    <div class="col" id="10"> </div>
    <div class="col" id="11"> </div>
    <div class="col" id="12"> </div>
    <div class="col" id="13"> </div>
  </div>
  <div class="row">
    <div class="col" id="14"> </div>
    <div class="col" id="15"> </div>
    <div class="col" id="16"> </div>
    <div class="col" id="17"> </div>
    <div class="col" id="18"> </div>
    <div class="col" id="19"> </div>
    <div class="col" id="20"> </div>
  </div>
  <div class="row">
    <div class="col" id="21"> </div>
    <div class="col" id="22"> </div>
    <div class="col" id="23"> </div>
    <div class="col" id="24"> </div>
    <div class="col" id="25"> </div>
    <div class="col" id="26"> </div>
    <div class="col" id="27"> </div>
  </div>
  <div class="row">
    <div class="col" id="28"> </div>
    <div class="col" id="29"> </div>
    <div class="col" id="30"> </div>
    <div class="col" id="31"> </div>
    <div class="col" id="32"> </div>
    <div class="col" id="33"> </div>
    <div class="col" id="34"> </div>
  </div>
  <div class="row">
    <div class="col" id="35"> </div>
    <div class="col" id="36"> </div>
    <div class="col" id="37"> </div>
    <div class="col" id="38"> </div>
    <div class="col" id="39"> </div>
    <div class="col" id="40"> </div>
    <div class="col" id="41"> </div>
  </div>
  <div class="row">
    <div class="col" id="42"> </div>
    <div class="col" id="43"> </div>
    <div class="col" id="44"> </div>
    <div class="col" id="45"> </div>
    <div class="col" id="46"> </div>
    <div class="col" id="47"> </div>
    <div class="col" id="48"> </div>
  </div>
</div>
<div id="panel">
  <input type="text" id="player-1-inp" placeholder="Player 1 Name">
  <input type="text" id="player-2-inp" placeholder="Player 2 Name">
  <button id="playButton">PLAY</button>
  <div id="message_area">
  </div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>

Would someone be able to help me and let me know what’s wrong with my code please?

Javascript simulate click on Button [closed]

I want that my code is clicking the first button on an ul item.

Here is what i found and tried, but its not working…

   let player_input = document.querySelectorAll('ul.playerResultsList button')[0];
   custom_event = new Event('click');
   player_input.dispatchEvent(custom_event);
   custom_event = new PointerEvent('click');
   player_input.dispatchEvent(custom_event);
   custom_event = new MouseEvent('click');
   player_input.dispatchEvent(custom_event);

does anyone have an idea? I also tried click() as well.

The page has an input field. When i type in few letters, than it shows some finds.
I can now click one i want, and than its done.

But now i want to click it automatically the first item but my code does not work.

This is how the HTML Element looks like

<ul class="ut-button-group playerResultsList">
      <button class=""><span class="btn-text">row 1</span><span class="btn-subtext">89</span></button>
      <button class=""><span class="btn-text">row 2</span><span class="btn-subtext">73</span></button>
      <button class=""><span class="btn-text">row 3</span><span class="btn-subtext">72</span></button>
      <button><span class="btn-text">row 4</span><span class="btn-subtext">72</span></button>
      <button class=""><span class="btn-text">row 5</span><span class="btn-subtext">70</span>  </button>
   </ul>

I tried dispatchEvents but that is not working. Also click() does not work

Blocking Specific Days for Events

Can we block specific days (eg.: Mondays,Wednesdays and Fridays for some Events) while enabling them on other days of the week (eg.:Tuesdays,Thursdays and Saturdays)?

  • We see that weekends can be turned off in the Calendar configuration. But we need more flexibility like blocking public holidays or alternate days.

I tried this script,but instead of blocking displayed days it block all the days.
We expect only to block (‘Monday’,’Wednesday’,’Friday’)

function(options) {
    options.eventConstraint = "businessHours";
    options.selectConstraint = "businessHours";
    options.businessHours = [{ 
        daysOfWeek: [ 2, 6, 4 ],
        startTime: '10:00:00',
        endTime: '13:00:00'
    }]
    return options;
}

Want to stop all internal redirection on webpage (on the same domain) [closed]

So, I am on a webpage. And very annoyingly, even when I type the exact URL of that page it redirects me to another page on the same domain/website . I don’t want to block that page’s JS (as it relies on JS to work), I just want it to stop redirecting me. It typically takes 1 – 2 seconds to realize that it has to redirect me.

Is there some solution for this? If the solution is any software, then also I am open towards it. Thanks in advance.

Blocking Specific Days in Oracle APEX Calendar for Events

Can we block specific days (eg.: Mondays,Wednesdays and Fridays for some Events) while enabling them on other days of the week (eg.:Tuesdays,Thursdays and Saturdays)?

  • We see that weekends can be turned off in the Calendar configuration. But we need more flexibility like blocking public holidays or alternate days.

I tried this script,but instead of blocking displayed days it block all the days.
We expect only to block(‘Monday’,’Wednesday’,’Friday’)
`function(options) {
options.eventConstraint = “businessHours”;
options.selectConstraint = “businessHours”;
options.businessHours = [{ daysOfWeek: [ 2, 6, 4 ],
startTime: ’10:00:00′,
endTime: ’13:00:00′
}]
return options;
}’

Want to stop all internal redirection on webpage (on the same domain)

So, I am on a webpage. And very annoyingly, even when I type the exact URL of that page it redirects me to another page on the same domain/website . I don’t want to block that page’s JS (as it relies on JS to work), I just want it to stop redirecting me. It typically takes 1 – 2 seconds to realize that it has to redirect me.

Is there some solution for this? If the solution is any software, then also I am open towards it. Thanks in advance.

Understanding UTC time in js

Backend give me data of gantt diagramm start and end points in format:

“horizont_start”: “2024-05-01T00:00:00Z”,
“horizont_end”: “2025-01-26T00:00:00Z”,

Next i give through props to another component Date format of this points like this:

  <NewGanttChart
                                        start={
                                            new Date(
                                                gantt?.horizont_start ||
                                                    new Date(
                                                        new Date().getFullYear(),
                                                        0,
                                                        1
                                                    )
                                            )
                                        }
                                        end={
                                            new Date(
                                                gantt?.horizont_end ||
                                                    new Date()
                                            )
                                        }
                                        data={gantt?.machine_types || []}
                                        isTooltip={true}
                                        tooltip={tooltip}
                                    />

in component i use function to calculate timeAxis intervals:

//also save in store start and end time
useEffect(() => {
        dispatch(setStartTime(start?.getTime()))
        dispatch(setEndTime(end?.getTime()))
    }, [start, end])
 const timeAxis = useMemo(() => {
       
        const axisLength = Math.ceil((end - start) / (measure * 60 * 60 * 1000))

        const axisDates = new Array(axisLength).fill(0).map((_, i) => {
            const date = new Date(start.getTime())
            const newDate = new Date(+date + 1000 * 60 * 60 * measure * i)

            return newDate.getTime()
        })

        console.log(axisDates)

        return axisDates
    }, [end, measure, start])

My main problem is local time, so i want to show start point time 00:00:00, but i got +5h 05:00:00, how to solve this problem?

How prevent moving of tables header while scrolling?

The header little moving up and down while vertical scrolling. I can`t use CSS sticky bacause my parent has horizintal sroll. Keep position of the header on the top of page while scrolling page (vertically).

Is it possible to do it?

const table = document.querySelector('.table');
const header = document.querySelector('.table header');

window.addEventListener('scroll', function() {
  const tableRect = table.getBoundingClientRect();
  const headerRect = header.getBoundingClientRect();

  // Проверяем, когда шапка должна прилипнуть к верхней части экрана
  if (tableRect.top < 0 && tableRect.bottom > headerRect.height) {
    const topOffset = Math.abs(tableRect.top);
    header.style.transform = `translateY(${topOffset}px)`; // Используем translateY для плавного перемещения
    //header.classList.add('header-fixed'); // Добавляем класс при фиксации
  } else {
    header.style.transform = `translateY(0px)`; // Сброс перемещения
  //  header.classList.remove('header-fixed'); // Убираем класс, если шапка не фиксируется
  }
});
.mobile-container {
 background-color: ;
  width: 30%;
   border: 1px solid red;
  display:flex;
  flex-direction: column;
    align-items: center;
  position:relative;
}

h1 {
  text-align: center;
}

.table {
  display: grid; /* если поменять на table пропадает горизонтальный скрол, зато шапка таблицы фиксируется наверху */
  overflow-x: auto;
  border: 1px solid #DCDCDC;
  border-radius: 0.5rem;
  width: 90%;
box-sizing: border-box;
  position: relative;

}



.table header {
  height: 2.625rem;
   display: grid;
  padding: 0.6875rem 1.25rem;
  color: #8C8C8C;
  border-bottom: 1px solid #DCDCDC;
  box-sizing: border-box;
  background: #FAFAFA;
  grid-template-columns: repeat(2, 15rem) repeat(2, 5rem);
  white-space: nowrap;

      column-gap: 1rem;
 
  z-index:10;
  top: 0;
  position: sticky; /* Используем позицию sticky */

  width: 100%;
  
 /*transition: transform 0.16s linear, opacity 0.16s linear; */


  div:nth-child(1) {
        display: none;
      }
  
}

.table main {
  > div {
    display: grid;
      grid-template-columns: repeat(2, 15rem) 6rem;
      row-gap: 0.25rem;
      column-gap: 1rem;
      padding: 0.5rem 1.25rem;
border: 1px solid #DCDCDC;
    box-sizing: border-box;
    
    div:first-child {
        grid-column: 1 / -1;
        position: sticky;
        left: 1.25rem;
        z-index: 1;
        white-space: nowrap;
        width: min-content;
      }
    
  }
  
  
}
<div class="mobile-container">
  <h1>Мобильная версия</h1>

<div class="table">
 
  <header>
    <div>Название</div>
    <div>Описание</div>
    <div>Цена</div>
    <div>Количество</div>
  </header>
   
  <main>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>
    <div>
      <div>Телевизор</div>
      <div>Большой цветной телевизор</div>
      <div>1000р</div>
      <div>10 штук</div>
    </div>

    <main>
      </div>
    
    </div>